Autoregressive transformer inference in production is fundamentally bounded by memory bandwidth rather than compute capability during the decoding phase. As context lengths scale from 8,000 to 128,000 tokens and beyond, storing and loading the Key-Value (KV) cache across tens of attention layers consumes the vast majority of GPU High-Bandwidth Memory (HBM) and degrades serving throughput.
While earlier architectures mitigated this bottleneck via Multi-Query Attention (MQA) or Grouped-Query Attention (GQA), these approaches trade away model expressivity by forcing multiple query heads to share a reduced set of key and value heads. Introduced by DeepSeek-AI in DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model (2024) and extended in DeepSeek-V3 Technical Report (2024), Multi-Head Latent Attention (MLA) resolves this compromise. MLA compresses keys and values into a low-rank latent subspace during generation, uses decoupled rotary positional embeddings to preserve relative positional geometry, and mathematically absorbs up-projection matrices directly into query and output projections during inference.
This technical analysis details the mathematical foundations of MLA, derives its decoupled rotary mechanics, examines its algebraic matrix absorption during decoding, and compares its memory footprint and serving economics against MHA, MQA, and GQA.
The KV Cache Memory Bandwidth Bottleneck
In standard multi-head self-attention (Vaswani et al., 2017), generating each new token during autoregressive decoding requires computing scaled dot-product attention against all preceding tokens in the sequence. To avoid recomputing keys and values for past tokens at every generation step, inference engines maintain a KV cache in GPU memory.
Cache Footprint Mechanics
For an autoregressive model with layers, key-value heads, head dimension , sequence length , batch size , and numerical precision storing bytes per element (such as 2 bytes for FP16/BF16 or 1 byte for FP8), the total memory required by the KV cache is:
Consider a representative frontier architecture with 60 layers, 128 query heads, head dimension , running at a sequence length of tokens in 16-bit precision:
- Multi-Head Attention (MHA) (): Storing 128 key heads and 128 value heads requires bytes (3.75 MB) per token. At , a single sequence consumes 480 GB of GPU RAM for the KV cache alone, exceeding the capacity of an 80GB NVIDIA H100 or 141GB H200 GPU.
- Grouped-Query Attention (GQA-8) (, as in Llama 3 70B): Compressing to 8 KV heads reduces cache consumption to bytes (240 KB) per token, or 30 GB per sequence at 128K context.
- Multi-Query Attention (MQA) (): Compressing to a single KV head requires bytes (30 KB) per token, or 3.75 GB per sequence at 128K context.
The Expressivity vs. Bandwidth Dilemma
While MQA and GQA reduce memory footprint by factors of 128x and 16x respectively, they introduce a fundamental representational constraint: multiple query heads attend to identical key-value subspaces. During complex multi-hop retrieval, code synthesis, and mathematical reasoning, distinct attention heads often require distinct projection subspaces.
During token generation, the arithmetic intensity (FLOPs per byte transferred) of the attention kernel drops to , making the memory bus the primary latency bottleneck. MLA was engineered to deliver the serving efficiency of MQA while preserving the full representational power of 128 independent attention heads.

Core Architecture of Multi-Head Latent Attention
Multi-Head Latent Attention decomposes the traditional wide key and value projections into a low-rank bottleneck projection paired with a decoupled positional encoding mechanism.
Low-Rank Joint Key-Value Compression
Let denote the hidden state vector of the -th token at a given transformer layer, where is the model hidden dimension. Instead of projecting directly into independent key and value vectors of dimension , MLA down-projects into a compressed latent vector :
where:
- is the down-projection weight matrix.
- is the latent key-value compression dimension (in DeepSeek-V2 and V3, , whereas ).
- stabilizes latent activations prior to subsequent transformations.
During training and prefill phases, the compressed vector is up-projected into full content key and value matrices:
where:
- is the key up-projection matrix.
- is the value up-projection matrix.
- indexes the attention head.
Low-Rank Query Compression
To reduce activation memory during training and distributed tensor parallelism overhead, MLA also applies low-rank compression to the query vector:
where:
- down-projects the query into latent dimension (where ).
- up-projects the latent query to head dimension .
The RoPE Incompatibility Problem and Decoupled RoPE
Rotary Position Embeddings (Su et al., 2021) encode relative token positions by applying a coordinate rotation matrix directly to the query and key vectors.
Why Standard RoPE Breaks Low-Rank Compression
If standard RoPE were applied directly to the up-projected keys:
the attention logit between query and key would be:
Because the rotation matrix depends on the absolute position , it does not commute with the projection matrix :
If RoPE were entangled with , the serving engine would be forced to decompress into the full -dimensional key for every token before applying rotation . The inference engine would have to cache the expanded keys in HBM, completely negating the memory benefits of low-rank compression.
The Decoupled RoPE Solution
MLA resolves this structural incompatibility by decoupling content representations from positional representations. Query and key vectors are partitioned into two concatenated segments:
where:
- is the content query vector derived from .
- is the rotary query vector generated via , where .
- is the content key vector derived from .
- is the shared rotary key vector generated via , where .
Crucially, is a single, decoupled rotary vector shared across all attention heads (with ).
What the Inference Engine Caches
Because the content key and content value are strictly linear projections of , the inference engine does not store or in the KV cache.
Instead, for each token , the KV cache stores strictly two vectors:
- The compressed latent vector (512 scalar elements).
- The decoupled positional key vector (64 scalar elements).
In 16-bit precision, this amounts to bytes per token per layer, representing a 56.9x reduction in cache size compared to standard MHA.
Inference Acceleration: Mathematical Absorption of Projection Matrices
The defining algebraic breakthrough of MLA during autoregressive decoding is the mathematical absorption of the up-projection matrices and . During generation, the model never materializes high-dimensional keys or values for historical tokens.
Attention Logit Matrix Absorption
The attention logit between query token and cached token for head decomposes into content and positional inner products:
Substituting the content key definition into the first term:
Let us define the absorbed query vector :
Because depends only on the single active query token at step , it is computed once prior to attending over the sequence. The attention score is then computed directly as:
The inner product operates directly between a 512-dimensional vector and the cached 512-dimensional latent vectors for all . Key decompression is entirely bypassed.
Value Output Matrix Absorption
Following softmax normalization, the attention weights $A_{t, j, i} = \text{softmax}_j\left(\frac{\text{Score}_{t, j, i}}{\sqrt{d_h^C + d_r}}\right)$ are applied to the values:
By linearity, the matrix can be factored outside the summation over the sequence:
Let denote the attention-weighted reduction in the latent space:
The multi-head attention block aggregates all heads and projects to the model hidden dimension via output projection weights $\mathbf{W}_O = [\mathbf{W}_O^1, \mathbf{W}_O^2, \dots, \mathbf{W}_O^{n_h}] \in \mathbb{R}^{d \times (n_h d_v)}$:
The product $\mathbf{W}_{\text{absorbed}}^i = \mathbf{W}_O^i \mathbf{W}_{UV, i} \in \mathbb{R}^{d \times d_c}$ is a static weight matrix. During model initialization or engine compilation, can be pre-computed offline:
During token generation:
- Attention weights are multiplied directly against cached latent vectors to produce .
- The final head output is computed via a single linear transformation against .
Intermediate -dimensional value tensors are never materialized or stored in memory during inference.
Architectural Comparison and Serving Economics
To quantify the efficiency gains of MLA, consider the structural and operational parameters of standard attention mechanisms evaluated against DeepSeek-V2 and DeepSeek-V3 configurations:
- Standard Multi-Head Attention (MHA): 128 Query Heads, 128 KV Heads, Head Dim 128. Caches 32,768 elements (65,536 bytes) per token per layer in FP16. Baseline reference (1.00x).
- Grouped-Query Attention (GQA-8): 64 Query Heads, 8 KV Heads, Head Dim 128. Caches 2,048 elements (4,096 bytes) per token per layer in FP16. 16.0x smaller cache than MHA.
- Multi-Query Attention (MQA): 128 Query Heads, 1 KV Head, Head Dim 128. Caches 256 elements (512 bytes) per token per layer in FP16. 128.0x smaller cache than MHA, but severe loss in head representational diversity.
- Multi-Head Latent Attention (MLA): 128 Query Heads, 128 effective KV Heads, Head Dim 128, Latent Dim 512 (+64 RoPE). Caches 576 elements (1,152 bytes) per token per layer in FP16. 56.9x smaller cache than MHA, and 71.9% smaller than GQA-8 while preserving 128 independent representational projections.
High-Throughput Serving Kernels: FlashMLA and SGLang
Standard attention kernels like FlashAttention-2 and FlashAttention-3 are optimized for GEMM layouts where and share identical dimensions with . In MLA, the asymmetry between 512-dimensional latent vectors and 64-dimensional decoupled RoPE components requires specialized fused kernels.
To maximize compute utilization on NVIDIA Hopper architectures, DeepSeek open-sourced FlashMLA, a specialized decoding kernel designed for variable-length MLA sequences:
- Paged Latent Allocation: The KV cache stores contiguous blocks of elements, integrated directly into memory managers like PagedAttention in SGLang and vLLM.
- Tile-Based GEMM Fusion: On H100/H800 SXM5 GPUs, FlashMLA utilizes Tensor Core MMA (Matrix Multiply-Accumulate) instructions to perform the absorbed query-latent dot product and softmax accumulation within Tensor Memory Accelerator (TMA) shared memory buffers.
- FP8 Quantized Latent Cache: In DeepSeek-V3, is quantized to FP8 (E4M3 format) alongside per-block scaling factors, reducing cache consumption to 576 bytes per token per layer.
PyTorch Reference Implementation
The following reference module illustrates the execution flow of Multi-Head Latent Attention during autoregressive decoding with matrix absorption.
import math
import torch
import torch.nn as nn
import torch.nn.functional as F
class MultiHeadLatentAttention(nn.Module):
def __init__(
self,
d_model: int = 5120,
n_heads: int = 128,
d_head: int = 128,
d_c_kv: int = 512,
d_c_q: int = 1536,
d_rope: int = 64,
):
super().__init__()
self.d_model = d_model
self.n_heads = n_heads
self.d_head = d_head
self.d_c_kv = d_c_kv
self.d_c_q = d_c_q
self.d_rope = d_rope
self.scale = 1.0 / math.sqrt(d_head + d_rope)
# Query compression and projection
self.w_dq = nn.Linear(d_model, d_c_q, bias=False)
self.q_norm = nn.RMSNorm(d_c_q)
self.w_uq = nn.Linear(d_c_q, n_heads * d_head, bias=False)
self.w_qr = nn.Linear(d_c_q, n_heads * d_rope, bias=False)
# Key-Value compression and projection
self.w_dkv = nn.Linear(d_model, d_c_kv, bias=False)
self.kv_norm = nn.RMSNorm(d_c_kv)
self.w_uk = nn.Linear(d_c_kv, n_heads * d_head, bias=False)
self.w_uv = nn.Linear(d_c_kv, n_heads * d_head, bias=False)
self.w_kr = nn.Linear(d_model, d_rope, bias=False)
# Output projection
self.w_out = nn.Linear(n_heads * d_head, d_model, bias=False)
def apply_rope(self, x: torch.Tensor, freqs_cis: torch.Tensor) -> torch.Tensor:
# 2D rotary embedding application on last dimension
x_complex = torch.view_as_complex(x.float().reshape(*x.shape[:-1], -1, 2))
x_rotated = torch.view_as_real(x_complex * freqs_cis).flatten(-2)
return x_rotated.type_as(x)
def forward_decode_absorbed(
self,
h_t: torch.Tensor, # [batch, 1, d_model]
cached_c_kv: torch.Tensor, # [batch, seq_len, d_c_kv]
cached_k_rope: torch.Tensor, # [batch, seq_len, d_rope]
freqs_cis_t: torch.Tensor, # [1, 1, d_rope // 2]
) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
batch_size = h_t.size(0)
# 1. Compress and project query
c_q = self.q_norm(self.w_dq(h_t))
q_c = self.w_uq(c_q).view(batch_size, 1, self.n_heads, self.d_head)
q_rope = self.w_qr(c_q).view(batch_size, 1, self.n_heads, self.d_rope)
q_rope = self.apply_rope(q_rope, freqs_cis_t)
# 2. Compress current token KV for cache append
c_kv_t = self.kv_norm(self.w_dkv(h_t))
k_rope_t = self.apply_rope(self.w_kr(h_t), freqs_cis_t)
new_cached_c_kv = torch.cat([cached_c_kv, c_kv_t], dim=1)
new_cached_k_rope = torch.cat([cached_k_rope, k_rope_t], dim=1)
# 3. Absorb Key Up-Projection Matrix W_UK into Query
w_uk = self.w_uk.weight.view(self.n_heads, self.d_head, self.d_c_kv)
q_absorbed = torch.einsum('bthd,hdc->bhtc', q_c, w_uk)
# 4. Compute Attention Scores directly in latent space
scores_c = torch.einsum('bhtc,bsc->bhts', q_absorbed, new_cached_c_kv)
scores_r = torch.einsum('bthd,bsd->bhts', q_rope, new_cached_k_rope)
scores = (scores_c + scores_r) * self.scale
attn_weights = F.softmax(scores, dim=-1)
# 5. Compute Latent Value Aggregation
u_tilde = torch.einsum('bhts,bsc->bhtc', attn_weights, new_cached_c_kv)
# 6. Absorb Value Up-Projection W_UV into Output Projection W_out
w_uv = self.w_uv.weight.view(self.n_heads, self.d_head, self.d_c_kv)
w_out = self.w_out.weight.view(self.d_model, self.n_heads, self.d_head)
w_combined = torch.einsum('mhd,hdc->mhc', w_out, w_uv)
# Final projection directly from latent space to hidden dimension
output = torch.einsum('bhtc,mhc->btm', u_tilde, w_combined)
return output, new_cached_c_kv, new_cached_k_ropePractical Deployment Implications
- Context Window Scaling: By reducing per-token memory consumption to 576 bytes (in FP8), a single 8-GPU NVIDIA H100 node (640 GB total HBM) can maintain concurrent active KV caches for over 1,000,000 tokens without requiring multi-node model parallel tensor distribution.
- Throughput Density: Under high-concurrency batching regimes, the reduction in memory-bus traffic increases decode tokens-per-second per GPU by 3.5x to 5.2x compared to standard GQA baselines.
- Training vs. Inference Duality: While MLA adds projection FLOPs during prefill and training, the matrix absorption property ensures that decoding remains strictly memory-bandwidth optimized.
Sources
- DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model (DeepSeek-AI, 2024)
- DeepSeek-V3 Technical Report (DeepSeek-AI, 2024)
- FlashMLA: High-Performance MLA Decoding Kernel for Hopper GPUs (DeepSeek-AI GitHub)
- RoFormer: Enhanced Transformer with Rotary Position Embedding (Su et al., 2021)
- FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning (Dao, 2023)
- FlashAttention-3: Fast and Accurate Attention with Asynchrony and Low-Precision (Shah et al., 2024)
- PagedAttention / vLLM: Efficient Memory Management for Large Language Model Serving (Kwon et al., 2023)
- SGLang: Efficient Execution of Structured Language Model Programs (Zheng et al., 2023)



