Runbooks/ LLM Inference Runbook Track C · Shrinking the footprint 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 09 · Quick learn Range vs precision · The block scale · Effective bits

What the bitsactually buy

What the bits in a float actually buy, why the nominal bit width is never the real one, and which of five methods to reach for on which hardware.

“Sixteen marks across three metres is useless. Sixteen marks across the range you actually have is precise.”
4.16 bits
what “4-bit” AWQ g128 really costs
4.90 bits
GGUF Q4_K_M — a 13B is 7.9 GB
8 exponent bits
why bf16 won
7.5 GiB
freed on an 8B by fp8 — 14% more users
What a number format istwo minutes here makes the rest obvious

Quantisation is usually explained without explaining what a float is, which turns the whole topic into memorisation. A floating-point number spends its bits on two things.

Exponent bits → range

How big or small the value can be.

fp32 and bf16: 8 bits · fp16: 5
Mantissa bits → precision

How finely it can be distinguished from its neighbours.

fp32: 23 · fp16: 10 · bf16: 7
Why bf16 won, in one paragraph

fp16 has five exponent bits, which caps the largest representable value at about 65,500. During training, activations and gradients routinely exceed that, so fp16 needs loss scaling and careful handling. bf16 spends the same sixteen bits differently: eight exponent bits, the same as fp32, so the same enormous range — and only seven mantissa bits.

That is the right trade, because networks tolerate imprecision far better than they tolerate overflow. Which is why almost every published checkpoint ships in bf16
The analogy — sixteen boxes on a form

One scheme uses most of the boxes for decimal places — brilliant for anything between 0.001 and 100, and unable to write down a million at all. The other reserves boxes for an exponent — it can write anything from a trillionth to a trillion, but only to three significant figures.

For measuring things whose magnitude you cannot predict, the second is the only one that works
What quantisation doesand the block scale that makes it work at all
16 marks over 3 metres

Everybody in a normal group rounds to the same value. Useless.

Look at the group first

All between 1.5 and 1.9 m — fit the same 16 marks across just that band.

That band is a block

Typically 32 to 128 weights that sit together.

The note is the scale

Stored alongside — and that is the catch.

effective bits = nominal + ( scale bits + zero-point bits ) ÷ block size
a 16-bit scale and a 4-bit zero-point per 128 weights adds 0.16 bits to every weight

The correction this document exists to make

16
bf16what the checkpoint ships in
16.00
8
int8 with scales~8.13 effective
8.13
K
GGUF Q4_K_Mmixed precision inside a layer — attention keeps more bits
4.90
A
AWQ / GPTQ g128one 16-bit scale per 128 weights
4.16
4
“4-bit”, as quotedthe nominal number, which nothing actually stores
4.00
Worked13B at Q4_K_M = ~7.9 GB, not the 6.5 the nominal width impliesa 20% gap — exactly the size that turns “it fits” into an OOM
Why the gap matters

4-bit formats store a scale — usually 16-bit — and often a zero-point, per block of 32 to 128 weights. And mixed-precision recipes keep sensitive tensors at higher precision.

Always size from the published file, or from effective bits — never from the nominal width
Group size is the whole tuning dial

Smaller blocks track the local range more tightly, so quality is better, and cost proportionally more overhead — a group of 32 has four times the scale cost of a group of 128.

128 is the usual default and a reasonable place to leave it
The five methodseach fixes a different weakness of naive rounding

Round-to-nearest has three weaknesses. Every named method is an attempt to fix one of them — and being able to say which is a far better answer than listing acronyms.

Round-to-nearest

Per-block scale from the largest magnitude; round to the nearest level.

No calibration
Runs anywhere · the baseline everywhere
GPTQ

Quantise weight by weight, adjusting the not-yet-quantised weights to compensate for each rounding error.

Needs calibration
GPU, hours · older GPU servers
AWQ

Find the ~1% of channels carrying large activations and scale those weights up before rounding.

Needs calibration
GPU, faster than GPTQ · the pre-Hopper default
k-quants (GGUF)

Mixed precision inside a layer — attention and output tensors keep more bits than the FFN.

No calibration
CPU, Apple silicon, GPU · laptops and local use
FP8

Cast to native 8-bit float; Hopper and later multiply it directly, with no unpacking.

No calibration
H100 and newer · the modern production answer
GPTQ attacks compounding error

It nudges the not-yet-quantised weights to compensate for each rounding error it introduces — like shifting people in a group photo when one has to move.

Can overfit to its sample texts, and uses heavier second-order machinery for the same job
AWQ attacks importance

It watches the activations, finds the roughly one per cent of channels carrying unusually large signals, and scales those weights up before rounding so they land where they should.

Simpler, faster to produce, more robust to the choice of calibration set, and slightly better in quality
What happens when the model runsmisunderstood constantly
Offline, once

A one-off job producing a smaller file. Same architecture, same tokeniser.

4-bit stays 4-bit

In VRAM, for the whole session. Never expanded back to full size in memory.

Unpacked per slice

To 16-bit inside on-chip memory, used, and discarded.

fp8 is the exception

Multiplied natively on Hopper-class hardware — no unpacking at all.

Three things, and keeping them straight makes half the confusion evaporate

Weights

Learned during training. Never change. One copy serves everyone.

Quantised offline, once, producing a new file · the recipe
Activations

Calculated from your input. Change every single request. Yours alone.

Quantised at run time if at all, and it is much harder · the ingredients
The KV cache

Activations that you chose to keep.

A runtime flag rather than an offline job — and its error accumulates over a generation, because a key quantised at token 10 is still read at token 10,000
It is the weights that unpack, not the activations

Activations were 16-bit all along. Getting this direction right is a genuine signal.

And weight quantisation error is fixed and calibrated against once; cache quantisation error is not. Test the cache on long outputs
Choosing, and measuring the damagethe honest version
H100 or later

fp8. No calibration data, minutes to produce, near-lossless, and multiplied natively.

It cuts operations as well as bytes — the only method that does
A100 and older

AWQ at group size 128.

Simpler and more robust than GPTQ, and slightly better in quality
Laptop / local

GGUF Q4_K_M.

~4.90 effective bits · mixed precision inside each layer
How to size the quality question honestly

The honest answer to “does quantisation make the model dumber” is: a little, it depends on the method and the bit width, and you measure it on your own workload rather than trusting a general claim.

What to actually do: take a fixed set of a few hundred real requests, run them against the bf16 model and the quantised one, and score on whatever the product cares about
Two failure modes specific to quantisation

It degrades unevenly. Aggregate scores can hold up while one capability falls off a cliff — frequently long-context retrieval, multilingual output, or exact formatting. Test the slices separately, not just the mean.

Below about 4 effective bits, ask a different question.

The honest comparison is not “4-bit versus 3-bit of this model” but “3-bit of this model versus a smaller model at higher precision” — and very often the smaller model at 8-bit wins on both quality and speed
Answer it out loudthe ninety-second version, then five questions
“Quantisation stores each weight in fewer bits, and the thing that makes it work is the per-block scale: you fit the available levels across the actual range of 32 to 128 neighbouring weights rather than across the whole model. The scale is stored too, so the nominal width is never the real one — 4-bit is really 4.16 with AWQ at group size 128, or 4.9 for a mixed GGUF recipe, which makes a 13B file 7.9 GB rather than 6.5. The methods each attack a different weakness of naive rounding: GPTQ compensates for compounding error, AWQ protects the one per cent of channels with large activations, k-quants mix precision inside a layer. On Hopper and later the answer is fp8, because the silicon multiplies it natively — so it cuts operations as well as bytes.”

Five questions, and the spine of each answer

Architect

What does quantisation do, and what does it cost?

  • Stores each weight in fewer bits — and the mechanism is the per-block scale
  • Without it you would spread sixteen levels across the whole dynamic range and everything would round to the same value
  • Quality: small for fp8, measurable for good 4-bit, noticeable below that — measure it on your own workload
  • Bookkeeping: the scale is stored too — 4-bit is really 4.16, or 4.9 for Q4_K_M
Which is why a 13B Q4_K_M file is 7.9 GB and not 6.5 — a 20% gap, and exactly the size of error that turns “it fits” into an OOM on the first request.
Architect

GPTQ or AWQ?

  • They attack different weaknesses of naive rounding
  • GPTQ: compounding error — nudge the not-yet-quantised weights to compensate
  • AWQ: importance — find the ~1% of channels with large activations and protect them
  • In practice AWQ on pre-Hopper: simpler, faster, more robust to the calibration set
But the first question is what hardware we are on — because on H100 or later the answer is neither. It is fp8: no calibration data, minutes, near-lossless, multiplied natively.
Architect

Does a 4-bit model run four times faster?

  • No — run the three-way test. It cuts bytes stored and bytes moved. It does not cut operations
  • Except on hardware with native support: fp8 on Hopper, fp4 on Blackwell
  • Decode is bandwidth-bound, so it does speed up — but unpacking 4-bit to 16-bit costs real work
  • And at scale the cache is most of the read — 81% at 8k × batch 64
Honest framing: quantise the weights for capacity first, because freeing 7.5 GiB on an 8B directly buys concurrency. Treat the speed as a welcome secondary effect.
Eng manager

Can we halve our GPU bill by quantising?

  • Depends which constraint we are under — answer with a measurement, not a prediction
  • Memory-constrained? bf16 → fp8 frees 7.5 GiB on an 8B = 14% more users. int4 frees 10.5 GiB
  • On a 24 GB A10: bf16 leaves room for one user; int4 leaves room for fourteen
  • Compute- or utilisation-constrained? Much less
Put the alternative on the table at the same time, because it is often bigger: a half-idle expensive GPU costs the same as a busy one, so consolidating traffic frequently beats any quantisation gain.
Architect

A 70B at 3-bit, or an 8B at bf16?

  • Roughly 4× the concurrency and 2.5× the streaming speed for the smaller model
  • That is a big enough gap to settle by head-to-head evaluation on a few hundred real requests
  • And I want the per-slice breakdown, because heavy quantisation degrades unevenly
Aggregate scores can hold up while one capability falls off a cliff. If the 70B at 3-bit does not clearly win on what the product cares about, it does not win.
Fast answersthe ten that come up most

QWhy is bf16 the format most weights ship in?

Same sixteen bits as fp16, split differently: eight exponent bits instead of five, so fp32’s dynamic range with less precision. Networks tolerate imprecision far better than overflow, so that trade is much more forgiving during training.

QDoes quantisation make the model dumber?

A little, and how much depends on method and bit width. fp8 is nearly indistinguishable; good 4-bit loses a small measurable amount; very low widths degrade noticeably. The honest answer is that it is a trade you measure on your own workload.

QCan I quantise a model myself?

Yes. Data-free methods — GGUF conversion, an fp8 cast — run on an ordinary machine in minutes to hours. Calibration methods (GPTQ, AWQ) need a GPU and can take many hours, because they run the model forward on sample text repeatedly.

QIs quantisation the same as pruning or distillation?

No. Quantisation keeps every weight but stores each with fewer bits. Pruning removes weights. Distillation trains a smaller model to imitate a bigger one. Quantisation is the only one that leaves the architecture untouched — which is why it is an afternoon rather than a project.

QWhat does group size control?

How many weights share one scale factor. Smaller groups track the local range more tightly and cost proportionally more overhead — a group of 32 has four times the scale cost of 128. 128 is the usual default.

QWhy does loading a model take so long?

Most of it is reading tens of gigabytes off disk. Which is a real argument for quantisation that nobody makes: a 4-bit model is a quarter of the bytes, so cold start is roughly four times faster — and cold start is what makes autoscaling an LLM hard.

QCan I mix fp8 weights and an fp8 cache?

Yes, and think of them as independent levers that multiply. fp8 weights free memory that becomes KV budget; an fp8 cache halves what each user needs from that budget. Evaluate them separately, because their error modes differ.

QWhat is SmoothQuant, and where does it fit?

It addresses the same activation-outlier problem AWQ does, but for activation quantisation — migrating the difficulty from activations into weights by rescaling both. Weight-only is far more common in serving because it captures most of the memory benefit.

QWhy is my quantised model slower than expected?

Most likely the kernel. A quantised format only gets its speedup if the server has a fused kernel reading the packed weights directly; a generic path that dequantises into a full-size buffer gives you the memory saving and none of the speed. Be suspicious if throughput barely changed while memory did.

QOne sentence on when to quantise?

When memory is the binding constraint. If cache utilisation is pinned and requests are queueing for blocks, quantising the weights directly buys concurrency. If the card is half idle, quantisation is solving a problem you do not have.

The nominal bit width is never the real cost. A 4-bit format stores a scale — usually 16-bit — and often a zero-point, per block of 32 to 128 weights, and mixed recipes keep sensitive tensors higher. AWQ at group size 128 is 4.16 effective bits; GGUF Q4_K_M is 4.90. Size from the published file, never from the number in the name — the 20% gap is exactly what turns “it fits” into an out-of-memory failure on the first request.

nominal 4.00
Q4_K_M 4.90
bf16 16.00
Where this goes next

Questions to ask them

What precision are you serving, and was it chosen for memory or for speed?

Has anyone measured the quality drop on your own traffic, per slice rather than on average?

Do you size models from the published file, or from nominal bit width?

Is the engine using a fused quantised kernel, or dequantising into a full-size buffer?

If you are on Hopper or later, is there a reason you are not on fp8?

Has anyone compared a smaller model at higher precision against the large one at 4-bit?

← 08 · Position Read the full chapter → 10 · Cache ops →