Kimi K3
Original paper · Kimi et al 2026
pre-reading expectations. what am i looking for?
post training recipe - opd? mopd? are we RLing distinct agents, if so how are we combining them? attention variant: linear hybrid or sparse route? rl algorithm - numerical instability? quantized rl? rl environments - any details on data pipeline (likely not)?
Kimi Delta Attention
Kimi Delta Attention (KDA), used in Kimi Linear and Kimi K3, is best understood as a refinement of Gated DeltaNet.
The main conceptual change is:
Gated DeltaNet: one forget gate per head
KDA: one forget gate per key channel inside each head
Before writing the KDA update, it is useful to make the multi-head structure explicit. Linear attention variants still fit into the usual multi-head attention architecture:
x_t
-> project to q, k, v for each head
-> each head runs its own recurrent state update
-> concatenate head outputs
-> output projection
For one head:
and the recurrent state is:
This follows the Kimi paper convention, where the output is read as:
So each head has its own associative memory. If there are heads, the total state per layer is:
not:
This is important because it keeps the recurrent state manageable.
In Gated DeltaNet, the forget gate is a scalar per head:
and the update is:
This means the whole memory matrix for that head is decayed by the same amount.
KDA changes from a scalar into a vector:
and applies it as a diagonal matrix over the key/address dimension:
making KDA's recurrent form:
The clean way to read this is in two stages.
Decay Old Memory
This scales the rows of , meaning each key/address channel gets its own forgetting rate:
key channel 1: decay by alpha_1
key channel 2: decay by alpha_2
key channel 3: decay by alpha_3
...
Apply Delta-Rule Update
Then apply the usual delta-rule correction to the decayed memory:
So the prediction is not made from the raw old memory. It is made from the already-forgotten memory:
Then KDA writes the error correction:
This gives and separate roles:
- : what old memory survives into this step
- : how strongly the new association is written
Attention Residuals
todo
MLA
MLA is easiest to remember as the same dense attention written in two forms:
training / prefill: MHA with small per-head K/V
decode: MQA over one wide shared KV latent
It does not try to reduce the quadratic attention cost during training/prefill. The win is that K/V are parameterised through a compressed latent, letting decode avoid storing expanded per-head K/V.
For K3:
- : compressed KV latent
- : per-head content Q/K dimension
- : legacy RoPE branch
- : query heads
Training / Prefill
The KV down-projection produces
Only goes through the expensive per-head up-projection:
So
The 64-d branch bypasses this and is shared across heads:
Thus training/prefill is ordinary dense MHA with
Decode - absorbing the up-projection aka "MLA Trick"
For the content branch,
and therefore
Define
Now every query head attends directly to the same cached . This is the MQA view: many distinct query heads, one shared KV representation. is broadcast logically, not duplicated in the cache.
The 64-d branch was never inside , so it remains alongside the absorbed content branch for the QK operation:
Hence decode is effectively a 576 head_dim MQA
Mental model: training sees MHA-192/128; decode rearranges the exact same computation into MQA-576/512.
attention head dimensions
Jianlin has repeatedly found that, for a fixed KV-cache budget, spending dimensions on a wider single KV head works better than splitting the same budget across more KV heads/groups. For one head,
So is a real capacity axis: more heads gives more separate attention maps, while larger head dimension makes each map's matching space richer. This is easy to miss in MLA because training visibly uses 128-d content heads, but absorption exposes a much wider 512-d latent matching space at decode. The empirical rule Jianlin arrives at is roughly:
For a fixed KV-cache size , prefer one MQA-style KV representation with head dimension about , shared by K and V.
Rather than divide cached numbers across several KV heads and separate K/V spaces, use one shared latent MLA's is close to this ideal. The absorbed 512-d query is still generated from the original 128-d query, so it is low-rank constrained rather than a completely free native 512-d query.
Why does K3 retain RoPE split despite removing RoPE encoding?
Traditional MLA needed the separate 64-d branch because RoPE is position-dependent and cannot participate in the same absorption as the NoPE content path.
K3 removes RoPE from its MLA layers, but keeps the old structural split:
The 64 dimensions are now just learned NoPE features. They still bypass the KV up-projection and are concatenated directly into Q/K. A cleaner NoPE design would make the whole thing one latent:
But this enlarges the expensive per-head up-projection:
current K3: 512 -> H * (128 + 128)
unified path: 576 -> H * (192 + 128)
That extra compute did not buy enough performance to justify it. Keeping the old split also preserves MLA infrastructure. Simply deleting the 64-d branch would be cheaper, but would reduce effective QK head dimension from to , which runs against the finding that wider head dimensions matter. So the retained branch is best viewed as cheap extra attention-score capacity:
It enlarges the QK matching space by 64 dimensions without carrying those dimensions through the full per-head K/V projection machinery.
thoughts: extra dimensions seem especially valuable when they enlarge the attention matching space itself; making those same dimensions participate in the full latent-to-per-head projections is much less cost-effective. given that RoPE information is no longer carried in the separate path, we now have much more flexibility in changing the relationship between these two paths. it seems worth exploring what the actual split should be, why 512;64?
Stable LatentMoe
Let
- : model hidden dimension
- : latent expert dimension
- : total experts
- : active experts per token
- : compression factor
MoE
For :
Experts operate directly in the -dimensional space. Roughly:
LatentMoE
First project into a smaller latent space:
With
each expert and each routed activation becomes times cheaper, which we instead spend on scaling the number of total and active experts:
Then the budgets transfer cleanly:
total parameters stay fixed
compute, expert-weight memory traffic, and all-to-all communication also stay roughly fixed.
We trade expert width for more experts, which has the same training and inference costs but with better performance.
Kimi K3's Stable LatentMoe
Employs LatentMoe with , meaning and moving from K2's 384 select 8 experts to 896 select 16 experts. So they halve routed width and exactly double active experts. To first order, the routed all-to-all volume has therefore not decreased at all.
The "Stable" label comes from adding a RMS Norm prior to the up-projection (decompression) to stabilise training

Stable LatentMoE
Let
- : model hidden dimension
- : latent expert dimension
- : expert intermediate dimension
- : total experts
- : active experts per token
- : expert-parallel ranks
- : tokens across the EP domain
- : latent compression factor
The MoE systems picture
For a SwiGLU expert, ignoring datatype constants:
while latency-critical expert-weight traffic is roughly
and routed all-to-all traffic is
There are two important operating regimes.
Latency-critical / small batch: expert GEMMs have too few tokens to amortize loading their weights and are HBM-bandwidth bound.
Throughput / large batch: expert GEMMs have enough tokens to reach the compute roofline. Now distributed MoE performance is governed by the relationship between expert compute and all-to-all communication.
For tokens uniformly routed across the EP domain:
where the factor is dispatch + combine, while
for SwiGLU's gate, up and down projections.
Thus
Once the expert GEMMs are compute-bound, all disappear from this ratio. Changing changes the absolute compute and communication costs together, but not their balance.
The important prerequisite is that each expert receives enough tokens:
If is too small, the expert GEMM is HBM-bound and the compute-vs-network roofline above is not the right model. This is why both latency-critical and throughput-oriented regimes have to be considered separately.
Cost-model lens
Architectural changes should be evaluated mechanically across the relevant serving regimes.
Latency-critical / small batch: expert execution is typically bandwidth-bound. Speed is largely about reducing bytes moved:
- expert weights / activations through HBM
- routed activations through the network
Throughput / large batch: first ask whether the expert GEMMs have enough arithmetic intensity to be compute-bound rather than HBM-bound. If they do, then ask whether there is enough expert compute to hide the all-to-all communication.
So for a change such as
don't reason about "cost" as one quantity. Ask separately:
A change can improve absolute cost without changing a roofline ratio, or preserve asymptotic cost while changing whether the underlying kernels actually reach that roofline.
Why reduce ?
To improve inference efficiency we want to reduce HBM traffic and all-to-all traffic.
- memory cost scales with and
- communication scales with and
- reducing or reduces the expert's nonlinear capacity and tends to hurt quality
- increasing and tends to improve expert specialization / mixture diversity
This leaves as the attractive dimension to compress. LatentMoE therefore projects
and performs routing, communication and expert computation in this smaller space.
Each routed expert invocation is now approximately times cheaper. LatentMoE proposes two variants of what to do with these cost savings.
-MoE: bank the savings
Scale the expert pool but keep the number of active experts fixed:
Total routed expert parameters stay fixed:
But active expert cost falls:
and communication falls by the same factor:
So:
The larger spends the reduced per-expert parameter cost on a richer expert pool, while the savings from the smaller routed representation are banked as lower active cost.
-MoE: reinvest the savings
Instead also scale the number of active experts:
Total parameters again remain fixed:
Now active expert cost is also restored to baseline:
and so is all-to-all traffic:
Hence compute, active-weight traffic and communication remain approximately iso-cost, but each token gets more active experts from a larger expert pool:
This is the main LatentMoE result: compress expert representation width, then spend that efficiency on expert diversity rather than keeping wider experts.
Kimi K3's Stable LatentMoE
K3 uses :
and moves from K2's select-8 routing to select-16:
So K3 spends the latent-width saving on twice as many active experts: its routed active width, and therefore first-order expert compute / all-to-all cost, stays roughly unchanged. It also expands the expert pool from to .
The Stable modification adds RMSNorm before the latent output is projected back into the model hidden dimension.