Kimi K3 · Explorer
The same explanations as the course, reached by pointing at a mechanism instead of scrolling to it. Ten parts, grouped the way the report groups them.
Each box below opens that mechanism's explanation in place. The layout is the argument: the three axes are how the report itself organises K3, and the two boxes tucked under Stable LatentMoE are there because they fix problems its extreme sparsity creates rather than standing on their own.
Nothing here is new material. If you are reading K3 for the first time, start at lesson 1 and let the sequence do its work; this page is built for coming back.
Choose a mechanism above.
Kimi K3 · Lesson 2 of 14 · Sequence axis
Three quarters of K3's attention layers never look at a past token. They keep a fixed-size notebook instead, and continuously fade, erase, and overwrite it.
Extracted from the full lesson, which adds the quiz, the references and the primary source to read next.
Last lesson you drew the block: three KDA layers to one Gated MLA layer. This lesson is about what a KDA layer actually does. By the end you should be able to explain, without equations, why a fixed-size memory makes a million-token context affordable, and what it gives up in exchange.
The mechanism only makes sense against the thing it replaces, so we start there.
Here is the part of a transformer that matters for this lesson. When a model reads a token, it produces three vectors from it. The query says what this token wants to know. Its key is a label advertising what it offers in return. The value is the content it hands over if asked.
To compute attention for a new token, the model takes that token's query and compares it against the key of every token before it. Strong matches get a high weight, weak matches get near zero, and the output is the weighted blend of all those values.
The cache is the whole problem. It has to hold a key and a value for every token so far, so it grows without limit as the context fills. And each new token must compare itself against every entry, so the work per token grows too.
FULL ATTENTION — keep everything, compare against everything
token: 1 2 3 4 5 ... n
│ │ │ │ │ │
cache: [k₁] [k₂] [k₃] [k₄] [k₅] … [kₙ] grows with n
[v₁] [v₂] [v₃] [v₄] [v₅] … [vₙ]
new token n+1 arrives with query q
│
├──▶ compare q against ALL n keys
│
└──▶ blend ALL n values by match strength
cost per token: proportional to n ← gets slower as you go
memory: proportional to n ← never stops growing
At a 4,000-token context nobody cares. At a million tokens, both terms are ruinous. Drag this to feel the shape:
The numbers above are relative units showing growth shape, not K3's exact byte counts. The shape is the point: full attention's state climbs a thousandfold between 1K and 1M, while a KDA layer's stays flat.
Now the alternative. Instead of keeping every past key and value, what if a layer kept one fixed-size scratchpad and wrote each new token into it as it arrived?
That scratchpad is a matrix, and it is the central object in KDA. Call it S. Its job is to store associations: given a key, hand back the value that key was filed under. It is the same read-a-key-get-a-value contract as the KV cache, except the storage never grows, because new writes go on top of old ones.
The obvious way to write into such a matrix is to just add: take the new key and value, form their outer product, and add it to what is already there. That is classical linear attention, and it has a well-known failure. Nothing is ever removed, so the matrix accumulates every association ever written and the useful signal drowns in old writes. Read from it after a hundred thousand tokens and you get mud.
KDA fixes this with two ideas layered on top of the plain write. Both are about removing information rather than adding it.
This is the core of the lesson. Every KDA layer performs three operations per token, in order.
Step ② is the one worth pausing on, because it is the "delta" in Kimi Delta Attention and it is the least intuitive. The name comes from the delta rule in classical associative-memory research: rather than blindly adding, you first ask what the memory currently returns for this key, then write the difference. If the memory already holds a stale association for a similar key, that stale association gets cleared instead of blended with the new one.
Step ① is what KDA adds over its predecessor, Gated DeltaNet. The decay is not one scalar for the whole memory but a separate factor for every channel, computed from the current token.1 The layer can hold one part of the memory steady across thousands of tokens while letting another part turn over rapidly.
From §2.1.1 of the report, this is the whole recurrence in one line:1
Reading it right to left, in the order things happen:
S_{t−1}: the memory matrix arriving from the previous token, shape (d_k × d_v).Diag(α_t), fade. A diagonal matrix of per-channel retention factors, each in (0,1). Multiplying by a diagonal matrix scales each channel independently, which is exactly what "channel-wise" means.(I − β_t k_t k_tᵀ), erase. The term k_t k_tᵀ projects onto the direction of the current key. Subtracting it from the identity removes whatever the memory currently stores along that direction, scaled by β.+ β_t k_t v_tᵀ, write. An outer product files v under k, with strength β.õ_t = S_tᵀ q_t, read. One matrix–vector product. Note it uses S at time t, not t−1, so a token can read what it just wrote.Where α and β come from, also §2.1.1:
Two details that matter later. ShortConv is a small convolution across neighbouring positions, so each query, key, and value sees a little local context before entering the recurrence. L2Norm on q and k bounds their magnitude, which keeps the erase term well behaved. The decay logits z_t come from a low-rank projection plus a per-head bias, and lesson 3 is about how z_t becomes α_t, a seemingly small choice that turns out to unlock the entire Tensor Core fast path.
The gain is the one the simulator showed. State per layer is constant, so a KDA layer costs the same at token 900,000 as at token 9. This is the mechanism behind K3's million-token context. It is also why K3 needs no positional encoding in its global layers, which is a strange enough claim that it gets its own treatment in lesson 3.
The cost is real and you should be able to state it. A fixed-size memory is a lossy summary. Full attention can retrieve token 12,345 exactly, because token 12,345's key and value are still sitting in the cache untouched. KDA cannot promise that. It has faded and overwritten that region of memory many times since, and what survives is whatever the gates chose to preserve.
This is the reason the block is 3:1 and not 4:0. Some tasks genuinely need exact retrieval from an arbitrary distance: finding one line in a large file, or quoting a number from page 200. The Gated MLA layers keep that capability, and the report places one at the very end of the backbone so the model's final act is always full global attention. K3 pays for perfect recall in a quarter of its layers and takes the cheap linear path in the rest.
| Layer type | State grows? | Exact recall? | Layers in K3 |
|---|---|---|---|
| KDA linear |
no, fixed | approximate | 69 (74%) |
| Gated MLA global |
yes, with n (compressed) |
exact | 24 (26%) |
MLA has a trick of its own for that growing cache: it stores one small latent vector per token instead of full keys and values. Lesson 3 takes it apart. Note what it does and does not achieve, because the distinction matters for the 1M-context claim: it shrinks the cache substantially, but the cache still grows with every token.
Kimi K3 · Lesson 3 of 14 · Sequence axis
A recurrence is sequential and a GPU is parallel. Resolving that tension is what separates a clever idea from a shipped model, and it turns on one number.
Extracted from the full lesson, which adds the quiz, the references and the primary source to read next.
Lesson 2 left KDA with a problem. The memory update is defined one token at a time: fade, erase, write, then hand the state to the next token. That is a loop with a thousand-step dependency chain, and a GPU hates nothing more. This lesson is about the three engineering decisions that make KDA fast, and then about the strangest choice in the whole architecture.
The resolution is to stop treating the sequence as a chain of single tokens and treat it as a chain of chunks. Within a chunk, every position is computed in parallel with dense matrix multiplication. Between chunks, the state passes sequentially as before.
NAIVE — one step per token, nothing overlaps
t₁ ─▶ t₂ ─▶ t₃ ─▶ t₄ ─▶ t₅ ─▶ … ─▶ t₁₀₀₀₀₀₀
└──── 1,000,000 sequential steps, GPU mostly idle ────┘
CHUNKWISE — sequential between chunks, parallel within
┌─ chunk 1 ─┐ ┌─ chunk 2 ─┐ ┌─ chunk 3 ─┐
│ t₁ t₂ … │──▶│ t₁ t₂ … │──▶│ t₁ t₂ … │──▶ …
│ all in │ S │ all in │ S │ all in │ S
│ parallel │ │ parallel │ │ parallel │
└───────────┘ └───────────┘ └───────────┘
Each chunk's output has two parts:
O = (Γ ⊙ Q) S ← INTER-chunk: what arrived from the past,
└─────────┘ one matmul against the incoming state
+
A Ṽ ← INTRA-chunk: interactions among tokens
└───┘ inside this chunk, masked causal
There is a wrinkle, and it is the whole reason this lesson exists. To compute the intra-chunk term in parallel, the math needs each key rescaled by the reciprocal of its accumulated decay. Written as 1/Γ. Since Γ is a product of numbers below 1, it shrinks fast, and its reciprocal grows fast.
So the reciprocal rescale is a numerical hazard sitting in the middle of the fast path. Kimi Linear handled it by computing decay in log space and splitting each chunk into 16-token tiles. That helped, but only partly: the off-diagonal tiles became clean matmuls while the diagonal tiles still needed explicit position-by-position computation. The report names this as the main intra-chunk bottleneck.
1
K3's fix is to change how the decay logits become the actual decay. Kimi Linear used a mapping whose output was unbounded below, meaning a channel could in principle decay arbitrarily hard, sending 1/Γ arbitrarily high. K3 replaces it with a scaled sigmoid that cannot go below a fixed floor:
g_min = −5. Every channel's log-decay is squeezed into the range (−5, 0), so no channel may ever forget faster than a factor of e−5 per token. Over a 16-token tile, the accumulated log-decay therefore cannot exceed 80, and the reciprocal cannot exceed e80.
Now the payoff. e80 is about 5.5 × 1034, which fits inside BF16's ceiling of 3.4 × 1038. Overflow becomes impossible by construction, so the diagonal tiles no longer need their special slow path. Every tile can be a dense Tensor Core matmul.
Drag both sliders. The margin is tighter than you might expect: leave the tile at 16 and move the decay floor to 6, or leave the floor at 5 and move the tile to 24. Either single step over the line is enough to break it.
Two things are worth noticing from playing with it. First, g_min and the tile size are co-designed, and the margin is thin. Overflow begins at a cumulative log-decay of about 88.7, and K3 sits at 5 × 16 = 80. One step in either direction, a floor of 6 or a tile of 24, puts it over. Neither constant was free to choose. Second, the choice is a genuine tradeoff rather than a free win. A floor on decay means a channel cannot forget instantly even when the model would like it to. K3 bought a fast kernel by giving up the ability to fully clear a channel in one step.
The mapping that changed, from §2.1.1 eq. 5:1
A_h is a learnable per-head log-scale initialised to 0, and g_min = −5 is fixed, never learned. Softplus is unbounded above, so negating it gives an unbounded-below log-decay. Sigmoid is bounded in (0,1), so scaling it by g_min bounds the log-decay in (−5, 0).
The arithmetic the bound guarantees:
The report is explicit about the consequence: This finite range allows both diagonal and off-diagonal tiles to use dense Tensor Core matrix multiplications, eliminating the position-pair diagonal path.
It also notes the parameterisation is closely related to the lower-bounded recurrence gates in prior work.
Smaller, but it belongs to the same story of K3 spending a little capacity to buy quality. After the recurrent read, KDA applies a gate that decides which channels of the result actually pass through. Kimi Linear computed that gate with a low-rank projection, a cheap approximation. K3 makes it full-rank and input-dependent, so every token gets a genuinely independent say over all channels.1 Gated MLA received the same upgrade, which is where its name comes from.
Now the layer that handles what KDA cannot. One in four attention layers in K3 is a Gated MLA layer doing full global attention, with exact retrieval at any distance.
Full attention's problem is the KV cache from lesson 2: a key and a value stored per token, per head, forever. MLA's trick is to not store them.
STANDARD ATTENTION CACHE MLA CACHE
per token, per head: per token, ONE vector:
[ k ] [ v ] [ c ] ← low-dim latent
[ k ] [ v ] cₜ = W_c · xₜ
[ k ] [ v ] × 96 heads
[ k ] [ v ] at attention time:
… … k, v ◀── up-project from c
for whichever head
needs them
cache size ∝ n × heads × 2 cache size ∝ n × 1
Note what MLA does and does not fix. It shrinks the constant, so the cache is much smaller per token. It does not change the growth: the cache is still proportional to sequence length. That is exactly why K3 needs KDA in the other three quarters of its layers, and why MLA alone was not enough to reach a million tokens.
Here is the part of K3 most worth being able to explain to someone else, because it sounds wrong.
Attention has no inherent sense of order. Feed it a shuffled sentence and it computes the same thing, because it compares every query to every key without regard to where they sit. Transformers therefore inject position explicitly. The dominant method is RoPE, which rotates queries and keys by an angle proportional to position, so their match strength encodes how far apart they are.
K3 applies NoPE to every one of its MLA layers. No rotation, no learned position embeddings, nothing. The global attention layers are genuinely order-blind.
The argument for why this works is the cleanest illustration of what a hybrid architecture buys. KDA is a recurrence. It processes tokens in order and decays its memory as it goes, so position is baked into its structure: something read recently has had less decay applied than something read long ago. Position information does not need to be injected into the attention scores, because three out of every four layers already carry it inherently.1
DIVISION OF LABOUR ON POSITION
KDA layers (69) MLA layers (24)
────────────── ──────────────
position: implicit, from position: none (NoPE)
decay and recurrence order
recency-aware by construction order-blind by construction
approximate retrieval exact retrieval,
unrestricted global reach
───────────────────────────────────────────────────────────
between them, position is handled once and structurally,
rather than encoded in every layer
CONSEQUENCE FOR CONTEXT EXTENSION
RoPE model: 8K ──▶ 1M needs frequency rescaling (YaRN etc.),
retuning, and usually costs quality
K3 (NoPE): 8K ──▶ 1M no positional parameters exist,
so there is nothing to retune
position-sensitive and recency-aware sequence mixingwhile MLA supplies
unrestricted global content interaction.Raschka notes K3 is the first frontier-scale model he knows of to go all-NoPE.3
The practical dividend appears in how K3 reaches a million tokens. Training runs a four-stage curriculum, 8K to 64K during pre-training, then 256K to 1M during cooldown. At no point does anyone rescale a frequency base or apply an interpolation scheme, because there are no positional parameters to touch. The report puts it directly: the model extrapolates directly to 1M-token contexts without any positional-encoding modification.
1
All-NoPE is a genuinely unusual bet, and K3 is the first model at this scale to make it. The report presents it as working, but there is no independent ablation isolating what it costs, and the KDA layers now carry sole responsibility for all positional information. If you are evaluating K3 for a task that depends on precise positional reasoning over very long inputs, this is the design decision to probe first rather than trust.
Kimi K3 · Lesson 4 of 14 · Depth axis
Most of K3's changes chase efficiency. This one chases quality instead, and it comes from noticing that depth has the same flaw sequence had.
Extracted from the full lesson, which adds the quiz, the references and the primary source to read next.
You have now seen K3's answer on the sequence axis. This lesson is the depth axis, and it rests on an observation the report makes in its first sentence on the subject: the residual stream is a bottleneck of exactly the kind attention was invented to fix.
A transformer passes information up through depth by accumulation. Layer 1 writes into a running state, layer 2 adds to it, layer 3 adds to that. By layer 70, that state holds contributions from 69 earlier layers, all summed together.
Summing works, but it destroys information about origin. Layer 70 receives one vector. It cannot ask what layer 12 contributed, or weight the embedding differently from layer 69. Everything arrives pre-mixed, in fixed proportions the layer has no say over.
The report's framing is the useful one, and it is worth quoting because it tells you exactly where the idea came from: standard residuals compress all prior information into a single state hl over depth — a bottleneck reminiscent of RNNs over time.
1
That comparison is the whole lesson. Recurrent networks had this exact problem along the sequence axis: everything read so far crushed into one hidden state, no way to reach back to a specific earlier token. Attention solved it by letting each position query all previous positions with learned, data-dependent weights. AttnRes applies that same move to depth.
THE SAME BOTTLENECK, TWICE
over SEQUENCE over DEPTH
───────────────── ──────────────
RNN Standard residual
one hidden state carries one residual stream carries
everything read so far everything computed so far
↓ ↓
cannot reach token 12,345 cannot reach layer 12
specifically specifically
── solved by attention ── ── solved by AttnRes ──
Transformer Attention Residuals
each position queries all each layer queries all
previous positions, with previous layers, with
learned weights learned weights
Lessons 2–3 this lesson
applies the same methodology to depth.Recognising this pattern is more valuable than memorising the mechanism, because it is how a great deal of architecture research proceeds.
The mechanism is small. Each layer gets a learned pseudo-query, a single vector belonging to the layer rather than to any token. Every earlier layer's output serves as both key and value, with the token embedding included as the earliest source. The layer's query is compared against all of them, softmax turns the comparisons into weights, and the layer reads a weighted blend instead of a plain sum.
One detail in the report matters more than its size suggests. The keys pass through RMSNorm before the comparison, which the authors say prevents layers with large-magnitude outputs from dominating the weights.
1 Without it, a layer that happens to produce big numbers would win the attention competition on volume rather than relevance.
From §2.2, eqs. 8–9. First, what serves as keys and values for layer l:
Then the weights and the read, a softmax kernel over depth:
Compare that to ordinary attention and the only differences are what the query is (learned per layer, not projected from a token) and what the index runs over (depth, not sequence position). The RMSNorm(k) inside the kernel is the magnitude-fairness fix.
Cost, in the report's own accounting: the arithmetic is O(L²d), which is affordable because network depth is modest (L < 100)
. The real problem is O(Ld) memory, because every layer output must stay alive, and must cross stage boundaries under pipeline parallelism.
Full AttnRes has a cost you can see without any math. If layer 70 attends over 69 earlier outputs, all 69 must still be in memory. Multiply by the size of each and by pipeline stages that need them shipped across devices, and the bill lands on memory and interconnect rather than arithmetic.
So K3 ships Block AttnRes. The 93 layers are partitioned into blocks of 12. Within a block, outputs are summed into one running representation, exactly as a standard residual would. Across blocks, full attention is applied over just the block-level summaries.
Switch between the three modes below and drag the layer slider. Watch the source count in each.
The shape to take away: a layer in the middle of the network reads from a handful of sources rather than one, and rather than seventy. Overhead falls from O(Ld) to O(Nd), and the report reports that N ≈ 8 recovers most of the benefit across model scales.
1
93 layers into 8 blocks of 12 does not divide evenly. Seven full blocks take 84 layers, leaving a partial final block of 9, so 8 blocks in all. The report then counts 9 when it adds the embedding as one more source. Two different nines, easy to conflate: nine layers in the last block, and nine total sources once the embedding joins the eight blocks. This is the kind of untidy detail that tells you a number came from a real training run, and it is worth checking whenever you read a config table.
Raschka's read of the report puts numbers on the overhead: roughly 4% in training cost and 2% in inference cost, for gains he describes as consistent but modest in validation loss and downstream performance.2 A few percent for a small, reliable gain is an unglamorous trade, which is worth stating plainly.
Two hedges belong on that sentence. The figures are the report's own, relayed by Raschka rather than measured independently, and no third party has isolated AttnRes from KDA at this scale. So "4% for a modest gain" is the authors' accounting of their own feature, and the gain is not separable from the other changes shipped alongside it. Repeat it as a claim, not a finding.
That is a genuinely unglamorous return, and saying so is the honest read. It also explains why the block form exists at all: at full-AttnRes memory cost the trade would likely not be worth making, and the block approximation is what brings the price down to where a few percent buys a real if small gain.
Block AttnRes was designed with inference in mind, not just training. Because a block's representation is computed once at its boundary and then shared by every layer after it, the inference-time state stays bounded. The report notes this lets the parallel inter-block results merge with the sequential intra-block partial sums using online softmax, significantly reducing inference time cost.
K3 also ships dedicated kernels for Block AttnRes, and §5.4.2 describes a two-phase schedule that keeps it off the critical path.1
K3 is not the only 2026 frontier model to decide the residual stream needed work, and the comparison sharpens what AttnRes actually is. DeepSeek V4 attacked the same bottleneck by making the residual path wider, using manifold-constrained hyper-connections. K3 instead kept the width and made the path selective across layers.2
TWO ANSWERS TO ONE BOTTLENECK
DeepSeek V4 — widen the pipe Kimi K3 — choose what to read
┌───────────────────────────┐ ┌───────────────────────────┐
│ more channels carrying │ │ same channels, but each │
│ more information │ │ layer weights its own │
│ forward │ │ sources across depth │
└───────────────────────────┘ └───────────────────────────┘
cost: width, so parameters cost: keeping earlier outputs
and memory everywhere reachable (bounded by N)
Kimi K3 · Lesson 6 of 14 · Width axis
896 experts per layer, 16 awake at a time. The expert pool is not a component of K3 so much as it is K3, and one compression trick is what makes it affordable.
Extracted from the full lesson, which adds the quiz, the references and the primary source to read next.
The third and last axis. Sequence was about mixing across tokens, depth about mixing across layers. Width is about mixing across channels, the dimensions inside a single token's representation, and it is where almost all of K3's 2.78 trillion parameters live.
By the end of this lesson you should be able to derive that 2.78T figure yourself from the config table, which is a better test of understanding than remembering it.
A conventional feed-forward layer sends every token through the same network. An MoE layer holds many networks and sends each token to a few. Two kinds of expert sit side by side in K3.
Sigmoid(W_r x) and takes the top 16.More experts sounds straightforwardly good: more room for specialisation, and since only 16 activate, the compute per token stays flat. So why does nobody just use 10,000?
Because compute is not the only cost. In a conventional MoE, each selected expert receives the token's full-width representation. All 7,168 numbers, copied to all 16 experts, which typically live on 16 different accelerators. The report names both consequences of naive expansion: communication and expert-weight traffic grow with the routing multiplicity.
1
| Cost | Conventional MoE | K3 LatentMoE |
|---|---|---|
| compute per token | flat in E | flat in E |
| parameters | E × full width | E × latent width |
| dispatch traffic | k × 7,168 = 114,688 floats |
k × 3,584 = 57,344 floats |
Latent width halves everything in this table that scales with E.
LatentMoE's move is to decouple two things that are normally the same number. The model works in 7,168 channels. The routed experts do not have to.
Before dispatch, the token is compressed by a down-projection to 3,584 channels, exactly half. The 16 selected experts do their work entirely in that smaller space. Their weighted output is normalised and expanded back to full width by an up-projection. Shared experts, meanwhile, keep the full-width path, because they run for every token and are few.1
You have met this move already. MLA compresses each token's key–value pair into a low-dimensional latent to shrink the KV cache. LatentMoE compresses each token's representation into a low-dimensional latent to shrink the expert pool. Raschka points out the family resemblance directly, noting LatentMoE compresses large linear layers in the spirit of multi-head latent attention.
2 One architectural instinct, applied in two places.
Now the payoff, which you can compute. Move the width slider and watch the total.
At K3's own setting the routed pool works out to roughly 2.72T. Push expert width to full d and that pool becomes 5.45T on its own, taking the whole model past 5.4T for the same number of experts and the same compute per token. Halving expert width halves almost the entire parameter count, because the routed pool is essentially the whole model.
This is worth doing once by hand, because it converts a memorised fact into something you can reconstruct, and because the method transfers to any MoE config table you meet.
ONE ROUTED EXPERT
a GLU holds three matrices: gate, up, down
3 × latent × hidden = 3 × 3,584 × 3,072 = 33.0M params
ONE LAYER'S ROUTED POOL
33.0M × 896 experts = 29.6B
ALL MoE LAYERS
29.6B × 92 layers = 2.72T ← 98% of the model
PLUS
W↓ and W↑ projections 2 × 7,168 × 3,584 × 92 = 4.7B
shared experts 3 × 7,168 × 3,072 × 2 × 92 = 12.2B
embedding + output 160K × 7,168 × 2 = 2.3B
MoonViT-V2 0.4B
attention (KDA + MLA) the remainder
─────────────────────────
report's total: 2.78T ✓
The same arithmetic explains the activated figure. Sixteen experts at 33.0M each across 92 layers is 48.6B, plus 4.7B of always-on projections and 12.2B of shared experts, giving 65.5B from the feed-forward path. Attention and embeddings supply the remaining ~39B of the 104.2B total.
The layer, from §2.3 eq. 11:1
W↓ x compresses the token from d = 7,168 to ℓ = 3,584 before dispatch, so the smaller vector is what crosses the interconnect.E_i^routed : ℝ^ℓ → ℝ^ℓ — routed experts map latent space to latent space. They never see full width.p_i — the router weight for expert i, normalised over the selected set.T_k(x) — the selected top-16.E_j^shared : ℝ^d → ℝ^d — shared experts, full width, N_s = 2, always active.W↑ RMSNorm(u) — normalise, then expand back to d. The RMSNorm placement is the subject of the next section.Router scores and weights, from §2.3.3 eq. 13:
That the bias b steers dispatch but never enters p is the design detail that makes load balancing possible without disturbing the router's gradients. Lesson 7b is about how b is set.
Sparsity of 56 is aggressive, and the report is candid that the vanilla design does not survive it. Two failure modes are named, and the word Stable in "Stable LatentMoE" refers to the fixes.1
FAILURE 1 — exploding activations
The routed path chains four matrix multiplies back to back:
W↓ ──▶ gate ──▶ up ──▶ W↑
└── the expert's GLU ──┘
An ill-conditioned chain at 2.8T scale produces
"exploding internal activations in the routed branch."
Fixes: RMSNorm before W↑ (§2.3.1, this lesson)
SiTU-GLU bounded activation (§2.3.2, lesson 7)
FAILURE 2 — load imbalance
Balancing ~10³ experts per layer "exceeds the regime in which
existing auxiliary-loss-free bias updates remain well behaved."
Some experts overheat, others never train at all.
Fix: Quantile Balancing (§2.3.3, lesson 7b)
The fix in this lesson is the smallest change in K3 and a good illustration of how much a normalisation placement can matter. In the original LatentMoE, the up-projection is applied directly to the aggregated routed output, whose scale varies depending on which experts were chosen and how strongly. K3 inserts an RMSNorm between aggregation and up-projection, so the routed branch arrives at a predictable scale before joining the full-width shared branch.
The report claims this earns its place twice over: Beyond stabilizing training, the additional RMSNorm consistently improves validation loss and downstream benchmarks.
1
Kimi K3 · Lesson 7 of 14 · Width axis
Sparsity of 56 breaks the vanilla design in two ways. This lesson is the first fix: capping an activation function nobody had questioned in years, because K3 trains in 4-bit.
Extracted from the full lesson, which adds the quiz, the references and the primary source to read next.
Lesson 6 ended with the report's admission that extreme sparsity amplifies two failure modes. First, activations explode in the routed branch. Second, load balancing stops working at nearly a thousand experts per layer. The word Stable in Stable LatentMoE names the fixes for both. This lesson takes the first; lesson 7b takes the second, which is the better story.
Every modern transformer's feed-forward network uses a gated linear unit. Two projections of the input, one modulating the other by multiplication.
| Variant | Gate branch | Up branch | Bounded? |
|---|---|---|---|
| GLU | σ(x) | x | no |
| SwiGLU | x · σ(x) | x | no |
| SiTU-GLU | β₁tanh(x/β₁) · σ(x) | β₂tanh(x/β₂) | yes, ≤ β₁β₂ |
x · σ(x). Roughly linear for large positive inputs, smoothly suppressed for negative ones. The gate function in SwiGLU.a complete account of its empirical effectiveness remains open.
The problem the report identifies is simple once stated: both of SwiGLU's factors are unbounded. When two large numbers happen to land in the same coordinate, their product is much larger, and the report warns this can produce activation outliers and increase overflow risk in low-precision arithmetic.
1
Why K3 cares more than most: it applies quantization-aware training from the SFT stage onward, with MXFP4 weights and MXFP8 activations (SFT, supervised fine-tuning, is the first post-training stage; lesson 12 covers it).1 A 4-bit float represents very few distinct magnitudes. One wild activation forces the scaling factor for an entire block to accommodate it, and everything else in that block loses precision. Outliers are far more damaging at 4 bits than at 16.
Cap the large values without changing the behaviour near zero. That second half matters, because SwiGLU's response shape around the origin is presumably why it works, and nobody wants to discover otherwise at 2.8T scale.
SiTU-GLU's answer is a soft cap: β·tanh(x/β), applied to both branches. The tanh function is almost exactly the identity near zero and flattens to ±1 far out, so scaling it by β gives a function that passes through the origin like x and saturates at ±β.
Switch between the two views. The near-origin view is the one that should surprise you.
Near the origin the two curves are indistinguishable, a deviation of 0.02% at x = 0.1. At x = 100 SwiGLU has reached 10,000 while SiTU-GLU has flattened at just under 100. Same function where it matters for learning, hard ceiling where it matters for precision.
From §2.3.2 eq. 12, with the soft cap softcap(x, β) = β·tanh(x/β):1
Note the gate branch keeps its sigmoid factor uncapped. Appendix B explains why: Because the sigmoid already drives the negative gate response toward zero, this change primarily controls large positive activations without removing the negative tail.
The two properties, from appendix B eqs. 18–19:
The bound follows immediately from |tanh| < 1 and 0 < σ < 1: the product of two factors capped at β₁ and β₂ cannot exceed β₁β₂.
One last detail worth noticing, because it explains why a smooth cap rather than a hard clamp: Unlike hard clamping of gate pre-activations, the smooth cap preserves nonzero gradients away from saturation boundaries, which we find to give better training behavior.
A hard clamp has zero gradient past the threshold, so a unit that saturates stops learning. Tanh always has some gradient.
SiTU-GLU's bound of 100 looks like an arbitrary detail here. It is not: it exists because §4.1.4 decided to train and serve K3 in 4-bit. Bounded activations are what make MXFP4 survivable, so an activation-function choice in §2.3.2 is really a consequence of a deployment decision. Lesson 11 returns to this from the serving side.
Kimi K3 · Lesson 7b of 14 · Width axis
The second stability fix, and the more satisfying one. It turns a fiddly tuned heuristic into a question with a direct answer, and that answer is the solution to a known problem.
Extracted from the full lesson, which adds the quiz, the references and the primary source to read next.
Lesson 7 fixed exploding activations with a bounded activation function. This is the other failure mode extreme sparsity creates: keeping nearly a thousand experts per layer evenly loaded. It is the last piece of Stable LatentMoE, and the width axis is complete once it lands.
The router learns which experts suit which tokens, and nothing stops it developing favourites. Left alone it will route heavily to a popular few while others receive almost nothing. Both ends of that distribution are bad.
WHY IMBALANCE IS EXPENSIVE
overloaded expert starved expert
───────────────── ──────────────
its device becomes the receives too few tokens
slowest in the batch; to learn anything useful;
every other device waits its parameters are dead weight
"Imbalanced routing slows expert-parallel training and may
leave some experts poorly trained." — §2.3.3
The standard fix is to add a per-expert bias to the router's scores, used only for choosing experts and deliberately excluded from the mixture weights. That exclusion is the clever part of the existing method: the bias steers dispatch without touching the router's gradients, so balancing does not fight learning.
The question is how to set that bias. The method K3 inherited nudges it by a fixed step: if an expert is above target, push its bias down a little; if below, push it up. It works, and the report names its weakness precisely: the step size trades off slow adaptation against load oscillation.
Too small and imbalance persists for thousands of steps; too large and loads swing back and forth. At 896 experts, the report says this exceeds the regime in which existing auxiliary-loss-free bias updates remain well behaved.
1
Try all three settings below. Start with no balancing to see the problem, then step the fixed-step method a few times, then switch to Quantile Balancing and press the button once.
The difference is not incremental. Fixed-step nudging is still badly imbalanced after six steps; Quantile Balancing drops imbalance by an order of magnitude in one, and revives every dead expert.
The insight is a reframing. Instead of asking "which direction should this bias move," QB asks "what bias would have produced exactly the target load?" That question has a direct answer, because it is a question about a quantile.
THE REFRAMING
fixed-step quantile
────────── ────────
"expert 7 is too busy "expert 7 should serve 64 tokens.
— nudge it down a bit Among all tokens' margins for expert 7,
and see what happens" the 64th largest is the threshold that
admits exactly 64. Set the bias there."
iterative, tuned direct, no step size to tune
HOW THE MARGIN IS OBTAINED
for each token, route with Top-(k+1) instead of Top-k:
rank: 1 2 3 … k │ k+1
● ● ● ● │ ○
└── actually used ──┘ │ └── the CUTOFF: the score an
│ expert must beat to get in
margin for expert j on token i = its score − that token's cutoff
bias for expert j = −(the (1 − k/n) quantile of its margins)
What makes this more than a trick is where it comes from. Appendix C derives QB from the optimal balanced assignment problem: maximise total router score subject to every token getting exactly k experts and every expert getting exactly mk/n tokens. That is an integer program, but its linear relaxation is exact for this structure, and in the dual, the expert-side multipliers are the biases.1 So QB approximates the solution to a problem whose optimum is known, which is a stronger footing than a heuristic that merely works in practice.
Routing, from §2.3.3 eq. 13:
The update, eq. 14, where α_i is token i's Top-(k+1) cutoff:
Three details that each matter:
1 − k/n because the target load is q = mk/n out of m tokens, and q/m = k/n. Setting the threshold at the (q+1)-th largest margin admits exactly q tokens.takes effect only in the next step, so a batch is never routed using a bias derived from itself. The report calls this causality; it prevents the balancing from peeking at its own outcome.
At inference the biases are frozen: balancing is purely a training-time concern.
An exact quantile needs all the margins in one place, and at K3's scale they number in the millions, spread across many devices and gradient-accumulation steps. Gathering them is not viable. So QB builds a histogram of each expert's margins instead: one all-reduce sums the per-device bin counts, and the quantile is read from the pooled histogram. Because counts add, the result reflects the true global batch regardless of how tokens were sharded, at a cost of only a few hundred bins per expert.
This is the kind of detail that separates a method that works on paper from one that ships at 2.8T.1
Kimi K3 · Lesson 8 of 14 · Input pathway
K3 throws away the standard recipe for building a vision encoder. The reason has nothing to do with how well that recipe performs, and everything to do with what it does to training stability.
Extracted from the full lesson, which adds the quiz, the references and the primary source to read next.
Everything so far has been the backbone. This lesson is what happens before it: how images and video enter the same token stream as text, and one decision that contradicts several years of accepted practice.
Most models that handle images were language models first. A vision encoder gets attached afterwards, and a separate alignment stage teaches the two halves to talk. K3 does not work that way.
THE CONVENTIONAL RECIPE KIMI K3
1. train a language model 1. train everything at once
on text text + images interleaved,
one next-token objective
2. take a vision encoder
pretrained contrastively ┌────────────────────────┐
(SigLIP, CLIP) │ MoonViT-V2 │
│ trained from scratch │
3. bolt them together with a │ with next-token │
projector │ prediction │
└───────────┬────────────┘
4. run an alignment stage to │
teach them to cooperate ┌───────────▼────────────┐
│ MLP projector │
└───────────┬────────────┘
│
┌───────────▼────────────┐
│ shared backbone │
│ 93 layers │
└────────────────────────┘
no post-hoc alignment stage
by a single shared backbone within one context, with no post-hoc modality-alignment stage.1
The payoff the report emphasises is behavioural, not benchmark. Because rendered output and the code that produced it live in the same token stream, K3 can write code, look at a screenshot of the result, and revise, with no hand-off to another model. That loop is what makes the launch post's chart-building and slide-making demos possible.2
Here is the part worth being able to explain to someone else.
Standard practice is to initialise a vision encoder from a model pretrained with a contrastive objective, typically SigLIP or CLIP. Kimi K2.5 did exactly this. The reasoning is intuitive: a contrastively pretrained encoder already knows a great deal about images, so the multimodal model starts ahead.
K3 trains MoonViT-V2 from scratch with next-token prediction instead. The report is direct about why, and the justification is about optimisation rather than accuracy: We depart from this practice primarily for training stability.
1
matches the SigLIP-initialized baseline across vision evaluations, indicating
contrastive pre-training is unnecessary as an initialization for multimodal language models at scale.
Two arguments are stacked here, and they are worth separating because only one of them is about stability.
The first is the stability finding above. Joint optimisation of a pretrained encoder and a language model fights itself: the encoder arrives with representations shaped by a different objective, and the gradient norms show the friction.
The second is about what the encoder learns. A contrastive objective rewards global semantics, which the report notes comes at a cost: it favors global semantics over fine-grained textual and structural cues.
Next-token prediction shapes the encoder's representations by the objective the whole model is actually judged on. For K3's real workloads, reading text in a screenshot, judging whether a rendered chart looks right, fine-grained structure is the thing that matters.
The finding is a negative result about accepted practice, and negative results are the most useful things in an architecture paper because they tell you what you can stop doing. If it holds up, an entire preparatory step in the standard multimodal recipe is optional at scale. Treat it as one team's ablation until someone replicates it, but note that they had no incentive to publish this particular conclusion.
The mechanics matter for a practical reason: images are expensive in context, and K3's design decisions are visible in the arithmetic.
ONE MAX-RESOLUTION IMAGE THROUGH MoonViT-V2
3584 × 3584 pixels
│
│ patch size 14
▼
256 × 256 = 65,536 patches 6.6% of a 1M context
│
│ pixel-shuffle, 2 × 2 downsample
▼
128 × 128 = 16,384 tokens 1.6% of a 1M context
│
│ MLP projector
▼
into the shared backbone
Roughly 61 max-resolution images fit in a 1M-token context.
Without the pixel-shuffle step, only 15 would.
affordable within the 1M-token context.1
Three more design choices, each small and each purposeful:
further stabilizes the from-scratch optimization. The same stability theme again.
precise and resolution-robust localization.That is what lets the model point at things in a screenshot regardless of its size.
The vision corpus deliberately scales programmatic data: code paired with the visual it renders, across SVG, 3D assets, webpages, games, and CAD schematics.1 This is training data purpose-built for the write-code-then-look-at-it loop. When you read that K3 tops WebDev Arena, this is a large part of why.
One infrastructure detail is worth a mention, because it is the kind of engineering that decides whether native multimodality is affordable.
A vision encoder is a serial cost sitting in front of the backbone, and a large image or long video makes it worse by loading some devices far more than others. K3 attacks this by hiding the work in gaps that already exist.
PIPELINE PARALLELISM HAS IDLE GAPS
stage 1 ████░░░░░░░░████ ░ = bubble, device idle
stage 2 ░░████░░░░████░░ waiting for other stages
stage 3 ░░░░████████░░░░
K3 schedules ViT work into those bubbles:
stage 1 ████▓▓▓▓▓▓▓▓████ ▓ = vision encoder work
stage 2 ░░████▓▓▓▓████░░
stage 3 ░░░░████████░░░░
Result: "most of the ViT computation is hidden within pipeline
bubbles, largely eliminating the effective overhead of
the vision encoder." — §5.2.3
One neat connection to lesson 4. K3 uses speculative decoding to speed up generation, and its draft model needs to see the target model's internal features. Which features? The outputs of AttnRes blocks 1, 4, and the final one, concatenated and projected, giving low-, mid-, and high-level representations respectively.1
Block AttnRes was introduced to cut memory overhead on the depth axis. A side effect is that it leaves clean, well-defined representations at block boundaries, and those turn out to be exactly what a draft model wants. The fusion matrix is even initialised as [0 0 I], so at the start it uses only the high-level feature and learns to incorporate the others gradually.
Kimi K3 · Lesson 9 of 14 · Optimisation
The last piece of the model sits outside the network entirely: how its weights get updated, and the empirical study that produced the claimed 2.5×.
Extracted from the full lesson, which adds the quiz, the references and the primary source to read next.
Architecture is only half of what determines whether a 2.8T model trains well. This lesson covers the optimiser and the empirical study that set K3's hyperparameters. Both are short sections in the report, and both contain a lesson that transfers well beyond K3.
Start with the optimiser everyone knows. Adam-family optimisers treat every weight as an independent scalar: track a running average of each weight's gradient, scale by a running average of its magnitude, step. Nothing in that procedure knows that the weights are arranged in a matrix.
Muon takes the arrangement seriously. Before applying an update to a matrix parameter, it orthogonalises the momentum matrix.
WHY ORTHOGONALISE AN UPDATE
raw momentum matrix after orthogonalisation
─────────────────── ───────────────────────
one direction dominates all directions comparable
████████████████████ ◀── the ██████
██ update ██████
█ is mostly ██████
█ this row ██████
the step moves the weights the step uses the full
almost entirely one way capacity of the matrix
Now K3's refinement, and it is worth reasoning through because the flaw it fixes is a general one.
Attention does not use one big matrix. It uses many heads, each reading and writing its own slice of the representation. K3 has 96 of them. But the query, key, and value projections are stored as single large matrices, with the heads sitting side by side inside them.
So when Muon orthogonalises the full Q, K, or V projection, it treats all 96 heads as one coupled block. The report spells out the consequence: heads with larger gradient or momentum scales dominate the shared update direction, while smaller-scale heads receive insufficiently normalized updates.
1
FULL-MATRIX MUON PER-HEAD MUON
┌───────────────────────────┐ ┌─────┬─────┬─────┬─────┐
│ h1 │ h2 │ h3 │ ... │ h96 │ │ h1 │ h2 │ h3 │ h96 │
└───────────────────────────┘ └─────┴─────┴─────┴─────┘
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
one orthogonalisation orthogonalise each
over everything head separately
a loud head sets the scale every head gets its own
for all 96; quiet heads get properly normalised update
updates that are barely
normalised at all
── and it is cheaper: Newton-Schulz on tall per-head blocks
costs less than on the full projection matrix
more balanced learning dynamics across heads and improves training stability at larger scales.
This is the same error shape you have already seen twice in this course. AttnRes exists because summing all earlier layers into one state loses the distinction between them. Channel-wise decay in KDA exists because one scalar decay rate for a whole memory cannot express different retention needs. Per-Head Muon exists because one orthogonalisation across 96 heads cannot express different update scales. When you see a single statistic standing in for many things that differ, that is a place to look for an improvement.
The report also notes it slightly reduces optimizer overhead
, since Newton–Schulz on tall thin per-head blocks is cheaper than on the full matrix. A quality improvement that also runs faster is rare enough to be worth noticing.
Muon has an awkward requirement under distributed training: orthogonalisation needs the full parameter matrix, but the optimiser shards parameters across data-parallel ranks. The obvious fix is an all-gather over the whole parameter buffer on every rank, which the report notes makes communication the primary bottleneck at scale.
K3 instead has each rank fetch only the shards of parameters it actually owns, peer to peer, then pipelines that communication against computation. The full-parameter buffer disappears entirely.1
Now the number quoted in every summary of K3, and what it actually means.
A scaling law is an empirical curve: train a family of small models at varying sizes and compute budgets, measure loss, and fit a relationship you can extrapolate. Its practical purpose is to choose hyperparameters for a run you can only afford to do once.
What the study retuned, because the architecture changes moved the optimum: batch size, learning rate, tokens-per-parameter ratio, and model shape.1 That last one is why K3 has 93 layers and a 7,168 hidden dimension rather than some other combination. The shape was fitted, not guessed.
The 2.5× is the authors' own fit, on their own held-out validation set, comparing against their own previous model. Nobody has replicated it. It is also not decomposed: you cannot tell from the report how much came from KDA versus AttnRes versus better data, and "refined data recipes" is doing unknown work inside that figure. When explaining K3 to someone, say "the report claims a 2.5× scaling-efficiency gain, attributed to the architecture and data changes together." That is both accurate and appropriately hedged.
The most interesting paragraph in §3.2 has nothing to do with 2.5×, and it is a lesson in experimental method rather than architecture.
Two learning-rate schedules compete in current practice. Cosine decay smoothly lowers the rate along a cosine curve. Warmup-Stable-Decay holds the rate constant for most of training, then drops it at the end, which is convenient because you can stop at any point. Recent work has reported WSD matching or beating cosine.
K3's study finds the opposite, and the explanation is the valuable part.
THE METHODOLOGICAL TRAP
the usual comparison what K3 did
──────────────────── ───────────
pick one set of hyperparameters search for the optimal
│ hyperparameters for
▼ EACH schedule separately
run cosine ──▶ loss A │
run WSD ──▶ loss B ▼
│ cosine at its own optimum
▼ ──▶ loss A'
declare a winner WSD at its own optimum
──▶ loss B'
but the two schedules have │
"markedly different optimal ▼
hyperparameters" — so this a fair comparison:
just measures which schedule cosine consistently wins
the shared settings suited
substantiallydifferent peak learning rates and batch sizes. Comparing them under shared settings
may unfairly favor one simply because those hyperparameters are better aligned with it.1
This is a trap worth recognising in any paper you read. Whenever two methods are compared under one shared configuration, ask whether that configuration was tuned for one of them. It very often was.
K3's final recipe, for reference: cosine decay, 1% linear warmup, weight decay 0.1 throughout, Per-Head Muon plus K2's weight-clipping mechanism, Quantile Balancing for the experts. Context starts at 8K and reaches 64K in pre-training, then 256K to 1M during cooldown.1
Kimi K3 · Lesson 11 of 14 · Systems
Every architectural choice in the preceding lessons shows up on an invoice. This is where the hybrid design gets awkward, and where it pays.
Extracted from the full lesson, which adds the quiz, the references and the primary source to read next.
The architecture is behind you. This lesson is about running the thing: what it costs, why the price list has a tenfold gap in it, and what the hybrid attention design does to a serving stack. This is the material that decides whether K3 is right for a given job.
KIMI K3 API PRICING, per million tokens
input, cache hit $0.30 ◀── ten times cheaper
input, cache miss $3.00
output $15.00
The report gives the scenario that explains the pricing, and it is worth doing the arithmetic. In a typical coding session at long context, a typical coding input carries a prefix of 400K tokens but requires a prefill increment of only 4K tokens.
1
ONE TURN OF A CODING SESSION
400,000 tokens of prefix + 4,000 new tokens
cache miss 404,000 × $3.00/M = $1.21
cache hit 400,000 × $0.30/M
+ 4,000 × $3.00/M = $0.13 9.2× cheaper
ACROSS A 50-TURN SESSION
all misses = $60.60
with prefix caching = $ 6.60
───────
saved $54.00
The launch post reports a cache hit rate above 90% in coding
workloads, giving a blended input price near $0.57/MTok.
At 1M context, cost is dominated by whether your prefix is stable. Append to a conversation and you hit the cache. Edit anything early in the prompt, reorder a system message, or reshuffle context between turns, and you invalidate everything after it and pay full price. Prompt architecture is cost architecture.
Here is where lessons 2 and 3 come due. K3 has two kinds of attention layer, and they need fundamentally different caches.
TWO CACHES, ONE REQUEST
Gated MLA layers (24) KDA layers (69)
────────────────────── ───────────────
grows with sequence length fixed size
paged per token one state per request
natural fine granularity snapshots affordable only
at sparse boundaries
───────────────────────────────────────────────────────────
a cached prefix is reusable ONLY if BOTH can be
restored at the SAME boundary
complicates prefix caching: the two cache types
differ fundamentally in size and lifetime, yet a cached prefix is reusable only when both can be restored together at the same boundary.1
The naive resolution is to force one shared block size on both. That fails badly, and the failure is instructive. Because a KDA state is one large object per sequence rather than per-token entries, checkpointing it is expensive, so it can only be saved at sparse boundaries. Forcing MLA to match pushes the shared block size to 1024 to 6144 tokens, and the report's verdict on that is blunt: At such a coarse granularity caching is nearly useless: requests shorter than one block can never be reused, and chunked prefill exports no cacheable prefix until it crosses a full block boundary.
1
K3's fix is to stop insisting the two granularities match.
typically coincide with conversation-turn boundaries.On a hit at B the server restores the KDA checkpoint, copies the partial MLA block on write, and resumes prefill from token B with zero recompute of the span before it.
That last detail is the elegant part. Checkpoints are expensive, so K3 keeps the ones most likely to be reused: the boundaries between conversation turns, which is exactly where a follow-up request will resume.
Both cache types are packed into one paged pool with pages unified to the same byte size, so allocation, reference counting, and eviction have a single implementation. The report notes a side benefit found during development: because the two layouts are structurally different, any type-confused access yields garbage rather than plausible data — a zero-overhead sanity check on the pooled layout.
1 Making your bugs loud instead of subtle is a good design instinct.
Recall the derivation from lesson 6: nearly all of K3's 2.78T parameters sit in the routed expert pool. Those weights have to live somewhere, and each token's 16 chosen experts must be reachable quickly.
supernode configurations with 64 or more accelerators.2
The requirement follows directly from the architecture. Total parameters set the memory floor, and dispatch traffic sets the interconnect floor. LatentMoE halves the second, and MXFP4 quantization shrinks the first, but 2.78T is 2.78T.
QUANTIZATION-AWARE TRAINING
MXFP4 weights + MXFP8 activations, from the SFT stage onward
trained AT the precision it is served at, not compressed after
│
└── which is why SiTU-GLU exists (lesson 7):
bounded activations are what make 4 bits survivable
This is the cleanest example in the whole report of architecture and deployment being designed together. SiTU-GLU's bound of 100 looks like an odd detail in §2.3.2. It is there because §4.1.4 decided to train in 4-bit.
Two production problems, both created by the million-token context, both with solutions worth knowing.
Cache affinity. If a hit is orders of magnitude cheaper than a miss, requests must be routed to the machine holding their cache, since moving a cache across clusters is slower than recomputing. But binding a session to one cluster means a cluster failure kills every session on it. K3 uses consistent hashing to pin each session to two clusters: a primary that serves it, and a secondary that takes over on failure and re-prefills from scratch. Because secondary assignments are spread uniformly, that recovery work lands across many clusters rather than one.1
Traffic variance. Production mixes requests under 2K tokens with requests up to 1M, so per-request cost spans roughly three orders of magnitude.
The failure mode is specific: a burst of long-context requests saturates compute, and short requests behind them wait, degrading time-to-first-token for everyone. Averages are useless here, so K3 gives each request class its own resource budget, letting long-context bursts consume at most their own share.1
Cost only means something next to capability, so before the price comparison, the standing. The report's own one-line summary of §6.1.4 is worth taking at face value: K3 closely trails the strongest proprietary models, Claude Fable 5 and GPT-5.6 Sol, while consistently outperforming Claude Opus 4.8, GPT-5.5, and GLM-5.2 across the benchmark suite.
1
| Domain | Benchmark | K3 | Standing |
|---|---|---|---|
| Reasoning | GPQA Diamond | 93.5 | competitive with the frontier |
| Reasoning | CritPt | 23.4 | behind Fable 5, GPT-5.6, GPT-5.5 |
| Coding | ProgramBench | 77.8 | best score |
| Agentic | BrowseComp | 91.2 | state of the art |
| Agentic | GDPval-AA v2 | 1686 | third, led by Fable 5 (1747) |
| Vision | OmniDocBench | 91.1 | highest score |
The shape to remember: K3 is at or near the top on agentic and document work, and behind on research-level reasoning. On HLE-Full it trails both leaders at 56.0% with tools and 43.5% without, and the authors name the weakness themselves rather than leaving you to find it: research-level reasoning remains a key direction for improvement.
1 That sentence is worth more than any single score, because it tells you which workloads to trial and which to leave alone.
Now the price. The report includes a cost-efficiency section, which is unusual and to its credit. The consistent finding: K3 trails the two strongest proprietary models on quality and beats them substantially on price.
| Benchmark | K3 result | Cost comparison |
|---|---|---|
| Kimi Code Bench 2.0 | 4.0 points behind Fable 5 | 38% of Fable 5's cost |
| Kimi Code Bench 2.0 | high effort ≈ Opus 4.8 at max | roughly one third the cost |
| BrowseComp | best score, 91.2 | $2.03/task, half of GPT-5.6 Sol |
| GDPval-AA v2 | within 50 Elo of GPT-5.6 Sol | 13% lower; 2.6× cheaper than Fable 5 |
| AA-Briefcase | second, behind Fable 5 | roughly half Fable 5's cost |
Every Fable 5 number in the report includes potential fallbacks
, and every GPT-5.6 Sol number includes potential cyberguards
. On SWE-Marathon, Fable 5 hit fallbacks on 35% of the tasks.
A fallback means the harness gave up and did something else, so those baseline scores are not clean. This cuts both ways: it may understate the competitors, and it also means K3's relative standing is measured against a noisy reference. Every K3 figure above is at max reasoning effort, which is also its most expensive setting, so capability and cost tables are not independent. Third-party standings, cited as of 23 July 2026, drift as leaderboards accumulate matches, and benchmark numbers date faster than anything else in this course.
You saw this simulator in lesson 2, when the question was theoretical. Now it is a serving question: this is the shape of what you pay for at long context.
Three quarters of K3's attention layers have flat per-token cost. That is why a million-token context is offered at all, and why the coding-session arithmetic above works out the way it does.
Kimi K3 · Lesson 12 of 14 · Behaviour
Pretraining produced something that can predict tokens. Nine specialist models and a consolidation step produced something that can work for hours. Then the team published three ways it falls short.
Extracted from the full lesson, which adds the quiz, the references and the primary source to read next.
Last piece of new material. The architecture explains what K3 can compute; this explains what it actually does, and the three caveats that matter if you deploy it.
① SFT cold start
synthesised agent trajectories from earlier Kimi models,
multi-stage verified, human-in-the-loop annotated,
serialised in an XTML-based chat template
▼
② RL specialise
3 domains × 3 effort levels = 9 expert models
general tasks ┐
general agents ├── each trained at low / high / max
coding agents ┘
▼
③ MOPD consolidate
Multi-Teacher On-Policy Distillation:
all nine experts distilled into ONE model that keeps
each specialisation at each effort level
training specialized RL models for individual tasks,it covers three broad domains each spanning a wide spectrum of sub-tasks.1
The choice worth noticing is that effort level is a trained axis, not a knob bolted on afterwards. Nine experts means each domain got its own model at each of low, high, and max. When you set effort on the API, you are selecting behaviour that was optimised at that budget.
MOPD is conceptually simple once you see the reward. For each token the student generates, compare the probability the appropriate teacher would have assigned it against the student's own. The log-ratio is the reward, clipped to keep extremes from destabilising training.1
MULTI-TEACHER ON-POLICY DISTILLATION
sample a domain d and an effort level e
│
▼
pick the matching teacher from the nine
│
▼
student generates a token yₜ
│
▼
reward = clip( log [ π_teacher(yₜ) / π_student(yₜ) ] , ±R_max )
└── dense: one signal per token, not per task ──┘
ON-POLICY means the student learns from its OWN outputs,
so it improves where it actually goes wrong
naturally enabl[es] infrastructure-level optimizations such as partial rollout training for long-horizon tasks.
One negative result reported in passing, and negative results are worth collecting: they also tried more fine-grained top-k distillation objectives and observed no clear advantage in either convergence speed or final performance.
The simple log-ratio was enough.
The environments are where K3's agentic behaviour is actually built. The report describes training a general loop of reasoning, acting, observing, verifying, and adapting, often over hundreds or thousands of tool calls and millions of accumulated context tokens.
1
Two infrastructure details make that loop trainable, and both are worth knowing because they explain what K3 is good at.
QAT runs through the entire post-training stage, SFT and RL both. During RL, rollout and training share the same quantization scheme — eliminating the train–inference mismatch.
1 The model does its reinforcement learning at the precision it will be served at, so it never has to adapt to a format change at deployment. MoE expert weights go to MXFP4; attention projections, latent MoE projections, shared experts, and routers stay higher precision.
The launch post includes a limitations section written against the team's own model. This is the most useful part of the release for anyone deciding whether to deploy, and the first one is a genuine operational trap.
① SENSITIVITY TO THINKING HISTORY ← the trap
K3 was trained in preserved-thinking-history mode.
If you do NOT pass its reasoning back on the next turn,
or switch sessions mid-stream, quality
"may become highly unstable."
▸ Practical: persist and replay the reasoning blocks.
Dropping them to save tokens is the expensive kind
of saving.
② EXCESSIVE PROACTIVENESS
May "make unexpected decisions on the user's behalf."
▸ Practical: constrain scope explicitly in the system
prompt or AGENTS.md. Assume it will act unless told
where the boundaries are.
③ USER-EXPERIENCE GAP
A "noticeable gap in user experience" versus Claude
Fable 5 and GPT-5.6 Sol, beyond what benchmarks capture.
▸ Practical: benchmark scores will overstate how it
feels to use. Trial it on your own work.
Most API integrations strip reasoning blocks between turns, because they are large and look like scratch work. For K3 that is a correctness issue, not an optimisation. If you evaluate K3 and find it erratic on multi-turn tasks, check whether your harness is preserving thinking history before concluding anything about the model.
Your mission included being able to make a grounded call on where K3 fits. Here is the summary the evidence supports.
| Question | What the evidence says |
|---|---|
| Is it the best model? | No. It trails Claude Fable 5 and GPT-5.6 Sol overall, and the report says so in its own abstract. |
| Where does it lead? | BrowseComp (91.2), ProgramBench (77.8), SWE-Marathon (42.0), WebDev Arena (1,678 Elo, first of 99). |
| Is it the best open model? | Yes, on this suite, and by a clear margin over GLM-5.2. |
| Is it good value? | Consistently. 38% of Fable 5's cost on KCB 2.0; best BrowseComp score at half GPT-5.6 Sol's price. |
| What is it for? | Long-horizon agentic work, web development, deep research at long context, and anything where open weights matter. |
| What would rule it out? | Under 64 accelerators for self-hosting; a harness that discards reasoning between turns; tasks needing the last few points of raw capability. |