AIAny. ← Back to AIAny

Lesson notes · One paper · two inventions · one memory bill

DeepSeek-V2

A 2024 model that stores 236 billion parameters but bills each token for only 21 billion — and that remembers a 300-page document in a cache 57× smaller than standard attention would keep. This page walks both tricks slowly enough that you can redo the arithmetic yourself.

Subject MoE language model Date May 2024 · arXiv 2405.04434 Scale 236B total · 21B active · 128K ctx Materials 8.1T tokens · H800 cluster

DeepSeek-AI ([email protected]) — published under the team name; the individual contributor list, over a hundred names long, is Appendix A of the paper.

The core idea

Capacity you store and capacity you pay for can be two different numbers.

In 2024 the reliable way to make a language model smarter was to make everything bigger — and every bigger number landed on the same bill: more compute per token to train it, more memory per token to serve it. DeepSeek-V2 is a bet that those couplings can be cut without giving up quality.

It cuts two of them. DeepSeekMoE stores 236B parameters but routes each token through only 21B of them, so training compute stops tracking total size. Multi-head Latent Attention (MLA) replaces attention's per-head memory of past tokens with one small compressed note per token, so serving a 128K-token context stops tracking head count. The paper's own ablations show the compressed attention scoring higher than the standard kind — the discount comes with no quality surcharge.

Two decouplings, one model: pay for 21B while storing 236B, and remember 128K tokens on a sliver of one GPU.

PART A

The memory bill

What this model promises, and what standard attention would charge for it

Step 1 · The black box

A 236B model that keeps most of itself asleep.

Here is the whole machine before we open it. You paste in a 300-page annual report — roughly 128K tokens, the word-pieces a model actually reads — and ask: “What changed in the risk section this year?” The model writes an answer, one token at a time, and every token it writes has to look back across everything you pasted. This report question is our running example; we will keep billing it, compressing it, and re-billing it for the rest of the page.

annual report ~128K tokens in DEEPSEEK-V2 236B parameters stored 21B awake per token how? steps 3–10 “Three new clauses on rate risk…” answer out, token by token
The running example. The box keeps 236B parameters on disk-warm standby but wakes only 21B of them for any single token — the “sleeping giant” arrangement Part C explains.

The paper leads with three numbers, all measured against DeepSeek 67B — the same lab's earlier, conventional (dense — every parameter works on every token) model: 42.5% cheaper to train, a 93.3% smaller KV cache, and 5.76× higher peak generation throughput. Notice what kind of numbers these are. Not accuracy records — prices. This is an economics paper wearing an architecture paper's clothes, and the two inventions inside it are both cost-cutting machines.

One of those terms needs its own step. The KV cache is the memory a model burns while writing, and it is the quiet villain of long-context AI. Let's price it properly before we admire anything.

From the abstract: “DeepSeek-V2 … comprises 236B total parameters, of which 21B are activated for each token, and supports a context length of 128K tokens.” Weights were released openly, plus a 15.7B little sibling (V2-Lite) for people who want to poke the architecture on one GPU.

Step 2 · The villain

Generation doesn't run out of compute — it runs out of memory.

Step 1 promised a model that reads your whole report and answers cheaply. Before trusting any of the discounts, let's compute what “reads your whole report” costs a standard Transformer at answer time.

You already know the attention recipe from the Transformer: each token makes a query, compares it against every other token's key, and uses the resulting weights to mix their values. During generation there's a crucial asymmetry: the keys and values of tokens already read never change. Recomputing them for every new token would be absurd, so every serving system stores them — that store is the KV cache.

Now the bill, with DeepSeek-V2's own shapes. Its attention has 128 heads, each 128 dimensions wide, across 60 layers. Cached the standard multi-head way, one token deposits a key and a value per head per layer:

2 (k and v)× 128 heads× 128 dims× 60 layers= 1,966,080 numbers per token

At two bytes per number (BF16) that's 3.93 MB for a single token. Multiply by the report — 131,072 tokens — and one conversation holds ≈ 515 GB of cache. An entire 8-GPU H800 node carries 640 GB, and the model's weights already want most of it. The picture below is that arithmetic drawn out; watch the bag on the right fill up.

tokens already read… Revenue fell 8% … ×131,072 each token: keys + values, every head, every layer KV CACHE (kept in GPU memory) 1,966,080 numbers / token × 2 bytes = 3.93 MB / token × 131,072 ≈ 515 GB one conversation. one user. for scale: one 8×H800 node totals 640 GB — weights not counted
The memory bill for our report question if V2 cached attention the standard way. The amber and coral strips are one token's keys and values; the dashed bag is the part that must sit in GPU memory for the entire conversation.

And memory is throughput. A GPU serves many users by batching their conversations; the cache decides how many fit. Halve the cache and you can roughly double the batch — which is why this page keeps talking about memory when the headline you may care about is tokens per second.

Key property

The KV cache grows as context × layers × heads × head-dim, and it throttles batch size — which is throughput. Whoever shrinks the cache without hurting quality wins on both context length and serving cost at once.

Accounting note: we price every cached number at 2 bytes (BF16) throughout. The paper's Table 1 counts elements, precision aside, and the deployed system squeezes each element to ~6 bits — we come back to that in Step 8 when the 93.3% headline gets audited.

Step 3 · The surgery map

Still a Transformer — with two organs swapped out.

The bill is real: ≈ 515 GB of cache for one 128K conversation, on hardware that carries 640 GB per node. DeepSeek-V2's response is not one clever trick but two separate surgeries.

Zoom into the box from Step 1 and you find nothing exotic: 60 identical Transformer blocks, each one an attention module followed by a feed-forward network (FFN), with normalization and residual connections in the usual places. The paper explicitly keeps every “tiny detail” identical to DeepSeek 67B. The novelty is concentrated in exactly two places, and the diagram below marks both — attention is replaced by MLA, and the FFN by DeepSeekMoE.

one block · ×60 token stream in RMS Norm Attention RMS Norm FFN → MLA shrinks the serving bill · Part B → DeepSeekMoE shrinks the training bill · Part C residual adds and everything else: unchanged from DeepSeek 67B
The whole novelty budget, spent in two places. Violet marks the attention swap (MLA), blue the FFN swap (DeepSeekMoE) — the same two colors will track these mechanisms for the rest of the page.

The two surgeries split the two bills between them. MLA attacks the serving bill — the 515 GB bag from Step 2 — and it is the invention this paper is remembered for, so Part B takes it apart slowly. DeepSeekMoE attacks the training bill — how a model stores 236B parameters while charging 21B per token — and Part C walks it at a brisker pace. If you came here from our DeepSeek-V3 page: this is the origin story of both organs that V3 later scaled up.

PART B

MLA, up close

Shrinking the cache 57× without making heads share — the paper's real invention

Step 4 · Prior art

The old fixes shrink the cache by making heads share — and quality pays for it.

Step 3 put the serving bill on attention's desk. Attention already had two well-known diets before this paper — worth one step, because MLA is built to escape their trade-off.

The cache is huge because every head keeps its own keys and values. So the obvious surgery is sharing. Grouped-Query Attention (GQA) makes groups of heads share one key/value pair — 8 groups instead of 128 heads cuts the cache 16×. Multi-Query Attention (MQA) pushes to the limit: all 128 heads share a single key/value pair, a 128× cut. LLaMA-class models shipped with GQA; it works.

But heads are the whole point of multi-head attention — each one watches the sentence differently, and sharing K/V forces them to watch through the same pair of glasses. The paper measures the damage directly, training three otherwise-identical 7B models:

7B dense modelMMLUBBHCache cut
with MQA37.933.2128×
with GQA (8 groups)41.235.616×
with full MHA45.237.01× (none)

Seven MMLU points between MQA and MHA — that's not a rounding error, that's a smaller model wearing a bigger model's name. So the question DeepSeek-V2 actually asks is sharper than “how do we shrink the cache?” It is: can the cache shrink like MQA while every head keeps its own view, like MHA? The fourth panel below is the answer, and the rest of Part B earns it.

MHA GQA-8 MQA MLA Q K V every head cached Q K V 4 heads share each pair Q K V all heads share one pair Q K, V not stored — recoverable from a note: one latent, all 128 views 32,768 2,048 256 576 numbers/token/layer quality tax heavier tax no tax — Step 8 8 of the 128 heads drawn; the dashed bag is what actually gets cached
The dashed bag shrinks left to right. GQA and MQA shrink it by deleting distinct keys and values; MLA (violet) shrinks it by storing a compressed note from which all 128 heads' keys and values can be recovered.

Ablation from Appendix D.1 (Table 8), 7B dense models trained on the same 1.33T tokens, parameter counts matched by adjusting depth. BBH is the BIG-Bench Hard reasoning suite.

Step 5 · The compression

Don't cache the wardrobe — cache the packing list.

GQA and MQA cut the bag by deleting heads' individual keys and values, and Step 4's table showed the seven-point bill for doing so. MLA wants the small bag and the 128 distinct views.

Here's the observation that makes it possible. A token's 128 keys and 128 values are not 256 independent facts — every one of them is computed, by fixed weight matrices, from the same hidden vector h. They are 32,768 numbers of outfit generated from 5,120 numbers of person. The wardrobe is hugely redundant, and low-rank compression is the standard tool for redundancy: pass h through a skinny down-projection and keep only that.

Concretely — and this is the paper's equation 9 — the token's hidden vector is squeezed to a latent (a compact learned summary): c = WDKV h, taking 5,120 numbers down to 512. Two up-projection matrices, WUK and WUV, can regenerate all 128 heads' keys and values from c whenever they're wanted. So the cache keeps the 512-number note and throws the 32,768-number wardrobe away.

Watch our running example go through it: the token “liability”, sitting at position 91,204 of the report, arrives at some layer as a 5,120-number vector — the long bar at the bottom of the figure. One matrix multiply later it is the short violet note, and only the note enters the dashed bag. The amber and coral rows above it are never stored.

keys k … ×128 heads = 16,384 numbers values v … ×128 heads = 16,384 numbers not cached — regenerated from the note only if ever needed WUK WUV c — the latent note · 512 numbers the only thing cached WDKV — down-projection, 5,120 → 512 h — hidden vector of “liability” (position 91,204) · 5,120 numbers the compression runs once per token per layer, at read time
Equation 9 drawn out. Down-project the 5,120-number hidden state to a 512-number violet note; cache the note; regenerate any head's key or value later by up-projecting. 512 numbers now stand in for 32,768.

Two honest debts before moving on. First: why should 512 numbers preserve enough of 32,768 to keep quality? The intuition is the redundancy above, but intuition isn't evidence — Step 8 pays this off with the paper's ablation, which is stranger than “quality survives.” Second, and more urgent: regenerating keys and values “whenever they're wanted” should worry you. The model wants them at every generation step, for every past token. Didn't we just trade a memory disaster for a compute disaster?

Simplification ledger: V2 also low-rank-compresses queries (to 1,536 dims) — that saves activation memory during training but changes nothing in the cache, so this page leaves it folded (§2.1.2). Likewise the extra RMS Norm applied to each latent for training stability (§3.1.2). And the 512 is a design choice, not magic: it's 4 head-widths, chosen small enough to matter and large enough to hold 128 heads' worth of distinctions — Step 8's slider lets you feel that trade-off.

Step 6 · The absorption trick

Move the parentheses and the keys never need to exist.

Step 5 shrank the bag to a 512-number note per token — at the apparent price of re-inflating notes into keys and values for every past token, at every one of the thousands of steps it takes to write an answer. That price would sink the whole idea.

It never gets paid, and the reason is one line of linear algebra. An attention score is a dot product, q·k. Write both sides out: the query is q = WQh (from the current token, the one being generated), and the key would be k = WUKc (regenerated from a past token's cached note). Chain them:

q·k= (WQh)·(WUKc) = h(WQ⊤WUK)c

WQ⊤WUK is a product of two fixed weight matrices — multiply them once, offline, call the result M. The score is just hMc.

Matrix multiplication is associative: it doesn't care where the parentheses sit. Grouped the left way, you rebuild k for every past token — the compute disaster. Grouped the right way, the two weight matrices merge into one matrix M before serving even starts, and at run time the current token's h is compared directly against the cached notes. The keys are never materialized. Neither are the values — the same move folds WUV into the output matrix WO. The paper calls this absorbing one matrix into another.

If that felt too cheap to be legal, you're in good company — we had to write it out with actual numbers before we stopped distrusting it. So let's do exactly that, with 2-dimensional toys. Take WQ = [[2,0],[1,1]], WUK = [[1,2],[0,1]], a current token h = (1, 2) and a cached note c = (3, 1). The slow path: q = (2, 3), k = (5, 1), score = 2·5 + 3·1 = 13. The absorbed path: M = WQ⊤WUK = [[2,5],[0,1]] (computed once), then Mc = (11, 1) and h·Mc = 1·11 + 2·1 = 13. Same score, and the second path never touched k. Now break it yourself:

Try it

Drag any slider — the two paths compute the score independently, and they cannot disagree

current h₁ 1
current h₂ 2
cached c₁ 3
cached c₂ 1

Slow path rebuild the key, then compare

q = (2, 3) · k = (5, 1) = 13

Absorbed path M merged offline — k never built

h = (1, 2) · Mc = (11, 1) = 13

scores agree: 13 = 13

What to look for: the left card does attention the textbook way; the right card only ever sees the cached violet note. Every slider position gives identical scores — associativity is doing all the work MLA needs.

Key property

After absorption, inference-time MLA looks like MQA — one shared cached object per token — but each head owns its own merged matrix Mi, so all 128 heads still read the note differently. MQA's cache bill, MHA's expressiveness.

Step 7 · The snag

RoPE jams the absorption — so position gets its own skinny channel.

The absorption in Step 6 worked because nothing stood between WQ⊤ and WUK — two constants, merged once. Position information is precisely the thing that has to stand between them.

Attention as computed so far is order-blind: “liability appears at position 91,204” is information no dot product has seen. DeepSeek models encode order with RoPE — rotary position embedding, which rotates each query and key by an angle proportional to its position, so that a score depends on how far apart two tokens are. Fair warning before the next paragraph: §2.1.3 is the densest spot in this paper, and we went around it three times before the shape of the problem clicked. Here is the slow version.

With RoPE, the score between our current token t and the cached “liability” at position j becomes q Rj−t k — a rotation matrix wedged between the query side and the key side, parameterized by the distance j−t. Now try to absorb: the merged matrix would be WQ⊤ Rj−t WUK. But t is the token being generated — it changes at every single step, so the distance changes, so the rotation changes, so there is no fixed M to precompute. Matrix multiplication is associative, not commutative: you can't slide the rotation out of the way. The escape routes are all bad — rebuild every past key each step (the compute disaster returns), or cache the rotated keys (the 32,768-number wardrobe returns).

The paper's exit is almost rude in its simplicity: if position jams the compressed channel, stop sending position through it. Split the job in two:

The content channel — everything from Steps 5 and 6, RoPE-free, absorbable, 128 dims per head served from the cached violet note. The position channel — a small side-car that carries RoPE and nothing else: each head gets a 64-dim decoupled query qR, and the token contributes one 64-dim rotated key kR shared by all 128 heads. Per head, the two channels just add up inside the softmax:

score= qC·kC + qR·kR√(128 + 64)

content dot + position dot, scaled by the joint width √192 — the paper's equation 18.

Why is this cheap? Sharing one rotated key across all heads is an MQA move — but applied only to position, the one signal where Step 4's quality tax has nothing to bite on (a rotation angle is the same fact for every head). The bag gains a single 64-number green strip per token per layer. In the figure, follow the two channels bottom to top: the violet note and the green strip are the only things inside the dashed bag.

softmax( (q·k) / √192 ) · v → output q = [qC 128 ; qR 64] · per head k = [kC 128 ; kR 64] · per head note c · 512 WUK (absorbed) kR · 64 · RoPE’d shared by all heads CACHED: 512 + 64 = 576 numbers / token / layer q-latent current token only — never cached RoPE→qR h — the token's hidden vector · 5,120 numbers WDKV WKR+RoPE MLA in full: content rides the violet note; position rides the skinny green strip; the bag holds 576 numbers
The finished machine (the paper's Figure 2, bottom half, redrawn). Violet = compressed content, green = the decoupled RoPE channel, amber = keys regenerated per head; values come off the same note, absorbed into the output projection. Only the two items inside the dashed bag survive into memory.

Full formulas, including the query-side compression we folded away, are Appendix C of the paper (equations 37–47). File the green strip away for Step 11 — when V2 stretches its context from 4K to 128K, the adjustment (YaRN) is applied exactly there, because that strip is the only place position lives.

Step 8 · The receipt

576 numbers a token — and the ablation says quality went up, not down.

Content rides the cached note (Steps 5–6); position rides a shared 64-number strip (Step 7). Time to re-total the bill from Step 2 and audit the paper's headline numbers.

Per token, per layer, the bag now holds 512 + 64 = 576 numbers. Run the same arithmetic you ran in Step 2:

(512 + 64)× 60 layers= 34,560 numbers= 69.1 KB per token

Against the 1,966,080 numbers of Step 2 that is a factor of 56.9 — call it 57×. Our 128K report drops from ≈ 515 GB of cache to ≈ 9.1 GB: from “six GPUs' entire memory for one user” to “a corner of one GPU.” Here is where that lands in the paper's comparison table, with V2's shapes plugged in:

MechanismCache per token (formula)With V2's shapesQuality
MHA2 · nh · dh · ℓ1,966,080strong
GQA (8 groups)2 · 8 · dh · ℓ122,880taxed
MQA2 · dh · ℓ15,360heavily taxed
MLA(dc + dhR) · ℓ34,560stronger than MHA

The paper's own summary of that last column: MLA costs the same as GQA would with just 2.25 groups — deep in quality-tax territory for actual GQA — yet outperforms full MHA. That is the IOU from Step 5, and the receipt is Appendix D.2: two MoE models, ~250B parameters, identical except for the attention mechanism, trained on the same 420B tokens:

~250B MoE, same dataCache/tokenMMLUBBHC-Eval
with MHA860.2K elem57.546.657.9
with MLA34.6K elem (4%)59.050.759.2

A 25× smaller cache and higher scores across the board. Why compression would ever help quality, the paper doesn't really explain — low-rank bottlenecks can act as a regularizer, but treat that as our speculation, not the paper's claim. What the paper does own is the measurement.

One audit remains: the abstract says 93.3%, but 34,560 ÷ 1,966,080 says 98.2%. Different comparison. The 93.3% is measured against DeepSeek 67B as actually served — a 95-layer GQA model caching about 195K numbers ≈ 389 KB per token — while deployed V2 also squeezes each cached number to ~6 bits, landing near 26 KB per token. 26 ÷ 389 ≈ 6.7%, hence “reduced by 93.3%.” Same-architecture, same-precision, the honest number is the 57× you computed yourself. Now stress-test it:

Try it

Drag the context — then drag d_c and watch MLA's bar trade memory for capacity

context length 128K
latent width dc 512
MHA
515.4 GB
GQA-8
32.2 GB
MQA
4.0 GB
MLA
9.1 GB

bars drawn to the same scale — MHA is always the full track

At dc = 512: 576 numbers × 60 layers = 34,560 per token = 69.1 KB → 9.1 GB for the 128K report · 57× below MHA's 515.4 GB, which is ≈ 6.4 H800s' worth of memory (80 GB each) for a single conversation.

What to look for: at V2's shipped dc = 512, MLA sits between MQA and GQA on cost with none of their sharing. Push dc to 2048 and the discount fades; pull it to 64 and you'd be asking 128 heads to share a note thinner than one head's key. GQA-8 and MQA carry Step 4's quality tax; MLA's bar carries Table 9's quality bonus.

The 5.76× throughput headline follows from this step plus batch arithmetic: smaller cache → more concurrent users per node → >50K generated tokens/sec on one 8×H800 node (§3.2.3). DeepSeek 67B's per-token cache is reconstructed from its published config (GQA, 8 KV heads, 95 layers, d_h = 128); it matches the ≈400 KB/token bar in the paper's Figure 1(b).

PART C

The other economy: DeepSeekMoE

How 236B parameters charge like 21B — at a brisker pace

Step 9 · Fine-grained experts

Many small specialists plus a few generalists beat a handful of giants.

MLA settled the serving bill. The other headline — training 42.5% cheaper — comes from the block's other organ, the FFN, which is where nearly all of V2's 236B parameters actually live.

A Mixture-of-Experts (MoE) layer replaces the one big FFN with many smaller FFNs — experts — plus a router that sends each token to a few of them. Parameters stored: all of them. Parameters computed per token: only the chosen few. That's the whole decoupling.

DeepSeekMoE (adopted from the lab's earlier MoE paper) sharpens the recipe in two ways, both visible in the figure. First, fine-grained experts: instead of a handful of giants, each layer has 160 small experts (hidden width just 1,536) and the router picks 6. Picking 6 of 160 gives combinatorially more distinct teams than picking 2 of 8 — sharper specialization from the same parameter budget. Second, 2 shared experts that every token visits unconditionally, so grammar-level common knowledge settles there once instead of being copied into all 160 specialists. When “liability” from our report reaches this layer, the router scores all 160 (a softmax over dot products with each expert's learned centroid), and the output is: input + the 2 shared + the 6 winners, gate-weighted.

shared shared always on 160 routed experts · hidden width 1,536 · the router lights 6 router · top-6 “liability” output = input + 2 shared + 6 chosen, gate-weighted
One MoE layer of V2. Olive = the two always-on shared experts; blue cells = the 160 routed specialists, with this token's 6 winners filled solid. 59 of the 60 blocks use this layer (the first keeps a dense FFN).

Where do “236B stored, 21B active” come from? Back-of-envelope, with rounding: each expert is 3 matrices of 5,120 × 1,536 ≈ 23.6M parameters; kept across 59 MoE layers, one expert-slot ≈ 1.4B. Then 162 experts ≈ 226B stored, plus ≈ 9B of attention machinery and ≈ 1B of embeddings → ≈ 236B. Active per token: 6 routed ≈ 8.4B + 2 shared ≈ 2.8B + the same 9B + 1B → ≈ 21B. The knob that sets the price is K, the number of routed experts per token:

Try it

Drag K — the compute bill moves, the 236B stored does not

routed experts K 6
always-on ≈ 12.6B (attention + 2 shared + embeddings) routed: K × ≈1.4B

K = 6 → ≈ 21.0B activated per token — the configuration V2 ships. The other 215B sleep until the router calls them.

What to look for: doubling K to 12 buys a bigger working team but nearly doubles the per-token bill; dropping to K = 1 collapses the combinatorics that make fine-grained experts worth having. All figures back-of-envelope from the shapes in §3.1.2.

Contrast worth filing: V2 keeps this MoE honest with auxiliary losses (next step). Its successor V3 drops those losses for a bias-nudge scheme — that story is the main lesson of our DeepSeek-V3 page, which assumes the MLA you just learned here.

Step 10 · Load balance

160 specialists are only cheap if the router actually uses them.

Step 9 handed the router 160 choices per layer. Routers left to themselves develop favorites — and a favorite expert is a failure mode with a name.

Routing collapse: early in training a few experts get slightly better, so the router sends them more tokens, so they get better still, until most experts sit untrained and the “160 specialists” are really five. Sparse compute also has a plumbing problem — experts live spread across 8 GPUs, and a token whose 6 experts sit on 6 different devices pays 6 network hops.

V2's countermeasures, at a brisk walk. Three auxiliary losses added to training: one nudging tokens to spread across experts (weight 0.003), one across devices (0.05), one balancing communication traffic (0.02). Device-limited routing: each token's experts may span at most M = 3 devices — the paper finds M ≥ 3 matches unrestricted routing. And a token-dropping escape valve: when a device still overflows its compute budget, the lowest-affinity tokens are skipped that layer (about 10% of training sequences are exempted so the model also learns the no-drop regime).

without balance: collapse one favorite trains; the rest atrophy with the three losses tokens spread; every expert earns its parameters device-limited routing: 8 GPUs hold the experts — one token's 6 picks may span at most M = 3 of them
Left panel: the failure the losses exist to prevent. Right: the behavior they buy. Bottom strip: the token's chosen experts (violet-tinted devices) confined to 3 of the 8 GPUs.

Every one of these balance losses is a small tax — gradient spent on logistics instead of language. V2 accepts the tax; a year later V3's aux-loss-free balancing showed how to stop paying it. We fold the three loss formulas here (equations 23–31 in §2.2.3 if you want them); nothing downstream depends on their exact form.

PART D

The receipts

Quality, cost, context — and what you should be able to rebuild

Step 11 · Report card

Top-tier scores while activating a third as much as its rivals.

Both organs are priced: attention remembers in 576-number notes, the FFN wakes 21B of 236B. The remaining question is whether the discounted model is actually good.

On MMLU it lands within half a point of LLaMA 3 70B while activating less than a third of the parameters per token — the bars below keep each model's activated count next to its score. Two honest asterisks before you read them. LLaMA 3 saw over four times V2's English data, and on English commonsense and trivia it still wins; V2's edge is the bilingual trade — on Chinese benchmarks it and Qwen1.5 trade blows at the top of the open field. And every economics headline on this page is measured against DeepSeek's own dense 67B, not some universal baseline.

21B active

MMLU, 5-shot · open-source models, May 2024 · axis starts at 60

DeepSeek 67B · dense, 67B act.
71.3
Qwen1.5 72B · dense, 72B act.
77.2
Mixtral 8x22B · MoE, 39B act.
77.6
LLaMA 3 70B · dense, 70B act.
78.9
DeepSeek-V2 · MoE, 21B act.
78.5
607080
172.8K GPU·hours / trillion tokens vs 300.6K for dense 67B — the 42.5% training cut, measured on the same H800 cluster.
>50K tokens/sec generated peak, on one 8×H800 node — 5.76× the 67B service; prompt intake tops 100K tokens/sec.
≈26 KB per token served KV cache after 6-bit quantization — the 93.3% cut you audited in Step 8.
128K context that works — YaRN applied to the green kR strip from Step 7; the needle-in-a-haystack grid comes back nearly all green.
8.1T pretraining tokens with ~12% more Chinese than English — the source of the bilingual profile above.
Weights released open — V2, V2 Chat, and a 15.7B V2-Lite (2.4B active) so the architecture can be studied on one GPU.

The long-context claim closes a loop from Step 7: because position lives only in the decoupled RoPE strip, stretching the context from 4K to 128K meant adjusting that one channel (with YaRN) and training a further 1,000 steps at 32K — the compressed content channel never had to know. Alignment gets one sentence and a pointer: the base model was instruction-tuned on 1.5M examples, then aligned with GRPO — the critic-free RL method DeepSeek later made famous — and that story is told properly on our DeepSeek-R1 page.

“Even with only 21B activated parameters, DeepSeek-V2 and its chat versions still achieve top-tier performance among open-source models.” — the abstract, arXiv 2405.04434

Step 12 · Self-check

The whole argument, compressed to six questions.

One report, two surgeries, one receipt. Before you close the tab, try to rebuild each piece from memory — peek only after you've committed to an answer.

Why does long-context generation hit a memory wall rather than a compute wall?

Every token already read must keep its keys and values available — the KV cache — and that store grows with context × layers × heads × head-width. It occupies GPU memory for the whole conversation and caps the batch size, which caps throughput.

What exactly does MLA cache for one token, in one layer?

576 numbers: a 512-dim latent note (the joint compression of all 128 heads' keys and values) plus a 64-dim shared RoPE key. Standard MHA at the same shapes would cache 32,768 — a 57× difference.

Why doesn't regenerating keys from the note cost extra compute at inference?

It never happens. By associativity, q·k = h(WQ⊤WUK)c, and the middle product is merged into one matrix offline. Scores are computed directly against cached notes; WUV is likewise absorbed into the output projection.

Why does RoPE break that absorption, and what is the fix?

RoPE inserts a rotation between the two matrices whose angle depends on the current generation step, so no fixed merged matrix exists. Fix: keep the compressed channel position-free, and carry position in a separate 64-dim RoPE'd channel — per-head queries plus one key shared by all heads.

What makes DeepSeekMoE different from a classic few-big-experts MoE?

Granularity and sharing: 160 small routed experts with 6 chosen per token (combinatorially more specialist teams), plus 2 shared experts that always run so common knowledge isn't duplicated. Balance comes from three auxiliary losses, device-limited routing (M = 3), and token-dropping.

Where do 42.5%, 93.3% and 5.76× each come from?

All vs DeepSeek 67B: GPU-hours per trillion training tokens (300.6K → 172.8K = −42.5%); served KV cache per token including 6-bit quantization (≈389 KB → ≈26 KB = −93.3%); and peak generation throughput on the same node (5.76×).

Homework — (1) Reproduce the 57× on paper: 2·128·128·60 against (512+64)·60. (2) Price a 1M-token context under MLA at BF16 — about 72 GB — and notice it barely fits one GPU; that's why the cache diet didn't end with this paper. (3) Explain to a colleague why sharing keys across heads taxes quality in GQA but sharing the 64-dim RoPE key in MLA doesn't.

The profound impact

The blueprint that V3 and R1 scaled — and the cache diet everyone copied.

DeepSeek-V2 is the paper where “open-source model” started to mean “cheap to serve,” not just “free to download.” Its two organs became the standing architecture of everything the lab built next.

2024 · successor

DeepSeek-V3

The same two organs, scaled to 671B stored / 37B active. MLA carries over almost unchanged; the balance losses of Step 10 retire in favor of a per-expert bias nudge — the headline lesson of our V3 page.

2025 · descendant

DeepSeek-R1

The reasoning model built on V3's base — which is to say, on V2's skeleton. GRPO, used quietly here to align V2 Chat, moved to center stage as R1's training engine.

beyond one lab

MLA leaves home

Latent-compressed KV became a standard serving option: open inference stacks grew dedicated MLA paths, and follow-up work retrofits existing GQA models into MLA form to inherit the smaller cache.

A year after release, the interesting question had inverted: not “can compressed attention match full attention?” but “why would you still pay for the uncompressed kind?”