Quantization, Mapped: Weights, Activations, KV Cache

The Serving Stack
by The Serving Stack··6 min read·
QUANTIZATION · 02WEIGHTSACTIVATIONSKV CACHE16 BITS → 4, 8, 8

A quantized checkpoint's name often hides three choices. "W4A16" means weights in 4 bits, activations in 16. "W8A8" means both in 8. "FP8 KV cache" means the attention cache is stored in FP8. Each choice quantizes a different kind of number, saves a different resource, and carries a different risk. This piece maps the three before the rest of the series goes into methods.

Three kinds of numbers

Diagram of one decoder layer: RMSNorm, q/k/v projections, attention reading the KV cache, o projection, RMSNorm, gate/up projections, SiLU, down projection. Projections are weights, the arrows between them are activations, and the KV cache stores past keys and values.Diagram of one decoder layer: RMSNorm, q/k/v projections, attention reading the KV cache, o projection, RMSNorm, gate/up projections, SiLU, down projection. Projections are weights, the arrows between them are activations, and the KV cache stores past keys and values.

  • Weights are the model's parameters: the matrices in every projection. They never change while serving, and every decoding step reads all of them.
  • Activations are the vectors flowing between layers, one per token. They are different for every input.
  • The KV cache holds the keys and values of every past token of every request, so attention does not recompute them. It grows with each token generated.

Weights: memory and decoding speed

Quantizing the weights shrinks the model in memory, and that alone speeds up decoding. Generating one token for one request reads every weight once and does little arithmetic with each, so decoding is limited by memory bandwidth (The Roofline for LLMs). Fewer bytes, faster tokens: on a GB10, Qwen3-8B's weights went from 15.27 GiB in BF16 to 5.98 GiB in NVFP4, and single-request decoding went from 13.6 to 36.1 tokens per second, 2.7 times faster for 2.6 times fewer bytes (NVFP4 on Blackwell).

Weight-only quantization (W4A16, W8A16) gets this gain without touching the math: the kernel turns the weights back into 16 bits just before multiplying. Some weights are usually left alone. The embeddings and the output layer often stay in BF16: for Qwen3-8B, with a 151,936-token vocabulary and separate input and output matrices, they are 2.3 GiB on their own, which is why a "4-bit" Qwen3-8B is 6 GiB and not 4. Norms stay in higher precision too (Where Low Precision Bites).

The risk is moderate and well understood: weights have outliers, so they need fine-grained scales (Integers for AI: INT4 needs groups of 128 or 32), and methods like GPTQ and AWQ pick the integers to protect the layer's outputs.

Activations: compute

Weight-only quantization saves bytes but not arithmetic. When many tokens are processed at once, reading a long prompt or decoding for many requests, the GPU is limited by computation instead, and the only way to go faster is to multiply in a smaller format. That needs both operands quantized: the weights and the activations. On the same GB10, NVFP4 weights and activations (W4A4) read an 8,000-token prompt in 871 ms against 1,735 ms for BF16, which a weight-only format would not do.

This is the riskiest of the three. Activations are different for every input, so their scales are computed on the fly, often per token. And they have outliers far worse than weights: Qwen3-8B carries "massive activations" of about 12,000 from layer 7 on (FP16 vs. BF16). That is why the format matters more here: on Qwen3-8B's activations, FP8 E4M3 has a quarter of INT8's error with one scale per tensor (FP8), and NVFP4's fine block scales bring 4-bit activation error down to 3.7% (NVFP4). Methods like SmoothQuant and rotations exist to tame activation outliers before quantizing them.

KV cache: memory per token

The KV cache costs a fixed amount per token: for Qwen3-8B, 36 layers × 8 key-value heads × 128 dimensions × 2 (keys and values) × 2 bytes = 144 KiB per token in BF16. That adds up fast:

Bar chart of Qwen3-8B memory in GiB. Weights: 15.27 BF16, 8.85 FP8, 5.98 NVFP4. KV cache for one 32,000-token request: 4.5 BF16, 2.25 FP8. For 32 requests of 8,000 tokens: 36 BF16, 18 FP8.Bar chart of Qwen3-8B memory in GiB. Weights: 15.27 BF16, 8.85 FP8, 5.98 NVFP4. KV cache for one 32,000-token request: 4.5 BF16, 2.25 FP8. For 32 requests of 8,000 tokens: 36 BF16, 18 FP8.

With one long request, the weights dominate. With 32 requests of 8,000 tokens, the cache needs 36 GiB in BF16, more than twice the BF16 weights. Storing it in FP8 halves it: in vLLM, --kv-cache-dtype fp8 (E4M3; fp8_e5m2 is the alternative). On the GB10, the NVFP4 checkpoint that also stored its KV cache in FP8 had room for 1.35 million cached tokens against 668,000 without, twice as many requests at once.

The risk sits between weights and activations: keys and values are activations stored for later, and attention reads all of them for every new token. A later piece in this series measures what FP8 and smaller caches cost.

Reading the names

You see Weights Activations KV cache Mostly saves
BF16 16-bit 16-bit 16-bit nothing (the reference)
W8A16, W4A16 (most GPTQ and AWQ checkpoints) 8 or 4-bit 16-bit unchanged memory, decode speed
FP8, W8A8 8-bit 8-bit unchanged memory, decode and prefill speed
NVFP4, MXFP4 with 4-bit activations (W4A4) 4-bit 4-bit unchanged the most memory and compute
"FP8 KV cache" any any 8-bit memory per request, longer contexts

The KV cache setting is independent of the checkpoint: you can store the cache in FP8 with BF16 weights, or keep it in BF16 with 4-bit weights.

What comes next

The rest of this series takes each part of this map in turn: what one model costs in size, speed, and quality in a dozen formats, measured (How Much Does Each Bit Cost?); how post-training quantization handles outliers; GPTQ, AWQ, SmoothQuant, and rotations; quantization-aware training; the KV cache; GGUF; mixture-of-experts models; and how to measure the damage.

The Serving Stack
The Serving Stack

Inference engineering and AI in production — depth-first, no hype.

Inference Notes

Once a week: what changed in serving AI models, and what it means if you build, run or pay for them, in about five minutes.

Related Articles