DL0107 Multi-head Latent Attention MLA

Explain Multi-head Latent Attention (MLA), as used in DeepSeek-V2 and DeepSeek-V3.

Answer

Multi-head Latent Attention (MLA) attacks the KV-cache bottleneck of autoregressive decoding by low-rank joint compression of keys and values instead of by deleting KV heads. Each token is projected down to a single shared latent vector c_t^{KV} of dimension d_c = 512, and that latent is the only thing cached; per-head keys and values are reconstructed on the fly by up-projection matrices W_i^{UK} and W_i^{UV}, so every head still gets its own distinct K and V, unlike GQA and MQA which force heads to share. Because RoPE does not commute with the up-projection, MLA adds a small decoupled RoPE key of dimension d_h^R = 64 that is shared across heads and cached directly, giving a total cache of 512 + 64 = 576 values per token per layer against 2 \cdot 128 \cdot 128 = 32{,}768 for the equivalent MHA configuration, a roughly 57x reduction. The reason this is not simply lossy compression is the absorption trick: at inference the up-projections fold into the query and output projections, so the model never materializes the full keys and values, and the attention score becomes a bilinear form on the two latents. The result reported in DeepSeek-V2 is unusual for a cache-reduction technique, since MLA matched or beat full MHA on benchmarks while caching about 1/57 as much, which is why DeepSeek-V3 kept it unchanged at 61 layers and 128 heads.

(1) Joint Low-Rank KV Compression: one down-projection produces a single latent per token that serves all heads and both K and V, so cache cost is (d_c + d_h^R) \cdot l rather than 2 n_h d_h l.
(2) Head Diversity Is Preserved: per-head up-projections mean MLA reduces cache without reducing the number of effective K/V heads, which is the quality cost GQA and MQA pay.
(3) Decoupled RoPE Path: position information travels in a separate small key dimension because applying RoPE inside the compressed path would make the up-projection position-dependent and destroy absorption.
(4) Absorption At Inference: W_i^{UK} folds into W_i^{UQ} and W_i^{UV} folds into W^O, so decoding reads only the cached latent and never reconstructs full K or V tensors.
(5) Query Compression Is A Separate Win: queries are also routed through a latent of dimension 1536, which cuts training activation memory but has no effect on the KV cache.
(6) Memory-Bandwidth Trade For FLOPs: the absorbed score is a dot product over 576 dimensions instead of 128, so MLA raises arithmetic intensity, exactly the right direction for memory-bound batch decoding.

MLA architecture diagram: the hidden state is projected into a query latent, a shared 512-dimensional KV latent that is cached, and a 64-dimensional decoupled RoPE key that is also cached; per-head keys and values are reconstructed by up-projections and attention runs over a 192-dimensional concatenated head

Figure 1: Only the two boxes inside the dashed region enter the cache: the 512-dimensional KV latent and the 64-dimensional decoupled RoPE key. Per-head keys and values are reconstructed from the latent, and at inference those up-projections are absorbed so they are never computed explicitly.

The decoupled RoPE dimension is the part candidates most often miss, and it follows from a single algebraic fact. The score between query t and key j in the compressed path is (W_i^{UQ} c_t^{Q})^\top (W_i^{UK} c_j^{KV}), which lets you precompute the constant matrix M_i = (W_i^{UQ})^\top W_i^{UK}. If RoPE were applied to k_j^C, that matrix would become (W_i^{UQ})^\top R_{t-j} W_i^{UK}, which depends on the relative position and therefore differs for every cached token, so nothing can be precomputed and every prefix key would have to be rebuilt at each step. MLA sidesteps this by carrying position in a separate 64-dimensional key that is cached in rotated form and shared by all heads, so the query concatenates a 128-dimensional content part with a 64-dimensional positional part, giving an effective head dimension of 192 during training. A practical consequence is that the value head dimension (128) differs from the query and key dimension (192), which is why MLA needs purpose-built kernels such as FlashMLA rather than a stock FlashAttention call.

Mathematical Formulation:
c_t^{KV} = W^{DKV} h_t
k_{t,i}^C = W_i^{UK} c_t^{KV}
v_{t,i}^C = W_i^{UV} c_t^{KV}
k_t^R = \mathrm{RoPE}(W^{KR} h_t)
q_{t,i} = [\,q_{t,i}^C ; q_{t,i}^R\,]
k_{t,i} = [\,k_{t,i}^C ; k_t^R\,]
(q_{t,i}^C)^\top k_{j,i}^C = (c_t^{Q})^\top M_i c_j^{KV}
M_i = (W_i^{UQ})^\top W_i^{UK}
d_c + d_h^R = 512 + 64 = 576

Where:

  • c_t^{KV} \in \mathbb{R}^{d_c} is the cached KV latent and k_t^R \in \mathbb{R}^{d_h^R} the cached decoupled RoPE key; together they are the entire per-token cache.
  • h_t \in \mathbb{R}^{d} is the layer input (d = 7168 in DeepSeek-V3), and c_t^{Q} is the query latent of dimension 1536.
  • t indexes the current token, j ranges over cached prefix positions with j \leq t, and i \in \{1,\ldots,n_h\} indexes the n_h = 128 heads.
  • d_h = 128 is the content head dimension, d_h^R = 64 the positional dimension, so the concatenated query and key have dimension 192 while values keep 128.
  • W^{DKV}, W^{DQ} are down-projections, W_i^{UK}, W_i^{UV}, W_i^{UQ} up-projections, W^{KR}, W^{QR} the RoPE-path projections, and W^O the output projection.
  • M_i is the absorbed score matrix, valid only because no rotation sits between the two up-projections; \mathrm{RoPE} applies the rotary transform, and [\,\cdot;\cdot\,] denotes concatenation.
Log-scale bar chart of KV cache per token per layer: MHA with 128 KV heads at 32768 values and 524 GB at 128K context, GQA with 8 groups at 2048 values and 32.8 GB, MLA at 576 values and 9.2 GB, MQA at 256 values and 4.1 GB

Figure 2: Totals assume 61 layers, bf16, and a 128K-token context. MLA lands between MQA and 8-group GQA on cache size, but reaches that point by compressing rather than by removing KV heads, which is why it does not carry their quality penalty.

PropertyMLAGQA (8 groups)MQA
What is cachedOne 512-dim latent plus a 64-dim RoPE keyFull K and V for 8 shared KV headsFull K and V for a single KV head
Values per token per layer5762,048256
Effective K/V per headDistinct for all 128 heads, reconstructed by up-projection16 query heads share one K and VAll 128 query heads share one K and V
Decode compute per keyDot product over 576 dims after absorption, higher FLOPs128 dims, plus broadcast of shared heads128 dims, lowest FLOPs
Kernel and tooling supportNeeds custom kernels (FlashMLA) because query/key is 192 and value is 128Supported by every stock attention kernelSupported by every stock attention kernel
Tensor-parallel behaviorLatent is shared by all heads, so it is replicated per rankKV heads shard cleanly across ranksSingle KV head must be replicated
Quality relative to MHAMatched or slightly better in the DeepSeek-V2 ablationsSmall but measurable degradationLargest degradation, especially on long context

Login to view more content


Log in to track your progress

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *