06.01 · Concept · Free
When One GPU Is Not Enough
Name the three separate reasons to shard: the weights do not fit, the KV cache does not fit, or the latency target is below what one device can reach. Recognise that they call for different strategies.
Curated for this lesson
The Fleet
When One GPU Is Not Enough
The speaker starts the distributed-inference problems with 'your model cannot fit into a single GPU,' then explains sharding weights with tensor parallelism, sharding the sequence dimension for long context, and distinguishes latency/communication tradeoffs where tensor parallelism 'can improve end latency' while pipeline parallelism 'doesn't actually improve end-to-end latency.'
One GPU can fail for three different reasons: model weights exceed device memory, the KV cache grows beyond available memory, or the required per-token latency is lower than one device can deliver. Each failure points to a different sharding axis, so adding GPUs is a diagnosis, not a single design pattern.
What this lesson answers
- why shard LLM inference across GPUs
- when does KV cache require sharding
- tensor parallelism versus pipeline parallelism latency
Notes
Sharding an LLM request means partitioning either persistent parameters, per-request state, or per-token computation across devices because a single GPU violates one of three constraints: weights capacity, KV-cache capacity, or latency. The governing capacity test is , where for grouped-query attention the KV cache is , with layers, batch size , sequence length , KV heads , head dimension , and bytes per element . The latency test is different: for decode on one GPU, a crude lower bound is , plus synchronization and kernel overheads. These three inequalities fail for different physical reasons, so “add GPUs” is not a single technique: tensor or pipeline parallelism addresses weight residency and per-token latency, while KV sharding or disaggregated serving addresses context residency and admission rate.
For weights, take a 70B model in FP16: before scales, embeddings, allocator padding, and CUDA graph workspaces. An 80GB H100 cannot hold that as one replica, even though its 3.35TB/s HBM bandwidth is excellent, so the first sharding reason is simply that . With tensor parallelism across two H100s, each stores roughly of weights, leaving only about for KV and runtime memory, so production systems usually use 4-way or 8-way TP for 70B FP16 if long contexts are expected. Megatron-LM’s tensor-parallel formulation, TensorRT-LLM’s tensor and pipeline parallel engines, vLLM’s distributed executor, SGLang’s multi-GPU serving, and NVIDIA Dynamo’s disaggregated runtime all implement variants of this idea. The trade is that every transformer layer now contains collectives, typically all-reduce or reduce-scatter/all-gather around attention and MLP projections, so insufficient NVLink bandwidth turns a capacity fix into a latency regression.
The second reason is KV cache capacity, and it is often invisible when people size only the checkpoint. For a 70B-class GQA model with , , , FP16 KV so , and sequences at , the KV footprint is bytes. That is bytes, or about , just for keys and values. Even if the weights are quantized to fit on one 80GB H100, this batch of long contexts cannot. PagedAttention from the vLLM paper “Efficient Memory Management for Large Language Model Serving with PagedAttention” attacks fragmentation and enables paging-style allocation, but it does not make the KV vanish; SGLang’s RadixAttention reuses prefix KV across requests, TensorRT-LLM supports paged KV cache, llm-d focuses on Kubernetes-native disaggregated inference, and Dynamo’s KV routing/cache management separates prefill-heavy and decode-heavy placement. This kind of sharding is about storing, reusing, and moving state, not splitting matrix multiplies.
The third reason is latency below what one GPU can reach, even when memory fits. Suppose a quantized 70B checkpoint occupies and a small active KV set fits on one H100. During batch-1 decode, each generated token still streams a large fraction of the weights, so the HBM lower bound is roughly , or per token before attention, launch overhead, sampling, and framework costs. If the product target is inter-token latency for an interactive agent, one H100 cannot satisfy it by scheduling alone. Tensor parallelism can reduce per-device bytes to about on 4 H100s, giving a bandwidth lower bound near , but now each layer pays NVLink collectives and the latency benefit depends on keeping those below the saved HBM time. FlashAttention, from “FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness,” improves attention IO and is essential for prefill, but it does not eliminate the decode weight-streaming bottleneck that motivates latency sharding.
The technique stops working when the bottleneck shifts from local HBM or capacity to communication, imbalance, or underfilled kernels. Pipeline parallelism can fit a model by placing different layer ranges on different GPUs, but for a single decode stream it creates bubbles: with pipeline stages and microbatch count , utilization is roughly , so gives only stage utilization. Tensor parallelism past the NVLink/NVSwitch sweet spot can make each token slower because all-reduce latency is paid dozens of times per layer stack; crossing PCIe or Ethernet for intra-layer collectives is usually disastrous for decode. KV sharding also has a failure mode: if every decode step must fetch remote KV blocks for attention, the request becomes network-bound, so systems try to route continuations to where the KV already lives. Prefix caching can become counterproductive when prompts have low overlap, because the index, hashing, and eviction overheads remain while reuse disappears. Speculative methods such as EAGLE, from “EAGLE: Speculative Sampling Requires Rethinking Feature Uncertainty,” reduce target-model decode steps, but they can hurt when acceptance rate is low or the draft path consumes scarce GPU memory and scheduler slots.
The named serving stacks differ mainly in which of the three failures they optimize first. vLLM popularized PagedAttention and continuous batching for KV-efficient high-throughput serving; SGLang added a programming/runtime layer with RadixAttention and aggressive prefix sharing for structured workloads; TensorRT-LLM packages fused kernels, quantization, tensor parallelism, pipeline parallelism, paged KV, and in-flight batching for NVIDIA GPUs; NVIDIA Dynamo, released as a distributed inference serving framework, emphasizes disaggregated prefill/decode, KV transfer, and fleet-wide routing; llm-d brings similar disaggregated LLM serving concerns into a Kubernetes-oriented open stack. FlashAttention is the kernel-level IO optimization underneath many prefill paths, not a fleet scheduler. EAGLE is a speculative decoding algorithm that trades extra draft computation for fewer expensive target passes. When diagnosing “one GPU is not enough,” the engineer should first identify which inequality failed: checkpoint bytes, KV bytes under the intended concurrency and context length, or per-token latency lower bound. Only then does the correct sharding axis become obvious.
References
Common questions
- How do I know whether an LLM needs multiple GPUs?
- Check three separate constraints. First, whether the weights plus runtime workspace fit. Second, whether the KV cache fits for the planned context length and concurrency. Third, whether one device can meet the inter-token latency target. The failed constraint determines whether you split weights, shard state, or parallelise computation.
- Why can KV cache be the limiting factor even when weights fit?
- KV cache scales with layers, batch size, context length, KV heads, head dimension, and element size. Long-context or high-concurrency serving can consume most of the memory even with quantised weights. Paged allocation helps reduce waste, but it does not remove the underlying state that must be stored and routed.
- Does pipeline parallelism make single-request decoding faster?
- Usually not. Pipeline parallelism can place different layer ranges on different devices, which helps when weights do not fit on one GPU. For a single decode stream it often introduces idle stages and communication overhead. Tensor parallelism is the more direct latency tool, but only while communication stays cheaper than the saved local memory traffic.
