Every LLM deployment decision β which GPU, how many concurrent users, whether the model fits at all β starts with one number: bytes per weight. Quantization is the highest-leverage knob you have, and it is worth understanding at the bit level, because the differences between formats are not marketing: they are concrete bit layouts with countable overheads and measurable accuracy costs.
This guide goes lower than most: what the bits inside FP8/FP4 actually encode, how block-scale metadata adds up, and how each popular format (NVFP4, MXFP4, FP8, GPTQ, AWQ, GGUF k-quants) spends its bits. Every number here is sourced from the primary papers, the OCP specification, or vendor documentation β and every size example is computed from the same formulas the site's VRAM calculator uses.
The One Formula That Matters
Model weights in memory:
where is the parameter count and is the effective bits per weight β the storage format's payload bits plus all scale/zero-point metadata, divided by the group size. The difference between "4-bit" formats is entirely in : naive 4-bit is 4.0, but real formats land between 4.125 and 4.85 bits per weight. On the Qwen3-VL-32B reference model (~33.4B parameters β 33,357,390,064 per the Hugging Face safetensors census β used throughout our VRAM deep dive), that difference is several gigabytes.
Generalized group overhead β this single expression generates almost every effective-bits number in this article:
= elements per group/block, = payload bits per element, and = bits for the scale (and optionally a zero-point) shared by the group. A 4-bit payload with one FP16 scale per 128 weights costs bits per weight; adding a 16-bit zero-point brings it to 4.25.
How a Float Becomes Bits
A binary floating-point number is three fields: sign , exponent , mantissa . The IEEE-754 pattern, generalized:
The exponent stores a power-of-two window; the mantissa stores position inside that window. Normal numbers have an implicit leading 1 (); when the number is subnormal (), extending the range down to zero at fixed spacing. The bias is set per format so the exponent range is centered usefully.
The 8-bit and 4-bit formats used in LLM inference are all this same structure with fewer bits:
| Format | Sign | Exponent | Mantissa | Bias | Largest finite value |
|---|---|---|---|---|---|
| FP32 (reference) | 1 | 8 | 23 | 127 | |
| BF16 | 1 | 8 | 7 | 127 | |
| FP8 E4M3 | 1 | 4 | 3 | 7 | 448 |
| FP8 E5M2 | 1 | 5 | 2 | 15 | 57,344 |
| FP4 E2M1 | 1 | 2 | 1 | 1 | 6 |
Two asymmetries in that table are deliberate, and both come from the FP8 formats paper that standardized E4M3/E5M2 (arXiv 2209.05433)1:
- E4M3 has no infinity and exactly one NaN pattern. Freeing those encodings extends its usable range to . It is the weights/activations format: transformer weight distributions need mantissa precision more than range.
- E5M2 follows IEEE conventions ( infinity + NaN), giving a much wider range () at lower precision. It is the gradients format, where magnitude spread dominates.
E2M1: All Sixteen Codes, On the Record
The 4-bit element at the bottom of every FP4 format is E2M1. With one mantissa bit and bias 1, its entire decode table has 16 entries β 8 magnitudes, each signed:
| Code (e,m) | Value | Code (e,m) | Value | |
|---|---|---|---|---|
| 00,0 | 0.0 | 10,0 | 2.0 | |
| 00,1 | 0.5 | 10,1 | 3.0 | |
| 01,0 | 1.0 | 11,0 | 4.0 | |
| 01,1 | 1.5 | 11,1 | 6.0 |
Sign bit set β the negative of each. That is the entire representable universe of FP4: β sixteen codes and β because +0 and β0 encode one value β fifteen distinct values, exactly. Raw E2M1 is far too coarse for transformer weights (which is why a 4-bit format without scaling is unusable); the entire low-bit-format design problem is how to reuse these sixteen levels block-by-block so they cover each weight neighborhood well. Everything else in this article is that trick, at different granularity settings.
The Granularity Ladder
Quantization error is dominated by outliers: one large weight in a group forces the scale up and wastes resolution on everything smaller. The historical fix is ever-finer scales:
- Per-tensor β one scale for all weights. Cheapest ( overhead) and least accurate. Classic FP8 inference works this way: a single FP32 scale per tensor, applied in software.1
- Per-channel β one scale per output row of each weight matrix. Still nearly free, much better. This is the default granularity of GPTQ and AWQ.
- Per-group (k=128) β one scale per 128 weights. GPTQ/AWQ's "small group size" setting; the AWQ paper notes round-to-nearest is already "quite strong" at group 128 with careful scaling (arXiv 2306.00978).2
- Per-block, power-of-two scale (k=32, E8M0) β the OCP MX standard: 32 E2M1 elements share one 8-bit power-of-two exponent (arXiv-tracked OCP MX v1.0 spec; the shared scale multiplies by a pure , so dequantization is an exponent add).3
- Per-block, FP8 scale + second level (k=16, E4M3 + FP32) β NVFP4, Blackwell's native format, detailed below.
Each rung adds scale bits β that is the arithmetic from the first section β and each rung contains outliers more tightly. The jump from rung 1 to rung 5 is roughly a 100Γ finer scaling mesh for about 0.5 bits per weight of metadata.
NVFP4 vs MXFP4: The Same Payload, Different Rulers
Two 4-bit block-floating formats ship on current hardware, and their difference is a textbook lesson in scale design. Both store E2M1 elements; neither touches the payload bits. Only the ruler differs:
| Property | MXFP4 (OCP standard) | NVFP4 (NVIDIA Blackwell) |
|---|---|---|
| Elements per block | 32 | 16 |
| Block scale | E8M0 (8-bit power of two) | E4M3 (8-bit FP8, fractional) |
| Second-level scale | β | FP32, one per tensor |
| Bits per element | ||
| Dequantization | bit-shift / exponent add | FP8 multiply |
| Native hardware | Broad MX ecosystem (AMD Instinct MI-series included) | NVIDIA Blackwell tensor cores |
Both layouts come straight from the NVIDIA NVFP4 introduction and the OCP MX specification.43 NVFP4's two changes attack the two error sources:
- Half-size blocks (16 vs 32): one outlier contaminates half as many neighbors.
- A fractional scale (E4M3 vs E8M0): an E8M0 scale must snap to the nearest power of two, so a block whose values sit between and loses up to half its representable range at the top. An E4M3 scale can land anywhere in the FP8 dynamic range. NVIDIA measures ~88% lower quantization error for E4M3 micro-block scaling versus power-of-two scaling, and in a head-to-head pretraining comparison MXFP4 needed ~36% more tokens to reach the same loss as NVFP4.5
The cost of the finer ruler is countable: 4.50 vs 4.25 bits per element, plus one FP32 per tensor (negligible at scale). And because the E4M3 scale has a narrower range than E8M0, NVFP4 adds the per-tensor FP32 second level to re-normalize whole tensors so every block's E4M3 scale stays well-conditioned β global range up top, local fit per block.
Accuracy, from NVIDIA's own PTQ study on DeepSeek-R1-0528 (converted FP8 β NVFP4): within 1% of FP8 across seven language-modeling evaluations, with AIME 2024 actually 2 points higher (89 β 91); MMLU-Pro 85 β 84, GPQA 81 β 80.45 The punchline β a 4-bit footprint behaving like an 8-bit model for most serving purposes:
which is exactly how NVIDIA states it (~3.5Γ and ~1.8Γ).4 On Blackwell tensor cores, FP4 dense throughput is 2Γ the FP8 rate β the same generational doubling FP8 did to FP16 on Hopper.
Weight-Only Integer Formats: GPTQ and AWQ
GPU hardware before Blackwell has no FP16ΓINT4 matrix path, so 4-bit integer formats are weight-only formats (W4A16): weights stored in 4 bits, dequantized on the fly, activations kept in FP16. The GPTQ paper is explicit that its speedups come from reduced memory movement, not cheaper math β there is no mixed-precision multiply on mainstream architectures (arXiv 2210.17323).6 For decode-time LLM inference that is precisely what you want: one user's token generation is memory-bandwidth-bound (see our inference math guide), so a 4Γ smaller weight stream is a near-4Γ faster token stream until you hit other ceilings.
The two families differ in how they choose the rounding:
- GPTQ (arXiv 2210.17323) quantizes weights column-by-column, propagating the rounding error of each column into the not-yet-quantized ones using an approximate second-order (Hessian-based) correction. It compensates errors, needs a calibration set, and quantizes OPT-175B-class models in hours, not days.6
- AWQ (arXiv 2306.00978, MLSys 2024 Best Paper) observes that 0.1β1% of weight channels are salient β identifiable from the activation distribution, not the weights β and protects them by searching a per-channel scaling that makes the full-4-bit representation of salient channels more accurate. No backprop, no reconstruction: it generalizes across domains and modalities without overfitting the calibration set.2
Both typically ship at group size 128 with FP16 scales: bits/weight before zero-points and packing metadata. The interactive calculator models this class of format with a flat 12% overhead factor (int4/AWQ Γ1.12) to stay conservative across implementations; hand-check with the formula above when it matters.
One warning from the low level: the scale layout β how scales are interleaved with packed values in memory β varies between exports (block-interleaved, scales-after-values, per-K, tile-major) and is a recurring source of serving-stack bugs when a checkpoint quantized by tool A is loaded by runtime B. If a 4-bit model produces garbage, suspect the scale layout before the model.
GGUF K-Quants: The Byte Layouts, Verified
llama.cpp's k-quants are the most deployed weight quantizers in the world, and they document their own arithmetic. The 2023-of-record k-quant PR defines the super-block structure (QK_K = 256), and llama.cpp's source carries static_asserts that force the byte counts; these are the published per-weight bit costs:7
| Type | Super-block structure | Bytes | Effective bits/weight |
|---|---|---|---|
| Q4_K | 8 blocks x 32 weights: FP16 scale + FP16 min + 12 B of 6-bit block scales/mins + 128 B payload | 144 / 256 w | 4.5 |
| Q5_K | same + 32 B high-bit plane | 176 / 256 w | 5.5 |
| Q6_K | 16 blocks x 16 weights: FP16 super scale + 16 B of 8-bit block scales + 192 B payload | 210 / 256 w | 6.5625 |
| Q8_0 | FP16 scale + 32 B INT8 payload per 32 weights | 34 / 32 w | 8.5 |
Read Q4_K's row as the generic formula again: 2 bytes d + 2 bytes dmin + 12 bytes packed 6-bit scales + bytes of nibbles = 144 bytes per 256 weights β bits per weight, plus sixteen levels with a two-level scale hierarchy (super-block FP16 scale over per-block 6-bit scales) so fine scaling doesn't cost a full FP16 per 32 weights.
The _S/_M/_L suffixes are a tensor policy, not a format: they pick which tensors get stored above base width (Q4_K_M keeps attention.v and MLP down-proj at higher precision than Q4_K_S). The published effective bpw therefore varies slightly per model: Q4_K_M measures 4.84 bpw on Llama-2-7B, 4.83 on 13B, 4.80 on 70B β the llama.cpp quantize README's own table.7 Quality ordering from llama.cpp's published perplexity runs (Llama-2-7B): Q8_0 at 5.9070 vs F16 5.9066 β effectively indistinguishable; Q4_0/K variants sit between; and quality-wise the community default Q4_K_M costs roughly 1% perplexity for ~30% of the FP16 size.
Putting the Formats Side by Side
Effective bits and what you pay for them, using from the group-overhead formula (integer formats at typical group 128; NVFP4 at 4.50; GGUF at published bpw):
| Format | GB per 33.4B params | Quality position | |
|---|---|---|---|
| FP16 / BF16 | 16.0 | 66.7 GB | reference |
| FP8 E4M3 (+3% scale overhead) | 8.24 | 34.4 GB | β lossless vs FP16 in serving; the de-facto flagship checkpoint format |
| GGUF Q8_0 | 8.5 | 35.4 GB | perplexity delta ~0.004% on Llama-2-7B β reference quality |
| GGUF Q6_K | 6.5625 | 27.4 GB | near-nil quality loss, ~59% smaller than FP16 |
| GGUF Q4_K_M | 4.84 | 20.2 GB | ~1% perplexity cost, the community default |
| NVFP4 | 4.50 (spec) / 4.95 (site-calculator, +10% scale overhead) | ~18.8 / 20.6 GB | within ~1% of FP8 (NVIDIA PTQ study)4 |
| AWQ / GPTQ int4 (+12% overhead) | 4.48 | 18.7 GB | strong at g=128; AWQ guards salient channels2 |
| MXFP4 | 4.25 | 17.7 GB | needs ~36% more tokens to match NVFP4 loss in pretraining5 |
Three honest observations fall out of the table:
- "4-bit" spans a ~16% size range (17.7β20.6 GB) purely from scale metadata. When a quantized model "doesn't quite fit", the metadata is where the budget went.
- FP8 has effectively won the high end. Flagship open models ship FP8 checkpoints first (Qwen3-Next, DeepSeek), and E4M3 is the default inference format on Hopper and Blackwell. 16β8 bit halves the footprint at βzero serving-quality cost.
- The 4-bit formats are now quality-competitive with 8-bit. NVFP4's β€1% delta vs FP8 and Q6_K's near-nil cost mean the 4-5 bit band delivers 3.2β3.8Γ more model per GB than FP16 β with quantization error now dominated by calibration quality, not bit count.
Which Format Should You Run?
Self-hosted, single-user or small-batch (llama.cpp/LM Studio/Ollama): start Q4_K_M. Size any step-up with against your VRAM after reserving KV-cache (the break-even calculator's KV math applies unchanged). If code/math quality matters, Q6_K; if you are establishing a reference, Q8_0.
vLLM/SGLang/TensorRT-LLM serving on Hopper: FP8 (E4M3 weights, per-tensor or per-block scales per your runtime's support). 4-bit integer weights (AWQ/GPTQ) when VRAM pressure demands it β expect a measurable but small quality step.
Blackwell serving at scale: NVFP4. It is the native format of the hardware's 4-bit tensor cores, the ecosystem (vLLM/TRT-LLM model optimization) supports it directly, and the accuracy tax vs FP8 is ~1% per NVIDIA's measurements. MXFP4 remains the OCP-standard option with broader cross-vendor portability (AMD's MI-series supports MX-family formats).
Whatever you pick, measure. Publish your own before/after on your workload β the perplexity deltas above are Llama-family measurements under llama.cpp calibration; arrival distributions, long-context regimes, and tool-calling patterns shift them. The formulas in this article give you the frontier; only your benchmark tells you where on it to sit.
Further Reading
- LLM VRAM Requirements: A Mathematical Deep Dive β the full weight + KV-cache memory model this article's examples plug into.
- LLM Inference Math: From Theory to Hardware β why decode is memory-bound, which is why is also your throughput knob.
- How LLMs Actually Work β tokenizers, attention and sampling background for the format decisions above.
Footnotes
-
Peng et al., FP8 Formats for Deep Learning, arXiv:2209.05433 (NVIDIA/Arm/Intel). β© β©2
-
Lin et al., AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration, MLSys 2024, arXiv:2306.00978. β© β©2 β©3
-
OCP Microscaling Formats (MX) Specification v1.0, Open Compute Project β block size k=32, E8M0 shared scale. β© β©2
-
NVIDIA Developer Blog, Introducing NVFP4 for Efficient and Accurate Low-Precision Inference (block layout, E4M3+F32 scaling, DeepSeek-R1-0528 accuracy, ~3.5Γ/~1.8Γ footprint ratios). β© β©2 β©3 β©4
-
NVIDIA Efficient AI research blog, Pushing Intelligence to 4-bit (~88% error reduction vs power-of-2 scaling; MXFP4 +36% tokens head-to-head; MMLU-Pro/GPQA/AIME numbers). β© β©2 β©3
-
Frantar et al., GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers, arXiv:2210.17323. β© β©2
-
llama.cpp repository β
ggml/src/ggml-common.hk-quant structs with sizeof static_asserts,examples/quantize/README.mdBPW/perplexity tables (ggml-org/llama.cpp). β© β©2