🎉 75% of content is free forever — Unlock Premium from $10/mo →
CW
đŸ’ŧ Servicesâ„šī¸ Aboutâœ‰ī¸ ContactView Pricing Plansfrom $10

Model Parallelism and Tensor Parallelism

Inference OptimizationParallel InferenceđŸŸĸ Free Lesson

Advertisement

Inference Optimization

Model Parallelism for Inference — Serving Models Too Large for One GPU

When a model exceeds single-GPU memory, model parallelism splits it across multiple GPUs. This guide covers tensor parallelism, pipeline parallelism, and hybrid strategies for inference.

  • Tensor Parallelism — Split individual layers across GPUs
  • Pipeline Parallelism — Split model stages across GPUs
  • Expert Parallelism — Distribute MoE experts across GPUs

The model does not care how many GPUs it runs on — it only cares about serving responses.

Model Parallelism for LLM Inference

Modern LLMs like LLaMA-2 70B (140GB in FP16) and GPT-4 (~360GB) exceed the memory of any single GPU. Model parallelism distributes the model across multiple GPUs to enable inference on models that cannot fit in one device.

Tensor Parallelism for Inference

How It Works

Tensor Parallelism — Column SplitXW = [W₀ | W₁](column-split across GPUs)GPU 0: Y₀ = X @ W₀(first half columns)GPU 1: Y₁ = X @ W₁(second half columns)ConcatY = [Y₀|Y₁]
import torch.distributed as dist
from torch.distributed.tensor.parallel import parallelize_module, ColwiseParallel, RowwiseParallel

def tensor_parallel_inference(model, world_size):
    """Apply tensor parallelism for inference."""
    # Define parallel plan
    tp_plan = {
        "self_attn.q_proj": ColwiseParallel(),
        "self_attn.k_proj": ColwiseParallel(),
        "self_attn.v_proj": ColwiseParallel(),
        "self_attn.o_proj": RowwiseParallel(),
        "mlp.gate_proj": ColwiseParallel(),
        "mlp.up_proj": ColwiseParallel(),
        "mlp.down_proj": RowwiseParallel(),
    }
    
    # Parallelize the model
    model = parallelize_module(model, tp_plan)
    return model

Communication Pattern

Pipeline Parallelism for Inference

How It Works

Pipeline Parallelism — InferenceGPU 0: Layers 0-19KV cache 0-19GPU 1: Layers 20-39KV cache 20-39GPU 2: Layers 40-59KV cache 40-59GPU 3: Layers 60-79Final outputRequest Flow:Request 1GPU0GPU1GPU2GPU3ResponseRequest 2GPU0GPU1GPU2GPU3ResponseRequest 3GPU0GPU1GPU2GPU3ResponseTokens flow sequentially through pipeline stages

Hybrid Parallelism

TP + PP Combination

Hybrid TP=2, PP=4 on 8 GPUsPipeline Stage 0GPU0 (TP rank 0)GPU1 (TP rank 1)Layers 0-19Pipeline Stage 1GPU2 (TP rank 0)GPU3 (TP rank 1)Layers 20-39Pipeline Stage 2GPU4 (TP rank 0)GPU5 (TP rank 1)Layers 40-59Pipeline Stage 3GPU6 (TP rank 0)GPU7 (TP rank 1)Layers 60-79TP=2 (intra-stage)TP=2 (intra-stage)TP=2 (intra-stage)TP=2 (intra-stage)Memory per GPU:GPU 0-1: Layers 0-19GPU 2-3: Layers 20-39GPU 4-5: Layers 40-59GPU 6-7: Layers 60-79TP reduces latency within stages, PP distributes memory across stages

Expert Parallelism for MoE Models

def expert_parallel_forward(x, expert_indices, expert_params):
    """Forward pass with expert parallelism."""
    # Route tokens to appropriate GPUs
    local_experts = [i for i in range(num_experts) if expert_owner[i] == local_rank]
    
    # Gather tokens for local experts
    local_tokens = all_to_all_dispatch(x, expert_indices, local_experts)
    
    # Compute local expert outputs
    local_outputs = []
    for expert_id in local_experts:
        expert_output = expert_forward(local_tokens[expert_id], expert_params[expert_id])
        local_outputs.append(expert_output)
    
    # Scatter outputs back
    output = all_to_all_combine(local_outputs, expert_indices)
    return output

Serving Frameworks

Tensor Parallelism in Practice

FrameworkTP SupportMax TPCommunicationNotes
vLLMYes8 GPUsNCCLBest for general serving
TensorRT-LLMYes8 GPUsNCCLFastest inference
SGLangYes8 GPUsNCCLBest for structured generation
TGIYes8 GPUsNCCLProduction-ready

Loading Models with TP

# vLLM tensor parallel serving
from vllm import LLM, SamplingParams

# Serve LLaMA-2 70B with TP=2
llm = LLM(
    model="meta-llama/Llama-2-70b-chat-hf",
    tensor_parallel_size=2,
    gpu_memory_utilization=0.9,
    max_model_len=4096,
)

# Generate
sampling_params = SamplingParams(temperature=0.7, max_tokens=512)
outputs = llm.generate(["What is machine learning?"], sampling_params)

Communication Optimization

Overlapping Communication and Computation

def overlapped_tp_forward(layer, x, comm_group):
    """Tensor parallel forward with communication overlap."""
    # Start async reduce-scatter for previous layer output
    handle = dist.reduce_scatter_async(x, group=comm_group, async_op=True)
    
    # Compute current layer while communication proceeds
    output = layer(x)
    
    # Wait for communication to complete
    handle.wait()
    return output

Practice Exercises

  1. Parallelism Design: Design a parallelism strategy for serving a 405B parameter model on 16 GPUs. Justify your choice of TP and PP degrees.

  2. Latency Analysis: Calculate the inference latency for a 70B model with TP=2 vs TP=4 on 4 GPUs. Assume 100GB/s interconnect bandwidth.

  3. Memory Analysis: If a 70B model requires 140GB in FP16, how much memory does each GPU need with TP=2, TP=4, and TP=8?

  4. Communication Volume: For a 70B model with TP=4, calculate the total communication volume per token generation step.

Key Takeaways


What to Learn Next

-> Distributed Training for LLMs Parallelism strategies for training.

-> Mixture of Experts MoE architectures and expert routing.

-> Flash Attention and Memory Efficiency IO-aware attention algorithms.

-> KV Cache Optimization Reducing memory usage of the key-value cache.

-> LLM Inference Optimization Broader inference optimization strategies.

-> Building Production LLM Applications End-to-end production systems.

Need Expert LLM Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement