Skip to content
inference.academy

Explainer

Cut every matrix, or cut the stack

A 70B model does not fit on one GPU, so it is cut into eight pieces. There are two ways to cut. Give every GPU a slice of every layer and they all work on every token, stopping twice a layer to agree. Or give each GPU ten whole layers and pass the token down the line, a few kilobytes at each handoff. Same weights, same memory per card, and a very different picture of who is busy when.


Below, the same requests against the same eight GPUs under tensor parallelism, pipeline parallelism, and the hybrid that most multi-node deployments actually run. Rows are GPUs on one clock. The pipeline keeps every stage busy by splitting the requests into micro-batches and staggering them, which is the mechanism, and the cost of the mechanism is the whole story.

GPUs: 8
Requests in flight: 16
Context per request: 4K tokens
Interconnect: NVLink
0 ms22 ms44 ms66 ms87 msTP 88.2 ms a tokenTP 4 x PP 213.3 ms a token0101010101010PP 842.7 ms a token0123456701234567
a GPU reading its shard and computingall-reducesend to the next stagerows are GPUs; digits are micro-batches; the tick is one token’s worth of time
layoutper tokentokens/scomm sharelink bytes per GPU per tokenweights read per roundper GPU
TP 88.2 ms2.0K26%73 MB5.2 ms20 GB
TP 4 x PP 213.3 ms1.2K16%16 MB10.4 ms20 GB
PP 842.7 ms3750%32 KB41.8 ms20 GB

With 16 in flight the step is bound by reading weights, and the pipeline reads each stage’s shard once per micro-batch: 8 reads of the weights per round against one. A request gets a token every 42.7 ms under PP 8 and every 8.2 ms under TP 8, 5.2x apart, and the pipeline’s only consolation is 32 KB on the link per GPU per token against 73 MB.

Against requests in flight, 8 GPUs, 4K context, NVLink
tokens per second, whole deployment011.3K416642561024requests in flighttime between a request's tokens055 ms416642561024requests in flight
TP 8TP 4 x PP 2PP 8configurations that do not fit are not drawn
Llama 3.3 70B in BF16 on H100 SXM GPUs, decode only. Every layout holds the same bytes per GPU: weights over 8, and the cache of everything in flight over 8, by head under tensor parallelism and by layer under pipeline. Tensor parallelism runs one batch of all 16 requests per step; a pipeline of p stages runs p micro-batches of 16/p staggered, so every stage stays busy and each request comes round every p stage-times. A stage’s time is its shard of weights and cache against 3.35 TB/s or its share of the arithmetic against 989 TFLOPS, whichever is slower, plus two all-reduces per layer across its tensor-parallel group, priced as on the multi-GPU communication page. A stage boundary is one send with the same 12.5 us floor, which is pessimistic for the pipeline. Prefill is not drawn.

A pipeline stage reads its weights once per micro-batch, not once per token. Decode is bound by reading the weights. Under tensor parallelism each GPU reads its eighth of them once and every request in the batch gets a token. A pipeline of eight stages has eight micro-batches in flight, so each stage reads its eighth of the weights eight times per round, once for each micro-batch passing through. The round produces the same tokens for eight times the weight traffic, and the time between a request’s tokens is the whole round. That is why the pipeline rows in the lab are all busy and still slow: busy re-reading. The gap closes as the requests in flight grow, because the cache traffic and the arithmetic are the same under every layout and come to dwarf the re-reads, but at small batch it is nearly the full factor of eight. Topcu and others measured it plainly on eight GPUs: pipeline parallelism yields no latency benefit at any depth.

What the pipeline buys is silence on the link. A stage boundary moves one activation per micro-batch, batch times hidden size times two bytes, and it moves it once. The same layers under tensor parallelism all-reduce that tensor twice per layer across every GPU in the group. On NVLink the difference is a rounding error against the weight re-reads. On PCIe, or across servers on InfiniBand, or across servers without it, it is the deployment. vLLM’s Llama 3.1 405B launch measured two H100 nodes without InfiniBand: eight-way tensor parallelism inside each node with a two-stage pipeline across them ran 6.6 times faster than sixteen-way tensor parallelism spanning both, and with InfiniBand the two were similar. Megatron’s rule from 2021 is still the rule: tensor parallelism up to the number of GPUs in a server, pipeline parallelism beyond it.

The hybrid is not a compromise, it is the shape of the hardware. Tensor parallelism within the NVLink island, where the all-reduce is cheap, and a pipeline across islands, where the link is slow, is what the eight-GPU row labelled TP 4 x PP 2 stands for. It pays half the all-reduce tax and one send. In the lab it sits between the two on NVLink and overtakes pure tensor parallelism on PCIe once the batch is large enough for the all-reduce bytes to matter, which is the same crossover the multi-GPU communication page draws from the other side. The pipeline also asks something of the workload: enough requests in flight to fill every stage’s micro-batch. vLLM implements each stage as its own virtual engine with its own scheduler and cache, so a max_num_seqs of 256 under a four-stage pipeline means four batches of 256, and the memory for all of them.


What this model leaves out

Prefill, which is where the pipeline’s reputation comes from. Prefill is compute-bound, so the weight re-reads that hurt decode do not matter, the bubble at the start of a batch is amortised over long chunks, and a stage boundary carries a whole chunk’s activations once instead of all-reducing them twice a layer. SGLang’s chunked pipeline for long context is built on that, and the lab does not draw it.

The bubble. A pipeline with p stages and m micro-batches idles for about (p-1)/(m+p-1) of a batch while the first micro-batch fills the stages and the last drains them, GPipe’s formula, negligible once m is four times p. The lab shows the fill at the start of its window and then a steady state with no bubbles, which is what continuous batching gives decode; a real engine sees the fill again every time the queue runs dry.

The stage boundary is priced with the same latency floor as an all-reduce, which is pessimistic: a point-to-point send over NVLink starts faster than a collective, and the measured inter-node round trip on 400 Gb/s InfiniBand is about 16 microseconds. No public benchmark gives tokens per second for a 70B model at TP 8 against PP 8 against TP 4 x PP 2 on the same H100s, so the lab’s numbers are a roofline argument with measured components, not a measurement of the comparison.


Read next