The biggest term in the cache formula, and the one lever you cannot turn at serving time — so it becomes a model-selection decision worth a factor of four.
Document 06 showed that kv_heads is the biggest lever in the cache formula. This document is about that one term. The dial is: how many key-value heads exist for the query heads to share?
32 query heads, 32 KV heads. Every head has its own.
32 query heads, 8 KV heads. Groups of four share one.
32 query heads, 1 KV head. All thirty-two share it.
8 KV heads on a 4,096‑wide model gives 8 × 128 = 1024 columns. It is not 4096 ÷ 8 = 512. Head dimension is fixed at 128; you multiply it by the head count.
Thirty-two researchers each have their own question — those are the query heads, and they stay thirty-two in every version. MHA gives each a private copy of the whole reference collection: no contention, enormous storage. MQA gives one copy for all thirty-two: minimal storage, but some questions are badly served.
d × d, always 4096×4096.
d × d, always 4096×4096.
d × (kv_heads × 128).
d × (kv_heads × 128).
Many heads end up looking at similar material, so sharing the redundant part costs little. Queries stay genuinely diverse, and they are untouched — every one of the 32 query heads still computes its own scores and its own output.
The query heads never learn to depend on 32 distinct key spaces in the first place.
You have an MHA checkpoint and you want GQA without paying for pre-training again. The GQA paper’s contribution is a recipe for exactly this — and it is a favourite follow-up because it separates people who read the paper from people who read a summary.
The existing key and value projections — one head per query head.
Into the size the target implies: fours, to go 32 → 8.
Each group down to one head. It beat both alternatives tried.
Continue pre-training on ~5% of the original compute.
Wrong, and it sounds it. You would be throwing away three quarters of the learned key and value information rather than combining it.
Five per cent of a frontier pre-training run is still a serious job with a serious bill.
GQA reduces how many things you store. Multi-head latent attention keeps all of them and reduces how big each one is. Same goal, opposite direction.
Keep 8 full-size KV heads instead of 32.
Keep all 32 heads; project them jointly into one small latent and cache that.
Keys are rotated for position before caching, and a rotated key cannot be cleanly squeezed and unsqueezed. DeepSeek split the key into a compressed content part and a small separate part carrying the rotation.
MLA is an architectural decision made before training, exactly like GQA. You cannot switch a GQA model to MLA with a flag. Support is also newer.
Nothing in quality; everything in memory.
A fraction of a percent of quality.
A real, measurable quality drop — and training instability.
Genuinely lossy beyond the window; awkward with prefix caching.
Extra arithmetic per step; newer, less universally supported.
“For serving, I do not choose this — I inherit it by choosing the model, because it is baked into the weights. So it becomes a model-selection criterion: I would read num_key_value_heads from the config before anything else, because on an otherwise equal comparison a model with 8 KV heads serves four times the users of one with 32. If long context is central I would look seriously at an MLA model; if exact long-range recall is not critical, a sliding-window or hybrid design for the bounded cache.”
What problem does GQA actually solve?
How does GQA differ from MQA, and why did GQA win?
Can you convert an existing MHA model to GQA?
How is MLA different from GQA, and why did DeepSeek choose it?
Two models look equivalent on benchmarks. How do you choose for serving?
Why is 8 KV heads so common?
Does GQA hurt long-context quality more than short?
QDoes GQA reduce model parameters?
Slightly. On the 8B, attention parameters per layer fall from about 67M to about 42M because W_K and W_V shrink — roughly 4% of the whole model. Real, but an order of magnitude less interesting than the cache saving. Mention it second or third, never first.
QCan I change a served model’s KV head count with a flag?
No. It is baked into the weights — the shape of W_K and W_V. What is a runtime flag is the cache dtype: fp8 KV halves the same number and stacks multiplicatively with whatever head ratio the model already has.
QDoes GQA interact with tensor parallelism?
Yes, and it is a good detail to raise. With 8 KV heads and 8-way TP, each GPU holds exactly one — clean. If the degree exceeds the head count you must replicate heads across devices, which costs the memory back.
QIs “GQA gives an 8× saving” correct?
Only for models where it happens to be true. It gives query heads ÷ KV heads — 4× on Llama 3.1 8B and 8× on the 70B, within the same family. Quoting a single ratio as a general fact is wrong roughly half the time.
QWhat is sliding-window attention doing differently?
It bounds the cache instead of shrinking each entry. Each token attends only to the last W tokens, so the cost becomes flat in context length rather than linear. Genuinely lossy: a token outside the window is not attended to at all. Gemma 2’s alternating design is the interesting compromise.
QCould a model use different KV head counts per layer?
Nothing forbids it, and hybrid designs are an active area — Gemma 2’s alternation of local and global layers is this idea applied to the attention pattern. Mainstream open models keep it uniform, which is why the cache formula has a single layers multiplier.
QIs MLA going to replace GQA?
Unknown, and the honest answer is that it depends on whether the quality result replicates across labs and on tooling support catching up. What is clear is that it is a pre-training decision either way — track it as a model-selection input, not a migration plan.
QWhat about MoE — does it help the cache?
Not at all. Mixture of experts replaces the feed-forward block; attention — and therefore the KV cache — is completely untouched. It cuts operations per token and saves no memory whatsoever. MoE and GQA solve orthogonal problems and are frequently used together.
You do not choose this. You inherit it by choosing the model. The KV head count is baked into the shape of W_K and W_V and no flag changes it — which makes num_key_value_heads a model-selection criterion worth a factor of four in users per GPU. Two models that tie on a leaderboard can differ by 3–4× on cost per million tokens, and it is a half-hour calculation you can do before anyone commits.
What is num_key_value_heads on the models you serve?
Was the KV head count part of how the model was chosen, or discovered afterwards?
If you use tensor parallelism, is the degree above or below the KV head count?
Have you evaluated any MLA or sliding-window models, and does your stack support them well?
For long context, has anyone tested retrieval across the full window?