AI Infra Interviews logo
LLM Inference & Serving / 09
mediumNewDeepSeekMetaFireworks

Compare the KV cache footprint of multi-head, grouped-query and multi-head latent attention with numbers.

Same model size, three attention layouts, a 30x spread in cache per token. The formulas are short, and they explain why DeepSeek can hold four times the context of a dense 70B on the same cards.

Updated Sep 2026 · Grounded in real AI infrastructure interview loops and written to a senior-engineer editorial bar, with every number worked and every diagram hand-built.

TL;DR: Cache per token is 2 × layers × KV heads × head dim × bytes for MHA and GQA, so a 70B-class model with 64 heads stores 2.6 MB per token and Llama 3.1 70B with 8 KV heads stores 328 KB, an 8x cut for a small quality cost. MLA stores one compressed latent plus a small RoPE key per layer with no factor of two: DeepSeek-V3's 61 × (512 + 64) × 2 B = 70 KB per token, which is why a 671B model holds more context per GPU than a dense 70B.

How to approach it

Write the general formula first and name the variable that changes between the three: KV heads. Ask which models the interviewer wants compared, or offer Llama 3.1 70B (GQA), a hypothetical 64-KV-head version of it (MHA) and DeepSeek-V3 (MLA). Compute each per-token figure, scale one of them to a full sequence so the difference is visible in gigabytes, then say what each layout trades away.

A strong answer

A typical situation: two models of the same parameter count are benchmarked on the same card and one holds four times the concurrent users. The difference is in config.json, in a field most capacity plans never read.

The KV cache stores, for each layer and each token, whatever the attention mechanism needs to reconstruct keys and values. Attention Variants: MHA, GQA, MQA and MLA differ in how much of that is kept per head.

general (MHA, GQA, MQA): KV per token = 2 × layers × KV heads × head dim × bytes

MHA, 70B-class, 64 KV heads (every query head has its own K and V):
  = 2 × 80 × 64 × 128 × 2 = 2,621,440 B ≈ 2.6 MB per token

GQA, Llama 3.1 70B, 8 KV heads (8 query heads share one KV head):
  = 2 × 80 × 8 × 128 × 2 = 327,680 B ≈ 328 KB per token     (8x smaller)

MQA, 1 KV head:
  = 2 × 80 × 1 × 128 × 2 = 40,960 B ≈ 41 KB per token        (64x smaller than MHA)

MLA, DeepSeek-V3: KV per token = layers × (latent + RoPE key) × bytes, no factor of 2
  = 61 × (512 + 64) × 2 = 70,272 B ≈ 70 KB per token

sanity: at 32k context one sequence costs 86 GB (MHA), 10.7 GB (GQA-8), 1.3 GB (MQA), 2.3 GB (MLA-V3)

The 32k row is where it lands. On a single 80 GB H100 with weights elsewhere, an MHA 70B cannot hold even one 32k sequence's cache; GQA-8 holds 7; DeepSeek-V3's MLA holds about 34, and that is a 671B model.

Why the layouts differ. MHA keeps a distinct K and V projection per query head, which gives the model the most expressive attention and the largest cache. GQA groups query heads (8 per group in Llama 3) onto a shared K and V head, so the cache shrinks by the group size while the projection weights shrink by the same ratio; Llama 3 reports the quality cost as small, and every major dense model since 2023 has used it. MQA takes the group size to the whole layer; it is the cheapest and it costs noticeable quality on large models, so it is mostly seen in older or small models.

MLA is a different idea. Instead of storing K and V, it stores a low-rank latent c (512 wide in V3) from which K and V for all heads are reconstructed by up-projection matrices at attention time, plus a small decoupled RoPE key (64 wide) because rotary position embedding does not commute with the compression. The factor of 2 disappears because one latent serves both K and V. The cache shrinks to 70 KB per token for 128 heads of attention, and DeepSeek reports quality at or above MHA because the latent is trained, not a post-hoc compression.

What MLA costs: the up-projection is a matmul at every decode step per token per layer, so the attention kernel does more compute per byte read. That is a good trade for decode, which is bandwidth-bound and has compute to spare. The kernels are custom (FlashMLA and the SGLang and vLLM MLA paths), and the "absorbed" form that folds the up-projection into the query projection is what makes it fast; a naive implementation reconstructs full K and V and loses the memory advantage inside the kernel.

LayoutKV per token (70B-class or V3)32k sequenceQualityKernel
MHA, 64 heads2.6 MB86 GBreferencestandard
GQA, 8 heads328 KB10.7 GBnear referencestandard
MQA, 1 head41 KB1.3 GBmeasurable loss at scalestandard
MLA (V3 dims)70 KB2.3 GBat or above referencecustom, absorbed form
KV PER TOKEN, SAME MODEL SIZE, THREE LAYOUTS MHA, 64 heads every head keeps K and V 2,560 KB GQA, 8 KV heads 8 query heads share one 320 KB MLA, 576-wide latent one compressed latent ≈ 88 KB Same parameter count, 30x apart on the number that decides concurrency. Read num_key_value_heads from config.json; the query head count is the 8x mistake.

KV Cache Sizing is the arithmetic this feeds. The reversal condition: a short-context product, where the cache never grows enough for the layout to matter and the weights dominate memory regardless. --kv-cache-dtype fp8 is a bigger lever than the attention variant at 2k context, and a smaller one at 128k. The decision for a serving engineer is rarely which layout to use (the model decides); it is what the layout permits. GQA-8 at 70B is the case the rest of this bank sizes. MLA is why serving DeepSeek-V3 behaves differently from a dense model of similar active size: memory like 671B for weights, cache like a 20B model.

What interviewers probe next

  • "Can you convert an MHA checkpoint to GQA?" Yes, by mean-pooling the K and V heads in each group and fine-tuning briefly (the GQA paper's recipe); quality recovers with a small fraction of pretraining tokens.
  • "Why does MLA need a separate RoPE key?" Rotary embeddings multiply keys by a position-dependent rotation; applying that inside the compressed latent would break the up-projection trick, so a small rotated key is stored uncompressed alongside the latent.
  • "How does fp8 KV combine with these?" It halves any of them: GQA-8 drops to 164 KB per token and MLA to 35 KB; the accuracy effect is small for K and V but should be measured per model.

Common mistakes

  • Using attention heads instead of KV heads for GQA and getting the MHA number.
  • Applying the factor of 2 to MLA.
  • Saying MLA is "just a smaller GQA" without the up-projection cost.
  • Treating MQA as free; it is where quality loss is measurable.

Key takeaways

  • MHA/GQA/MQA: 2 × layers × KV heads × head dim × bytes; the KV head count is the lever.
  • 70B-class: 2.6 MB (64 heads), 328 KB (8 heads), 41 KB (1 head) per token in bf16.
  • MLA: layers × (latent + RoPE) × bytes; DeepSeek-V3 is 70 KB per token, no factor of 2.
  • MLA moves cost from bytes to compute in the attention kernel, which suits bandwidth-bound decode.
That one was free — and so are 10 answers per topic without an account. Signing in doubles that to 20, opens the Plus lessons in the courses, and remembers which topics you keep getting wrong.no card · Google sign-in · nothing to cancel
HOW DID IT GO?
0
READING SIGNED OUT

Signing in doubles your free answers, from 10 to 20 per topic, and the site starts remembering you: mastery per topic, bookmarks, and a next-focus recommendation. Free, no card.

Sign in free

The concepts behind this question

Ranked by how closely each one overlaps this question's topic, so the first card is the thing to read if the answer above moved too fast.

Core
🚀 Inference & ServingSign in
Attention Variants: MHA, GQA, MQA and MLAThe KV cache scales with the number of key-value heads, and the four attention variants differ exactly there: multi-head keeps one KV head per query head, multi-query keeps one for all, grouped-query shares one across a group, and multi-head latent attention caches a compressed latent instead of keys and values at all. For Llama 3.1 70B that is the difference between 2.6 MB and 320 KB per token; for DeepSeek-V3 it is about 70 KB. The variant a model was trained with is a serving decision made before the first GPU was bought.
Foundational
🧮 Open Weights & Serving Engines
Multi-Head Latent Attention and Sparse IndexersGrouped-query attention shrank the KV cache by sharing key and value heads. Latent attention goes further by caching a single compressed vector per token per layer and reconstructing the heads on the fly, which cuts the cache by tens of times rather than by a small factor. On top of that, sparse indexers pick a few thousand relevant positions per query instead of attending to all of them, turning the quadratic term linear at long context. Both are now standard in open-weights models, and both change how a serving deployment is sized.
Foundational
🧮 Napkin Math & Capacity
KV Cache SizingThe KV cache is the memory that decides how many users a serving replica can hold and how long their context can be. Its size per token comes from four numbers in the model's config file (layers, KV heads, head dimension, bytes per element) and one formula; multiplied by context and concurrency it is the number every capacity plan is built on. This page derives it, works it for four models including an MLA one, and shows the two places candidates get it wrong by a factor of eight.
Foundational
🚀 Inference & Serving
The KV CacheThe KV cache stores each token's attention keys and values so decode never recomputes them, turning a quadratic cost into a linear one at the price of memory that grows with every token in every concurrent sequence. Its size, 128 KB per token for Llama 3.1 8B and 320 KB for 70B in bf16, is what caps concurrency and context on a given GPU, so it decides batch size, replica count and whether a model fits at all.
UP NEXT ON YOUR JOURNEY
FEDITOR'S NOTE

Scored on deriving the three per-token figures from architecture fields, and on explaining what MLA gives up (a decompression matmul at decode) for the memory it saves.

DISCUSSION · 0

No comments yet — be the first to share your approach.