Kimi K3 does not replace every attention layer with one new trick. Its text backbone alternates a fixed-state recurrent memory, Kimi Delta Attention (KDA), with periodic full Multi-head Latent Attention (MLA). Understanding it means answering three separate questions: what the state stores, how one token edits it, and why a few layers still keep a token-growing cache.
KDA is the central linear-attention mechanism in Kimi Linear and Kimi K3. Its direct predecessor, Gated DeltaNet, combines Mamba-2-style decay with DeltaNet's associative-memory update. The concrete reference throughout this post is Kimi K3's official Hugging Face code plus the production kernels in Flash Linear Attention (FLA).
1.Where KDA sits in Kimi K3
Kimi K3's text backbone has 93 decoder layers. The configuration marks 69 as KDA layers and 24 as full MLA layers. The dominant rhythm is:
fixed recurrent state
fixed recurrent state
fixed recurrent state
global token-to-token attention
These layers solve different problems. KDA compresses the past into a fixed matrix, so decode cost does not grow with context length. MLA can still look directly at every cached token, which helps exact long-context retrieval. K3 spends most layers on the cheap recurrent path and periodically restores full global interaction.
Keep the names separate: KDA is one attention mechanism. Kimi K3 is the larger hybrid architecture containing KDA, MLA, MoE blocks, and—in the multimodal model—a vision tower.
2.Why ordinary attention caches tokens
For one query \(q_t\), ordinary causal attention compares it with every earlier key and mixes the corresponding values:
\[ o_t=\sum_{i\le t} \operatorname{softmax}_i\!\left(\frac{q_t^\top k_i}{\sqrt{d_k}}\right)v_i. \]The useful feature is direct access: token \(t\) can assign a fresh weight to every earlier token. The cost is that decoding must preserve every earlier \(k_i\) and \(v_i\).
Softmax prevents us from simply computing \(K^\top V\) once and reusing it: the normalization depends on the current query and all of its scores. Linear attention changes the interaction so the history can be summarized before the query arrives.
3.Linear attention as a fixed associative memory
What are we trying to do? Ordinary attention keeps every past key and value as a growing list. Linear attention tries to replace that list with one fixed matrix \(S\). Each arriving key–value pair writes into \(S\); a later query reads from it.
The two-dimensional example below is not yet DeltaNet or KDA. It is the minimal baseline that shows what the matrix stores, how an outer product writes a key–value association, and how a query retrieves a mixture from that memory.
Start with the smallest useful case. Keys and values are both two-dimensional. Store this first pair:
\[ k_1=\begin{bmatrix}1\\0\end{bmatrix}, \qquad v_1=\begin{bmatrix}3\\4\end{bmatrix}. \]The outer product writes a matrix:
\[ S_1=k_1v_1^\top = \begin{bmatrix}1\\0\end{bmatrix} \begin{bmatrix}3&4\end{bmatrix} = \begin{bmatrix}3&4\\0&0\end{bmatrix}. \]Now store a second pair, \(k_2=[0,1]^\top\), \(v_2=[5,6]^\top\):
\[ S_2=S_1+k_2v_2^\top = \begin{bmatrix}3&4\\5&6\end{bmatrix}. \]Ask with \(q=[0.25,0.75]^\top\). The output is:
\[ S_2^\top q = 0.25\begin{bmatrix}3\\4\end{bmatrix} + 0.75\begin{bmatrix}5\\6\end{bmatrix} = \begin{bmatrix}4.5\\5.5\end{bmatrix}. \]Now generalize. Let a key have width \(K\), a value have width \(V\), and use column vectors:
\[ k_t,q_t\in\mathbb{R}^{K}, \qquad v_t\in\mathbb{R}^{V}, \qquad S_t\in\mathbb{R}^{K\times V}. \]Causal linear attention is the recurrence:
The state remains \(K\times V\) whether the sequence has 10 tokens or one million. That is the storage win.
\(S_t\) is not a token-by-token attention matrix. It has no sequence dimension. In K3, one head's state is \(128\times128\): key coordinates by value coordinates. The sequence has already been compressed into that matrix.
What plain additive memory gets wrong
The same fixed state is also the bottleneck. Outer products from many tokens overlap. If a new token uses a key similar to an old key, it adds another value on top; it cannot deliberately replace the old association. Nothing is forgotten, so interference accumulates.
4.DeltaNet: write the error, not the whole value
Suppose the memory currently maps \(k=[1,0]^\top\) to \([3,4]^\top\), but a new token wants that same key to map to \([9,2]^\top\). Adding the whole new value would leave both associations superposed. DeltaNet first asks what the memory already returns:
\[ \text{recalled value}=S_{t-1}^\top k_t. \]Then it computes only what is missing:
\[ \text{value error}=v_t-S_{t-1}^\top k_t. \]Old recall: \([3,4]\). New target: \([9,2]\). The error is \([6,-2]\).
With update strength \(\beta=0.5\), write half the error: \([3,-1]\). The new recall becomes:
\[ [3,4]+[3,-1]=[6,3]. \]The general delta-rule update is:
Here \(\beta_t\in(0,1)\) is a learned update strength. If \(k_t\) is unit-normalized, then reading with the same key after the update interpolates toward the target:
\[ S_t^\top k_t =(1-\beta_t)S_{t-1}^\top k_t+\beta_tv_t. \]That is why the delta rule is naturally described as an online learning step: \(S\) is a fast-weight map, and each token trains it on one \(k_t\mapsto v_t\) example.
One crisp correction: DeltaNet does not “subtract the current value.” It subtracts the value already recalled from memory from the new target value, then writes the residual.
5.Gated DeltaNet to KDA: learn when each channel forgets
DeltaNet can surgically revise the current key direction, but it has no fast way to clear broadly stale context. Gated DeltaNet (GDN) adds one data-dependent retention scalar \(\alpha_t\) per head. KDA changes that scalar into a vector with one retention value per key dimension.
| Mechanism | Forget gate | Targeted delta correction? |
|---|---|---|
| Mamba-2 / SSD view | one scalar per token and head | no |
| DeltaNet | none | yes |
| Gated DeltaNet | \(\alpha_t\in\mathbb{R}\) per token and head | yes |
| KDA | \(\boldsymbol{\alpha}_t\in\mathbb{R}^{K}\) per token and head | yes |
See the diagonal gate before the formula
Take a four-row state and four retention values:
\[ S= \begin{bmatrix} 1&2&3&4\\ 5&6&7&8\\ 9&10&11&12\\ 13&14&15&16 \end{bmatrix}, \qquad \boldsymbol{\alpha}= \begin{bmatrix}0.5\\0.9\\0.1\\1.0\end{bmatrix}. \]KDA scales each whole row:
\[ \operatorname{Diag}(\boldsymbol{\alpha})S = \begin{bmatrix} 0.5&1&1.5&2\\ 4.5&5.4&6.3&7.2\\ 0.9&1&1.1&1.2\\ 13&14&15&16 \end{bmatrix}. \]The first key coordinate is halved, the third is nearly cleared, and the fourth is retained. Implementations do not construct a diagonal matrix; they broadcast the four retention values across the rows and multiply elementwise.
The subsequent delta update is the same kind of error-correcting write. The core algorithmic change from GDN is the granularity of this decay; making it train efficiently requires KDA's new chunkwise formulation.
Why not one independent gate for every state element?
The most general recurrence could predict \(G_t\in(0,1)^{K\times V}\) and apply \(G_t\odot S_{t-1}\). The GLA paper explicitly starts from this form. In practice, full gates are factorized as \(G_t=\alpha_t\otimes\gamma_t\), or reduced to KDA's key-side vector.
An unconstrained K3 gate would grow from \(96\times128=12{,}288\) outputs per token to \(96\times128\times128=1{,}572{,}864\)—128 times larger. It would also give every value coordinate different temporal weights, preventing the value dimensions from sharing the same efficient chunkwise attention calculation. GLA reported only marginal gains from adding the second factor. Recent extensions such as Gated DeltaNet-2 instead add structured key-side erase and value-side write vectors while preserving the rank-one update.
6.The complete KDA recurrence
We can now read the entire recurrence without hiding any operation. Assume \(q_t\) and \(k_t\) have already been normalized.
Combining Steps 1–4 gives the report's compact equation:
The state transition is diagonal plus rank one:
\[ \left(I-\beta_tk_tk_t^\top\right)\operatorname{Diag}(\boldsymbol{\alpha}_t) = \operatorname{Diag}(\boldsymbol{\alpha}_t) - \beta_tk_t(k_t\odot\boldsymbol{\alpha}_t)^\top. \]This structure is the engineering key: KDA gains channel-wise forgetting without giving up the matrix operations needed by its specialized chunkwise training algorithm.
Exactly how K3 computes the forget values
K3 does not use the raw projected gate directly. For head \(h\) and key channel \(j\), let \(g_{t,h,j}\) be the token-dependent projection, \(b_{h,j}\) the learned channel bias, and \(A_{\log,h}\) one learned sensitivity scalar for the whole head. K3 computes:
\[ \alpha_{t,h,j} = \exp\!\left[ -5\, \sigma\!\left( e^{A_{\log,h}} \left(g_{t,h,j}+b_{h,j}\right) \right) \right]. \]| Quantity | Shape in K3 | Role |
|---|---|---|
| raw \(g\) | [B,T,96,128] | dynamic signal from the current token |
dt_bias | [96,128] | static baseline / threshold per channel |
| \(A_{\log}\) | [96] | positive head-level sensitivity through \(e^{A_{\log}}\) |
| final \(\alpha\) | [B,T,96,128] | actual retention factor applied to the state |
The sigmoid \(\sigma(\cdot)\) maps into \((0,1)\). Multiplying by \(-5\) creates a log-retention in \((-5,0)\), and the outer exponential produces:
\[ \alpha\in(e^{-5},1)\approx(0.0067,1). \]| Sigmoid output | Log-retention | Actual retention | Meaning |
|---|---|---|---|
| near 0 | near 0 | near 1 | retain |
| 0.5 | -2.5 | 0.082 | strong decay |
| near 1 | near -5 | 0.0067 | almost erase |
The original Kimi Linear formulation uses \(\log\alpha=-e^{A_{\log}}\operatorname{softplus}(g+b)\), which has no fixed lower bound. Kimi K3 keeps the same KDA state recurrence but switches to the bounded \(-5\,\sigma(e^{A_{\log}}(g+b))\) “safe gate” above. The mechanism is KDA in both cases; the checkpoint-specific way of producing \(\alpha\) is different.
The update strength has a simpler path. K3 projects the hidden state to 96 raw values and applies sigmoid inside the kernel:
\[ \tilde\beta_{t,h}=\operatorname{b\_proj}(x_t)_h, \qquad \beta_{t,h}=\sigma(\tilde\beta_{t,h}). \]7.One Kimi K3 KDA layer, end to end
Now follow the real tensors. K3's text hidden width is 7168. Every KDA layer uses 96 heads with key and value width 128.
The short convolution is temporal, not channel mixing
Each of the 12,288 channels owns its own four-tap filter. For channel \(c\):
\[ y_{t,c} = \operatorname{SiLU}\!\left( w_{c,0}x_{t-3,c} +w_{c,1}x_{t-2,c} +w_{c,2}x_{t-1,c} +w_{c,3}x_{t,c} \right). \]There is no sum across other channels because the convolution uses groups=12288. Q, K, and V each have a separate convolution and a separate four-slot cache:
conv_state_q [B, 12288, 4]
conv_state_k [B, 12288, 4]
conv_state_v [B, 12288, 4]
During decode, the one new projected token joins those cached values. These are pre-convolution recent activations, not past attention keys and values.
Q/K normalization and query scaling
Before the KDA recurrence, each head's Q and K vectors are L2-normalized. The query is additionally scaled by \(1/\sqrt{128}\):
\[ k_t\leftarrow\frac{k_t}{\lVert k_t\rVert_2}, \qquad q_t\leftarrow \frac{q_t}{\lVert q_t\rVert_2\sqrt{128}}. \]Kimi does not pass an explicit scale from the attention module; FLA defaults to k.shape[-1] ** -0.5. The scaling keeps the state readout from growing with key width.
The output gate is not the forget gate
After KDA returns \(o=S^\top q\), K3 reuses the Python variable name g for a completely different gate. Because use_full_rank_gate=true, it projects directly from 7168 to 12,288 output logits:
For every head and value channel:
\[ o'_j = \frac{o_j}{\sqrt{\frac1{128}\sum_r o_r^2+\epsilon}} \;w_j\; \sigma(g^{\text{out}}_j). \]The learned RMSNorm weight \(w\in\mathbb{R}^{128}\) is static and shared across tokens and heads; the sigmoid output gate is dynamic per token, head, and channel.
8.A complete KDA update, with numbers
We have met every KDA operation separately. Now let one token perform the whole sequence: forget the old state, check what the current key already recalls, write half of the error, then read the updated state.
Use a two-dimensional state so every number stays visible. Before the current token arrives:
\[ S_{t-1}= \begin{bmatrix} 2&0\\ 0&1 \end{bmatrix}. \]Retention: \(\boldsymbol{\alpha}_t=\begin{bmatrix}0.5\\1\end{bmatrix}\) — halve row 1; keep row 2.
Key and query: \(k_t=q_t=\begin{bmatrix}1\\0\end{bmatrix}\) — address the first key coordinate.
Target value: \(v_t=\begin{bmatrix}3\\2\end{bmatrix}\) — the association this token wants.
Update strength: \(\beta_t=0.5\) — write half of the error.
After forgetting, this key recalled \([1,0]^\top\). The new target was \([3,2]^\top\). A half-strength delta update moved the answer exactly halfway to \([2,1]^\top\). That is one complete KDA token update.
9.Prefill, chunks, and packed requests
Training, prefill, and decode use the same KDA recurrence. They differ in how it is scheduled.
| Situation | Kimi path | Why |
|---|---|---|
| training | chunk_kda | has a backward pass and exposes large matrix multiplications |
| prefill, many tokens | chunk_kda | parallel work within fixed-size chunks |
| cached decode, one token | fused_recurrent_kda | one direct recurrent step with the cached state |
The attention module makes the decode choice with:
mode = "fused_recurrent" if use_cache and q_len == 1 else "chunk"
The fused kernel is capable of looping over multiple tokens, but Kimi normally sends prefill to the chunk implementation. Chunking compresses products of KDA's diagonal-plus-rank-one transitions into dense operations that tensor cores can execute efficiently.
What cu_seqlens means
Variable-length requests can be unpadded and concatenated into one packed token axis. The original batch dimension is then represented by boundary offsets.
packed tokens: [request 0 ...][request 1 ........][request 2 ..]
cu_seqlens: [0, 3, 8, 10]
Request 0 occupies packed positions [0,3), request 1 occupies [3,8), and request 2 occupies [8,10).
This is not “decode mode,” and it is not kernel tile padding. It is simply the boundary map that prevents the short convolution and recurrent state from crossing from one packed request into the next.
10.Why Kimi K3 keeps MLA layers
KDA is efficient because it compresses the entire past into one fixed matrix. That compression can lose exact token-level detail. MLA is full attention: it can still look directly at every cached token, but its cache grows with context length.
fixed \(128\times128\) state per head
constant decode memory per layer
lossy associative compression
one cache entry per token
direct global token-to-token lookup
memory grows with context
K3 therefore repeats three KDA layers followed by one MLA layer: KDA supplies the efficient recurrent path, while MLA periodically restores direct global access. That is MLA's role in this architecture. Its internal design is already covered in Understanding MLA and MLA Decoding: Materialize vs Absorb.
11.Cache size: KDA versus MLA
The comparison is simple: an optimized MLA layer keeps a compact entry for every token, while a KDA layer keeps one fixed recurrent state for the whole sequence.
| Layer | Persistent decode memory | Context dependence |
|---|---|---|
| KDA | one fp32 recurrent matrix plus three short-convolution states | fixed |
| MLA | 576 bf16 cached values per token in the optimized K3 layout | grows linearly |
KDA's fixed state
One KDA recurrent state contains:
\[ 96\times128\times128=1{,}572{,}864 \]fp32 values, exactly 6 MiB per request per layer. The three four-slot bf16 convolution caches add about 0.281 MiB. This does not change when the context grows.
The hybrid crossover
An all-MLA 93-layer comparison model has 93 token-growing caches. K3 has only 24; its other 69 layers carry fixed KDA and convolution state. Under the assumptions shown below, the fixed-state overhead is larger at very short contexts, then the hybrid crosses over near 5.7K tokens and approaches a 74% reduction.
One request; bf16 MLA entries of width 576; fp32 KDA recurrent state; bf16 four-slot Q/K/V convolution state; no allocator padding, cache quantization, speculative branches, or batch sharing. It compares cache mechanisms, not total model memory. Production kernels and cache formats can move the exact numbers.
At K3's maximum 1,048,576-token context, this simplified estimate gives roughly 112.3 GB for 93 all-MLA layers versus 29.4 GB for K3's hybrid cache. Almost all of the hybrid's long-context growth comes from its 24 MLA layers; the 69 KDA layers remain at about 0.45 GB combined per request.
12.Source map and final mental model
Kimi K3 ships its architecture as remote code in the model repository. The multimodal wrapper eventually hands text processing to KimiLinearForCausalLM. For source-first reading, use this order:
| Read | Why |
|---|---|
modeling_kimi_linear.py | K3's MLA, KDA layer, projections, caches, mode selection, and output gates |
fla/ops/kda/naive.py | the recurrence in the most readable executable form |
short_conv.py | depthwise causal short convolution and its four-slot state |
| Kimi Linear report | derivation, DPLR chunk algorithm, ablations, hybrid design, and efficiency results |
The misconceptions worth keeping cleared
| Tempting interpretation | Correct mental model |
|---|---|
| \(S\) is a token attention matrix | \(S\) is a fixed \(K\times V\) associative map with no sequence axis |
| KDA's rows “are values” | each row is one key-coordinate's complete contribution in value space |
| the forget gate acts only along \(k_t\) | forgetting scales every key row; the delta correction is the operation targeted by \(k_t\) |
| \(\beta\) is per channel in K3 | \(\beta\) is one dynamic scalar per token and head; \(\alpha\) is per key channel |
| short-conv state is a KV cache | it stores four recent pre-convolution projected values per Q/K/V channel |
| prefill and decode use different attention math | same recurrence, different schedules: chunk-parallel versus fused recurrent |
| K3 has no growing cache | KDA layers are fixed-state; the 24 MLA layers still grow with context |
Forget broadly by key channel. Read the old value at the current key. Write only the error. Read the updated memory with the query.
\[ \bar S_t=\operatorname{Diag}(\boldsymbol{\alpha}_t)S_{t-1}, \quad e_t=v_t-\bar S_t^\top k_t, \quad S_t=\bar S_t+\beta_tk_te_t^\top, \quad o_t=S_t^\top q_t. \]References
- Kimi Linear: An Expressive, Efficient Attention Architecture.
- Kimi K3 Technical Report.
- Gated Delta Networks: Improving Mamba2 with Delta Rule.
- Linear Transformers Are Secretly Fast Weight Programmers.
- Gated Linear Attention Transformers with Hardware-Efficient Training.
- Transformers are SSMs: Generalized Models and Efficient Algorithms Through Structured State Space Duality.
- DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model.
- MoonshotAI/Kimi-Linear, Kimi K3 model repository, and FLA KDA kernels.
How to cite this post
Dong, S. (2026). Linear Attention, From Scratch to Kimi 3
(Kimi Delta Attention).
https://simondong1.github.io/linear-attention.html