Runbooks/LLM Inference RunbookTrack D · Scale and speedRAG Runbook →0%
  1. 00 Start
  2. /
  3. 01 Tokens
  4. 02 Anatomy
  5. 03 Journey
  6. /
  7. 04 Hardware
  8. 05 Phases
  9. 06 KV cache
  10. /
  11. 07 Attention
  12. 08 Position
  13. 09 Precision
  14. 10 Cache ops
  15. /
  16. 11 Many GPUs
  17. 12 Engines
  18. 13 Decode loop
  19. /
  20. 14 Planning
  21. 15 Production
LLM Inference Runbook · Document 11 of 15 · Track D — Scale and speed

Track D · Document 11 · Scale and speed

Many GPUs: Parallelism, MoE and Replication

Splitting a model is a workaround for a memory limit, not a performance feature — and mixture of experts saves compute rather than the thing you actually buy.

Reads in about 25 minutes · 6 figures, one a live layout planner · 7 interview questions · prints to clean A4

What is in this document

  1. GPU, node, cluster
  2. Replication first, always
  3. Tensor parallelism
  4. The other three kinds
  5. Mixture of experts
  6. Interview questions
  7. FAQ
  8. Cheat sheet

1 · GPU, node, cluster

THREE WORDS USED LOOSELY, AND THEY MEAN SPECIFIC THINGS GPU one card, 79.65 GiB 3.35 TB/s to its own memory NODE — one server, 8 GPUs 637 GiB total, joined by NVLink 900 GB/s between any two cards inside it CLUSTER — many nodes joined by network, not NVLink ~25 GB/s — 36× slower than inside the box EIGHT GPUs DO NOT GIVE YOU ONE BIG MEMORY An 8-GPU node with 80 GB each does not behave like a single 640 GB device. There is no automatic pooling. A model that needs 100 GiB will not simply load across two 80 GiB cards — the software has to be explicitly told how to cut it up, and how you cut it changes everything. NVLINK IS A FAST ROAD, NOT ONE HOUSE It lets one GPU read another’s memory directly and quickly, which is what makes splitting a model workable at all. It does not make eight cards into one card. AND VIRTUAL MACHINES DO NOT HELP GPUs are handed to a VM whole, not sliced. If a VM has two GPUs, it has two GPUs — not one bigger one. Partitioning one card into smaller isolated pieces is the opposite operation.

This trips up nearly everyone coming from a systems background, where adding servers usually just adds capacity. Here, adding a card adds capacity only if you tell the software how to use it — and the two ways of telling it have completely different costs.

The analogy

Eight GPUs in a node are eight chefs with eight separate pantries in one kitchen. They can pass ingredients to each other across the bench very quickly — that is NVLink. What they cannot do is treat the eight pantries as one large pantry: a recipe needing more ingredients than any single pantry holds does not simply work. Somebody has to decide, in advance and explicitly, which chef stores what. And chefs in the next building can still be handed things, but only by courier, which changes what kinds of collaboration are possible.

2 · Replication first, always

Before any discussion of how to split a model, the question that settles most cases: does it need splitting at all?

A 7B MODEL AND EIGHT GPUs · TWO WAYS, AND ONE OF THEM IS ALMOST ALWAYS WRONG SPLIT ACROSS ALL EIGHT 1/8 of every layerGPU 11/8 of every layerGPU 21/8 of every layerGPU 31/8 of every layerGPU 41/8 of every layerGPU 51/8 of every layerGPU 61/8 of every layerGPU 71/8 of every layerGPU 8 a collective exchange at every layer, for every token — and one server, so if any card fails the whole thing stops EIGHT INDEPENDENT COPIES the whole modelGPU 1the whole modelGPU 2the whole modelGPU 3the whole modelGPU 4the whole modelGPU 5the whole modelGPU 6the whole modelGPU 7the whole modelGPU 8 zero communication between GPUs, eight independent servers behind a load balancer, and any one can die without taking the rest with it fits on one card? → replicate. Always, unless you have a specific reason does not fit? → split, reluctantly, and only as far as you must
  1. Split across all eight. Each GPU holds one eighth of every layer, with a collective exchange at every layer for every token — and it is one logical server, so any card failing stops everything.
  2. Eight independent copies. Zero communication between GPUs, eight servers behind a load balancer, and any one can fail without taking the rest with it.
  3. If the model fits on one card, replicate — always, unless there is a specific reason not to.
  4. If it does not fit, split — reluctantly, and only as far as you must.

This is a genuinely good interview answer because it shows you reach for the simplest thing that works rather than the most impressive-sounding one. Parallelism exists because the model does not fit, not to make a single request faster.

Why replication wins whenever it is available

Zero communication. No collectives, no synchronisation, nothing to tune. Each GPU runs at the speed it would run at alone.

Better failure behaviour. One card dies and you lose one eighth of capacity, not the whole service. A tensor-parallel group is a single failure domain.

Simpler to reason about and to scale. Adding capacity is adding a replica behind a load balancer, which is a problem your infrastructure team has already solved.

The only reason to split is that the model does not fit. Splitting to “go faster” is the classic over-engineering tell in this area, and the counter is one sentence: splitting adds a collective on every layer for every token, so if it fits on one card you should never split it.

3 · Tensor parallelism

TENSOR PARALLELISM · CUT EACH LAYER SIDEWAYS every layer’s weight matrices are sliced column-wise or row-wise, one slice per GPU GPU 1 · a quarter of WGPU 2 · a quarter of WGPU 3 · a quarter of WGPU 4 · a quarter of W each computes its slice of the result — a partial answer that is useless on its own partial outputpartial outputpartial outputpartial output ALL-REDUCE — every GPU needs the sum before the next layer can start over NVLink at 900 GB/s: about 2% of a decode step over a 25 GB/s network: comparable to the whole step And it is the per-message latency, not the bandwidth, that bites. Two collectives per layer × 32 layers = 64 round trips per token. At roughly 5–10 microseconds each that is 0.3–0.6 ms — 5 to 10% of a 6 ms step, on top of the bytes.
  1. Every layer’s weight matrices are sliced, one slice per GPU.
  2. Each GPU computes its slice of the result — a partial answer that is useless on its own.
  3. An all-reduce combines them, because every GPU needs the full sum before the next layer can start.
  4. Over NVLink at 900 GB/s that is about 2% of a decode step. Over a 25 GB/s network it is comparable to the entire step — which is why tensor parallelism stops at the edge of a node.
  5. And it is the per-message latency rather than the bandwidth that bites: two collectives per layer × 32 layers is 64 round trips per token, which at 5–10 microseconds each is 5 to 10% of a step before you count any bytes.

The analogy: four accountants each add up a quarter of the columns, then compare notes before starting the next page. The comparing is the cost — and it happens at every layer, for every single token.

Where the 2% and the 5–10% come from

Each all-reduce moves a tensor the size of one token’s activation — 8 KiB at d_model 4,096 in bf16 — times the batch. At batch 128 across four GPUs, the ring exchange is about 100 MB per decode step, which at 900 GB/s is roughly 112 microseconds against a 6 millisecond step. Under 2%.

But there are 64 collectives per token — two per layer, thirty-two layers — and each carries a fixed latency of roughly 5 to 10 microseconds regardless of size. That is 0.3 to 0.6 milliseconds of pure round-trip cost, which is 5 to 10% of the step.

So the honest framing is: bandwidth is not the problem, message count is. That is also why the overhead does not shrink when the batch is small — it gets proportionally worse, because the fixed cost is spread over fewer tokens.

The KV head constraint, which is easy to miss

With tensor parallelism, each GPU holds the cache for the heads it owns. With 8 KV heads and 8-way parallelism, each card gets exactly one — clean, and part of why 8 has become conventional.

Push the parallelism degree above the KV head count and the heads must be replicated across devices. Sixteen-way parallelism on a model with 8 KV heads means every head lives on two cards, so aggregate cache memory doubles rather than staying flat. The KV head count therefore quietly caps how far tensor parallelism is useful, and beyond it you want pipeline parallelism instead.

DOES IT FIT, AND WHAT DOES THE SPLIT COST YOU? weights, total 131.40 GiB 70.55B parameters × 2 bytes memory available 143.38 GiB 2 cards × 71.69 GiB usable KV budget left 5.98 GiB after 3 GiB of activations on each card users at 8k context 2 at 2.50 GiB per user KV heads vs split degree 8 vs 2 clean — each card owns 4 KV heads, nothing is duplicated collective overhead ~7% of a decode step, over NVLink This works. Try fp8 before raising the split degree — halving the weights frees far more KV budget than adding a card does.

Two traps are built in. Raise the split degree past the KV head count and the heads must be replicated, so aggregate cache goes up rather than down. And select the L40S, which has no NVLink: the arithmetic still works and the deployment does not.

4 · The other three kinds

FOUR WAYS TO USE MORE THAN ONE GPU · THEY COMPOSE, AND THEY ARE NOT ALTERNATIVES TENSOR each layer sliced across GPUs talks: every layer, every token needs: NVLink, inside a node use: a 70B across 2–4 cards PIPELINE the stack cut into groups of layers talks: once per boundary needs: tolerates a network use: frontier models across nodes EXPERT MoE experts spread across GPUs talks: routing, per token per layer needs: fast links; load can skew use: large mixture-of-experts models DATA / REPLICAS whole copies, load-balanced talks: not at all needs: nothing use: whenever the model fits THE STANDARD SHAPE FOR A MODEL THAT DOES NOT FIT ON ONE NODE Tensor parallelism inside each node, where NVLink can carry a collective at every layer. Pipeline parallelism between nodes, where one handover per boundary tolerates a network. Then replicate the whole arrangement for capacity and availability. TWO THINGS ABOUT PIPELINE PARALLELISM THAT CATCH PEOPLE OUT A single request is only ever being worked on by one machine at a time, so with one request in flight the other machines idle. You must keep several requests in flight to avoid bubbles. And it does nothing for per-request latency — if anything it adds hops. Like tensor parallelism, you do it because the model does not fit, not to go faster.

The one to say out loud: “Parallelism exists because the model does not fit. Splitting adds communication on every layer, so if it fits on one card you should never split it.” Then, if pressed on very large models, the tensor-inside-pipeline-between shape.

TensorPipelineExpertData / replicas
CutsEach layer across GPUsThe stack into groups of layersMoE experts across GPUsNothing — whole copies
CommunicatesEvery layer, every tokenOnce per boundaryRouting, per token per layerNot at all
NeedsNVLink — inside one nodeTolerates a networkFast links; routing can skew loadNothing
Effect on KV cacheSplit by head, unless degree > KV heads, then replicatedSplit by layer — each stage holds its own layers’ cacheUnchanged — attention is untouchedEach replica has its own, entirely separate
LatencySlightly better bandwidth, eaten by collectivesWorse — extra hops, and bubbles unless several requests are in flightAdds routing hopsUnchanged
Use whenA 70B across 2–4 cardsFrontier models across nodesLarge MoE modelsWhenever the model fits

5 · Mixture of experts

700 BILLION PARAMETERS, RUNNING ABOUT AS FAST AS A 30 BILLION MODEL. BOTH CLAIMS ARE TRUE. inside each layer, the feed-forward block — the part that processes each token alone — is replaced by many copies of itself 128 experts, all of them resident in GPU memory, all of the time the router a tiny component: takes the token’s vector, produces one score per expert, picks the top two work per token: only two experts run — about 30B active memory: all 128 stay resident — the full 700B, always THE POINT EVERYONE GETS WRONG: MoE SAVES COMPUTE, NOT MEMORY. The router’s choice cannot be predicted, so every expert must be ready. A 700B MoE at 8-bit is 652 GiB. Eight H100s at 0.90 give 573 — a full node is not enough. You need 8×H200 or 16×H100, before a byte of KV cache. AND IT DOES NOTHING FOR THE KV CACHE MoE replaces the feed-forward block. Attention is untouched, so the cache is identical. MoE and grouped-query attention solve completely orthogonal problems and are frequently used together in the same model — which is worth saying, because the two get conflated constantly.
  1. Inside each layer, the feed-forward block is replaced by many copies of itself — say 128 experts, all resident in GPU memory all of the time.
  2. A tiny router takes each token’s vector, produces one score per expert, and picks the top two.
  3. Work per token corresponds to two experts — about 30B active. Memory corresponds to all 128 — the full 700B, always.
  4. MoE saves compute, not memory. The router’s choice cannot be predicted, so every expert must be ready. A 700B MoE at 8-bit is 652 GiB; eight H100s give 573, so a full node is not enough.
  5. And it does nothing for the KV cache — MoE replaces the feed-forward block and leaves attention untouched. MoE and GQA solve orthogonal problems.

The hospital analogy: 128 specialists on the payroll, and the receptionist sends each patient to the two most relevant. The visit is quick because only two doctors see them. All 128 are still in the building and still being paid, because nobody can know in advance who tomorrow’s patients will need.

How the routing actually works, and what emerges

The router is small and simple: it takes the token’s current vector and produces one score per expert. The top two win, their scores become weights that sum to one, and their outputs are blended in that proportion.

Nobody programmed the specialisms. Routing is learned during training and it is self-reinforcing — an expert picked for a certain kind of token gets the learning signal for that kind of token, so it gets better and gets picked more. A balancing penalty is added during training to stop one expert winning everything while others starve.

And the specialisms that emerge are usually not human categories. They tend to be things like punctuation, code syntax or numbers, and often resist interpretation entirely. If asked, say that plainly rather than claiming there is a “medicine expert” — the overclaim invites a follow-up you cannot support.

Why routing different tokens to different experts breaks nothing

Worth raising yourself, because it sounds like it should be a problem. Attention is where tokens look at each other; the feed-forward block — the part MoE replaces — processes each token independently even in a dense model. So sending different tokens to different experts changes which weights a token’s private refinement uses, and the next layer’s attention re-mixes everything regardless.

The rhythm is: mix, refine privately, mix again. MoE only touches the middle step. Note also that routing happens per token and per layer, not once per request — a single sentence touches many different experts on its way through the model.

The honest summary, and the fair comparison

A 700B MoE with 30B active costs you the memory of a 700B model and the speed of a 30B one, and produces quality somewhere in between — better than a dense 30B, a bit worse than a dense 700B would be if anyone could afford to run one.

So the fair comparison is against a dense model of the same active size, and there MoE is meaningfully better. Comparing it against a dense model of the same total size is the comparison that makes it look bad, and comparing the parameter count against a dense model is the comparison that makes it look magical. Neither is the useful one.

Three real downsides to name: training is less stable, because picking experts is a hard on-or-off decision rather than a smooth one; serving is more complex, because experts have to be distributed sensibly; and uneven routing can leave some cards busier than others, which is a tail-latency problem rather than an average one.

6 · Interview questions

ArchitectWhen would you split a model across GPUs?

When it does not fit on one. That is the only reason, and I would say it that plainly, because splitting to go faster is the common over-engineering answer here.

Splitting adds a collective exchange at every layer for every token. Over NVLink that is a few per cent of a decode step in bandwidth terms — but there are 64 collectives per token, two per layer, and each carries a fixed round-trip latency, so the real overhead is five to ten per cent and it gets proportionally worse at small batch. Over a network it is comparable to the entire step, which is why tensor parallelism stops at the edge of a node.

So the ladder is: quantise first, because fp8 halves the weights and frees far more than adding a card does. Then split, as little as you can. And if it already fits, run independent replicas behind a load balancer — zero communication, and one card failing costs you one eighth of capacity rather than everything.

ArchitectDoes tensor parallelism make a single request faster?

Sometimes a little, because there is more total memory bandwidth working on the same weights — four cards reading a quarter of the model each can move the bytes faster than one card reading all of it. But the collectives eat into that, and at small batch, where single-request latency actually matters, the fixed per-message latency dominates.

The honest framing is that you do it for capacity, not speed. If someone proposes tensor parallelism as a latency optimisation for a model that already fits, I would want to see the measurement before believing it — and I would point out that they are also converting eight independent failure domains into one.

ArchitectDoes the KV cache get split too?

Yes, by head. With tensor parallelism each GPU holds the cache for the attention heads it owns, so with 8 KV heads and 8-way parallelism each card holds exactly one — clean, nothing duplicated, and part of why 8 KV heads has become conventional.

The trap is going further. If the parallelism degree exceeds the KV head count, heads must be replicated across devices: sixteen-way on a model with 8 KV heads puts every head on two cards and doubles the aggregate cache. So the KV head count quietly caps how far tensor parallelism is useful, and beyond that point you want pipeline parallelism between nodes rather than more tensor parallelism within them.

Eng managerA 700B mixture-of-experts model is described as running like a 30B. What do we actually need to buy?

The memory of a 700B and the compute of a 30B, and the memory is what you buy hardware for.

All the experts stay resident, because the router’s choice for the next token cannot be predicted. At 8-bit a 700B model is 652 GiB. A full node of eight H100s at the usual 0.90 utilisation gives 573 GiB, so a node is not enough — we would need eight H200s at 141 GB each, or sixteen H100s across two nodes, and that is before a single byte of KV cache.

Two follow-ons worth having ready. It does nothing for the cache, because MoE replaces the feed-forward block and leaves attention untouched — so all the per-user memory arithmetic is unchanged. And the fair quality comparison is against a dense model of the same active size, where MoE genuinely wins. If the business case was built on “it is as cheap as a 30B”, that case is wrong, and it is better to correct it now than after the purchase order.

ArchitectHow would you lay out a model that does not fit on one node?

Tensor parallelism inside each node, pipeline parallelism between them. The reasoning is entirely about the communication pattern: tensor parallelism needs a collective at every layer, which NVLink at 900 GB/s can carry and a 25 GB/s network cannot. Pipeline parallelism needs one handover per boundary, which a network handles fine.

Then replicate the whole arrangement for capacity and availability, because a single pipeline is a single failure domain spanning several machines.

Two things I would watch. The tensor degree must not exceed the KV head count, or heads get replicated and cache goes up. And pipeline parallelism needs several requests in flight to avoid bubbles, because a single request is only ever being worked on by one stage at a time — so it interacts with the batching strategy rather than being independent of it.

ArchitectCan I run a big model by spilling into CPU RAM?

Technically yes, and it is dramatically slower. PCIe is around 64 GB/s against HBM’s 3,350 — fifty-two times slower — and decode is already bandwidth-bound, so you are putting the bottleneck on the slowest link in the system. Expect something like an order of magnitude on tokens per second.

It is fine for experimentation and for running something on a laptop. It is not a serving strategy. The one place host memory genuinely earns its place in production is as a swap destination for preempted requests, where you are trading a 34-millisecond transfer against a 421-millisecond recompute — that arithmetic works. Continuous execution out of host memory does not.

Eng managerSomeone suggests eight-way tensor parallelism for a 7B model to cut latency. How do you handle it?

By turning it into a measurement rather than a disagreement, but I would be fairly confident of the outcome.

A 7B fits comfortably on one card, so splitting it buys no capacity. It adds 64 collectives per token, each with fixed latency, so at the small batch sizes where single-request latency matters the overhead is proportionally worst. It also converts eight independent failure domains into one, and eight independent servers into one — so we lose the ability to lose a card gracefully.

The alternative is eight replicas: zero communication, eight times the users, and any card can die. If the real goal is single-user streaming speed, the levers that actually work are speculative decoding at low batch, quantised weights to move fewer bytes, and a smaller cache — all of which are in documents 09, 10 and 13. I would propose measuring one replica against the eight-way split on inter-token latency at batch 1 and at batch 32; that settles it in an afternoon and leaves nobody arguing.

7 · FAQ

Why can I not just add GPUs and get more memory?

Because each GPU’s memory belongs to that GPU and there is no automatic pooling. An 8-GPU node with 80 GB each is not a 640 GB device. NVLink lets one card read another’s memory quickly, which is what makes splitting workable — but the software has to be told explicitly how to cut the model up.

What is a sensible tensor-parallel degree?

The smallest one that fits, capped at the KV head count, and never crossing a node boundary. For a 70B in bf16 on H100s that is 2 at a squeeze or 4 comfortably; at fp8 it fits on one. Always try quantisation before raising the degree, because halving the weights frees more budget than adding a card does.

Does MoE help my KV cache?

Not at all. MoE replaces the feed-forward block; attention and therefore the KV cache are untouched. MoE and grouped-query attention solve completely different problems and are often used together in the same model. Conflating them is one of the most common mistakes in this area.

Can I fine-tune a MoE model to add a new specialism?

Fine-tuning nudges the existing routing but will not reorganise which expert handles what — the structure was established during pre-training and is largely set. Adding genuinely new specialisation means training, not fine-tuning.

Why does pipeline parallelism need several requests in flight?

Because a single request is only ever being worked on by one stage at a time. With one request, the other stages idle — the classic pipeline bubble. You need enough concurrent requests to keep every stage fed, which means pipeline parallelism interacts with your batching strategy rather than being independent of it.

What is expert parallelism?

Spreading a MoE model’s experts across GPUs so each card holds a subset. It composes with tensor and pipeline parallelism rather than replacing them. Its specific difficulty is load skew: routing is data-dependent, so some cards can end up busier than others on a given batch, which shows up as a tail-latency problem.

What about TPUs and other accelerators?

Different hardware, same principles. Memory per chip, a fast interconnect within a group, a slower one between groups, and the same reasons for splitting models. Everything in this document transfers — only the constants change.

Does splitting change the model’s output?

It should not, and in principle it does not — the arithmetic is the same. In practice, floating-point addition is not associative, so a different reduction order can produce very slightly different numbers, and with sampling that can occasionally change a token. If you need bit-identical output across configurations, that is worth knowing about before you promise it.

Why is 8 GPUs the standard node size?

It is what the reference server designs ship, and it maps onto power, cooling and NVLink topology. The consequence for us is that 8 is the natural ceiling for tensor parallelism, and it is not a coincidence that 8 KV heads became conventional at the same time.

One sentence for the whole document?

Parallelism exists because the model does not fit; if it fits on one card, replicate instead; and mixture of experts saves compute rather than memory, so it changes what you buy less than the parameter count suggests.

8 · Cheat sheet

the hierarchy GPU (79.65 GiB, 3.35 TB/s) · node (8 GPUs, NVLink 900 GB/s) · cluster (network, ~25 GB/s). Each step down is roughly an order of magnitude
the first rule fits on one card? replicate. Zero communication, better failure behaviour, simpler to scale
tensor parallelism each layer sliced, all-reduce every layer. NVLink only. Do it because it does not fit, not for speed
the real overhead bandwidth is ~2% of a step; 64 collectives per token at 5–10 µs each is 5–10%. Message count, not bytes
the KV head cap degree > kv_heads → heads are replicated and aggregate cache goes up. 8 KV heads caps useful TP at 8
pipeline parallelism stack cut into groups, one handover per boundary, tolerates a network. Needs several requests in flight or stages idle
the standard shape tensor inside a node, pipeline between nodes, replicate the whole thing
MoE saves operations, not bytes stored. All experts resident. A 700B at 8-bit is 652 GiB — more than a full H100 node
MoE and the cache completely unchanged. It replaces the feed-forward block; attention is untouched
the order of operations quantise → replicate if it fits → tensor-parallel within a node → pipeline across nodes. Never skip straight to the last one

The ninety-second version

“Eight GPUs are not one big memory — each card’s memory is its own and the software has to be told explicitly how to cut a model up. The first question is whether it needs cutting at all: if the model fits on one card, run independent replicas, because that costs zero communication and any card can fail without taking the service down. If it does not fit, tensor parallelism slices each layer across cards with an all-reduce at every layer — which NVLink can carry at a few per cent overhead and a network cannot, and where the real cost is sixty-four round trips per token rather than the bytes. Beyond a node you switch to pipeline parallelism, one handover per boundary. And the degree is capped by the KV head count, because above it the heads get replicated and the cache grows. Mixture of experts is a separate axis: it routes each token through two of many feed-forward blocks, so it saves compute and not one byte of memory, because every expert has to stay resident.”

Where this connects

Thread started herePicked up in
The feed-forward block that MoE replaces, and its 70% share 02 · Inside the model
NVLink against PCIe against the network, on one log scale 04 · The GPU and the roofline
The cache that gets split by head, and the budget it comes from 06 · The KV cache
Why the KV head count is the cap on the split degree 07 · Attention variants
Quantising first, which frees more than adding a card 09 · Precision
Swap to host memory, where PCIe genuinely earns its place 10 · Paging and prefix reuse
The flags that set the parallel degrees 12 · Serving engines
Turning all of this into a fleet size and a bill 14 · Capacity planning

Questions to ask them