Runbooks/ LLM Inference Runbook Track B · The machine and the two phases Deep readQuick learn
  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
Document 04 · Quick learn Bandwidth, not TFLOPS · The sparsity trap · The ridge point

Three numbersdecide everything

A datasheet has forty numbers on it. Three decide whether your deployment works, the industry leads with the least important of them, and the headline figure needs halving before you use it.

“A vast kitchen with one narrow doorway. Hiring more chefs does not widen the doorway.”
989 TFLOP/s
dense bf16 — not the 1,979 on the box
3.35 TB/s
the number that decides decode
295 FLOP/byte
the ridge point — ~150 in practice
209 tok/s
single-stream ceiling, 8B bf16
What is actually on the cardthree numbers out of forty

A GPU datasheet has about forty numbers on it. Three of them decide whether your deployment works — and the industry leads with the least important of the three.

Capacity

79.65 GiB on an H100. What the card actually reports, not the 80 on the box.

Decides whether it runs at all, and for how many users
Bandwidth

3.35 TB/s HBM3. How fast weights cross from memory to the compute units.

Decides decode — and therefore what streaming feels like
Compute

989 TFLOP/s dense bf16. The one the marketing leads with.

Decides prefill, and the batch at which decode goes compute-bound
The sentence that reframes most GPU conversations

“For a decode-heavy workload I am buying bandwidth, not TFLOPS. Producing one token means dragging every weight in the model out of HBM, so tokens per second for a single stream is just memory bandwidth divided by model bytes — nothing about the compute enters into it.”

“The compute number matters for prefill and for the batch size at which I go compute-bound. Those are real — they are the second and third questions.”
The analogy — a vast kitchen with one narrow doorway

Inside are two hundred chefs who can chop faster than anybody. The pantry is on the other side of the doorway. If the recipe needs a lot of chopping per ingredient, the chefs are the limit. If the recipe is “fetch every ingredient in the pantry and stir once”, the doorway is the limit and the chefs stand around.

Decode is the second recipe. Hiring more chefs — buying a card with more TFLOPS — does not widen the doorway
The sparsity trapone correction that halves half the published figures
The datasheet says

“BFLOAT16 Tensor Core: 1,979 teraFLOPS*”

The asterisk reads

“with sparsity”

Which means

2:4 structured sparsity — two of every four weights exactly zero, then fine-tuned to recover.

You are serving

A dense checkpoint. The sparse path is never taken.

WorkedUse 989 TFLOP/s dense · ridge point 295, not 148 · and the same footnote is on the A100, L40S and Blackwell pagesH100 SXM

The full set of derates, in order

1 · Strip the sparsity factor

Divide the headline tensor-core number by two unless you are genuinely serving a 2:4-pruned model. You are not.

Skip this and your capacity plan is out by 2×
2 · Apply a utilisation factor

Nobody achieves dense peak either. 35–50% of dense peak is realistic for prefill; 65–85% of peak bandwidth for decode.

Use 40% and 80% for planning — and say you would measure both
3 · Use the right precision row

An fp8 number is not a bf16 number. A model quantised to fp8 only reaches the fp8 row if the kernels actually use the fp8 tensor cores rather than upconverting.

Three separate checks, and they compound
The rooflineone picture, three consequences

It plots how much arithmetic you can actually achieve against how much arithmetic your workload does per byte it reads. It explains why a faster chip does nothing for decode, why batching works, and why batching stops working.

ridge point = peak FLOP/s ÷ bandwidth  —  decode intensity = 2B ÷ bytes_per_weight
989 ÷ 3.35 = 295 FLOP/byte on an H100 · and in bf16 the decode intensity is simply the batch size
Where the decode intensity comes from

Each step reads the weights once — N parameters at w bytes each — and performs about 2×N×B operations for a batch of B. Divide: intensity is 2B/w operations per byte. In bf16 w is 2, so the intensity is exactly the batch size.

A neat consequence: at fp8 the bytes halve and the peak doubles, so the ridge batch is unchanged. Quantisation moves the speed, not the knee

Below the ridge — memory-bound

Intensity under 295. The tensor cores are waiting on HBM.

  • Decode lives here at any realistic batch
  • Extra users are nearly free — the weights were read anyway
  • A faster chip changes nothing. Buy bandwidth, or shrink the model
  • Single-stream ceiling = bandwidth ÷ model bytes
The knee is at
batch ≈ the ridge point
295 in theory, ~150 in practice

Above the ridge — compute-bound

Intensity over 295. HBM is keeping up; the arithmetic is not.

  • Prefill lives here — 2,000 positions through one weight read
  • Every extra user now genuinely slows everyone down
  • The fix is admission control, not optimisation
  • MFU against dense peak is the number that means something
Worked295 × 0.40 ÷ 0.80 ≈ 150 — the practical knee once you apply both deratesH100, 8B, bf16
Comparing cardsderived against your model, not against a benchmark

Single-stream tokens per second for an 8B in bf16 is just bandwidth ÷ 16.06 GB. Nothing about the compute enters into it.

H2
H200 SXM 141 GB4.80 TB/s · ridge 206 · 100 users at 8k
299 tok/s
H1
H100 SXM 80 GB3.35 TB/s · ridge 295 · 53 users at 8k
209 tok/s
A1
A100 SXM 80 GB2.04 TB/s · ridge 153 · 53 users at 8k
127 tok/s
Pe
H100 PCIe 80 GB2.00 TB/s · ridge 378 · weaker card-to-card link
125 tok/s
L4
L40S 48 GB0.864 TB/s · ridge 210 · 22 users at 8k
54 tok/s
A1
A10 24 GB0.600 TB/s · ridge 208 · one user at 8k
37 tok/s
The choosing rule, in one paragraph

Work out the KV budget first, on the card you are considering, at the precision you intend — if that number is small or negative, nothing else matters. Then pick on bandwidth if the workload is chat or agents, and on compute if it is classification, extraction or embedding. Check NVLink only if the model genuinely will not fit on one card.

And put tokens-per-watt next to tokens-per-pound — in a colocation facility one of those is the binding constraint, and it is usually not the one people quote
The 24 GB card, worked

An 8B in bf16 on an A10: 22.00 × 0.90 = 19.80 GiB, minus 14.96 of weights, minus about 3 of activations, leaves 1.84 GiB of cache.

That is one concurrent user at 8k. The server starts and cannot serve — which is the difference between “fits” and “serves”
Everything is a memory hierarchythe same argument at six speeds

The roofline is about one link — the bus between HBM and the compute units. The rest of the system is the same argument repeated.

1
On-chip SRAMwhere FlashAttention keeps the score matrix
20,000 GB/s
2
HBM3the roofline link — every weight, every decode step
3,350 GB/s
3
NVLinkcard to card inside the box
900 GB/s
4
PCIehost memory, and cache offload
64 GB/s
5
Networkbox to box
25 GB/s
6
Local NVMecold start, loading weights
7 GB/s

What each drop costs you

FlashAttention is not optional at long context

It keeps the score matrix in SRAM instead of writing it to HBM. Six times the bandwidth, and the S×S matrix never has to exist.

Exact attention, not an approximation · doc 05
If the model fits on one card, never split it

Tensor parallelism adds an NVLink collective at every layer for every token.

You pay that forever to solve a problem you do not have · doc 11
Tensor parallelism stops at the box

900 GB/s inside, 25 GB/s between. A collective every layer over the network…

…makes decode slower than a single card · doc 11
Cache offload is a fallback, not a plan

PCIe is 52× slower than HBM, and decode is already bandwidth-bound.

It buys survival under pressure, not capacity · doc 10
Cold start takes minutes

140 GB off local NVMe at 7 GB/s is twenty seconds at best. Object storage is far worse.

Which is why autoscaling an LLM is not like autoscaling a web app · doc 15
What is not on the datasheetand the honest Blackwell caveat
GPU utilisation is a duty cycle, not an efficiency

nvidia-smi reports the fraction of time at least one kernel was resident. A decode step at batch 1 keeps a kernel resident for the whole 5 ms while using under half a percent of the arithmetic — and reports 100%.

The numbers that mean something: achieved bandwidth against peak for decode, and MFU against dense peak for prefill. Both are computable from work done and time taken, with no special tooling
The Blackwell-era caveat, stated honestly

Newer parts move all three numbers — substantially more memory, substantially more bandwidth, and new low-precision formats such as fp4 with hardware support. The reasoning here does not change. What changes is every constant.

SKUs differ in memory between variants, and the headline compute figure is an fp4 number with sparsity — so it needs dividing twice before it enters a roofline
Answer it out loudthe ninety-second version, then seven questions
“Three numbers matter: capacity, bandwidth and compute. Capacity decides whether the model and its cache fit at all. Bandwidth decides decode speed, because producing one token means reading every weight — single-stream tokens per second is just bandwidth over model bytes, 209 on an H100 for an 8B. Compute decides prefill, and the batch size at which decode goes compute-bound. That crossover is the ridge point, peak FLOP/s over bandwidth, 295 on an H100 — and since decode arithmetic intensity in bf16 is simply the batch size, the knee is at batch 295 in theory and nearer 150 once you apply real derates. And the headline 1,979 TFLOPS is a sparsity figure: use 989.”

Seven questions, and the spine of each answer

Architect

Why is decode bandwidth-bound and prefill compute-bound?

  • Both read exactly the same weights. The difference is how many tokens that read is amortised over
  • Prefill: 2,000 positions through one read — intensity high, tensor cores fed
  • Decode: one position through the same read — about 1 FLOP/byte at batch 1, against hardware that wants 295
16.06 GB ÷ 3.35 TB/s = 4.79 ms per token, and nothing about the arithmetic moves that. Batching is the fix, which is why KV cache memory ends up governing decode throughput.
Architect

What is the ridge point and why should I care?

  • Peak compute ÷ peak bandwidth — 989 ÷ 3.35 = 295 FLOP/byte on an H100
  • At decode the intensity is the batch size in bf16
  • Below ~295 sequences the GPU is memory-starved and each extra user is nearly free; above it every extra user slows everyone
With 40% of compute and 80% of bandwidth achieved, the real knee is nearer 150. Confirm it by measuring ITL against batch size rather than trusting the arithmetic.
Architect

The datasheet says 1,979 TFLOPS. Your numbers say 989.

  • Both, for different things. 1,979 requires a 2:4 structured-sparse model — pruned so two of every four weights are zero, then fine-tuned
  • Almost nobody serving open weights has one, so the sparse path is never taken
  • The damage compounds: halves the ridge point, doubles the prefill estimate, under-counts the GPUs
And the same footnote is on the A100, L40S and Blackwell pages, so the error travels with you. Strip sparsity first, then apply ~40% utilisation — in that order.
Eng manager

H100s, or twice as many L40S for the same money?

  • It depends on workload shape — say so, then give the test rather than a preference
  • Chat: H100s. 209 tok/s single-stream against 54, because that number is bandwidth over model bytes
  • Twice as many L40S does not fix per-user streaming speed — it is not a quantity you buy in parallel
  • Batch or classification: the L40S can win on throughput per pound
So: what is the output length distribution? Median under fifty tokens, take the test seriously. Three hundred, take the H100s. And no NVLink means a 70B is off the table.
Architect

Would more memory or more bandwidth help us more?

  • Different symptoms — look at two gauges first
  • Cache utilisation pinned near 100%, requests queueing for blocks? Capacity. An H200 roughly triples the KV budget for an 8B
  • Cache comfortable but ITL is the complaint? Bandwidth — and the same H200 helps, 4.8 TB/s against 3.35
Subtlety worth adding: the H200 has the same compute, so its ridge point is 206 rather than 295 — better balanced for decode, and nothing at all on prefill.
Architect

Our GPU utilisation reads 90%. Are we using the card well?

  • No — that metric is a duty cycle, the fraction of time a kernel was resident
  • Batch-1 decode reports 100% while using under 0.5% of the arithmetic
  • Measure achieved bandwidth for decode, MFU for prefill
Both computable without special tooling: tokens per second × model bytes gives the bandwidth you achieved. If that is 15% of peak, the card is idle no matter what utilisation says.
Eng manager

Finance wants to know why we cannot use cheaper GPUs.

  • Because what we are buying is memory bandwidth and capacity, and those are exactly what the cheaper parts remove
  • On a 24 GB card an 8B leaves 1.84 GiB of cache — one user. The server starts and cannot serve
  • Single-stream speed is bandwidth ÷ model bytes, so a third of the bandwidth is a third of the streaming speed
Then give the real options, because that is the conversation finance wants: quantise to int4, use a smaller model, or raise utilisation — a half-idle expensive GPU is usually a bigger line than the hardware choice.
Fast answersthe ten that come up most

QWhy does a faster GPU not make decode faster?

Because “faster” usually means more arithmetic, and decode is not waiting on arithmetic — it is waiting for every weight to cross the memory bus. Buy bandwidth or shrink the model; those are the only two levers.

QWhat is arithmetic intensity, in one line?

Operations performed per byte read from memory. Compare it against the ridge point and you know immediately which resource you are starved of. Below the ridge, memory; above it, compute.

QWhy is decode intensity equal to the batch size?

Each step reads N parameters at w bytes and performs 2NB operations. Dividing gives 2B/w per byte; in bf16 w is 2, so it is exactly B. Pleasing consequence: at fp8 the bytes halve and the peak doubles, so the ridge batch is unchanged — quantisation moves the speed, not the knee.

QWhat is MFU and what is a good number?

Model FLOPs utilisation — the fraction of dense peak you achieve. 35–50% is realistic for prefill; use 40% for planning. For decode the equivalent is achieved bandwidth against peak, where 65–85% is realistic.

QDoes an 80 GB card give me 80 GB?

No, twice over. It reports 81,559 MiB, which is 79.65 GiB — the “80” is decimal marketing. Then the engine takes 0.90, leaving 71.7. Then weights and activations come off that. Always start the ladder from what the card reports.

QIs NVLink necessary?

Only if you split a model across cards. Tensor parallelism performs a collective at every layer for every token — NVLink at 900 GB/s carries it, PCIe at 64 GB/s does not. If your model fits on one card and you run independent replicas, do not pay for it.

QWhat is FlashAttention doing, in hardware terms?

Keeping the attention score matrix in on-chip SRAM instead of writing it to HBM — roughly six times the bandwidth, and the full S×S matrix never has to exist. It computes exact attention; it is not an approximation.

QWhy is an H100 PCIe so much worse than an H100 SXM?

Same name, different part. 2.0 TB/s against 3.35 and 756 dense TFLOP/s against 989, so single-stream decode is 40% slower and its ridge point is the worst of the common cards at 378 — you stay memory-bound longer while carrying compute you cannot feed. Never quote “H100” without the form factor.

QShould I care about tokens per watt?

If you rent by the hour, no — you are buying time, not electricity. If you own the rack or are power-constrained, it is frequently the binding constraint, and it reorders the table: an A10 at 150 W looks much better per watt than per token.

QHow do I sanity-check a vendor benchmark?

Three questions. Dense or with sparsity? What batch size and request rate, and at saturation or a fixed rate? And what prompt and output length distribution? A throughput number with short outputs and a huge batch is a different universe from a chat workload.

Capacity decides whether it runs. Bandwidth decides decode. Compute decides prefill. In that order, for a chat workload — and the industry leads with the third one, printed with an asterisk that doubles it. Strip the sparsity factor, apply a utilisation factor, then do the arithmetic. Every roofline argument built on 1,979 TFLOPS is wrong by a factor of two.

SRAM 20,000
HBM 3,350
NVLink 900
PCIe
Where this goes next

Questions to ask them

Which card and which form factor — SXM or PCIe?

Has anyone measured achieved bandwidth during decode, or only GPU utilisation?

What batch size does inter-token latency start climbing at, on your model?

Was the capacity plan built on dense or sparsity-inflated TFLOPS?

Are you power-constrained in the rack, or purely cost-constrained?

If the card you want is unavailable for two quarters, what is the fallback?

← 03 · Journey Read the full chapter → 05 · Phases →