The setup: one model, N GPUs
Up to now a model has lived on one GPU. This part of the course asks what changes when it can't — and the surprising answer is that the wire between the GPUs, not the GPUs themselves, decides whether splitting was worth it.
Two ways to use more than one GPU
You can run replicas — put a full copy of the model on each GPU and send different requests to each. Or you can run model parallelism — split one copy of the model across several GPUs so they cooperate on every request. This lesson is about the second.
Tensor parallelism is the workhorse
The form of model parallelism used for inference is tensor parallelism (TP): run one model across N GPUs by sharding each layer's weight matrices. Each GPU holds a slice of the weights and computes a partial result.
The catch arrives immediately
Because each GPU only has a slice, the partial results must be stitched back together before the next layer. That stitching is communication over a wire — and on inference's per-token critical path, the speed of that wire is what makes or breaks the whole idea.
Keywords — tap to unfold the plain meaning
Replicas duplicate the whole model; tensor parallelism splits one model across GPUs. Splitting buys you capacity but forces the GPUs to talk — and the wire becomes the bottleneck.
What tensor parallelism actually splits
"Split the model" is vague. The precise version: every big matrix in every layer is cut into slices, one slice per GPU. Knowing exactly where the cut happens is what tells you where the communication has to happen.
Slice the weight matrices
TP takes each layer's weight matrices and shards them across the N GPUs. A column-parallel layer splits the weights by columns; the following row-parallel layer splits by rows. Each GPU multiplies only its slice and produces a partial output.
Partial results, then a merge
No single GPU has the full answer for a layer — each holds one piece. Before the next layer can run, the pieces are combined with an all-reduce: every GPU sends its partial result, and they all come away with the summed-up full result.
This is Megatron's design
This column-parallel / row-parallel + all-reduce pattern is the original recipe from Megatron-LM (Shoeybi et al., 2019, arXiv 1909.08053) — still the template every inference engine uses for TP today.
Keywords — tap to unfold the plain meaning
TP shards each layer's matrices (column-parallel, then row-parallel) so every GPU computes a partial result, and an all-reduce merges them before the next layer. That's Megatron's recipe.
The hidden cost: all-reduce every layer, every token
One all-reduce sounds cheap. The problem is how many of them there are, and that none can be hidden: each is a hard stop where every GPU waits for everyone else before the next layer can start.
Two all-reduces per layer
Megatron does two all-reduces per transformer layer — one after attention, one after the MLP. Each is a point where the GPUs must synchronize and exchange their partial results.
Multiply by depth, per token
In decode, a 64-layer model therefore needs ~128 all-reduces to emit one token. And it pays that toll for every single generated token, not once per request.
All on the critical path
None of this overlaps useful work: the all-reduces sit on the critical path — the next layer waits until the merge finishes. Slow communication doesn't just add overhead; it directly stretches per-token latency.
Math, decoded
- Lthe number of transformer layers in the model — 64 in this example
- 2 ×two all-reduces per layer: one after attention, one after the MLP
- 128total all-reduces to produce a single token — and it repeats for every token
Two all-reduces per layer, times 64 layers, is ~128 synchronizations on the critical path for each token you generate. The deeper the model, the more often the GPUs must stop and talk.
Keywords — tap to unfold the plain meaning
Two all-reduces per layer × 64 layers = ~128 synchronizations to emit one token, all on the critical path. The next layer can't start until the merge finishes.
So the wire matters: NVLink vs PCIe
If communication is on the critical path and happens ~128 times per token, then the bandwidth of the link between GPUs is no longer a footnote — it's the single number that decides whether tensor parallelism helps or hurts.
NVLink is the fast lane
NVLink is NVIDIA's direct GPU-to-GPU interconnect, running roughly 640–900 GB/s. On NVLink, the all-reduces are quick enough that the merge barely shows up in per-token latency.
PCIe is the slow hallway
PCIe — the general-purpose bus — moves data at only ~128 GB/s, about 7× slower than NVLink. Force ~128 all-reduces per token across PCIe and each one becomes a visible stall.
Same model, very different result
Identical TP setup, identical model: on NVLink it's a win, on PCIe it's the worst case. The compute didn't change — only the wire did — yet the wire is what governs the outcome.
Numbers, decoded
- GB/sgigabytes per second — how fast partial results can move between GPUs
- 640–900NVLink's range; fast enough that all-reduce barely dents per-token latency
- 128PCIe's bandwidth; the same all-reduces now stall on a slow bus
- ~7×how much slower PCIe is — multiplied across ~128 all-reduces per token
The merge step is communication-bound, so its time scales with bandwidth. Dropping from ~640–900 GB/s to ~128 GB/s makes every one of the ~128 per-token all-reduces ~7× slower.
Keywords — tap to unfold the plain meaning
NVLink ≈ 640–900 GB/s; PCIe ≈ 128 GB/s, ~7× slower. Same model, same TP — the wire alone decides whether the all-reduces are invisible or crippling.
TP=N or replicas? The decision
Because TP's cost is all that communication, the right question is never "how many GPUs?" but "do I actually need to split, and is the wire fast enough to make splitting pay?"
Fits on one GPU → replicas
If the model fits in one GPU's memory, replicas (TP=1 × N) usually win on throughput. Each GPU runs a full copy independently with zero all-reduce overhead — no GPU ever waits on another.
Doesn't fit, or latency-critical → TP=N
If the model doesn't fit, or you need minimum token latency, use TP=N — but it's only worth it on NVLink. TP can lower latency by spreading one token's compute over N GPUs, provided the wire doesn't eat the savings.
The trade is throughput vs latency
Replicas maximize total tokens served (throughput) by avoiding communication. TP minimizes time-per-token (latency) by parallelizing one request — at the cost of the all-reduce tax. NVLink is what keeps that tax small enough to be worth paying.
Keywords — tap to unfold the plain meaning
Fits on one GPU → replicas (TP=1 × N) win throughput. Doesn't fit, or you need minimum token latency → TP=N — but only worth it on NVLink.
On your cluster: this is exactly the trap
Every rule in this lesson collides in one real misconfiguration on the cluster. A model that needed no splitting is split, onto the one link that can't carry it. Seeing it makes the whole lesson click.
The fault, exactly
On the cluster, qwen35-27b (27B, FP8, ~27 GB) runs with --tensor-parallel-size 2 on GPU0 + GPU1 — the one pair whose NVLink is down. So the ~128 all-reduces per token cross PCIe (~128 GB/s): the worst case from Station 04.
Why it's doubly wrong
The model is ~27 GB — it fits comfortably on a single 94 GB H100. By the decision tree, it should run as a replica with no all-reduce at all. Instead TP=2 was chosen, adding communication that creates latency rather than reducing it — and then routed over the slow wire on top.
The misconfiguration on the 4×H100 box
vllm serve qwen35-27b \ --tensor-parallel-size 2 # GPU0 + GPU1 # ↳ but NVLink on this pair is DOWN # ↳ ~128 all-reduces/token now cross PCIe (~128 GB/s) # ↳ and the model (~27 GB) fits on ONE 94 GB H100 anyway
qwen35-27b (27B FP8, ~27 GB) on --tensor-parallel-size 2 over GPU0 + GPU1, whose NVLink is down — forcing all-reduces across PCIe (~128 GB/s, ~7× slower than NVLink's 640–900 GB/s). Since it fits on one 94 GB GPU, TP=2 is unnecessary: it manufactures latency instead of reducing it. Fix: run it as a single-GPU replica, or pin TP to an NVLink-connected pair.
Keywords — tap to unfold the plain meaning
Check yourself (recall, don't peek)
- Picture the two chefs and the combine step — what exactly does tensor parallelism split, and what stitches the slices back together?
- Why does a 64-layer model fire ~128 all-reduces to emit one token, and why can't that work be hidden?
- NVLink vs PCIe — why does the same TP setup win on one wire and fail on the other?
- The model fits on a single GPU. Should you run TP=2 or a replica, and why?
A model that fits on one GPU, split TP=2 across a dead-NVLink pair, sends ~128 all-reduces/token over PCIe. It's the worst case — and the fix is simply a replica.