One GPU can't hold a modern model, let alone train it. So the model and its data get split across many GPUs — but "split" is not one operation. Split the batch, split the weight matrices, or split the layers, and you get three different training runs with three very different amounts of chatter between machines.
Each step, this strategy communicates the full gradient, all-reduced across every GPU, once per training step.
The same tiny 2-layer model, the same 4 GPUs. Switch strategies and watch what actually gets sent over the network change — not just how much of it, but what kind of thing it even is.
All three strategies eventually bottom out in a ring all-reduce: GPUs arranged in a ring, each sending and receiving of a payload during a reduce-scatter pass, then again during an all-gather pass, to end with every GPU holding the same combined result:
- — the size of the payload being combined across GPUs.
- — the number of GPUs.
- — total communication volume for one ring all-reduce of that payload.
The three strategies differ only in what payload goes through this operation, and how often:
- — the model's total parameter count (every GPU holds a full copy).
- — the hidden dimension of one layer's activation.
- — the number of layers.
- Data parallel: sync the whole gradient
Every GPU holds the entire model and computes on its own slice of the batch, so what has to sync is the full gradient — one ring all-reduce over all
params, every single step. - Tensor parallel: sync one activation, at every layer
Weights are sharded across GPUs (no gradient sync needed at all), but each layer boundary needs its partial activations combined — a much smaller payload (, not
params), paid times per step (forward and backward, at every layer). - Pipeline parallel: no collective, ever
Layers are assigned whole to different GPUs. Only the boundary between adjacent stages needs an activation handed across — point-to-point, not a ring all-reduce — so it never pays the collective overhead at all.
Grow the cluster and data-parallel volume grows with it, since as climbs — more GPUs means more ring hops. Tensor-parallel volume grows the same way, just against a much smaller payload. Pipeline-parallel volume doesn't move at all: it was never a function of in the first place.
- The model: 2 layers, 4×4 each, 32 parameters total, 4 GPUs
. Ring all-reduce factor at : .
- Data parallel
— the entire gradient, moved once.
- Tensor parallel
Per boundary: . Two boundaries per layer (forward + backward) × 2 layers: .
- Pipeline parallel
Only inter-layer boundary, forward and backward: — the least of the three, because it never pays the ring all-reduce factor at all.
Same 2-layer, 4×4 model, now spread across 8 GPUs. What is the data-parallel communication volume?
None of the three strategies is "the" way to distribute training — they're different trades. Data parallelism is simple and scales the batch, but every GPU needs the whole model to fit in memory and the gradient sync grows with parameter count. Tensor parallelism shrinks the per-GPU memory footprint but pays a communication tax at every single layer. Pipeline parallelism communicates the least, but idles GPUs during the fill-and-drain of its pipeline unless the batch is sliced into enough microbatches to keep it full. Real large-model training (Megatron-LM, DeepSpeed, GPT-NeoX) combines all three at once, tuned to the cluster's actual network topology. Having built and trained something, the next chapter turns to serving it: finding the nearest match to a query among millions of stored vectors, without comparing against every one.