Skip to content

Inference physics chains: the ridge, the decode floor and what a step costs

8 chains

These are the numbers a physics round asks for before anyone draws a box. Every hardware figure is a dense peak from the part's datasheet, as recorded in the site's hardware table; sparse peaks are twice as large and do not apply to a dense model.

The ridge point

inputs   dense BF16 peak and HBM bandwidth per GPU
H100 SXM 989 TFLOP/s / 3.35 TB/s = 295 FLOP per byte
H200 SXM 989 TFLOP/s / 4.8 TB/s  = 206 FLOP per byte
B200     2,250 TFLOP/s / 8 TB/s  = 281 FLOP per byte
H100 FP8 1,979 TFLOP/s / 3.35 TB/s = 591 FLOP per byte
sanity   batch-1 decode does about 1 FLOP per byte: bandwidth-bound by
         two orders of magnitude on all three parts

Using the "with sparsity" peak doubles the ridge and moves every crossover after it. The H200 has the same compute as the H100 and more bandwidth, so its ridge is lower: more work becomes compute-bound.

Drilled in: The roofline model for inference

The batch-1 decode floor

inputs   Llama 3.1 8B, BF16: 16.06 GB of weights read once per step
formula  step >= bytes read / bandwidth
H100     16.06 GB / 3.35 TB/s = 4.79 ms   (209 tokens/s)
H200     16.06 GB / 4.8 TB/s  = 3.35 ms   (299 tokens/s)
B200     16.06 GB / 8 TB/s    = 2.01 ms   (498 tokens/s)
sanity   the floor scales with bandwidth alone; the B200's extra compute
         does nothing for this step

A floor is a lower bound. It leaves out KV reads, kernel launches and sampling, so a real step sits above it, and how far above is what MBU measures.

Drilled in: Batch-1 decode floor on two H100s · H100 to B200 by regime

Prefill time

inputs   Llama 3.3 70B, 70.55e9 parameters, BF16, TP=2 on H100 SXM
         a 4,096-token prompt; dense FLOPs about 2 x parameters per token
linear   2 x 70.55e9 x 4,096 = 578 TFLOP
attention 2 x 80 layers x 4,096^2 x 8,192 = 22 TFLOP (3.7%)
time     600e12 / (2 x 989e12) = 303 ms at peak
sanity   0.074 ms per prompt token; real prefill runs below peak, so
         divide by the MFU you can defend before quoting a TTFT

The 303 ms is a floor at 100% of peak. Quote it with the MFU assumption attached, because the interviewer will ask for one.

Drilled in: FLOPs per token from the config · Prefill time for a 4K prompt on 70B

Where batching crosses the ridge

inputs   one weight matrix of N parameters in BF16 (2N bytes)
decode   batch B: 2NB FLOPs over 2N bytes = B FLOP per byte
prefill  chunk of T tokens: 2NT FLOPs over 2N bytes = T FLOP per byte
H100     compute-bound once B or T passes about 295
FP8 W8A8 2NT FLOPs over N bytes = 2T, against a 591 ridge: T = 295 again
sanity   halving the bytes and doubling the peak leaves the crossover
         where it was

The crossover covers the weight GEMMs only. Attention reads each sequence's own KV, which no other sequence shares, so long-context decode stays bandwidth-bound at any batch size.

Drilled in: Arithmetic intensity per decode op

When KV reads overtake weight reads

inputs   Llama 3.1 8B BF16: 16.06 GB of weights, 128 KiB of KV per token
         batch 64, every sequence at context L
formula  KV per step = B x L x 131,072 B; equal to weights when
         L = 16.06e9 / (64 x 131,072) = 1,914 tokens
sanity   past 1,914 tokens of context the KV, not the model, sets the
         step time at this batch

Bigger batches pull the crossover in: at batch 256 it is 479 tokens. Capacity plans that price decode by weights alone are wrong for any chat workload with history.

Drilled in: Context where KV reads overtake weights

A batched decode step

inputs   Llama 3.1 8B BF16 on one H100 SXM, batch 64, 2,048 tokens each
KV       64 x 2,048 x 131,072 B = 17.2 GB
step     (16.06 + 17.2) GB / 3.35 TB/s = 9.9 ms at the floor
output   64 / 9.9 ms = 6,450 tokens/s in aggregate, 101 per stream
sanity   batching multiplied throughput by 31 and cost each stream half its
         batch-1 speed

Throughput per GPU and speed per user move in opposite directions along the same curve. Which point on it a product wants is the decision the arithmetic serves.

Drilled in: Decode throughput-latency curve

One output token against one prompt token

inputs   the Llama 3.3 70B TP=2 deployment above, batch 1, 4,096-token context
decode   weights 70.55 GB + KV 0.67 GB per GPU = 71.2 GB / 3.35 TB/s = 21.3 ms
prefill  0.071 ms per prompt token for the linear layers
ratio    21.3 / 0.071 = 300x
sanity   the ratio is the ridge point, as it must be at batch 1

Providers price output above input for this reason, and by much less than 300x, because a loaded server spreads each decode step's weight read across many sequences.

Drilled in: Prefill versus decode

MBU from a measured step

inputs   suppose Llama 3.1 8B at batch 1 measures 6.0 ms per step on an H100 SXM
formula  MBU = bytes the step must read / step time / peak bandwidth
         16.06e9 B / 6.0e-3 s / 3.35e12 B/s = 80%
sanity   80% of the floor is good for batch-1 decode; the missing 20% is
         launches, sampling and the parts of the step that are not reads

Count only bytes the step must read: weights once, plus each sequence's KV. Adding activations or counting a shared prefix once per sequence inflates MBU past what the memory delivered.

Drilled in: Measure MBU on a running server · Model bandwidth utilization

Next card: KV Cache Interview Chains