nvidia-smi says 100%. Your dashboard is green. The GPU is, in the only sense that tool means, fully busy.
It is also doing about a third of one percent of the arithmetic you are paying for. Both statements are true, and the gap between them is the most expensive misunderstanding in this part of the book.
Two numbers, both called utilisation
GPU utilisation as reported by nvidia-smi is the fraction of sampled time during which at least one kernel was resident. It answers "is the card doing something?" It does not answer "how much?" A kernel that reads memory and computes almost nothing pins it at 100%.
Model FLOPs Utilisation (MFU) is the useful arithmetic actually performed divided by what the chip could perform at peak. It answers the question your invoice asks.
For decode these two diverge by roughly two orders of magnitude, and the reason is entirely mechanical.
The ceiling has a closed form
Memory bandwidth is the product established that decode is bandwidth-bound. Push that one step further and you get a ceiling you can compute in your head.
During autoregressive decode with a batch of B sequences, each step:
- performs roughly 2N FLOPs per sequence (N = parameters), so 2NB in total;
- reads the entire weight matrix exactly once, regardless of B.
Time per step is therefore floored by bytes ÷ bandwidth, and the achieved arithmetic rate is:
achieved FLOPS = 2NB ÷ (2N ÷ BW) = B × BW
Divide by the chip's peak and the model cancels out entirely:
MFU_decode = B × BW ÷ F_peak
The model you serve does not appear. Only how many sequences you decode at once, the memory bandwidth, and the peak FLOPS of the silicon.
What that ceiling actually is
NVIDIA's headline tensor-core numbers all carry an asterisk reading "With sparsity" — so the dense figure, which is what dense LLM inference gets, is half the number on the page. The H100 SXM's 1,979 BF16 teraFLOPS is 989.5 dense.
| GPU | Dense BF16 peak | Bandwidth | MFU per sequence | B for 50% MFU |
|---|---|---|---|---|
| A100 SXM | 312.0 TFLOPS | 2.04 TB/s | 0.6535% | 77 |
| H200 | 989.5 TFLOPS | 4.80 TB/s | 0.4851% | 104 |
| H100 NVL | 835.5 TFLOPS | 3.90 TB/s | 0.4668% | 108 |
| H100 SXM | 989.5 TFLOPS | 3.35 TB/s | 0.3386% | 148 |
| L40S | 733.0 TFLOPS | 0.86 TB/s | 0.1179% | 425 |
On an H100 SXM:
| Concurrent sequences | MFU |
|---|---|
| 1 | 0.34% |
| 8 | 2.71% |
| 32 | 10.83% |
| 64 | 21.67% |
| 148 | 50.11% |
One user talking to a model on a $2.99/hour H100 uses 0.34% of its arithmetic. The other 99.66% is idle silicon that you are renting, waiting on memory.
Quantisation does not fix this
The obvious move is to quantise: fewer bytes per weight, fewer bytes to read, faster decode. It works — and it does nothing for MFU.
At FP8 the weights halve to N bytes, so achieved FLOPS becomes 2 × B × BW. But the H100's FP8 dense peak is exactly 2× its BF16 dense peak (3,958 vs 1,979 with sparsity; 1,979 vs 989.5 dense). Numerator and denominator both double:
| B | MFU at FP16 weights | MFU at FP8 weights |
|---|---|---|
| 1 | 0.3386% | 0.3386% |
| 9 | 3.0470% | 3.0470% |
| 148 | 50.1061% | 50.1061% |
Identical to fifteen decimal places. Quantisation buys you tokens per second. It does not buy you a better-used chip, because it shrinks the work and the clock in the same proportion. The only lever in B × BW ÷ F_peak that you control at serving time is B.
The collision
Here is where this chapter meets the last one. VRAM sizing computed how many concurrent sequences actually fit: Qwen2.5-72B at FP8, 4K context, weights taking 67.71 GiB off the top.
| GPU | Sequences needed for 50% MFU | Sequences that fit | Achieved MFU | Shortfall |
|---|---|---|---|---|
| H100 SXM | 148 | 9 | 3.05% | 16.4× |
| H100 NVL | 108 | 21 | 9.80% | 5.1× |
| H200 | 104 | 58 | 28.14% | 1.8× |
| L40S | 425 | 0 | — | model does not fit |
The batch size that would use the chip well is 16.4× larger than the batch size that fits in its memory. These two constraints are not independent problems to optimise separately — they are the same problem pulling in opposite directions, and on an 80 GB card with a 72B model, memory wins decisively.
This also re-explains, from a third direction, why the H200 was the right buy in the previous chapter: not because it is fast, but because capacity is what unlocks the batch that unlocks the arithmetic.
The cheaper chip is easier to use well
Notice the ordering in the ceiling table. The A100 SXM has the best MFU per sequence of any card here — 0.6535%, needing only 77 sequences for 50%. The L40S is the worst at 0.1179%, needing 425.
That is not a mistake. BW ÷ F_peak is the reciprocal of the chip's compute-to-bandwidth ratio, and newer accelerators have raised compute far faster than bandwidth. The A100 is 5.54× easier to saturate than the L40S, because it has proportionally less compute to leave idle.
So a low MFU on a modern chip is not necessarily bad engineering. Often it is the honest consequence of buying a chip whose balance does not match your workload — which is precisely the accelerator ladder's point, arriving again by a different route.
The diagnostic
- Stop reading
nvidia-smiutilisation as a cost metric. It reports occupancy. It will read ~100% at 0.34% MFU. - Compute
B × BW ÷ F_peakfor your setup. Three numbers, all public. It takes a minute and it is the ceiling — you cannot beat it by tuning. - Halve every headline TFLOPS figure you read. NVIDIA's tensor-core numbers are quoted with sparsity; dense inference gets half.
- Check your ceiling against what fits. If the batch needed for a decent MFU exceeds the batch your VRAM allows, MFU is not your problem — capacity is, and no kernel tuning will help.
- Do not expect quantisation to raise MFU. It raises throughput. Those are different claims and only one of them is true.
- If MFU matters more than latency, batch harder or go bigger. Both are capacity plays, not compute plays.
- Measure achieved tokens per second too. MFU is an efficiency ratio; it says nothing about whether you are fast enough, which benchmarking tokens per second per dollar covers.
What this chapter is not saying
It is not saying low MFU means you are doing something wrong. For interactive single-stream serving, a low MFU is structural — it is what bandwidth-bound decode on a compute-heavy chip looks like, and no amount of engineering changes B × BW ÷ F_peak.
It is saying that "the GPU is at 100%" is not evidence of anything you are paying for, and that the number which is evidence has a two-line derivation almost nobody performs. Do it once for your own stack. If the answer is 3%, you now know that 97% of your GPU bill buys nothing — and, more usefully, exactly which constraint you would have to move to change that.