A unified tensor view of MLA, and the conclusions it reveals.
2026-07-08 · NonLinear-1
1. Opening
This note uses one lens throughout: write attention as tensor contractions, while keeping every dimension explicit. From this view, several seemingly separate MLA phenomena can be understood more deeply and more uniformly. Specifically, we get a few interesting conclusions:
In prefill, MLA reduces the FLOPs of the linear projections, but it cannot absorb too early: the quadratic core-attention term should still be computed in dk,dv, not dc.
In decode, the best order changes because the cache already exists. After absorbing key/value projections, the length-t cache computation can go through the latent state instead of reconstructed per-head K,V.
RoPE gets in the way exactly because it makes the latent-to-key map position-dependent, which breaks full key absorption.
Q compression mainly reduces training activation memory and prefill/training projection FLOPs, while contributing little to decode.
MTP-style speculative decoding behaves differently on MLA because MLA decode no longer reads the full per-head KV cache; it reads the compressed latent and RoPE caches and performs additional contractions instead.
2. Tensor View
Takeaway. Unlike a flattened matrix view, the tensor view keeps every meaningful axis explicit. FLOPs can be read directly from the output and contracted axes, while different computation orders can be compared in the same notation.
The tensor view is just this: every tensor contraction is determined by three kinds of axes — output axes, contracted axes, and broadcast axes. Once these axes are explicit, FLOPs become shape accounting.
General Form. For a batched contraction whose output axes are B1,…,Br,m,n and whose contracted axis is k, the FLOPs count is:
FLOPs=2⋅B1⋯Br⋅m⋅n⋅k.
In words: multiply every output dimension by the contracted dimension, then multiply by 2 for multiply-adds (the standard GEMM convention counts one fused multiply-add as one multiplication plus one addition). Thus Q=XWQ costs 2hTddk, while S=QK⊤ costs 2hT2dk.
3. Notation and Preliminaries
Takeaway. This section fixes notation by annotating shapes directly on the equations, then gives a basic introduction to MHA, MLA, and the RoPE rotation used later.
For broader background from MHA/MQA/GQA to MLA, see Jianlin Su's note. Here we do not try to survey those variants. We use MHA as the clean algebraic reference, MLA as the object of the derivation, and introduce only the RoPE identities needed for the later absorption discussion.
To keep the derivations simple, we use the following conventions:
Elementwise attention scores are always written as Ss,t,u: h is the number of heads, s=1,…,h selects one head, t is the query position, and u is the key position. Thus rows of the score matrix correspond to t, and columns correspond to u.
RoPE is omitted from the MLA equations until Section 5.
We ignore the causal mask; readers can replace the full attention matrix with its causal form directly.
Softmax is omitted from the FLOPs comparison. MHA and MLA apply the same softmax to the same-shaped attention scores, while model FLOPs use the dominant GEMMs and tensor contractions as the comparable measure. Optimized implementations such as PyTorch SDPA also fuse softmax into scaled-dot-product attention. Section 5 still counts the explicit addition of the content and RoPE scores, because it is an extra operation introduced by the decoupled branch and scales with the full attention matrix.
A⊤ means transposing only the last two axes, leaving batch axes untouched.
The last line contracts both the head axis and the dv axis. This is equivalent to the usual implementation that concatenates all heads and then applies one output projection: flattening (h,dv) into a single hdv axis does not change the sum,
The FLOPs are also identical. In the tensor-contraction form, the output axes are T and d, and the contracted axes are h and dv, giving 2Tdhdv. After concatenation, the multiplication has shapes (T,hdv)(hdv,d), giving 2T(hdv)d=2Thdvd.
MLA. The KV path replaces per-head K,V projections with a shared latent. To keep the derivation simple, we temporarily omit RoPE from the MLA form until Section 5:
The DeepSeek-V2 paper claims that query compression reduces activation memory during training; DeepSeek-V2-Lite, however, does not compress queries. This gives us a natural comparison: first derive MLA without query compression, then add it back and isolate what changes.
In the tensor view, RoPE inserts a position-dependent linear map on the last tensor dimension without changing the tensor shape. Because RoPE acts on Q and K, we use their tensor dimension dk as the rotation dimension. For even dk, the standard rotation matrix is
Writing the RoPE base as b, we have θj=b−2(j−1)/dk. RoFormer uses b=10000; modern language models may use a larger base for longer contexts. Since we use row vectors, stack the transposed position rotations into one tensor: (T,dk,dk)R, where Rt,:,:=Rt⊤.
RoPE and the subsequent score contraction are then
The two T axes are identified as the same position axis, so only one T remains in the output. The dk axis of Q or K contracts with the first dk axis of R, while the second dk axis remains; R is broadcast across the head axis. Therefore the (h,T,dk) shapes of Q,K are unchanged. Since Rt⊤Ru=Ru−t,
so each rotation encodes absolute position, while the score depends only on relative position.
The actual elementwise computation. The rotation tensor above is an algebraic representation; an implementation need not construct a dense dk×dk matrix. Let m=dk/2. For any q∈Rdk, define the adjacent-pair coordinates
qj,0:=q2j−1,qj,1:=q2j,j=1,…,m.
Using the same θj as above, the corresponding phase tensor is
Here ⊙ is elementwise multiplication; the cosine and sine tensors broadcast across the head axis. In the pair notation above, rotate_half is defined by
It preserves the shape and removes no axis. This elementwise formulation is exactly equivalent to the rotation-tensor formulation above. We include it in the tensor view, but do not count it separately in the later FLOPs comparison of the main tensor contractions.
4. Computation Order and FLOPs in Prefill, Training, and Decode
We derive each tensor contraction and its FLOPs, comparing MHA with MLA.
4.1 Prefill and Training: The Standard Computation Order
Takeaway. MLA reduces the FLOPs of the linear projections. It does not reduce the T2 core-attention FLOPs, because QK⊤ and PV still contract over dk and dv, respectively.
MHA.
For MHA prefill, the complete score expression is
S=QK⊤=(T,d)X(h,d,dk)WQ(h,dk,d)WK⊤(d,T)X⊤.
How to compute S in a cost-effective way? From a FLOPs perspective, the important point is to minimize the coefficient of the dominating T2 term. Since dk<d, the computation order is to first construct Q=XWQ and K=XWK to reduce the d feature and keeping dk, then we compute S=QK⊤:
We still focus on the T2 term as our optimization goal. Here the ordering question is which tensor dimension accompanies the quadratic multiplication by P. Constructing V first ensures that attention operates on dv, rather than carrying the wider model dimension d through all token pairs.
use (P(XWV))Wo, not ((PX)WV)Wo or P(X(WVWo)).
Every way of forming the score has output shape (h,T,T), so the factor hT2 is fixed; we only need to compare the contracted tensor dimension. We therefore want this dimension to be dk (dk=128<dc=512<d=5120 in DeepSeek-V2). Thus, we can divide the formula into two parts: XWDQWUQ and XWDKVWUK.
Query-projection order: use (XWDQ)WUQ, not X(WDQWUQ).
Without query compression, Q=XWQ is the same as in MHA (FLOPs: 2Thddk). It contains only one contraction, so there is no query-side computation order to choose. The comparison below appears only after WQ is factorized into WDQWUQ.
With query compression, the factorized order first maps each token to CQ, then expands the head axis through WUQ:
where the second expression excludes the additional weight-precomposition cost 2hddqcdk. The factorized order is cheaper when
dqc(d+hdk)<hddk.
The saving comes from introducing CQ:(T,dqc) between the two contractions, so the per-head contraction uses dqc rather than d.
Similarly, for the key and score order, compute CKV=XWDKV, reconstruct K=CKVWUK, then form S=QK⊤.
With the DeepSeek-V2 dimensions, the key-projection order (XWDKV)WUK costs 22.0MT, while X(WDKVWUK) costs 167.8MT, excluding the one-time cost of composing the weights.
Value and output order: use (P(CKVWUV))Wo, not ((PCKV)WUV)Wo or P(CKV(WUVWo)).
Computing PCKV first changes the quadratic term to 2hT2dc. Precomposing WUVWo instead changes it to 2hT2d. Since dv<dc<d, reconstructing V first keeps the quadratic contraction in the smallest tensor dimension, dv.
Without query compression, the dense MLA prefill FLOPs are
Prefill FLOPs consist of three parts: the linear projections, the core-attention computation, and the final output projection. The table summarizes the derivation and substitutes the DeepSeek-V2 dimensions; the figure then plots the resulting FLOPs as functions of sequence length T, except for the RoPE branch.
Method
Linear-projection FLOPs
Core-attention FLOPs (QK⊤ and PV)
Output-projection FLOPs
DeepSeek-V2 prefill FLOPs (except the RoPE branch)
Takeaway. In one decode step, the current-query length is 1 while the cache length is t. The cheaper order keeps this 1 outside, contracts away the other dimensions as early as possible, and expands only afterward. This avoids reconstructing full K,V for all t cached tokens: MLA's FLOPs grow faster with t, but it reads much less cache data.
MHA.
Before decoding the current position t, the historical K<t,V<t have already been computed in previous decode steps. The current step only computes the new qt,kt,vt; after kt,vt are appended, the cache read for this step is K≤t,V≤t. Across all heads, the current-token projection cost is 2dh(2dk+dv).
Unlike prefill, there is only one new query, so the quadratic T2 interaction disappears. The growing factor is now t: the current query scans t cached keys, and the resulting probabilities combine t cached values.
Both chains follow the same principle: start from the singleton current-token state and choose the contraction order that keeps every intermediate as small as possible.
The full value-output chain, with every dimension explicit, is
Evaluating from left to right keeps the singleton query axis as an output axis and contracts away the cache-length axis before the output projection. The other order applies Wo to all t cached values, carrying both t and d in the intermediate, which is more costly.
The score path follows the same principle. With dimensions explicit,
MLA caches the shared latent rather than per-head K,V. At this single decode step, the new latent is
(1,d)xt(d,dc)WDKV→(1,dc)ctKV,FLOPs=2ddc,
and the cache after appending it is C≤tKV=[C<tKV;ctKV] with shape (t,dc). We now write the complete contraction chains first, without assuming an association.
Score chain. It is enough to analyze the Q-compressed case. The complete contraction is
First consider the coefficient of t. The cache is the only factor carrying the t axis. If every factor on its left is contracted first, the left intermediate has shape (h,1,dc), and the final contraction costs
2htdc.
This is the smallest possible length-t term: h, t, and dc are unavoidable, while the remaining query axis has size 1. Applying C≤tKV earlier would retain an additional feature axis in a length-t intermediate. Therefore, the cache should be contracted last:
The table lists the five online binary associations, followed by every distinct offline precomposition of two or three adjacent weights. Excluding the common final cache contraction 2htdc, their per-step costs are shown below; the one-time offline composition costs are omitted.
With the DeepSeek-V2 dimensions, the first row remains the minimum even after allowing all offline precompositions. It also has the clearest interpretation: multiplying by the singleton xt first eliminates d, then the same length-1 axis is carried through dqc, dk, and dc. The chosen order is therefore left to right, with total cost
Without Q compression, delete WDQ,WUQ and replace them with WQ. The chain has fewer factors, so we leave the same association argument to the reader; the resulting minimum is
First consider the coefficient of t. Contracting pt with C≤tKV immediately removes the cache-length axis through the singleton query axis, at a cost of
2htdc.
This is the smallest possible length-t term. If C≤tKV is expanded through WUV first, that step alone costs 2htdcdv. Therefore, ptC≤tKV should be evaluated first, producing oc:(h,1,dc).
It remains to associate the three-factor chain
(h,1,dc)oc(h,dc,dv)WUV(h,dv,d)Wo.
Excluding the common first contraction 2htdc, the table includes the two online associations and the offline-precomposed variant; its one-time composition cost is omitted:
Association
FLOPs after ptC≤tKV
DeepSeek-V2
(((h,1,dc)oc(h,dc,dv)WUV)(h,dv,d)Wo)
2hdcdv+2hdvd
184.5M
(h,1,dc)oc((h,dc,dv)WUV(h,dv,d)Wo)
2hdcdvd+2hdcd
86.6B
(h,1,dc)oc(h,dc,d)(WUVWo)offline
2hdcd
671.1M
The first row remains the minimum. Again, the cheaper order keeps the length-1 axis outside and evaluates the chain from left to right. The complete value-side cost is
Combining the chosen associations, the complete cached-decode costs are
FMLA,decode,cached,noQFMLA,decode,cached,Qcomp=current-token projections2ddc+2hddk+score absorption and latent reductions2hdkdc+4htdc+value and output projections2hdcdv+2hdvd,=current-token projections2ddc+2ddqc+2hdqcdk+score absorption and latent reductions2hdkdc+4htdc+value and output projections2hdcdv+2hdvd.
DeepSeek-V2 attention configuration: d=5120,h=128,dk=dv=128,dc=512,dqc=1536. Both FLOPs and cache values omit the RoPE branch.
In this RoPE-free comparison, MLA's decode FLOPs grow 4× faster with t, while its cache is 64× smaller than MHA's, a 98.4% reduction in cached elements.
4.3 Why Compress Q Too?
The two MLA variants above give a direct ablation of Q compression. Since it factorizes only the query projection, its effects are concentrated on query-side activations and projection FLOPs rather than the cache path:
Training activation memory. We do not know DeepSeek's internal implementation, but we think recomputation and kernel fusion can be used to reduce activation memory.
Prefill and training FLOPs. The factorized projection is cheaper when dqc(d+hdk)<hddk, as the comparison in Section 4.1 shows.
Decode. Only the current-token query projection changes; the latent cache and the length-t attention term remain the same. Q compression therefore contributes little to decode compared with KV compression.
5. Making MLA Compatible with RoPE
5.1 Why RoPE and MLA Compression Are Incompatible
Takeaway. Without RoPE, WUK can be absorbed into the query, producing one latent query that is reused across all key positions. With RoPE, a key-position-dependent Ru appears before WUK, so the same absorbed query can no longer be reused across all keys.
Start with the complete RoPE QK⊤ expression. Fix a head s. Let qs,tC:(1,dk) be its content query at position t, let cuKV:(1,dc) be the KV latent at position u, and let WUK,s:(dc,dk). The reconstructed content key is ks,uC=cuKVWUK,s. Under the row-vector RoPE convention from Section 3, the query and key are right-multiplied by Rt⊤ and Ru⊤, respectively. The score for this pair of positions is therefore
The only question is how to parenthesize this matrix chain. First remove RoPE and recall why ordinary MLA supports key absorption. Let T be the number of query positions and U the number of key positions. The complete score chain is
WUK is a fixed weight, so the absorbed query QC=QCWUK⊤ is independent of the key position. Each query needs this (h,T,dc) intermediate only once, after which it can be multiplied by every cached latent. This is key absorption.
Now put RoPE back. The complete score can be evaluated by reconstructing and rotating the key first:
(qs,tCRt⊤)(Ru(WUK,s⊤(cuKV)⊤)).
Or we can try to put every factor before the key latent into the left parenthesis, just as we did above:
the part we would like to absorb into the query(qs,tCRt⊤RuWUK,s⊤)(cuKV)⊤.
The difference is now visible in the chain itself: the parenthesis contains Ru. It changes with key position u, so it cannot produce one QC that is shared by all keys. Expanding all query and key positions makes the shape of this intermediate not (h,T,dc) but
(h,T,U,dc).
Here U is the key-position axis: U=T during prefill; for one decode step, T=1 and U=t. RoPE does not invalidate the matrix multiplication, but it turns the supposed “absorbed query” into a different object for every (t,u) position pair. The key-length axis remains, defeating the purpose of absorption. If the cache stores only CKV, decoding must either reconstruct and rotate the historical keys or explicitly form this (h,1,t,dc) intermediate.
Standard RoPE and position-independent key absorption therefore cannot occupy the same feature path. The elementwise RoPE formulation in Section 3 is exactly equivalent to the rotation-matrix form used here; rewriting the computation elementwise does not remove its dependence on key position u, so it cannot recover position-independent absorption. Full MLA separates the two in Section 5.2: an absorbable content branch and a dedicated positional branch for RoPE.
5.2 Full Formulation of MLA: Decoupled Rotary Position Embedding
Takeaway. Full MLA keeps the content channel unrotated and absorbable, while a separate low-dimensional RoPE channel carries position. The cache stores CKV and one shared RoPE key, and the two channel scores are added before softmax.
Section 5.1 showed that one path cannot simultaneously support standard RoPE and position-independent key absorption. Full MLA therefore stops asking the same representation to do both jobs and splits the feature space into two branches: an unrotated content branch that remains fully compressible and absorbable, and a positional branch that is free to apply RoPE without preserving absorption. In short, one branch is designed to compress cleanly, while the other is designed to rotate cleanly.
MLA with decoupled RoPE.
Let dr denote the per-head dimension of the decoupled RoPE branch, written as dhR in the DeepSeek-V2 report. We use the same rotation tensor as Section 3, now over dr:
The query-side RoPE operation can remain unchanged. The key side is different: if the RoPE key were stored in compressed form, every decode step would have to expand and rotate all t historical keys again, creating substantial repeated computation. Full MLA therefore caches the materialized KR, rather than a compressed positional-key latent.
Storing a separate positional key for every head would add hdr cache elements per token. Full MLA instead uses one KR:(T,dr) shared by all h query heads. The RoPE branch is therefore MQA-style: it keeps per-head positional queries QR:(h,T,dr), but uses a single shared positional key head. This keeps the additional cache at dr elements per token.
The full per-head query and key are the feature-axis concatenations
(h,T,dk+dr)Q=[(h,T,dk)QC;(h,T,dr)QR],(h,T,dk+dr)K=[(h,T,dk)KC;(T,dr)KR broadcast over h].
Why does the score become the sum of two terms? Concatenation partitions the last tensor dimension into two disjoint blocks. For head s, query position t, and key position u, the full dot product is
The same identity can be read as block tensor multiplication:
(h,T,T)S=[(h,T,dk)QC(h,T,dr)QR](h,dk,T)(KC)⊤(dr,T)(KR)⊤ broadcast over h=(h,T,T)SC+(h,T,T)SR.
There are no cross terms such as QC(KR)⊤ or QR(KC)⊤: the content and RoPE coordinates occupy different feature blocks, and the dot product pairs coordinates only within the same block. Therefore, the two score channels can be computed separately:
Thus the content key and value remain behind CKV, while only the shared rotated key KR is cached explicitly.
Cache supplement.
Form
Cached tensors per token per layer
Elements
DeepSeek-V2
MHA
K,V
h(dk+dv)
32768
MLA in Section 4, with RoPE omitted
CKV
dc
512
Full MLA
CKV,KR
dc+dr
576
For DeepSeek-V2, dc=512 and dr=64. The full cache reduction relative to MHA is therefore 32768/576≈56.9×, rather than the 64× obtained from the RoPE-free latent alone.
FLOPs supplement.
This supplement follows the accounting in Section 4 and counts the tensor contractions introduced by the decoupled branch. It also counts the explicit addition SC+SR: one addition for every score element, or hT2 FLOPs in prefill and ht FLOPs in cached decode. The structured elementwise RoPE rotations themselves remain outside the comparison.
Phase
Added projections
Added score computation
Total added FLOPs
DeepSeek-V2
Prefill / training
2Thdqcdr+2Tddr
2hT2dr+hT2
2Thdqcdr+2Tddr+2hT2dr+hT2
25,821,184T+16,512T2
Cached decode
2hdqcdr+2ddr
2htdr+ht
2hdqcdr+2ddr+2htdr+ht
25,821,184+16,512t
For cached decode, the coefficient of t is now 4hdc+2hdr+h=278,656 for DeepSeek-V2.
6. How MLA Changes MTP's Speculative-Decoding Gain
Takeaway. MHA speculative verification reuses KV-cache data and can hide the added query computation behind the memory-bound read. MLA reduces that read and moves attention toward the compute-bound regime, increasing the marginal cost of each additional query.
The DeepSeek-V3 Technical Report trains MTP as an auxiliary objective. Its actual configuration uses one MTP module (D=1), which predicts one additional token. The module can be discarded for ordinary inference or used to draft a token for speculative decoding. On DeepSeek-V3, the report gives an 85%-90% acceptance rate for this second token and reports 1.8× TPS with speculative decoding.
In MHA, several verification queries reuse the same KV-cache data. Because decode is strongly memory-bound, much of their additional attention computation can be hidden behind that cache read: memory bandwidth is already the bottleneck, while the compute units still have room. MLA changes this balance. It replaces the full per-head KV cache with CKV and the decoupled RoPE key, while absorption adds contractions around CKV. The cache read becomes smaller and attention moves toward the compute-bound regime, leaving less room to hide the additional computation. This is why MLA weakens part of MTP's speculative-decoding gain.
Contributions and Acknowledgements
This note was written under NonLinear-1. Place holder contributed to the derivations and writing. We thank Place holder for discussions and feedback.
How to cite this article.
If you would like to cite this article, please use:
@online{nonlinear1-mla-dim-by-dim, title={MLA, dim by dim}, author={{NonLinear-1}}, year={2026}, month={July}, url={\url{https://nonlinear1.com/en/posts/mla-dim-by-dim}},}