Introduction
DeepSeek-V3.2 pairs architectural changes with a large-scale reinforcement learning and environment synthesis pipeline to make long-context reasoning and multi-turn tool use affordable at scale. It modifies how attention reads a long conversation history, stabilizes off-policy reinforcement learning across a massive mixture-of-experts network, and trains on thousands of synthetic agent environments where actions can be verified automatically.
This book builds that technical story from the ground up. Each chapter introduces the required mathematical and systems context, walks through one subsystem in detail, and connects its design choices to the rest of the stack. You can read the chapters sequentially or jump directly to a specific subsystem.
Our primary source is DeepSeek-V3.2: Pushing the Frontier of Open Large Language Models (arXiv:2512.02556v1, submitted 2 December 2025), supplemented by revision-pinned configuration, inference, and encoding files from the official open-weights release. Where the paper leaves training hyperparameters or systems numbers unstated, we note those gaps directly and derive what we can from the published equations and checkpoint specifications.
Contents
| Chapter | Question it answers |
|---|---|
| 1. The problem and the model family | What changed, and why do efficiency, reasoning, and agents belong together? |
| 2. The foundations the report assumes | What are tokens, attention, caches, language modeling, and reinforcement learning? |
| 3. Inside the inherited backbone | How do the transformer, experts, and parameter counts fit together? |
| 4. Multi-head latent attention | How can many attention heads read one compressed cache? |
| 5. The lightning indexer and sparse selection | How does DSA decide which 2,048 tokens to read? |
| 6. Converting a dense model to sparse attention | How is the selector trained without breaking the existing model? |
| 7. Computation, memory, and inference cost | Which costs shrink, and why is the whole model still not asymptotically linear? |
| 8. Specialists, distillation, and mixed learning | How does the base model become a general assistant? |
| 9. GRPO from first principles | What exactly does learning from groups of answers optimize? |
| 10. The corrected KL estimator | Why does the sampling distribution matter for regularization and its gradient? |
| 11. Keeping off-policy learning stable | What do sequence masking, routing replay, and sampling masks fix? |
| 12. Rewards, length, and reasoning behavior | What does the model learn when success, helpfulness, and brevity compete? |
| 13. Reasoning with tools and conversation state | Why do message roles and retained reasoning change agent behavior? |
| 14. Synthesizing general agent environments | How are hard but verifiable tasks created at scale? |
| 15. Coding agents and code interpreters | What makes an executable training environment credible? |
| 16. Search agents and difficult questions | How are long-tail search tasks constructed and rewarded? |
| 17. What the synthesis experiments establish | Do synthetic tasks transfer to unfamiliar tools and environments? |
| 18. Context management and test-time scaling | What happens when an agent fills the 128K window? |
| 19. Reading the reasoning benchmarks | What do the math, science, knowledge, and coding scores actually mean? |
| 20. Reading the agent benchmarks | How much of an agent score belongs to the model, framework, or environment? |
| 21. Speciale and competition-level reasoning | What buys higher reasoning scores, and what does a gold-medal result measure? |
| 22. Understanding the released implementation | How do configuration, precision, encoding, and kernels affect deployment? |
| 23. One request through the whole system | How do attention, experts, learning, tools, and context cooperate? |
| 24. Limits, practical choices, and research questions | What should a reader conclude, and what evidence is still missing? |
| 25. Glossary, equations, and source atlas | Where can a reader check terminology, numbers, and original sources? |
Reading paths
If you are focused on model architecture, read Chapters 2–7 and 22. For reinforcement learning, read Chapters 8–12 and 21. For agent training and tool use, read Chapters 13–18, 20, and 23. For benchmarks and deployment trade-offs, read Chapters 1, 7, 19–21, and 24. Chapter 25 serves as a technical glossary, equation index, and file atlas.
Whichever path you take, start with Chapter 1 to keep the four model variants in the paper straight: DeepSeek-V3.1-Terminus, DeepSeek-V3.2-Exp, the final DeepSeek-V3.2, and DeepSeek-V3.2-Speciale represent distinct training stages and capability trade-offs.
Source and numerical conventions
Chapter source notes cite the corresponding report sections, TeX files, and official repository artifacts preserved under ../_sources/. The TeX source archive is stored at ../2512.02556v1-source.tar.gz with ../main.tex as its entry point, and original figures are retained under ../figures/ alongside rasterized versions in assets/.
Unless noted otherwise, K, M, and B denote powers of 1,000. In the continued-training token calculations, however, the paper's sequence counts and token totals only reconcile if 128K denotes 131,072 tokens (). We retain the paper's 128K shorthand when discussing the context window and note where the configuration files specify different limits (examined in Chapters 3 and 22). Memory capacities use GB for bytes and GiB for bytes. Differences between percentage scores are stated in percentage points, while Codeforces comparisons use rating points.
1. The Problem and the Model Family
A language model that answers short prompts fluently can still fall apart on multi-step engineering or research problems. Fixing a software bug requires inspecting source files, writing a patch, running the test suite, and recovering when an initial hypothesis fails. Answering an open-ended research question requires issuing multiple searches, cross-checking sources, and reconciling conflicting claims. Proving a competition math theorem often takes thousands of tokens of Scratchpad exploration before a viable proof strategy emerges.
Tasks like these strain three parts of the stack simultaneously: the model needs strong multi-step reasoning habits, a large reinforcement-learning budget to practice them, and an attention mechanism that can read a long, growing context without blowing up inference cost. DeepSeek-V3.2 tackles all three together, treating sparse attention, RL optimization stability, and synthetic agent environments as mutually reinforcing pieces of a single design.
Why long reasoning changes the economics
Because an autoregressive transformer generates one token at a time conditioned on the entire preceding sequence, a 20,000-token reasoning trace requires forty times as many decode passes as a 500-token reply—and each pass attends over a longer history than the last. Tool use compounds this growth: every file dump, compiler trace, or search snippet returned by an external environment is appended directly to the context window. Even if the model writes terse action calls, verbose tool outputs rapidly fill a 128K window.
Under dense causal attention, every query token compares against every preceding key token. Prefilling a long prompt scales quadratically with sequence length , while decoding each new token requires scanning a cache whose length grows linearly with every step. That cost hits twice: once when serving long-horizon user requests in production, and again during reinforcement learning, when the training cluster must sample thousands of long rollouts per update.
To cut the cost of reading long histories, the paper introduces DeepSeek Sparse Attention (DSA). A lightweight module called the lightning indexer scores all past positions, and the main Multi-head Latent Attention (MLA) kernel loads only the top 2,048 token entries per query. The indexer itself still scans the full prefix—a crucial systems nuance we analyze in Chapter 7—but the heavy main-attention read drops from to during prefill.
Why architecture alone cannot produce an agent
Making long contexts cheaper to read does not automatically teach a model how to use them. Given a fast 128K context window, a poorly trained assistant will still hallucinate tool arguments, drop constraints halfway through a task, or declare victory without verifying its output.
The authors trace the gap between open-weights models and frontier proprietary systems to two bottlenecks: insufficient post-training RL compute and a shortage of diverse, verifiable agent environments. In DeepSeek-V3.2, the post-training RL budget exceeds 10% of the total pre-training cost (the report states this as a relative share without disclosing raw GPU-hours or dollar figures). Lowering attention cost makes long-horizon rollouts cheaper to sample, while stabilizing off-policy GRPO updates lets the model absorb a much larger RL compute budget across synthetic coding, search, and tool-use environments.
Keeping the four model variants straight
The report tracks four distinct checkpoints across its experiments:
| Name | Role in the story | What the report uses it for |
|---|---|---|
| DeepSeek-V3.1-Terminus | Preceding dense-attention checkpoint | Baseline backbone for architectural parity and speed comparisons |
| DeepSeek-V3.2-Exp | Intermediate checkpoint with DSA | Isolating whether converting dense attention to DSA hurts quality |
| DeepSeek-V3.2 | Final general-purpose release | Main model trained for reasoning, tool use, coding, search, and chat |
| DeepSeek-V3.2-Speciale | Long-horizon reasoning specialist | Pushing math, coding, and Olympiad scores with relaxed length penalties |
Separating these checkpoints prevents a common misreading of the benchmark tables. The architectural ablation compares DeepSeek-V3.1-Terminus against DeepSeek-V3.2-Exp, which shares the Terminus training style after continued training to install DSA. The jump in reasoning and agent scores between V3.2-Exp and the final DeepSeek-V3.2 comes from the expanded post-training pipeline—specialist distillation, mixed RL, and synthetic agent environments—not from sparse attention itself.
DeepSeek-V3.2-Speciale branches off the same post-training pipeline but trains exclusively on reasoning data with a weaker length penalty, plus the dataset and proof-verification reward system from DeepSeekMath-V2. According to the official model card, Speciale omits tool-calling support altogether; it is built to maximize competition reasoning performance at the cost of much longer token trajectories, not to serve as a drop-in replacement for the general model.
Three distinct forms of sparsity and truncation
Because DeepSeek-V3.2 uses selection mechanisms at three completely different stages of computation, it helps to separate their scopes upfront:
- Expert sparsity (MoE): Each token routes through 8 out of 256 routed feed-forward experts per layer (plus 1 shared expert), bounding the active FFN parameter count per token.
- Attention sparsity (DSA): Each query token reads 2,048 historical key-value entries out of a prefix of up to 128K tokens, bounding the main attention cost.
- Sampling truncation (top- / top-): During rollout generation, the sampler zeros out low-probability vocabulary tokens before drawing the next token, which shapes rollout diversity and must be preserved via sampling masks during off-policy RL updates.
Although the paper discusses masks and top- selection in all three contexts, they operate on different axes: feed-forward modules, sequence positions, and vocabulary logits.
What the open release includes
The weights and inference code for DeepSeek-V3.2 are released under the MIT license, allowing direct inspection of the layer definitions, quantization formats, and chat templates, as well as local deployment. As with most open-weights frontier releases, however, the full pre-training corpus, distributed RL orchestration code, reward models, and synthetic task generators remain internal. Throughout this book, we cross-check the paper's equations against the released model.py and config.json artifacts so you can see exactly where the paper's high-level description meets the production tensor shapes.
Reading the paper's headline claims
When evaluating the report's three headline claims—frontier parity, Olympiad gold-medal performance, and reduced attention complexity—it pays to look closely at the underlying unit of measurement:
- Parity with frontier models: V3.2 matches or approaches GPT-5-High on several math and reasoning benchmarks, while trailing on broad factual knowledge and complex multi-turn tool benchmarks. Speciale overtakes frontier baselines on several reasoning tests, but uses substantially more output tokens per problem and drops tool support.
- Olympiad gold-medal scores: On IMO, CMO, ICPC, and IOI evaluations, the reported scores reflect a complete test-time system that includes parallel candidate sampling, filtering, and—for mathematical proofs—iterative self-verification, rather than single-pass greedy decoding.
- End-to-end task economics: Even if sparse attention speeds up per-token prefill and decode on long sequences, a model that generates twice as many reasoning tokens or executes dozens of tool turns can still cost more per completed task. The meaningful systems metric is the total compute spent to solve a problem, not the latency of a single attention kernel in isolation.
Sources: Report §1 and §3 (sections/01-0-intro.tex, sections/02-post.tex); official model card at the preserved revision. Continue with the foundations.
2. The Foundations the Report Assumes
Before diving into DeepSeek-V3.2's specific modifications, this chapter establishes the core notation and mechanics the report takes for granted: autoregressive tokenization, pre-norm transformer blocks, causal attention and KV caching, and policy-gradient reinforcement learning over multi-turn agent trajectories.
Tokens and next-token probabilities
A tokenizer maps raw text into a sequence of integer IDs drawn from a fixed vocabulary . Depending on the byte-pair or subword vocabulary, a single token might represent a full word, a subword stem, punctuation, whitespace, or a reserved control symbol such as <|tool▁call▁begin|>. Token counts therefore vary across languages and formatting styles for the exact same semantic content.
At the input layer, each token ID is mapped to a learned embedding vector. A stack of transformer layers refines these vectors into contextual representations, and a final linear head projects the top-layer hidden state into one logit per vocabulary item. Applying a softmax yields the next-token probability distribution conditioned on the prefix :
During generation, a sampler selects the next token according to a decoding rule (such as temperature scaling followed by top- truncation), appends it to the prefix, and runs the next step. Whether the emitted tokens form a natural-language paragraph or a JSON tool invocation makes no difference to the underlying probability model; an external runtime parser watches the output stream and intercepts structured tool calls when a stop sequence appears.
Transformer blocks: communication vs. local computation
Each transformer layer alternates between two operations wrapped in residual connections and root-mean-square normalization (RMSNorm):
Attention moves information across sequence positions, letting token read states from tokens . The feed-forward network (FFN) transforms features within each position independently, operating on a single token's residual vector after attention has mixed in contextual signals. In a Mixture-of-Experts (MoE) layer, that single dense FFN is replaced by a bank of parallel expert FFNs controlled by a learned router.
Queries, keys, and values
Inside a single attention head, position projects its normalized hidden state into a query vector , while every historical position projects its state into a key vector and a value vector . The scaled dot product between and scores their compatibility, and a softmax converts those scores into convex combination weights over the value vectors:
In short, the query specifies what the current position is looking for, the keys determine where to attend, and the values supply what gets read. Multi-head attention runs dozens of these heads in parallel with distinct learned projections so a token can simultaneously attend to different positions and subspaces, then concatenates and projects the head outputs back into the residual stream.
Causal masking and the quadratic triangle
Because an autoregressive model cannot peek at future tokens when predicting token , a causal mask sets attention logits for all positions to , driving their softmax weights to zero. Over a prompt of length , the number of valid query-key pairs with is the lower triangular sum:
Thus, causal masking cuts the work in half relative to bidirectional attention, but the pair count still scales as .
Prefill, decode, and the KV cache
Inference splits into two distinct execution regimes:
- Prefill ingests an entire prompt of length at once. Because all prompt tokens are already known, the hardware can evaluate all queries in parallel using dense matrix multiplications, subject to the lower-triangular causal mask.
- Decode generates new tokens one at a time. Because token must be sampled before token can be computed, decode steps are inherently sequential and typically bottlenecked by memory bandwidth rather than raw arithmetic throughput.
To avoid recomputing keys and values for every historical token at every decode step, inference engines maintain a KV cache in GPU memory. Standard multi-head attention caches explicit and tensors for every head, which quickly consumes tens of gigabytes on long sequences. DeepSeek's Multi-head Latent Attention (MLA) compresses that cache into a shared low-rank latent vector per token, while DeepSeek Sparse Attention (DSA) reduces how many cached tokens each query actually reads. MLA shrinks the storage footprint of the history; DSA shrinks the read volume per step.
From next-token cross-entropy to post-training
Pre-training minimizes the standard cross-entropy loss over a massive text corpus:
Predicting the next token over trillions of words teaches the base model syntax, world knowledge, code idioms, and reasoning patterns, but it does not align the model to follow multi-constraint user instructions or recover from runtime errors in an interactive environment. Post-training bridges that gap through three mechanisms:
- Supervised fine-tuning (SFT) trains on curated prompt-response demonstrations.
- Knowledge distillation transfers behavior from specialized domain teacher checkpoints into a single general student checkpoint.
- Reinforcement learning (RL) samples candidate trajectories from the model, scores them with rule-based verifiers or reward models, and updates the weights to increase the probability of high-scoring trajectories.
Policies, agent trajectories, and advantages
In RL terminology, the language model is a stochastic policy parameterized by weights . For a single-turn prompt , the probability of generating an output sequence factors autoregressively over its tokens:
In a multi-turn agent environment, a trajectory interleaves model-generated tokens (internal reasoning and tool calls) with environment observations (command outputs, search results, or error traces). Although the model conditions on the entire interleaved transcript when generating its next action, only the tokens actually sampled from are actions of the policy; environment observations must be masked out when computing policy gradients.
A verifier or reward function assigns a scalar reward to the completed trajectory, and Group Relative Policy Optimization (GRPO, detailed in Chapter 9) converts a group of rewards for the same prompt into a baseline-subtracted advantage. If four sampled rollouts receive binary rewards , their group mean is , yielding mean-centered advantages that push probability mass toward the successful rollouts and away from the failures.
Because a verifier only needs to check a final answer or run a unit test suite rather than grade every intermediate step, tasks that are hard to solve but cheap to verify—such as software patches, math proofs, and constraint-satisfaction puzzles—form the backbone of scalable RL training. Even so, an RL policy is only as good as its verifier: if a test suite has gaps or a constraint checker has a bug, the optimizer will happily exploit it.
Sources: Transformer and RL policy formulation in Report §§2–3; released model.py (MLA, Block, and Transformer classes) in the pinned official implementation. Continue with the backbone and experts.
3. Inside the Inherited Backbone
DeepSeek-V3.2 builds directly on the Mixture-of-Experts (MoE) transformer backbone introduced in DeepSeek-V3 and refined through V3.1-Terminus. While sparse attention is the headline architectural addition in V3.2, attention is only one piece of the forward pass: every token still flows through embeddings, RMSNorm layers, query/key/value projections, routed feed-forward experts, and a 129,280-entry vocabulary head.
Inspecting the revision-pinned config.json and model.py files in the official repository anchors the paper's equations in concrete tensor dimensions.
Architectural dimensions in the released checkpoint
| Component | Preserved release value | Role in the network |
|---|---|---|
Vocabulary (vocab_size) |
129,280 | Total token identifiers in the embedding and LM head |
Hidden width (dim) |
7,168 | Residual stream dimension across all layers |
Main transformer layers (n_layers) |
61 | Total stacked attention + FFN blocks |
Initial dense FFN layers (n_dense_layers) |
3 | Leading layers that use a standard dense FFN instead of MoE |
Main attention heads (n_heads) |
128 | Parallel query/output heads per MLA layer |
Query latent rank (q_lora_rank) |
1,536 | Bottleneck dimension for low-rank query compression |
KV latent rank (kv_lora_rank) |
512 | Compressed latent width stored in the MLA cache |
Non-RoPE query/key head width (qk_nope_head_dim) |
128 | Content-addressing head dimension without positional rotation |
RoPE head width (qk_rope_head_dim) |
64 | Decoupled rotary-position head dimension |
Value head width (v_head_dim) |
128 | Per-head value dimension before output projection |
Routed experts per MoE layer (n_routed_experts) |
256 | Conditional FFN experts available in Layers 3–60 |
Activated routed experts (n_activated_experts) |
8 | Routed experts evaluated per token in each MoE layer |
Shared experts (n_shared_experts) |
1 | Always-on expert evaluated for every token in each MoE layer |
Expert intermediate width (moe_inter_dim) |
2,048 | Hidden dimension inside each routed and shared expert |
Indexer heads / width (index_n_heads / index_head_dim) |
64 / 128 | Head count and dimension for the DSA lightning indexer |
Attention selection budget (index_topk) |
2,048 | Number of historical tokens selected per query by DSA |
The Hugging Face config.json also lists num_nextn_predict_layers: 1, which carries over the auxiliary Multi-Token Prediction (MTP) head from DeepSeek-V3. During standard autoregressive inference in model.py, the model executes the 61 main layers; using the MTP head for speculative decoding requires dedicated runtime support outside the minimal reference script.
Why 128 heads do not mean a 128-head KV cache
A glance at num_key_value_heads: 128 in config.json can mislead off-the-shelf memory calculators designed for standard Grouped-Query Attention (GQA). In a conventional transformer with 128 KV heads, caching per-head keys and values for every token would require storing elements per token per layer.
DeepSeek-V3.2 uses Multi-head Latent Attention (MLA), which never materializes per-head key and value caches in memory. Instead, each layer caches a single shared 512-dimensional latent vector alongside a 64-dimensional rotary positional key—just 576 elements per token per layer—and folds the per-head expansion matrices into the query and output projections at runtime. Chapter 4 walks through this matrix absorption step by step.
Inside an MoE layer: SwiGLU experts and group-limited routing
After the first three layers (which use standard dense SwiGLU feed-forward networks with intermediate dimension 18,432), the remaining 58 layers replace the dense FFN with an MoE module. Each individual expert is a gated SwiGLU network mapping through a 2,048-dimensional bottleneck:
For each token , a learned router selects a subset of 8 routed experts out of 256, scales their outputs by gating weights , and adds the result to an always-active shared expert:
In the reference implementation (Gate in model.py), routing follows a two-stage group-limited procedure:
- Unbiased affinity scoring: The router computes a linear projection followed by a sigmoid activation, producing raw affinity scores across all 256 experts.
- Biased group and top- selection: A learned load-balancing bias is added to form selection scores . The 256 experts are partitioned into 8 groups of 32; each group is scored by summing its top 2 biased expert scores, the top 4 groups are retained, and the top 8 experts overall are picked from those 4 groups.
- Unbiased weight normalization: Once the 8 expert IDs are chosen, their combination weights are computed by normalizing the original unbiased sigmoid scores across the 8 selected experts and multiplying by
route_scale = 2.5.
Separating biased discrete selection from unbiased continuous weighting keeps load balancing from distorting the magnitude of expert contributions. At the same time, because top- selection is a discrete argmax operation, tiny floating-point shifts between rollout generation and training replay can flip which experts cross the threshold—the exact instability that motivates the Keep Routing replay mechanism covered in Chapter 11.
Parameter accounting: 671B total vs. 37B active
The DeepSeek-V3 backbone is cited at roughly 671B total parameters with 37B activated per token (adding the V3.2 lightning indexer changes the total by less than 0.2%). We can verify how the MoE layers dominate that budget directly from the tensor shapes.
Ignoring normalization vectors and router biases, a single expert contains three matrices of shape :
Across the 58 MoE layers, the 256 routed experts per layer account for:
When processing a single token, however, each MoE layer evaluates only 8 routed experts plus 1 shared expert, activating:
Adding the 3 initial dense FFN layers, the 61 MLA blocks, the embedding matrix, the LM output head, and the MTP module brings the per-token active count to roughly 37B parameters and the stored total to roughly 671B.
While a single token only pays the FLOP cost of 37B parameters, a serving cluster cannot fit the model into the VRAM of a 37B dense checkpoint: across a batch of tokens, almost all 256 experts in every layer will be touched, so the full 671B weight footprint must stay resident in high-bandwidth memory across the GPU cluster.
MoE layer experts vs. post-training domain specialists
The paper uses the word "specialist" for two completely unrelated mechanisms at different scales:
| Term | Granularity | How it works |
|---|---|---|
| MoE routed expert | A single SwiGLU module inside one layer | Dynamically selected per token during the forward pass by the layer's router |
| Post-training domain specialist | A full 671B checkpoint fine-tuned with RL on a single domain (e.g., math, code, or search) | Used offline to generate synthetic distillation trajectories for training the unified V3.2 checkpoint |
Domain specialists exist only during the post-training pipeline (Chapter 8); at inference time, a single unified checkpoint serves all tasks, and its internal MoE routers pick combinations of FFN submodules token by token without any explicit notion of task labels.
Reconciling the three context-length numbers in the release
If you inspect the paper alongside the repository files, you will encounter three different sequence-length constants:
- 128K (131,072 tokens): The context window used throughout the paper's continued pre-training, RL rollouts, and long-context evaluations.
- 163,840 tokens: The
max_position_embeddingsfield in the Hugging Faceconfig.json, parameterized with YaRN rotary scaling (factor: 40overoriginal_max_position_embeddings: 4096). - 16,384 tokens: The default
max_seq_lenhardcoded in the minimalinference/model.pydemo script so that a reference test run does not pre-allocate a massive KV cache by default.
Throughout our analysis, we use 128K when discussing the paper's training and evaluation regime, and write out explicit token counts ( vs. ) whenever we compute exact FLOPs or memory footprints.
Sources: Report §2 (sections/01-method.tex); released config.json; pinned inference/config_671B_v3.2.json and inference/model.py (Gate, MoE, and Block classes). Continue with Multi-head Latent Attention.
4. Multi-Head Latent Attention
Multi-Head Latent Attention (MLA) compresses the per-token attention state stored in the KV cache. DeepSeek-V3.2 inherits MLA directly from the V3 backbone and wraps sparse token selection around it. Understanding how MLA structures its cache explains both what DeepSeek Sparse Attention (DSA) actually selects and why sharing each selected token entry across all 128 query heads maps so cleanly onto GPU memory hierarchies.
The core algebraic insight of MLA is straightforward: instead of caching explicit per-head key and value vectors for every past token, the layer caches a single low-rank latent vector and reconstructs per-head keys and values through linear projections. Because those reconstructions are linear, the up-projection matrices can be absorbed directly into the query and output projections during decoding.
Compressing keys and values into a shared latent
Let () be the hidden state at historical position . MLA projects down into a compressed key-value latent vector () and applies RMSNorm:
For each attention head , learned up-projection matrices and map that shared 512-dimensional latent into head-specific content keys and values:
Even though all 128 heads read from the same compressed latent , each head applies its own learned subspace projection and , preserving distinct per-head attention patterns. Queries undergo a similar low-rank bottleneck () to save parameter and activation memory, though only the key-value latent persists in the historical cache across decoding steps.
Absorbing the key up-projection into the query
During decoding, explicitly multiplying for every historical token and every head would defeat the bandwidth savings of caching a compact latent. Instead, look at the content compatibility score between query head at current position and historical position :
By associativity of matrix multiplication, we can group with the current query vector instead of the historical latent:
For a single new decode token , the model multiplies by once to form an absorbed query in latent space. All 128 absorbed query heads then compute dot products against the exact same cached vector , eliminating per-head key materialization across the historical sequence.
Absorbing the value up-projection into the output
The same associativity trick eliminates per-head value reconstruction. Given softmax attention weights for head , the head output is:
Factoring the position-independent matrix outside the sum over gives:
Instead of expanding into 128 distinct value vectors at every historical position , the attention kernel accumulates a weighted sum of the shared 512-dimensional latents for each head, and only multiplies by once per head after the sequence reduction is complete (or fuses directly into the final output projection ).
Why rotary position embeddings require a separate 64-dim path
Relative positional encoding via Rotary Position Embedding (RoPE) applies a position-dependent rotation matrix to queries and to keys so that their inner product depends on the relative offset . If we tried to apply RoPE inside the compressed latent before multiplying by , the position-dependent matrix would sit between and , preventing us from absorbing into the query vector at step .
MLA solves this by decoupling content addressing from positional addressing. Alongside the 512-dimensional content latent , each token produces a single shared 64-dimensional positional key rotated by , while each query head produces a 64-dimensional positional query rotated by . The full attention logit adds the two inner products:
followed by softmax scaling () and causal masking. Each historical token therefore caches numbers per layer—shared across all 128 query heads. (Chapter 22 covers the exact runtime scale factors and RMSNorm placement in model.py.)
MHA mode vs. MQA mode execution
Appendix A of the report contrasts the two ways an engine can execute the exact same MLA layer:
Reproduced from Report Appendix A (Figure 7). Both diagrams compute the same mathematical function, arranged for different compute-to-memory-bandwidth regimes.
- MHA mode (unabsorbed): Explicitly projects into 128 per-head keys and values before running standard Multi-Head Attention. During dense prefill or training over long prompts, many queries are processed simultaneously, arithmetic intensity is already high, and avoiding the wider 512-dim per-head dot product keeps FLOPs lower.
- MQA mode (absorbed): Keeps unexpanded in memory and absorbs and into the query and output paths. Structurally, the attention kernel now looks like Multi-Query Attention (MQA), where 128 query heads attend to a single shared key-value head of dimension 576 () and accumulate values of dimension 512 ().
In DeepSeek-V3.1-Terminus, the engine runs MHA mode for training and prefill, and switches to MQA mode for decoding. In DeepSeek-V3.2, DSA is built specifically around MQA mode: when the lightning indexer selects 2,048 token indices for query , a sparse MQA kernel gathers each selected 576-element entry once from HBM and reuses it across all 128 query heads in SRAM. Only on short-sequence prefills—where dense matrix kernels outperform sparse gather kernels—does the engine fall back to a masked MHA kernel to simulate the sparse selection pattern.
Sizing the MLA cache at 128K
To see the memory footprint in concrete terms, consider a single sequence of tokens across all 61 layers. If both the 512-dimensional latent and the 64-dimensional RoPE key are stored in BF16 (2 bytes per element), the MLA cache for one sequence requires:
By comparison, an un-compressed 128-head BF16 KV cache with head dimensions would require per sequence. Furthermore, as noted in the model.py source comments, production deployments quantize the KV cache to FP8, cutting the MLA footprint roughly in half again (though DSA adds a small separate cache for indexer keys, which we account for in Chapter 7).
Why MLA and DSA fit together
MLA compresses each token's feature vector along the channel axis without merging neighboring tokens along the time axis; every token position still has its own distinct cache slot . That design gives DSA clean, fine-grained addressability—it can cherry-pick individual token positions rather than coarse multi-token blocks—while MLA's shared-latent MQA layout ensures that every irregular memory gather from the KV cache feeds all 128 query heads at once.
Sources: Report §2.1 and Appendix A (sections/01-method.tex, sections/appendix.tex); pinned inference/model.py (MLA class) in the official inference repository. Continue with the lightning indexer.
5. The Lightning Indexer and Sparse Selection
DeepSeek Sparse Attention (DSA) splits attention into a cheap candidate-ranking pass and an expressive latent-reading pass. First, the lightning indexer scans the prefix and scores every historical token position for the current query. Next, a top- selector picks the 2,048 highest-scoring positions, and Multi-head Latent Attention (MLA) runs only over those selected entries.
Because the ranking is computed freshly at every layer and every query position, token selection is fully dynamic and content-dependent rather than constrained to fixed stride patterns or local sliding windows.
DSA architecture overview
Reproduced from Report Figure 1. Green modules denote the lightning indexer and top- selector; black paths denote the surrounding MLA computation.
As the diagram shows, the indexer runs alongside MLA inside every transformer block. In the released implementation, the indexer query branches off the same normalized low-rank query latent () used by main attention, whereas the historical indexer key is projected directly from the layer's input hidden state and stored in its own lightweight cache.
The lightning indexer scoring equation
For a query token at position and a candidate historical token at position , the lightning indexer computes a scalar relevance score :
Each variable plays a specific role in keeping the scan fast:
| Symbol | Dimension in V3.2 | Role |
|---|---|---|
| Number of indexer query heads (half the 128 heads of main MLA) | ||
| Indexer query vector for head at current token | ||
| Single shared indexer key vector at historical token | ||
| Query-dependent scalar weight combining head 's contribution | ||
| Final scalar ranking score for candidate token |
Notice that has no head index : just as MLA in MQA mode shares one latent vector across all query heads, the indexer shares a single 128-dimensional key vector across all 64 indexer query heads. Replacing a softmax with avoids expensive row-wise exponentiation and normalization during the scan, and executing the inner products in FP8 keeps memory bandwidth and arithmetic cost small. Because the head weights come from an unconstrained linear projection of , individual weights can be positive or negative even though .
How head weights shape candidate selection
To see how the query-dependent head weights steer selection, consider a two-head toy slice with weights scoring four historical tokens:
| Candidate | Raw dot products | After | Aggregate score |
|---|---|---|---|
| Position A | |||
| Position B | |||
| Position C | |||
| Position D |
With , a top-2 selector picks Position A and either B or C. If the next query token shifts its head weights to , Position B jumps to and Position D rises to , completely changing which historical tokens get loaded into MLA.
Once the selector passes those top- indices to MLA, main attention computes its own softmax weights from scratch using the full 576-dimensional MLA latents; the indexer score only determines membership in the active set , not the final attention weight inside MLA.
Shared token-level top- selection
During sparse training and inference, each query selects at most historical positions:
If , the prefix has no more than tokens and DSA reads the entire history identically to dense MLA. Once , contains the 2,048 indices with the highest scores.
Three structural properties of stand out:
- Shared across main query heads: At a given layer and token , all 128 MLA heads attend over the same 2,048 selected positions (though each head computes its own independent softmax distribution over those 2,048 entries). Sharing across heads is what allows the sparse MQA kernel to load each selected latent once and reuse it 128 times.
- Token-level granularity: Selection picks individual token indices rather than coarse 64-token or 128-token page blocks, avoiding wasted budget on irrelevant tokens that happen to sit next to a single critical keyword.
- No hardcoded local window: Unlike sliding-window + sink-token architectures, the V3.2 DSA prototype does not reserve fixed slots for initial sink tokens or a mandatory local window; any recency bias or anchor-token retention is learned directly by the indexer (which has its own RoPE dimensions).
Enforcing causality across both stages
To prevent information leakage from future tokens , causal masking must hold in both the indexer and main attention. During prefill, model.py adds an upper-triangular mask to before calling torch.topk.
A subtle boundary case arises during prefill for early tokens where : when a fixed-width topk(2048) kernel runs on row of a rectangular score matrix, the remaining slots in the returned index tensor will be filled with -scored future indices . Consequently, the main MLA stage must still apply its own causal mask (or filter out indices ) so those padding slots receive zero probability in the softmax. During single-token decoding, the cache slice only contains positions , so future tokens are absent by construction.
Hadamard rotation and FP8 quantization in model.py
Inspecting the Indexer class in inference/model.py reveals several engineering refinements beyond Equation (1) of the paper:
- Partial RoPE: Each 128-dimensional indexer query and key splits into a 64-dimensional RoPE half (
qk_rope_head_dim = 64) and a 64-dimensional non-RoPE half, concatenated back to width 128. - Fast Hadamard Transform (FHT): Before quantizing and to FP8,
rotate_activationmultiplies both vectors by a normalized Walsh-Hadamard matrix () and scales by . Because is orthogonal, in exact arithmetic, while spreading activation outliers evenly across coordinates so per-tensor/per-token FP8 quantization loses much less precision. - Fused weight scaling: The head weights are multiplied by , the softmax scale factor, and the per-token FP8 query quantization scale before being passed into the
fp8_indexkernel, folding three scalar multiplications into one.
The retrieval bottleneck
Why not simply use main attention's own query-key dot products to pick the top 2,048 entries? Because evaluating 128 heads of 576-dimensional dot products across all is already half the cost of dense MLA. The indexer cuts that scanning cost by reducing the head count from 128 to 64, shrinking the head dimension from 576 to 128, sharing a single 128-byte FP8 key across heads, and using instead of softmax.
The trade-off is a hard retrieval bottleneck: if the lightning indexer fails to rank a critical historical token inside the top 2,048 at layer , main attention at layer gets zero signal from that token and cannot send gradients back through the discrete topk operator to fix the miss. Training the indexer to track main attention accurately before switching on sparsity is therefore essential—and is the subject of Chapter 6.
Sources: Report §2.1 (sections/01-method.tex); pinned inference/model.py (Indexer class) in the official repository. Continue with continued training.
6. Converting a Dense Model to Sparse Attention
DeepSeek-V3.2 does not train a 671B sparse-attention model from random initialization. Instead, it starts from the dense DeepSeek-V3.1-Terminus base checkpoint—already extended to a 128K context window—and converts it to DeepSeek Sparse Attention (DSA) through a two-stage continued pre-training curriculum totaling roughly 945.8B tokens.
Retrofitting sparse selection onto a pre-trained dense model poses an obvious bootstrap problem: if you turn on top-2,048 truncation while the lightning indexer weights are still random, every attention layer suddenly loses access to 98% of a 128K context window, corrupting hidden states and destabilizing gradients across the backbone. DeepSeek avoids this shock by warming up the indexer against the frozen dense model before switching on sparse selection.
Stage 1: Dense warm-up (freezing the backbone to train the selector)
In the dense warm-up stage, all inherited backbone parameters remain frozen and main attention continues to run densely over the full causal prefix. Only the newly initialized lightning indexer parameters are updated.
To give the indexer a dense supervision target without hand-labeled retrieval annotations, the authors extract the actual softmax attention distributions computed by the 128 main MLA heads at query , sum them across all heads , and L1-normalize the result across historical positions :
Because each head's causal attention distribution already sums to over , normalizing their sum simply averages the 128 head distributions into a single consensus distribution over the prefix. That consensus target matches the structural constraint of DSA, which picks one shared set of 2,048 token positions for all 128 MLA heads.
The indexer scores are passed through a softmax over , and the indexer is trained to minimize the forward Kullback-Leibler (KL) divergence from the teacher distribution :
Using the forward KL divergence is a deliberate choice: forward KL is mean-seeking (zero-avoiding), meaning it heavily penalizes the student distribution whenever assigns near-zero probability to a position where any group of main attention heads placed substantial mass .
For example, if four historical positions receive consensus attention mass and an untrained indexer initially assigns , a top-2 selector would drop the token carrying 60% of the teacher's attention weight. Minimizing rapidly pulls the indexer's top logits into alignment with the high-mass positions of the frozen dense model.
Warm-up compute budget
The dense warm-up stage is short and uses a relatively high learning rate of (safe because the pre-trained backbone is frozen). Training runs for 1,000 steps with a batch size of 16 sequences of 128K tokens, which with tokens gives:
Stage 2: Sparse training (co-adapting the backbone and selector)
Once the indexer can reliably identify the tokens that dense MLA attends to, Stage 2 turns on top- sparse selection () and unfreezes all backbone parameters so the model can adapt its representations to sparse reading.
During this stage, main MLA only computes attention over the selected index set . Consequently, the teacher distribution is only available on the selected subset , and the indexer's KL loss is restricted to that same active support:
Here, the main attention weights are already softmax-normalized over , and the indexer softmax is likewise taken over the 2,048 logits in . As the un-frozen backbone adjusts its attention heads to work within a 2,048-token budget, this within-set KL loss keeps the indexer's relative ranking calibrated to the evolving main attention heads.
Detached gradients: why and are decoupled
A crucial implementation detail in Stage 2 is that the indexer inputs are detached from the computation graph (stop_gradient), separating the backward pass into two independent optimization paths:
- Backbone update: The standard next-token cross-entropy loss backpropagates through the sparse MLA layers, MoE routers, and experts, updating the main model weights without sending any gradients into the indexer.
- Indexer update: The KL alignment loss backpropagates only into the lightning indexer parameters; because its hidden-state and query-latent inputs are detached, never perturbs the backbone's residual stream or query projections to make the indexer's job artificially easy.
Because the discrete operator has zero gradient almost everywhere, DeepSeek does not attempt to differentiate through token selection via straight-through estimators or Gumbel-Softmax relaxations. Instead, language modeling adapts the reader to whatever 2,048 tokens are selected, while KL distillation keeps the selector tracking the reader's preferences.
Sparse adaptation compute budget
Stage 2 drops the learning rate to and runs for 15,000 steps at a batch size of 480 sequences of 128K tokens:
At nearly a trillion tokens—roughly 450 times the warm-up budget—Stage 2 is a major continued pre-training run in its own right. Both stages sample from the exact same 128K long-context extension corpus used for DeepSeek-V3.1-Terminus, ensuring that comparisons between Terminus and the resulting DeepSeek-V3.2-Exp checkpoint isolate the transition from dense MLA to DSA rather than a shift in data mixture.
Trade-offs of attention-matching supervision
Using summed attention weights as the retrieval target is pragmatic, though it comes with two theoretical approximations worth noting:
- Attention weight vs. causal importance: A high softmax weight does not always mean token is critical to the final output (for instance, attention sinks often absorb large softmax weights associated with near-zero value norms), and conversely, a head with a small weight multiplied by a large value vector might carry a crucial signal that gets diluted when averaging across all 128 heads.
- No out-of-set supervision in Stage 2: Because Stage 2 only evaluates on , a token that falls just below the 2,048 cutoff receives no direct dense-teacher comparison during Stage 2; keeping those borderline tokens ranked properly relies on the Stage 1 warm-up initialization and the shared representations of the 2,048 tokens that do make the cut.
Even with those approximations, the benchmark comparison between V3.1-Terminus and V3.2-Exp (examined in Chapter 19) shows that two-stage distillation plus 943.7B tokens of sparse adaptation preserves short- and long-context quality across standard evaluations, setting the stage for the systems cost analysis in Chapter 7.
Sources: Report §2.1.1 and §2.2 (sections/01-method.tex). Continue with computation, memory, and inference cost.
7. Computation, Memory, and Inference Cost
DeepSeek Sparse Attention (DSA) makes the heavy MLA reader sparse, but it does not eliminate the lightning indexer's prefix scan, shrink the total KV cache footprint, or reduce the FLOPs spent in MoE feed-forward layers. Building an accurate mental model of V3.2's performance requires separating the pieces that scale with the sparse budget from the pieces that still scale with the full sequence length .
Counting query-key pairs in main attention
Over a prompt of length , dense causal attention evaluates all lower-triangular pairs with , totaling interactions per layer. Under DSA, each query attends to at most historical tokens, capping the total main-attention pairs during prefill at:
When , the first tokens attend densely to their short prefixes while the remaining tokens each attend to exactly entries:
Plugging in the paper's full context window and sparse budget illustrates the gap between prefill and final-token decode:
- Full-sequence prefill pairs: Dense causal attention evaluates pairs per layer, whereas sparse main attention evaluates pairs—a 32.25 reduction in main-attention pair count across the whole sequence.
- Final-token decode pairs: When decoding a single token at the end of a 131,072-token prefix, dense attention scans all 131,072 cached entries while sparse main attention reads only 2,048 entries—a 64 reduction in candidate reads for that step.
The prefill ratio () is roughly half the final-token decode ratio () because the average prefix length across a prompt of length is , not .
Why full-sequence complexity is still asymptotically
Although main attention drops from to during prefill, the lightning indexer must still score every valid candidate pair with to determine which indices win. Writing out the total prefill cost of a transformer block as a function of gives three scaling regimes:
Here, captures the quadratic prefix scan inside the lightning indexer, captures the sparse MLA read over tokens, aggregates token-wise linear work (QKV/output projections and the 9 active MoE experts per token), and represents the top- selection kernel.
Because , the asymptotic complexity as for fixed remains . What makes DSA fast at is the ratio of the leading constants :
- Fewer heads and narrower vectors: The indexer computes 64 heads of width 128 ( multiply-adds per pair, with No-RoPE/RoPE fused and no value aggregation), whereas main MLA in MQA mode computes 128 heads of 576-dim score inner products plus 128 heads of 512-dim value accumulations ( multiply-adds per pair)—more than a reduction in raw arithmetic per pair.
- FP8 execution and : Running the indexer dot products in FP8 with a cheap activation instead of BF16/FP16 with row-wise softmax synchronization cuts both memory bandwidth and tensor-core cycles further.
During single-token decoding at prefix length , the per-token cost scales linearly with in the indexer and stays constant in for main attention:
Thus, decoding a 20,000-token reasoning chain still pays a linear scan in the indexer at every step, plus the fixed sparse MLA read and MoE expert execution.
Sparse reads do not shrink the KV cache footprint
A common misconception is that attending to 2,048 tokens means the engine only needs to keep 2,048 tokens in GPU memory. Because token selection is dynamic, a token ignored at step may be selected at step . The serving engine must therefore retain the entire historical sequence in HBM—both the MLA cache and the new indexer key cache.
In Chapter 4, we calculated that a 131,072-token MLA cache (512 latent + 64 RoPE dimensions) takes ~9.21 GB in BF16 (or ~4.61 GB in FP8). On top of that, DSA must cache one 128-dimensional FP8 indexer key plus one 4-byte FP32 quantization scale per token per layer (k_cache and k_scale_cache in model.py):
So DSA actually increases total KV cache storage per sequence by roughly 1 GB at 128K context in exchange for cutting the memory bandwidth read per token during decoding by an order of magnitude.
Kernel engineering vs. the reference model.py script
Achieving wall-clock speedups from token-level sparsity on modern GPUs requires specialized kernels (fp8_index and sparse FlashMLA). Naive sparse gather operations over individual tokens suffer from uncoalesced HBM reads unless each fetched cache line performs enough compute to hide memory latency. Because DSA shares the same 2,048 selected token indices across all 128 MLA query heads in MQA mode, a single 576-element gather from the MLA cache feeds all 128 query heads simultaneously inside shared memory/registers, restoring high arithmetic intensity.
If you benchmark the reference inference/model.py script shipped in the repository, be careful not to confuse it with the production kernels: in model.py, the MLA.forward method computes the full dense (or ) attention score matrix scores first and then overwrites unselected indices with -inf via index_Mask. That reference code is written to verify mathematical equivalence and checkpoint loading; actual FLOP and bandwidth savings require replacing the dense matmul + mask with a fused sparse gather-and-attend kernel such as TileLang/FlashMLA.
Production H800 cost curves
To show how these systems trade-offs play out on real hardware, the authors benchmark end-to-end serving throughput for DeepSeek-V3.1-Terminus and DeepSeek-V3.2 on a cluster of NVIDIA H800 GPUs, converting throughput into dollar cost per million tokens at a reference rental rate of US$2 per H800 GPU-hour:
Reproduced from Report Figure 2 (figures/cost_prefilling.pdf and figures/cost_decoding.pdf). Vertical axes show estimated serving cost (USD per 1M tokens) as a function of token position inside a 128K context window, priced at $2/GPU-hour on H800 hardware.
Several practical behaviors stand out in Figure 2:
- Short-sequence prefill crossover: At very short sequence lengths, sparse indexing and gather overhead can outweigh dense matrix efficiency, so the authors use a custom masked MHA kernel to simulate DSA on short prompts before switching to sparse MQA as sequence length grows.
- Marginal vs. cumulative cost: The horizontal axis plots the marginal cost at a specific token position (32K, 64K, 96K, 128K), not the average cost across a full request. Estimating the total cost of prefilling a 128K prompt or decoding a 32K trajectory requires integrating the area under the curve from the starting position to the final position.
- Amdahl's law at the model level: Even at 128K context, where main attention reads 64 fewer tokens during decoding, total per-token decoding cost drops by roughly 3–4 rather than 64. By Amdahl's law,
the non-attention portion of the forward pass ()—communicating tokens via all-to-all dispatch/combine, executing 9 SwiGLU experts per layer, running MLA projections, and scanning the FP8 indexer cache—places a hard floor on per-token cost.
That per-token savings is what makes the next part of the paper feasible: scaling post-training reinforcement learning to long-horizon reasoning and multi-turn agent trajectories.
Sources: Report §2.3 (sections/01-method.tex); Report Figure 2 (figures/cost_prefilling.pdf, figures/cost_decoding.pdf); pinned inference/model.py (Indexer and MLA classes). Continue with post-training: specialists, distillation, and mixed RL.
8. Specialists, Distillation, and Mixed Learning
Converting DeepSeek-V3.1-Terminus into the sparse-attention base checkpoint (DeepSeek-V3.2-Exp base) only solves the pre-training half of the problem. Turning that base checkpoint into a general assistant that can prove theorems, debug repositories, orchestrate search tools, and hold normal conversations requires a three-stage post-training pipeline: training dedicated domain specialists via large-scale RL, distilling their trajectories into a unified student checkpoint, and running a final mixed-domain GRPO stage.
Throughout all three post-training stages, the model retains the exact same DeepSeek Sparse Attention (DSA) architecture introduced during continued pre-training.
Stage 1: Training six domain specialists
Instead of jumping straight from the base model into a single multi-task RL run, the authors first branch off six specialized models, each initialized from the same pre-trained V3.2 base checkpoint and trained with large-scale reinforcement learning on a single domain:
- Mathematics
- Programming
- General logical reasoning
- General agent tasks
- Agentic coding
- Agentic search
Alongside these six technical domains, the pipeline maintains specialized teachers for writing and open-ended question answering.
Training separate domain specialists first solves a practical reward-engineering and curriculum problem. A math or competitive-programming specialist benefits from binary outcome verifiers, long rollout limits, and near-zero KL penalties, whereas an agentic search or general chat model requires rubric-based reward models, formatting checks, and stricter style regularization. Decoupling the domains during the initial RL push lets each specialist saturate its domain benchmark without cross-domain gradient interference or reward-scale tuning headaches.
Stage 2: Distilling Thinking and Non-Thinking trajectories
Because deploying six separate 671B checkpoints behind a routing classifier is operationally unwieldy, the specialist models are used as data generators to train a single unified checkpoint. Each specialist generates both thinking mode trajectories (with explicit <think>...</think> scratchpad blocks and interleaved reasoning across tool turns) and non-thinking mode trajectories (direct answers and immediate tool calls).
Training a student policy on filtered specialist trajectories via standard supervised cross-entropy minimizes:
(While the paper describes generating domain-specific data from the specialists to train the merged checkpoint, it does not publish the exact rejection-sampling filters, dataset sizes, or whether token-level logit distillation supplements sequence-level SFT.)
According to the report, the unified checkpoint resulting from specialist distillation lands only slightly below the individual domain specialists on their respective benchmarks—and the subsequent mixed RL stage closes that remaining gap completely.
Supporting both thinking and non-thinking modes inside the same weights gives downstream applications a clean latency-versus-accuracy knob. Both modes execute the exact same 61-layer sparse MoE transformer; the difference is purely behavioral, triggered by the chat template (covered in Chapter 13). On straightforward queries or latency-sensitive agent loops, non-thinking mode skips the multi-thousand-token scratchpad while retaining strong tool-calling accuracy (for instance, scoring 67.6% vs. 73.1% on SWE-bench Verified, examined in Chapter 20).
Stage 3: Unified mixed-domain GRPO
Imitation learning on teacher trajectories has a well-known limitation: once the student model makes a slight mistake at test time, it enters states the teacher never visited. To make the unified model robust on its own rollout distribution—and to erase the small gap left by distillation—DeepSeek-V3.2 runs a consolidated mixed RL stage using Group Relative Policy Optimization (GRPO) that blends reasoning, agent, and human-alignment prompts into a single training loop.
Sequential multi-stage RL (for example, running math RL first, then coding agent RL, then chat RL) notoriously suffers from catastrophic forgetting: optimizing for concise chat responses degrades long-chain math reasoning, while aggressive math exploration degrades instruction formatting. By mixing all domains in every update step, the policy must satisfy all reward signals simultaneously:
- Reasoning and agent tasks: Scored by rule-based outcome verifiers, explicit length penalties, and language-consistency rewards (preventing unwanted mid-sentence language switching).
- General alignment and writing tasks: Scored by a generative reward model that grades responses against prompt-specific rubrics.
Scaling RL compute and branching DeepSeek-V3.2-Speciale
Across specialist training and unified mixed RL, the post-training RL compute budget exceeds 10% of the total pre-training cost. In an agentic RL loop, compute goes not just to forward and backward passes on the 671B policy, but also to autoregressive rollout decoding over 64K–128K contexts, container execution for coding environments, search API queries, and generative reward-model grading.
From this pipeline, the authors produce two distinct final checkpoints:
- DeepSeek-V3.2 (Main): Trained with the full mixed-domain RL recipe (reasoning + agents + general alignment) and calibrated length penalties so token consumption stays practical for everyday production serving.
- DeepSeek-V3.2-Speciale: Branched specifically to probe the upper bound of long-horizon reasoning. Speciale trains exclusively on reasoning data during its RL stage, relaxes the length penalty so the model can allocate tens of thousands of thinking tokens to hard problems, and incorporates the proof dataset and self-verification reward pipeline from DeepSeekMath-V2. Because it skips agent and tool-use RL, Speciale does not support tool calling in the released checkpoint.
Why doesn't cranking RL compute above 10% of pre-training cause the 671B MoE policy to collapse? As the authors detail in Section 3.1 of the report, naive GRPO breaks down at this scale unless you fix three subtle mismatches between rollout generation and gradient updates—the focus of Chapters 9, 10, and 11.
Sources: Report §3 opening and §4.1 (sections/02-post.tex). Continue with GRPO from first principles.
9. GRPO from First Principles
Group Relative Policy Optimization (GRPO) eliminates the separate value-network critic of Proximal Policy Optimization (PPO) by sampling a group of candidate outputs for each prompt, scoring them with a verifier or reward model, and using the group's average reward as the baseline. For a 671B-parameter MoE model, dropping the critic cuts memory and compute overhead nearly in half while avoiding value-estimation errors over 64K-token reasoning chains.
The three policies in a GRPO update
Every GRPO step involves three distinct probability distributions over next tokens:
| Policy | Notation | Role in training |
|---|---|---|
| Rollout (behavior) policy | The inference snapshot that actually sampled the rollout trajectories | |
| Current (trainable) policy | The active model weights being updated by gradient ascent | |
| Reference policy | A frozen anchor checkpoint used to penalize excessive policy drift via KL divergence |
Why distinguish from ? First, to amortize the cost of generating long reasoning and agent trajectories, a single batch of rollouts from is typically split into multiple mini-batches for several gradient updates, so drifts away from after the first step. Second, even before a single weight update occurs, the high-throughput inference engine running (using FP8 kernels and custom paging) and the distributed training engine running produce slightly different token probabilities due to floating-point and kernel differences.
Group mean-centered advantages
Given a prompt , the rollout worker samples a group of outputs from and evaluates their scalar rewards . In DeepSeek-V3.2, the advantage assigned to token of output is the group mean-centered reward:
Notice two specific details in Equation (5) of the report:
- Sequence-level credit assignment: Every token generated in trajectory receives the exact same outcome advantage .
- No standard-deviation division: Unlike earlier GRPO formulations that divide by , DeepSeek-V3.2's displayed equation subtracts the group mean without dividing by the group standard deviation. Avoiding division by prevents exploding advantages when all samples in a group receive nearly identical rewards (for instance, when only one sample incurs a tiny length or formatting penalty).
Consider a group of rollouts with binary verification rewards . Their mean is , yielding advantages . If a prompt is so easy that all rollouts pass () or so hard that all fail (), all outcome advantages become , contributing zero policy-gradient signal from the outcome verifier. Maintaining a task curriculum where prompts sit at intermediate pass rates is therefore critical for sample efficiency.
Token-level importance ratios and the clipped surrogate
Because the tokens were drawn from rather than , the update reweights each token by its conditional likelihood ratio:
Notice that is the ratio of single-token conditional probabilities at prefix , not the product of ratios across the whole sequence (which would explode or vanish exponentially over thousands of tokens).
Putting the clipped PPO surrogate, per-response length averaging, and token-level KL penalty together gives the complete GRPO objective maximized by DeepSeek-V3.2:
How length normalization and clipping behave
Two structural terms inside govern how long trajectories are weighted and bounded:
- Per-trajectory length normalization (): Dividing the inner sum by averages the surrogate across tokens within each trajectory before averaging across the trajectories. Without , a 16,000-token reasoning rollout would contribute 16 times as many token gradient terms as a 1,000-token rollout simply by being verbose. Even with normalization, however, the reward itself must still include a length penalty if you want the policy to prefer concise solutions over long ones.
- Sign-sensitive PPO clipping: The around acts as a pessimistic lower bound.
- When (a better-than-average trajectory), the objective increases with up to , above which the flat clipped branch wins and stops the gradient from pushing any higher on that stale sample.
- When (a worse-than-average trajectory), multiplying by a negative number flips the inequality: the objective increases as drops toward , below which the flat clipped branch is more negative than and cuts off further downward pressure.
Credit assignment and action masking in multi-turn trajectories
Assigning a single sequence-level advantage to every token means GRPO relies on statistical averaging across batches to separate productive reasoning steps from dead-end detours inside a winning trajectory. If a 10,000-token proof meanders for 3,000 tokens before finding the right lemma and succeeding, all 10,000 tokens receive a positive update on that step; only across many groups—especially when paired with a length penalty that gives higher reward to shorter proofs—do redundant detours get washed out.
In multi-turn agent trajectories, the transcript alternates between model-generated tokens (thoughts and tool calls) and environment observations (tool outputs). Because environment observations are injected by the runtime rather than sampled from , the training loop masks environment tokens out of the inner sum over , conditioning on them in the prefix while computing gradients only on tokens emitted by the model.
Finally, look closely at the two places where , , and interact in : the KL penalty and the importance ratio . In standard RL codebases, subtle bugs in both terms routinely destabilize large MoE runs. Chapters 10 and 11 examine how DeepSeek-V3.2 fixes them.
Sources: Report §3.1 (sections/02-post.tex, Equations 4–5). Continue with the corrected KL estimator.
10. The Corrected KL Estimator
To keep the trainable policy from drifting too far from the reference checkpoint during GRPO, the objective subtracts a KL penalty at every generated token position . Rather than materializing full 129,280-vocabulary softmax distributions for both and at every token to compute the exact sum, RL implementations typically estimate the KL divergence from the single sampled rollout token using Schulman's nonnegative K3 estimator.
There is a catch: the K3 estimator is only an unbiased estimator of when the token is sampled from . In off-policy GRPO, however, the rollout token was sampled from , not . DeepSeek-V3.2 corrects this mismatch by multiplying the K3 estimator by the importance ratio .
Why the standard K3 estimator works on-policy
Fix a single prefix and abbreviate the next-token probability distributions over the vocabulary as:
Assume all three distributions have full support on (so ). We want to estimate the forward KL divergence from the reference to the current policy :
The standard single-sample K3 function is:
Because for all (with equality if and only if ), is guaranteed to be nonnegative for every token , reducing variance compared to the naive log-ratio . If we draw , its expectation is:
What goes wrong when sampling from
During an off-policy GRPO step, the token was actually drawn from , not . Taking the expectation of the uncorrected K3 term under yields:
To see the numerical bias on a two-token vocabulary, take:
The true KL divergence between and is:
Evaluating the uncorrected K3 function on the two tokens gives and . Because the rollout policy samples token 1 four times as often as token 2, the uncorrected expectation under is , overestimating the true KL divergence by 25%.
Even worse than the value bias is the gradient pathology when . Differentiating the uncorrected K3 term with respect to gives:
When the current policy assigns very small probability to a token that was sampled by and favored by , the coefficient explodes. In uncorrected K3 implementations, those rare off-policy tokens hit with massive, unclipped gradient spikes that push probability mass violently back toward and destabilize training.
DeepSeek-V3.2's importance-weighted K3 estimator
Equation (6) of the report fixes both the expectation mismatch and the gradient spike by multiplying the K3 term by the importance weight :
Taking the expectation over at the fixed prefix cancels cleanly:
In our two-token example, the importance-weighted values become and , whose expectation under is —recovering exactly.
Why the importance ratio must stay inside the autodiff graph
If you implement Equation (6) in PyTorch, there is a critical implementation detail: do not wrap the leading ratio in torch.no_grad() or .detach(). To get an unbiased estimator of the gradient , the numerator in the importance weight must be differentiated alongside the inner K3 bracket.
We can verify this directly by multiplying through the bracket before differentiating:
Since and do not depend on , differentiating with respect to via the product rule cancels the and terms:
Taking the expectation of this gradient under yields the exact gradient of :
where the final equality uses .
Look at what happened to the gradient magnitude: multiplying through the bracket before differentiating completely eliminated the explosive term, leaving a logarithmic factor that stays well-behaved even when . If an engineer mistakenly detaches as a stop-gradient weight, the term survives in the backward pass and the gradient becomes biased again.
Domain-specific tuning and remaining off-policy limits
Fixing the KL estimator gives the hyperparameter clean semantics across domains. As the authors note in Section 3.1, different domains benefit from very different regularization strengths: complex competition mathematics often performs best with a very weak KL penalty—or altogether—so the policy is free to depart from its initial token distribution and discover much longer reasoning chains, whereas general alignment tasks keep a stronger to preserve fluency and formatting.
Note two boundaries of this derivation:
- Conditional vs. prefix unbiasedness: The importance weight makes unbiased conditioned on the visited prefix , not across the entire marginal distribution of prefixes (which are still visited according to ).
- Truncated sampling supports: Our derivation used . When top- or top- sampling truncates the active vocabulary support of and to a subset (as discussed in the next chapter), is slightly less than unless is also renormalized on .
What if the rollout batch is so stale that or a negative-advantage trajectory has drifted far away from ? That is where DeepSeek-V3.2's three off-policy stabilization mechanisms step in.
Sources: Report §3.1, "Unbiased KL Estimate" (sections/02-post.tex, Equation 6). Continue with off-policy stability.
11. Keeping Off-Policy Learning Stable
In a large-scale RL system, rollout generation and gradient optimization run on decoupled software stacks. High-throughput inference servers (such as SGLang or vLLM) generate large batches of trajectories using FP8/INT8 quantization and paged attention kernels, while distributed training clusters (such as Megatron/DeepSpeed) consume those trajectories across multiple mini-batch gradient steps in BF16/FP32.
That architecture introduces two distinct sources of off-policy divergence between and :
- Temporal staleness: As takes multiple gradient steps on a large rollout batch, its parameters drift away from the checkpoint that generated the rollouts.
- Execution mismatch: Even at step zero—before a single weight update is applied—the inference engine's quantized kernels, reduction orders, MoE routing decisions, and top- truncation masks produce slightly different probabilities than a standard training forward pass.
To prevent this off-policy gap from destabilizing the 671B MoE model, DeepSeek-V3.2 sets directly to the token probabilities returned by the inference engine and introduces three targeted interventions: Off-Policy Sequence Masking, Keep Routing, and Keep Sampling Mask.
1. Off-Policy Sequence Masking
When a sampled trajectory has a negative advantage (), the policy gradient pushes down the probability of its tokens. If has already drifted far away from on that trajectory, continuing to push down on a stale failure modes can overshoot and destabilize the policy—especially because PPO's lower clip only bounds the per-token ratio, not the cumulative drift across thousands of tokens or the unclipped branch when .
DeepSeek-V3.2 measures how far has drifted from on trajectory using the length-averaged log probability ratio across its tokens:
In expectation at each step, this empirical sample average approximates the token-average KL divergence along the trajectory. The algorithm then defines a binary mask (constant across all tokens in sequence ) that zeros out the surrogate loss whenever a negative-advantage trajectory exceeds a divergence threshold :
Applying to the GRPO objective (Equations 7–8 of the report) gives:
Two asymmetries in this formula are worth highlighting:
- Positive-advantage sequences are never masked: If a trajectory succeeded (), regardless of how large is. Learning from an off-policy success is beneficial—it pulls the current policy toward a verified solution—whereas actively repelling the policy away from an already-abandoned region of trajectory space () injects destructive variance. (The paper leaves the exact hyperparameter unspecified.)
- Only the policy surrogate is masked: In Equation (7), multiplies the policy surrogate term, while the KL penalty sits outside .
2. Keep Routing: Replaying MoE expert assignments
In each of DeepSeek-V3.2's 58 MoE layers, a token routes through 8 out of 256 routed experts based on a discrete top- selection over sigmoid affinity scores. Because top- is a discontinuous step function, even a tiny numerical discrepancy between the FP8 inference engine and the BF16 training engine—or a single gradient step on the router weights—can flip the 8th-ranked and 9th-ranked experts for token .
When an expert flip occurs between rollout and training, the importance ratio breaks down:
- The denominator was generated by evaluating one subgraph of active experts (say, Experts ).
- The numerator is computed by evaluating a different subgraph of active experts (say, Experts ), causing a sudden jump in logits and directing gradients into Expert 9 even though Expert 8 was responsible for producing the rollout token.
To eliminate this credit-assignment discontinuity, Keep Routing caches the exact indices of the 8 routed experts selected at every layer and every token by the inference engine during rollout generation, and forces the training forward pass to route through those exact same expert indices instead of recomputing top- selection. With the discrete computational graph held fixed between rollout and training, evaluates and updates the exact expert parameters that generated the trajectory. The authors note that Keep Routing has been a critical pillar of their MoE RL pipeline since DeepSeek-V3-0324.
3. Keep Sampling Mask: Aligning truncated vocabulary supports
During rollout generation, inference servers rarely sample from the raw 129,280-token softmax distribution; instead, they apply top- (nucleus) or top- truncation to zero out the low-probability tail and renormalize over the surviving candidate set :
If the training pass computes over the untruncated vocabulary (or recomputes a fresh top- mask from 's shifted logits), and no longer share the same probability space or normalization constant.
To see how inconsistent normalization distorts the importance ratio , consider a three-token vocabulary where the raw probabilities are and top- () retains the first two tokens :
- After renormalizing on , the rollout policy actually samples from .
- Suppose after one step the raw training probabilities shift to .
- If you carelessly divide the untruncated training probability by the truncated rollout probability , you get .
- If you instead apply the exact same saved mask to , the renormalized training distribution on is , and the true importance ratio on the shared action space is .
Even worse, if training recomputed a fresh top- mask from , the sampled token could fall just outside the new threshold , driving to zero!
Keep Sampling Mask prevents both bugs by recording the truncation mask produced by during rollout sampling and applying that identical mask when normalizing during the training pass:
Summary of the RL stability stack
Together with the importance-weighted K3 estimator from Chapter 10, these three mechanisms ensure that the mathematical objects in the GRPO objective match the actual system execution:
| Mechanism | Mismatch it fixes | What the rollout worker must log |
|---|---|---|
| Unbiased K3 KL | Off-policy sampling bias & gradient spikes in KL penalty | Token probabilities |
| Off-Policy Sequence Masking | Destructive updates from stale negative-advantage trajectories | Sequence log-ratio drift & advantage sign |
| Keep Routing | Discontinuous MoE expert flips between inference and training | Selected expert IDs () |
| Keep Sampling Mask | Mismatched vocabulary support and normalization under top-/top- | Retained vocabulary mask (or truncation threshold) |
With the optimizer stabilized against off-policy drift, the next design question is what reward signals actually drive the policy—and how outcome accuracy, length penalties, and rubric rewards interact.
Sources: Report §3.1, "Off-Policy Sequence Masking," "Keep Routing," and "Keep Sampling Mask" (sections/02-post.tex, Equations 7–8). Continue with rewards, length, and reasoning behavior.
12. Rewards, Length, and Reasoning Behavior
A reinforcement-learning policy optimizes whatever reward signal it is given. For a general-purpose assistant, that signal has to balance several competing goals at once: solving verifiable problems accurately, keeping reasoning chains concise enough to serve affordably, staying in the user's requested language, and writing helpful, well-structured responses on open-ended prompts.
DeepSeek-V3.2 combines four reward families across its specialist and mixed-RL stages: rule-based outcome rewards, length penalties, language-consistency rewards, and rubric-based generative reward models. (While the report specifies which reward types apply to each task family, it does not publish the exact mixing weights or functional forms for each penalty.)
Rule-based outcome rewards
On reasoning and agent tasks—mathematics, competitive programming, repository repair, constraint planning, and fact-seeking search—the primary signal comes from a rule-based verifier that checks the final outcome:
- Does the extracted final math answer match the ground-truth expression?
- Does the edited repository pass the unit and regression test suite?
- Does the proposed travel itinerary satisfy every budget, rating, and uniqueness constraint in the sandbox database?
Evaluating only the final outcome gives the policy complete freedom over its intermediate reasoning steps: a 15,000-token scratchpad can explore dead ends, backtrack, and switch strategies without being penalized by a step-by-step process critic that might misjudge an unconventional approach.
The flip side is that outcome verifiers only guard what they explicitly test. If a repository test suite misses an edge case or a synthetic constraint checker omits a boundary condition, GRPO will happily reinforce patches that pass the verifier while failing the underlying specification.
Length penalties: pricing test-time compute during training
Left unconstrained under a binary outcome reward, RL-trained reasoning models rapidly inflate their output length: because generating an extra verification pass or re-deriving an identity slightly increases the probability of catching an arithmetic slip, the optimizer pushes trajectories toward the context limit.
To keep token consumption bounded in the main DeepSeek-V3.2 checkpoint, the reward combines outcome success with an explicit length penalty, alongside language-consistency and quality terms:
To see how shifts the learned reasoning strategy, compare two candidate behaviors on a math benchmark:
- Strategy A (concise): Succeeds 80% of the time using 10,000 tokens.
- Strategy B (exhaustive): Succeeds 85% of the time by running extra self-checks over 25,000 tokens.
If charges reward units per 1,000 tokens on a success scale, Strategy A nets an expected reward of , whereas Strategy B nets —so GRPO favors the longer Strategy B. Raise the length penalty to per 1,000 tokens, and Strategy A () overtakes Strategy B ().
Crucially, training with a different length penalty changes how the model reasons from the very first token, not just where it stops. You cannot turn the main DeepSeek-V3.2 checkpoint into DeepSeek-V3.2-Speciale simply by raising max_tokens at inference time: Speciale is trained with a substantially reduced length penalty during RL so that it learns to unpack long case analyses, test multiple proof strategies, and run iterative self-verification loops that the main model was trained to prune away.
Language-consistency rewards
Multilingual reasoning models trained with pure outcome RL frequently develop code-switching drift—for instance, receiving a prompt in Chinese or English, switching into the other language mid-thought when recalling a technical theorem, and bleeding that switch into tool arguments or the final user response.
DeepSeek-V3.2 includes an explicit language-consistency reward during RL to penalize unintended language mixing. As noted in Chapter 11, the authors also found that pairing top- sampling with Keep Sampling Mask plays a direct role here: without sampling-mask replay, off-policy updates on truncated tails often inject erratic low-probability tokens from other scripts that trigger mid-sentence language switches.
Rubric-based generative reward models for open-ended tasks
For open-ended writing, instruction following, and general chat where no deterministic verifier exists, DeepSeek-V3.2 uses a generative reward model guided by prompt-specific rubrics. Rather than mapping to a single opaque scalar through a linear value head, a generative reward model evaluates the candidate response against a checklist of criteria tailored to the prompt—such as factual accuracy, completeness, tone, formatting constraints, and absence of hallucinated citations—before producing its reward score.
Prompt-specific rubrics avoid the one-size-fits-all bias of traditional preference models (which often unconditionally favor longer, bulleted responses regardless of whether the user asked for a one-line shell command or an architectural essay). Even in agentic search, where training starts from hard, short-answer verifiable queries, the authors blend in helpfulness-oriented search prompts graded by multi-dimensional rubrics so the final assistant writes clear, well-cited synthesis reports rather than terse benchmark entity strings.
Emergent side effects: redundant self-verification in agents
Reward engineering also explains one of the main failure modes documented in the paper's agent evaluations. On complex coding and tool-use benchmarks, DeepSeek-V3.2 sometimes falls into redundant self-verification loops—repeatedly re-running test suites, re-reading files it just edited, or double-checking already-confirmed search facts until the transcript hits the 128K context ceiling.
When outcome correctness carries a high reward and a single broken edit ruins the entire trajectory, a risk-averse policy naturally learns to spend extra tool turns verifying its work before submitting. Teaching an agent to calibrate the marginal value of one more verification call against context-window exhaustion remains an active tension in agentic RL—and makes context management across tool turns (Chapters 13 and 18) a first-class systems concern.
Sources: Report §3, §4.1, and §4.2 (sections/02-post.tex, sections/06-high.tex). Continue with reasoning with tools and conversation state.
13. Reasoning with Tools and Conversation State
Early reasoning models such as DeepSeek-R1 were built around a single-turn loop: the user sends a prompt, the model emits a <think>...</think> block followed by a final answer, and when the user sends a follow-up prompt, the prior <think> block is stripped from the context window.
That single-turn rule breaks down catastrophically in multi-step tool use. If an agent calls 15 bash or search tools to solve a single request and its <think> blocks are deleted after every tool output, the model loses its working plan, hypotheses, and eliminated dead ends at every step—forcing it to re-read the entire transcript and reconstruct its reasoning from scratch on every turn. DeepSeek-V3.2 redesigns both its conversation-state retention policy and its cold-start RL curriculum around thinking with tools.
Retaining reasoning across tool turns vs. stripping on user turns
DeepSeek-V3.2 draws a sharp state-management boundary between a tool observation (role: "tool") and a new user turn (role: "user"):
- Within an ongoing task (appending
toolmessages): When the assistant emits a<think>block and one or more tool calls, and the runtime replies solely withtoolobservation messages, all historical<think>blocks from the current user turn are retained in the context. - Across user turns (appending a new
usermessage): Only when a newusermessage arrives are the<think>blocks from earlier user turns stripped from the prompt—while all historical tool calls and tool outputs remain preserved in the transcript.
Tracing a two-turn debugging session shows exactly what stays in context at each step:
Turn 1, Step 1:
user: "Fix the failing date-parser test in tests/test_parser.py."
assistant: <think>[Plan A: inspect test_parser.py]</think>
<tool_call>read_file("tests/test_parser.py")</tool_call>
tool: "[file contents...]"
Turn 1, Step 2 (Reasoning from Step 1 is RETAINED):
assistant: <think>[Test expects ISO-8601 timezone offset; patch parser.py and run pytest]</think>
<tool_call>run_bash("pytest tests/test_parser.py")</tool_call>
tool: "1 passed in 0.12s"
Turn 1, Step 3 (Reasoning from Steps 1 & 2 is RETAINED):
assistant: <think>[Test passes; summarize fix]</think>
"I updated parse_tz() in parser.py to handle Z and ±HH:MM offsets."
Turn 2 (New user message arrives -> Turn 1 <think> blocks DROPPED, tool calls/outputs KEPT):
user: "Now add a unit test for leap-second timestamps."
Keeping <think> blocks intact across tool turns saves massive amounts of tokens and latency: instead of re-deriving why test_parser.py failed after every shell command, each subsequent <think> block picks up directly where the previous one left off. Dropping <think> blocks once the user asks a new question reclaims context space while leaving the concrete record of executed tool calls and outputs visible for future turns.
Why agent frameworks that fake tool outputs as user messages break thinking mode
Because this retention rule triggers specifically on "user" messages, it exposes a critical integration trap in third-party agent harnesses. Several popular coding agents (the report specifically flags Roo Code and Terminus in its evaluation setups) do not use native "tool" role messages; instead, they serialize tool execution results into a "user" message and send it back to the model.
Under DeepSeek-V3.2's chat template, injecting a tool output as role: "user" tricks the encoder into thinking a brand-new user turn has started—wiping out all prior <think> blocks after every single tool call and forcing the model to re-reason from scratch at every step. For frameworks that encode tool outputs as user messages, the authors explicitly recommend running V3.2 in non-thinking mode until the harness is updated to emit proper "tool" messages.
Cold-start bootstrapping: teaching the model to interleave thinking and tools
Before launching full-scale agentic RL, the base model has to learn the syntax and control flow of interleaved <think> blocks and <tool_call> invocations. At the start of post-training, the authors already had strong non-agentic reasoning traces (single-turn math/code <think> data) and non-thinking agent traces (multi-turn tool calls without <think>), but no natural corpus combining the two.
Rather than manually annotating thousands of multi-turn thinking-with-tools demonstrations, DeepSeek-V3.2 uses prompt-driven cold-start bootstrapping (illustrated in Report Appendix B, Figures 8–10):
- The model is given explicit system instructions detailing how to interleave
<think>tags with<|tool▁calls▁begin|>...<|tool▁calls▁end|>blocks, pause after emitting a tool call, wait for<|tool▁outputs▁begin|>...<|tool▁outputs▁end|>, and resume reasoning inside a fresh<think>block. - In the Appendix B example prompts, the model is instructed to use a Python interpreter tool during problem solving (with per-prompt sandbox constraints such as a 3-second execution timeout and a 20-call cap) before emitting a
\boxed{}final answer. - Even though zero-shot adherence to this composite format is initially noisy and brittle, the model succeeds often enough to seed the initial RL rollout buffer. Once GRPO takes over, positive outcome rewards rapidly reinforce valid interleaved formatting and prune away malformed calls.
Verifying message encoding with encoding_dsv32.py
The official repository ships a standalone Python reference encoder (encoding/encoding_dsv32.py) rather than a Jinja2 chat template, because the state-dependent <think> stripping logic depends on scanning the index of the last "user" message in the conversation array.
Before benchmarking or deploying DeepSeek-V3.2 in a custom agent loop, run a quick four-message sanity test through encode_messages:
- Pass
[user_1, assistant_think_tool_1, tool_output_1]withthinking_mode="thinking"and verify thatassistant_think_tool_1's<think>...</think>substring is present in the rendered prompt string. - Append
[assistant_final_1, user_2]and verify thatassistant_think_tool_1's<think>...</think>block is removed, while its<|tool▁calls▁begin|>and<|tool▁outputs▁begin|>blocks remain intact.
Also note a practical warning from the official model card: parse_message_from_completion_text in encoding_dsv32.py is a strict reference parser without defensive error recovery for truncated or malformed XML/special-token sequences. Production runtimes should wrap tool-call parsing in validation and retry handlers.
With the conversation format and cold-start mechanism in place, the next three chapters examine how DeepSeek-V3.2 builds the 85,267 training environments that turn this cold-start policy into a general, coding, and search agent.
Sources: Report §3.2.1–3.2.2 and Appendix B (sections/02-post.tex, sections/appendix.tex); official encoding_dsv32.py; pinned model card ("Chat Template" section). Continue with synthesizing general agent environments.
14. Synthesizing General Agent Environments
Training an agent to handle unfamiliar APIs and multi-step constraints requires thousands of interactive environments. While coding and web search have natural real-world substrates (GitHub repositories and the live web), general tool use—booking itineraries, managing enterprise databases, scheduling resources, or reconciling financial records—lacks a public corpus of interactive sandboxes with programmatic verifiers.
To fill that gap, DeepSeek-V3.2 builds an automated environment synthesis pipeline that generates self-contained sandboxes, custom toolsets, multi-constraint tasks, and deterministic Python verifiers from scratch. Every synthesized training instance is packaged as a four-part tuple:
Breaking down the 85,267 agent training prompts
Table 1 of the report summarizes the four environment families used in agentic RL:
| Agent domain | Environment source | Prompt source | Retained tasks |
|---|---|---|---|
| Code Agent | Real (GitHub repos) | Extracted (Issue–PR pairs) | 24,667 |
| Search Agent | Real (Search APIs) | Synthesized | 50,275 |
| General Agent | Synthesized (1,827 sandboxes) | Synthesized | 4,417 |
| Code Interpreter | Real (Jupyter notebooks) | Extracted | 5,908 |
| Total | 85,267 |
Summing the four rows () explains the paper's headline figure of "over 1,800 environments and 85,000 complex prompts": the 1,827 synthesized environments specifically house the 4,417 general-agent tasks, while the remaining 80,850 prompts execute against real software repositories, search APIs, and Jupyter kernels.
The four-stage synthesis loop for General Agent sandboxes
Generating a general-agent environment that is both nontrivial and guaranteed to be solvable follows a four-step agentic workflow powered by DeepSeek-V3.2 itself:
- Database construction: Given a seed task category (for example, multi-city itinerary planning), a synthesis agent uses bash and search tools inside a sandbox to gather or generate realistic domain tables—such as cities, hotels, restaurants, attractions, prices, ratings, and train schedules—and populates a local sandbox database.
- Toolset synthesis: The synthesis agent writes a suite of task-specific Python tool functions (e.g.,
list_hotels(city),get_restaurant_details(id),query_transport(origin, dest)) that query the underlying database. Crucially, the downstream policy being trained cannot read the raw database directly; it can only inspect state by invoking these documented tool interfaces. - Iterative task, solution, and verifier co-generation: The synthesis agent proposes an initial simple task alongside two Python functions: a reference
solution()function and averify(candidate)function. To prevent the reference solution from cheating,solution()is strictly restricted to calling the exposed tool functions and performing in-memory logic—it is forbidden from reading the database files directly or importing privileged helpers. The pipeline executessolution()and checks whether its return value passesverify(). Once validated, the synthesis agent iteratively layers on harder constraints, updatingsolution(),verify(), and the toolset in lockstep whenever the current tools prove insufficient. - Pass@100 reachability filtering: Finally, the pipeline runs 100 rollout attempts per task with DeepSeek-V3.2 and discards any task where pass@100 is zero—retaining only the 1,827 environments and 4,417 tasks where the model achieves at least one verified success out of 100 tries.
Requiring both a tool-restricted reference solution() and a nonzero pass@100 filters out impossible or contradictory prompts that would otherwise waste RL compute with all-zero reward groups.
Why constraint satisfaction is hard to search but cheap to verify
The core design principle of the synthesis pipeline is asymmetric complexity: finding a valid solution requires exploring a combinatorial state space across dozens of tool calls, whereas verifying a proposed solution takes a few lines of deterministic Python.
Consider the three-day travel itinerary task described in Section 3.2.3 of the report:
- Global uniqueness and consistency: Pick 3 distinct cities (one per day), 1 hotel, 1 attraction, and 2 distinct restaurants (lunch and dinner) per day, with zero repeated establishments across the trip and every establishment located in that day's assigned city.
- Interdependent conditional budget on Day 2:
- Branch A (Luxury hotel, price ): Combined Day 2 lunch + dinner price must stay , both restaurants must have rating , and the attraction ticket must be .
- Branch B (Mid-range hotel, price ): Combined lunch + dinner price , at least one restaurant rating .
- Branch C (Budget hotel, price ): Combined lunch + dinner price .
For the agent solving the task, discovering a valid Day 2 package requires querying hotels in candidate cities, branching on the hotel price tier, fetching restaurant menus and ratings, and backtracking whenever a city has luxury hotels with -rated restaurants whose combined price exceeds 350 CNY.
For the verifier, grading the submitted three-day JSON plan is a simple lookup:
def verify_itinerary(plan, db):
if len(plan) != 3 or not all_ids_unique(plan):
return False
for day in plan:
if not all_located_in_city(day, db):
return False
day2 = plan[1]
h_price = db.hotels[day2.hotel_id].price
r1, r2 = db.restaurants[day2.lunch_id], db.restaurants[day2.dinner_id]
t_price = db.attractions[day2.attraction_id].price
if h_price >= 800:
return (r1.price + r2.price <= 350) and (r1.rating >= 4.0 and r2.rating >= 4.0) and (t_price < 120)
elif h_price >= 500:
return (r1.price + r2.price <= 500) and max(r1.rating, r2.rating) >= 4.2
else:
return (r1.price + r2.price <= 600)
For example, if an agent proposes a Day 2 luxury hotel at 900 CNY, lunch at 160 CNY (rating 4.2), dinner at 180 CNY (rating 4.1), and an attraction at 100 CNY, the combined restaurant spend is and every Branch A condition passes. If dinner instead costs 195 CNY, the combined restaurant bill hits 355 CNY and verify_itinerary returns False immediately.
Potential failure modes of synthetic environments
While co-generating solution() and verify() eliminates most broken tasks, two edge cases always warrant attention in synthetic data pipelines:
- Correlated specification bugs: If the synthesis agent misinterprets an ambiguous phrase in its own natural-language prompt (such as whether "500–800 CNY" includes 800.00 CNY) and writes the exact same off-by-one boundary into both
solution()andverify(), the self-consistency check will pass even though the prompt text is ambiguous to the student model. - Survivorship bias from pass@100 filtering: Discarding tasks with removes broken tasks, but also drops valid tasks that require more than 100 trials for the current checkpoint to stumble across a solution.
As we will see in Chapter 17, training on these 4,417 synthetic general-agent tasks transfers directly to held-out out-of-distribution tool benchmarks like MCP-Mark, Tau2Bench, and Toolathlon—confirming that the model learns generalizable tool-exploration and constraint-tracking habits rather than memorizing the 1,827 sandbox schemas.
Sources: Report §3.2.3, Table 1 and "General Agent" (sections/02-post.tex). Continue with coding agents and code interpreters.
15. Coding Agents and Code Interpreters
Software engineering provides one of the cleanest reward signals in reinforcement learning: compile the code and run the test suite. Turning raw GitHub history into a reliable RL training environment, however, requires far more than scraping pull-request diffs. Every candidate repository must build cleanly inside an isolated container, reproduce the exact bug before the fix is applied, and pass both the new bug-fix tests and the existing regression suite once the patch is applied.
DeepSeek-V3.2 splits its code-executing RL environments into two distinct categories (Table 1 of the report): 24,667 Code Agent tasks built from real multi-language GitHub repositories, and 5,908 Code Interpreter tasks executed inside stateful Jupyter notebooks.
| Task family | Retained count | Execution environment | Primary skill trained |
|---|---|---|---|
| Code Agent | 24,667 | Containerized multi-file software repositories | Repository navigation, root-cause diagnosis, patch authoring, regression testing |
| Code Interpreter | 5,908 | Stateful Jupyter notebook kernels | Translating mathematical, logical, and data-science problems into executable Python |
Mining and filtering millions of GitHub Issue–PR pairs
To construct the 24,667 Code Agent environments, the pipeline starts from millions of historical GitHub Issue–Pull Request pairs across eight programming languages: Python, Java, JavaScript, TypeScript, C, C++, Go, and PHP. Heuristic rules and LLM filters narrow that raw pool down to candidate pairs that contain:
- A clear, self-contained issue description (which becomes the task prompt).
- A correlated gold code patch (the actual implementation diff that resolved the issue).
- A test patch (the unit or integration test diff added or updated in the PR to verify the fix).
Filtering out noisy PRs—such as sweeping refactors, dependency bumps, documentation edits, or issues whose reproduction steps live in external screenshots—is essential before spending compute on container builds.
Automated container building and JUnit normalization
Even a well-written GitHub PR is useless for RL if its dependencies fail to install or its test runner crashes. Rather than writing manual Dockerfiles for thousands of repositories, DeepSeek uses an automated environment-setup agent powered by DeepSeek-V3.2 to provision each candidate repository at its pre-PR commit:
- The setup agent inspects the repository's build manifests (
pyproject.toml,package.json,pom.xml,CMakeLists.txt,go.mod,composer.json), installs system and language packages, resolves version conflicts, and runs the test suite. - Across all eight languages and their diverse test runners (
pytest,maven/gradle,jest,ctest,go test,phpunit), the setup agent normalizes test execution outputs into a single standardized JUnit XML report so the RL verifier can parse pass/fail counts uniformly.
The F2P and P2F differential acceptance test
Simply getting a test runner to exit without crashing does not prove an environment is a valid RL task. The pipeline validates every container using two transition metrics measured by applying the PR's test patch before and after the gold code patch:
- Fail-to-Pass (F2P): Tests that fail on the base commit (with the test patch applied) and pass after the gold code patch is applied.
- Pass-to-Fail (P2F): Tests that pass on the base commit and fail after the gold code patch is applied (indicating a broken environment or regression).
A candidate environment is accepted into the training pool if and only if applying the gold patch yields:
Tracing three tests inside a candidate container illustrates how this rule filters out broken setups:
| Test case | Base commit + Test patch | Base commit + Test patch + Gold patch | Classification |
|---|---|---|---|
test_issue_412_timezone_z |
FAIL | PASS | F2P (proves the test catches the bug and the gold patch fixes it) |
test_standard_iso_dates |
PASS | PASS | Preserved regression test (must stay passing) |
test_locale_formatting |
PASS | FAIL | P2F (disqualifies the environment: gold patch broke an existing test) |
Requiring guarantees that the test patch actually reproduces the reported bug and is solvable by a known patch; requiring ensures the environment is deterministic and free of flaky tests that fail randomly between runs.
What the policy learns inside a repository sandbox
During RL rollouts, the gold patch is hidden; the agent receives only the issue description and bash/file-editing tools inside the pre-PR container. Because a repository may contain hundreds of thousands of lines of code, the agent cannot dump the entire codebase into its context window. Instead, it has to learn an interactive debugging loop:
- Search the directory tree (
grep/find) to locate the modules implicated by the issue description. - Read the relevant source and test files into context.
- Formulate a root-cause hypothesis inside its
<think>block and apply a minimal edit. - Run the local test suite to see whether its patch resolves the failure without breaking existing tests, using compiler errors or stack traces to iterate if the first attempt fails.
Code Interpreter environments: stateful Jupyter notebooks
The 5,908 Code Interpreter tasks target a different workflow: using an interactive Jupyter notebook kernel to solve competition math, logic puzzles, and data-analysis problems.
Unlike stateless one-shot script execution, a Jupyter kernel preserves variables, imports, and data structures in memory across cell executions. If Cell 1 loads a dataset or precomputes a prime sieve into variable primes, Cell 2 can inspect and slice primes directly without recomputing it. At the same time, stateful execution forces the agent to manage mutable state carefully: if an earlier cell mutates a list in place or times out mid-loop, subsequent cells inherit that mutated state.
Code interpreter tasks also train the model to combine symbolic reasoning with computational verification—for instance, deriving a closed-form combinatorial formula in <think>, writing a 10-line Python brute-force script to enumerate small cases, checking whether the formula matches the enumeration, and revising the derivation when a mismatch appears.
As with any test-driven environment, container hygiene is paramount: the sandbox must strictly isolate the git history and remote remotes so the agent cannot simply run git log --all or fetch the gold PR commit from GitHub during a rollout.
Sources: Report §3.2.3, "Code Agent," "Code Interpreter Agent," and Table 1 (sections/02-post.tex); Report Appendix B (cold-start interpreter prompts). Continue with search agents and difficult questions.
16. Search Agents and Difficult Questions
A capable search agent has to recognize when its parametric memory is insufficient, formulate targeted search queries, cross-check conflicting web snippets, and synthesize a grounded answer. If a training prompt can be answered directly from pre-training memorization—or solved with a single obvious keyword lookup—reinforcement learning will never pressure the model to plan multi-hop searches.
To train DeepSeek-V3.2 on genuinely demanding retrieval problems, the authors construct 50,275 search-agent tasks (the largest domain in Table 1) using an automated multi-agent synthesis and adversarial filtering pipeline executed against real commercial search APIs, supplemented by rubric-graded helpfulness tasks.
Step 1: Sampling long-tail entities
To prevent the policy from coasting on memorized facts about famous people, landmarks, or events, the pipeline starts by sampling informative long-tail entities across diverse domains from large-scale web corpora. Because obscure entities appear rarely in pre-training data, answering fine-grained questions about their attributes almost always requires live tool use.
Step 2: Configurable depth-and-breadth exploration
Next, a question-construction agent equipped with search tools explores each seed entity using configurable depth and breadth parameters:
- Depth (multi-hop chaining): The agent follows relational links across multiple search steps—for instance, starting from a regional literary prize, finding the winning novel in a specific year, identifying the translator of its foreign edition, and looking up the university where that translator earned their doctorate.
- Breadth (multi-source synthesis): The agent gathers multiple attributes or compares related entities across distinct sources, consolidating the discovered facts into a complex question–answer pair whose resolution requires combining several search observations.
Step 3: Adversarial filtering with heterogeneous answer agents
Not every synthesized multi-hop question is actually hard; a clever single query might still surface a Wikipedia summary table containing the answer on the first turn. To filter out easy or flawed questions, the pipeline subjects every candidate pair to a panel of heterogeneous answer-generation agents alongside a multi-pass search-enabled verifier:
- Heterogeneous candidate generation: Multiple answer agents—configured with different model checkpoints, system prompts, and sampling strategies—attempt to solve . Varying the checkpoints and prompts ensures that a question isn't kept merely because one specific prompt template stumbled on a formatting quirk.
- Multi-pass search verification: A dedicated verification agent with search access runs multiple verification passes on both the proposed ground-truth answer and all candidate answers produced by the heterogeneous panel.
- Strict retention rule: A sample is retained in the RL training set if and only if the ground truth is verified as correct and every candidate answer from the heterogeneous panel is verifiably incorrect.
Requiring all panel candidates to fail guarantees that the retained 50,275 prompts sit at the frontier of current capability, while multi-pass verification of filters out ambiguous questions, outdated web claims, or hallucinated ground truths.
To see why both filters are necessary, consider a question asking for the birthplace of the translator of a specific 1998 edition of a novel. Without entity-resolution care, an agent might confuse the 1998 translator with the better-known 1974 translator, confuse the translator with the foreword author, or trust an unsourced blog snippet. Only questions that defeat shallow single-hop retrieval while admitting an unambiguous, verifiable ground-truth entity survive into the RL training buffer.
Blending exact-match verification with helpfulness rubrics
Training exclusively on short-answer multi-hop trivia carries a well-known failure mode: the assistant learns to emit terse, one-word benchmark answers ("Kyoto") even when a real user asks an open-ended research question requiring context, citations, and trade-off analysis.
To make the search agent useful in production conversations, the authors augment the verifiable short-answer dataset with filtered helpfulness-oriented RL queries—prompts where live web search measurably improves response quality. During RL, these open-ended search trajectories are graded by a generative reward model using detailed multi-dimensional rubrics (covering factual grounding, coverage, organization, and citation accuracy) alongside the rule-based outcome rewards used for short-answer tasks.
Runtime dependencies in search evaluation
Unlike self-contained math or repository-container tasks, search-agent rollouts interact with a live external search engine (the report uses a standard commercial search API in its evaluations). That introduces two systems variables that any evaluation or reproduction must account for:
- Index drift and API behavior: Commercial search engines continuously update their indices, ranking algorithms, and snippet lengths, meaning the exact top-10 snippets returned for a query today may differ from those returned during the December 2025 evaluation run.
- Webpage bloat and context overflow: Because fetched web pages and search batches often dump thousands of tokens of HTML/markdown text into each
toolobservation, search trajectories fill the 128K context window faster than almost any other workload—over 20% of BrowseComp trajectories exceed 128K tokens if left unmanaged. Chapter 18 examines how DeepSeek-V3.2's context-management strategies handle that overflow at test time.
Sources: Report §3.2.3, "Search Agent" and Table 1 (sections/02-post.tex); Report §4.1 search evaluation notes. Continue with what the synthesis experiments establish.
17. What the Synthesis Experiments Establish
Synthesizing 1,827 sandbox environments and 4,417 general-agent tasks (Chapter 14) only pays off if two hypotheses hold:
- The synthesized tasks are genuinely difficult, challenging frontier models rather than testing trivial API calls.
- RL training on those synthetic sandboxes transfers out-of-distribution, improving performance on unfamiliar third-party agent benchmarks whose tool schemas and domains were never seen during training.
In Section 4.3 of the report, the authors test both hypotheses directly through a 50-task difficulty audit and a controlled RL ablation starting from the supervised fine-tuned checkpoint (DeepSeek-V3.2-SFT).
Experiment 1: Auditing task difficulty on 50 sampled instances
To measure how hard the synthesized general-agent tasks are, the authors draw a random sample of 50 task instances from the retained general-agent dataset and evaluate four models across , , and :
| Metric | DeepSeek-V3.2-Exp | Claude-4.5-Sonnet | Gemini-3.0-Pro | GPT-5-Thinking |
|---|---|---|---|---|
| Pass@1 | 12% | 34% | 51% | 62% |
| Pass@2 | 18% | 47% | 65% | 75% |
| Pass@4 | 26% | 62% | 74% | 82% |
Notice first that the DeepSeek baseline in Column 1 is DeepSeek-V3.2-Exp (prior to the new synthetic general-agent RL pipeline), which solves only 12% of the sampled tasks on the first try and 26% within four tries. Even the strongest frontier baseline tested—GPT-5-Thinking—fails 38% of the tasks at and 18% at .
Why empirical scales sub-independently across tasks
Recall that measures the probability that at least one of sampled trajectories passes the environment verifier. If every task in the benchmark shared an identical, independent per-attempt success probability , then drawing independent attempts would yield a theoretical success rate of:
In Table 3, however, DeepSeek-V3.2-Exp's actual is 26%, well below 40%. That gap is a classic signature of heterogeneous task difficulty: when a benchmark contains a mix of moderate tasks () and very hard tasks (, which survived the filter in Chapter 14 by succeeding once or twice in 100 rollouts), the Jensen inequality guarantees that . (When estimating from rollouts containing successes per problem, standard evaluation harnesses use the unbiased combinatorial estimator .)
Also keep the sample size in mind when reading small percentage shifts: on a 50-problem sample (), a single problem flips the score by percentage points, and the binomial standard error near is roughly percentage points. Even with that sampling noise, the 50-point spread between V3.2-Exp (12%) and GPT-5-Thinking (62%) clearly establishes that the synthesis pipeline creates demanding multi-step constraint problems.
Experiment 2: Out-of-distribution transfer from synthetic-only RL
To isolate whether RL on the 4,417 synthetic general-agent tasks actually teaches transferable agent skills—rather than riding on the coattails of extended <think> scratchpads or coding/search RL—the authors run a clean ablation starting from DeepSeek-V3.2-SFT in non-thinking mode:
- Intervention run (blue curves): RL trained exclusively on the synthesized general-agent tasks, with thinking mode disabled.
- Baseline 1 (
V3.2-SFTdashed line): The starting SFT checkpoint before RL. - Baseline 2 (
V3.2-Expdashed line): A checkpoint that underwent RL only in coding and search environments, without synthetic general-agent environments.
Reproduced from Report Figure 5 (figures/synthesis-rl-plot.png). Training curves track non-thinking evaluation accuracy across RL steps on -bench (Airline, Retail, Telecom, Overall), MCP-Mark (Filesystem, Postgres, Overall), and MCP-Universe (Location Navigation, Repository Management, Financial Analysis, Browser Automation, Web Searching, Overall).
The twelve subplots in Figure 5 isolate two striking findings:
- Coding and search RL alone do not transfer to general tool use: Comparing the two horizontal dashed lines shows that
V3.2-Exp(trained with RL on real GitHub repositories and search APIs) barely budges—and in several categories slightly trails—V3.2-SFTon -bench, MCP-Mark, and MCP-Universe. Mastering bash, pytest, and web search does not automatically teach an agent how to navigate stateful airline-reservation policies or MCP database schemas. - Synthetic general-agent RL transfers across held-out domains: Even in non-thinking mode, running GRPO solely on the 1,827 synthetic sandboxes drives steady gains over both
V3.2-SFTandV3.2-Expacross -bench (rising roughly 10+ points overall), MCP-Mark (Filesystem and Postgres), and MCP-Universe.
What skills transfer across unfamiliar tool schemas?
Because the tool definitions, database schemas, and domain rules of -bench, MCP-Mark, and MCP-Universe were never seen during synthetic sandbox generation, the improvements in Figure 5 cannot come from memorizing function names. Instead, RL on verifiable constraint-satisfaction sandboxes pressures the policy to internalize domain-agnostic operational habits:
- Inspecting tool docstrings and parameter types carefully before issuing a state-modifying call.
- Querying all relevant records (such as checking all three days of an itinerary or all linked customer tables) before committing to an action.
- Cross-checking conditional rules ("if tier , verify condition X; else verify condition Y") against returned tool payloads.
- Recovering from tool error messages by adjusting arguments rather than repeating the exact same failing call.
While this ablation cleanly establishes that synthetic general-agent RL drives large out-of-distribution gains over SFT and code/search-only RL, note that once an agent scales up to dozens of tool turns in production, it eventually runs into the 128K context ceiling—the problem addressed in Chapter 18.
Sources: Report §4.3 (sections/05-thinking-with-tool.tex, Table 3, and figures/synthesis-rl-plot.png). Continue with context management and test-time scaling.
18. Context Management and Test-Time Scaling
Even with a 128K context window and DeepSeek Sparse Attention, multi-turn search agents routinely run out of context space. On BrowseComp—a demanding deep-search benchmark where each tool call fetches bulky web snippets and page dumps—the authors report that over 20% of trajectories exceed the 128K token limit before the agent can finalize an answer.
When an agent approaches the edge of its context window, the runtime has to decouple per-step context capacity (capped at 128K tokens) from total test-time task compute (which can span hundreds of tool steps and hundreds of thousands of cumulative tokens). In Section 4.4 of the report, the authors evaluate four test-time scaling strategies on BrowseComp: three serial context-management policies that free up space mid-trajectory, and one parallel trajectory baseline.
Triggering context management at the 80% watermark
Waiting until token 131,072 to intervene leaves zero room for the next tool response or final answer. Instead, DeepSeek-V3.2's serial context-management policies trigger whenever the active transcript crosses 80% of the context window (roughly tokens).
Once a trajectory crosses that 80% watermark, the runtime applies one of three serial compaction rules to the accumulated tool history:
- Summary: The model generates a natural-language summary of the overflowing trajectory—compressing the entities found, hypotheses tested, and remaining questions—and restarts the rollout seeded with that summary in place of the raw tool history.
- Discard-75%: The runtime drops the oldest 75% of the tool-call history in place, keeping the original user prompt and the most recent 25% of tool calls and observations so the agent can continue without paying the latency of a summarization call.
- Discard-all: The runtime wipes 100% of the previous tool-call history, resetting the context back to the initial prompt so the agent starts a fresh search trajectory from scratch inside the same serial run.
As a fourth comparison point, the authors evaluate a pure parallel-scaling baseline without serial context resets:
- Parallel-fewest-step: The runtime samples independent trajectories in parallel and selects the completed trajectory that finishes in the fewest steps.
Comparing accuracy vs. step efficiency on BrowseComp
Reproduced from Report Figure 6 (figures/search.pdf). Curves plot BrowseComp accuracy against average real tool steps Executed under Summary, Discard-75%, Discard-all, and Parallel-fewest-step.
Comparing the trajectories in Figure 6 reveals several counterintuitive lessons about long-horizon search agents:
- Context management lifts BrowseComp by 16.2 percentage points: In the main evaluation table (Table 2), DeepSeek-V3.2-Thinking scores 51.4% on BrowseComp inside a single unmanaged 128K window, and jumps to 67.6% when Discard-all context management is enabled.
- Summary stretches step counts but lags in accuracy and efficiency: While Summary extends the average trajectory length to 364 steps and lifts accuracy to 60.2%, it underperforms both discard policies on accuracy-per-step. When a model summarizes 100K tokens of noisy web searches into a short paragraph, it frequently drops subtle negative evidence ("Source X was already checked and did not contain the date") or calcifies a mistaken intermediate guess into an authoritative-sounding summary statement that misleads the next segment.
- Discard-all matches parallel scaling at a fraction of the compute: Discard-all reaches 67.6% accuracy while using far fewer cumulative real steps than Parallel-fewest-step.
Why wiping the history (Discard-all) beats keeping a summary
At first glance, Discard-all looks paradoxical: if you throw away 100% of the previous tool calls when the context hits 80% capacity, how is that any different from simply failing and restarting?
First, in a stochastic policy (temperature 1.0), a trajectory that burns through 105,000 tokens of web searches without finding the answer is almost always trapped in a dead-end rabbit hole—chasing a mistaken entity disambiguation or issuing repetitive variations of a failing query. Keeping the last 25% of those dead-end tool outputs (Discard-75%) or summarizing them (Summary) keeps conditioning the model on the very distraction that caused the trajectory to stall. Wiping the tool history (Discard-all) breaks that path dependence immediately, giving the policy a clean slate to draw a fresh initial search plan.
Second, unlike Parallel-fewest-step—which blindly spawns trajectories upfront for every question, including the 80% of questions that succeed on the first try within a single 128K window—Discard-all allocates extra retry compute adaptively, spending a second or third 105K-token attempt only on the hard queries that actually overflow the 80% watermark.
Why Discard-all works for read-only search, not stateful coding
Before applying Discard-all to every agent workload, notice a crucial systems distinction between read-only environments (like web search) and state-mutating environments (like repository editing or database transactions):
- In BrowseComp, search queries are idempotent and side-effect-free; wiping the transcript resets the state completely.
- In a coding container or enterprise database, if an agent edits three files, runs a migration script, hits 80% context capacity, and wipes its tool history via
Discard-all, the container filesystem still has the modified files even though the agent has forgotten making the edits! In stateful environments, an agent after a full transcript reset must either inspectgit status/git diffto rediscover its workspace state, or the runtime must pair context resets with container snapshots/rollbacks.
As the authors note, combining adaptive serial context management with parallel candidate verification—so an agent can allocate both sequential depth and parallel breadth dynamically—is a natural next step for test-time scaling.
Sources: Report §4.4 (sections/03-seach-agent.tex, Figure 6 / figures/search.pdf); Report §4.1 and Table 2 (tables/eval_main.tex). Continue with reading the reasoning benchmarks.
19. Reading the Reasoning Benchmarks
In Section 4 of the report, DeepSeek-V3.2 is evaluated across general knowledge, graduate-level science, competition mathematics, and competitive programming. Before comparing headline numbers against GPT-5-High or Gemini-3.0-Pro, it helps to examine the exact evaluation protocol, prompt templates, and token budgets behind Table 2.
Evaluation protocol and prompt sensitivity
All reasoning benchmarks in Table 2 run at temperature 1.0 with a 128K context window. For mathematical and scientific reasoning benchmarks—specifically AIME 2025, HMMT (Feb & Nov 2025), IMOAnswerBench, and Humanity's Last Exam (HLE)—the evaluation harness appends a lightweight formatting instruction:
{question}\nPlease reason step by step, and put your final answer within \boxed{}.
Prompt formatting matters more than casual readers often realize. In a footnote to Section 4.1, the authors note that evaluating DeepSeek-V3.2-Thinking on text-only HLE with the benchmark's official default template yields 23.9%, whereas using the \boxed{} step-by-step instruction above yields 25.1%—a 1.2-percentage-point swing from a one-line prompt suffix on the exact same checkpoint.
Similarly, time-windowed benchmarks depend on their exact cutoff dates: the report's LiveCodeBench (2408–2504) column specifically evaluates problems released between August 2024 and April 2025 in Chain-of-Thought (CoT) mode.
Main reasoning and coding benchmark results
Table 2 of the report compares DeepSeek-V3.2 (Thinking) against leading closed- and open-weights reasoning models as of December 2025 (full table in the report also includes Claude-4.5-Sonnet and MiniMax-M2):
| Benchmark | Metric | DeepSeek-V3.2 (Thinking) | GPT-5-High | Gemini-3.0-Pro | Kimi-K2-Thinking |
|---|---|---|---|---|---|
| MMLU-Pro | Exact Match (%) | 85.0 | 87.5 | 90.1 | 84.6 |
| GPQA Diamond | Pass@1 (%) | 82.4 | 85.7 | 91.9 | 84.5 |
| HLE (Text-only, no tools) | Pass@1 (%) | 25.1 | 26.3 | 37.7 | 23.9 |
| LiveCodeBench (2408–2504) | Pass@1-CoT (%) | 83.3 | 84.5 | 90.7 | 82.6 |
| Codeforces | Rating | 2,386 | 2,537 | 2,708 | — |
| AIME 2025 | Pass@1 (%) | 93.1 | 94.6 | 95.0 | 94.5 |
| HMMT Feb 2025 | Pass@1 (%) | 92.5 | 88.3 | 97.5 | 89.4 |
| HMMT Nov 2025 | Pass@1 (%) | 90.2 | 89.2 | 93.3 | 89.2 |
| IMOAnswerBench | Pass@1 (%) | 78.3 | 76.0 | 83.3 | 78.6 |
Dissecting the capability profile: math vs. broad world knowledge
Looking across the rows of Table 2 reveals a clear split between deductive reasoning and parametric knowledge breadth:
- Near-parity with GPT-5-High on math and competitive coding: On AIME 2025 (93.1 vs. 94.6) and LiveCodeBench (83.3 vs. 84.5), V3.2-Thinking sits within 1.5 percentage points of GPT-5-High, and it outperforms GPT-5-High on HMMT Feb 2025 (+4.2 points), HMMT Nov 2025 (+1.0 point), and IMOAnswerBench (+2.3 points).
- Gap on broad factual and encyclopedic benchmarks: On MMLU-Pro (85.0 vs. 90.1), GPQA Diamond (82.4 vs. 91.9), and text-only HLE (25.1 vs. 37.7), V3.2 trails Gemini-3.0-Pro and GPT-5-High. As the authors note in Section 5, no amount of chain-of-thought reasoning can deduce an obscure domain fact that is missing from the model's weights, and they attribute this knowledge-breadth gap to spending fewer total pre-training FLOPs than massive proprietary frontier runs.
- How search tools change HLE: Notice that text-only HLE in Table 2 is 25.1% without tools; when V3.2-Thinking is given search tools in the agent section of Table 2, its HLE score jumps by 15.7 points to 40.8%, confirming that much of the text-only HLE deficit stems from long-tail factual recall rather than reasoning failure.
Also keep the distinction between short-answer Olympiad benchmarks and full proof grading in mind: AIME, HMMT, and IMOAnswerBench verify a final numerical or algebraic expression inside \boxed{}. A model can guess a pattern from small cases and get full credit on IMOAnswerBench without writing a rigorous proof. Full proof verification on IMO 2025 and CMO 2025 requires the dedicated DeepSeek-V3.2-Speciale pipeline analyzed in Chapter 21.
Token efficiency: accuracy per thousand generated tokens
Benchmark accuracy alone hides how much test-time compute a model burns to get its answer. In Table 4 of the report (examined alongside Speciale in Chapter 21), the authors report both accuracy and average output length (in thousands of tokens) across reasoning benchmarks:
| Benchmark | DeepSeek-V3.2 (Thinking) Score / Tokens | Kimi-K2-Thinking Score / Tokens | Gemini-3.0-Pro Score / Tokens |
|---|---|---|---|
| AIME 2025 | 93.1% (16K) | 94.5% (24K) | 95.0% (15K) |
| HMMT Feb 2025 | 92.5% (19K) | 89.4% (31K) | 97.5% (16K) |
| LiveCodeBench | 83.3% (16K) | 82.6% (29K) | 90.7% (13K) |
| Codeforces | 2,386 (29K) | — | 2,708 (22K) |
Compared to Kimi-K2-Thinking, DeepSeek-V3.2 achieves higher scores on HMMT Feb 2025 (+3.1 points) and LiveCodeBench (+0.7 points) while generating 39% to 45% fewer output tokens (19K vs. 31K on HMMT; 16K vs. 29K on LiveCodeBench). Compared to Gemini-3.0-Pro, however, V3.2 still uses slightly more tokens (16K–29K vs. 13K–22K) for lower accuracy—the exact token-efficiency gap that motivates branching DeepSeek-V3.2-Speciale to see what happens when V3.2's length penalty is relaxed.
Parity check: DeepSeek-V3.1-Terminus vs. DeepSeek-V3.2-Exp
Finally, remember the architectural baseline from Chapters 5–6: before running this new post-training pipeline, the authors validated that converting dense MLA (V3.1-Terminus) to sparse DSA (V3.2-Exp) under matched post-training recipes caused no degradation across short- and long-context evaluations (such as AA-LCR and Fiction.liveBench) or ChatbotArena Elo ratings. That parity check ensures that the capability profile in Table 2 reflects a genuine combination of lossless sparse attention and scaled post-training RL.
Sources: Report §2.2, §4.1, and §4.2 (sections/01-method.tex, sections/02-post.tex, sections/06-high.tex; tables/eval_main.tex). Continue with reading the agent benchmarks.
20. Reading the Agent Benchmarks
Evaluating an agent never measures a language model in a vacuum: every score reflects the coupled system of model checkpoint + chat encoder + agent scaffold + tool runtime + context-management policy. Change how the scaffold formats tool outputs, or swap out the context-reset policy, and the exact same model weights can swing by 10 to 16 percentage points.
In Section 4.1 and Appendix C of the report, the authors document the exact harness conditions behind DeepSeek-V3.2's coding, search, and general tool-use evaluations.
Main coding, search, and tool-use benchmark results
Table 2 of the report compares DeepSeek-V3.2 (Thinking) against closed- and open-weights baselines across eleven agent evaluations (the full table in the report also includes Claude-4.5-Sonnet, which reaches 77.2% on SWE-bench Verified and 38.6% on Tool-Decathlon, as well as MiniMax-M2):
| Benchmark | DeepSeek-V3.2 (Thinking) | GPT-5-High | Gemini-3.0-Pro | Kimi-K2-Thinking |
|---|---|---|---|---|
| Terminal Bench 2.0 | 46.4 | 35.2 | 54.2 | 35.7 |
| SWE-bench Verified | 73.1 | 74.9 | 76.2 | 71.3 |
| SWE-bench Multilingual | 70.2 | 55.3 | — | 61.1 |
| BrowseComp (no context mgmt) | 51.4 | 54.9 | — | — |
| BrowseComp (with context mgmt) | 67.6 | — | — | 60.2 |
| BrowseCompZh | 65.0 | 63.0 | — | 62.3 |
| HLE (with search & Python tools) | 40.8 | 35.2 | 45.8 | 44.9 |
| -bench | 80.3 | 80.2 | 85.4 | 74.3 |
| MCP-Universe | 45.9 | 47.9 | 50.7 | 35.6 |
| MCP-Mark | 38.0 | 50.9 | 43.1 | 20.4 |
| Tool-Decathlon (Toolathlon) | 35.2 | 29.0 | 36.4 | 17.6 |
How agent scaffolds interact with Thinking Mode
The footnotes and Appendix C tables for Terminal Bench 2.0 and SWE-bench provide a textbook case study in why scaffold details matter:
- Terminal Bench 2.0 scaffold mismatch: As we saw in Chapter 13, Terminal Bench's default Terminus agent scaffold serializes tool execution outputs into
role: "user"messages, which triggers DeepSeek-V3.2's chat template to strip all prior<think>blocks after every command. Consequently, the Table 2 headline score of 46.4% for V3.2-Thinking is evaluated using the Claude Code framework (which preservestoolroles properly). - Disentangling scaffold from thinking mode on Terminal Bench: Across Table 2 and Appendix C (
tables/nonthink.tex), the report gives three distinct Terminal Bench 2.0 numbers for DeepSeek-V3.2:
| Thinking mode | Agent scaffold | Terminal Bench 2.0 score |
|---|---|---|
| Thinking | Claude Code | 46.4% |
| Non-Thinking | Claude Code | 37.1% |
| Non-Thinking | Terminus | 39.3% |
Comparing 46.4% vs. 37.1% (both inside Claude Code) isolates the true +9.3-percentage-point gain from retained <think> blocks on complex terminal tasks, whereas comparing 46.4% (Claude Code) directly against 39.3% (Terminus) confounds thinking mode with a scaffold change.
- SWE-bench Verified robustness across scaffolds: The headline 73.1% score on SWE-bench Verified uses DeepSeek's internal coding scaffold, and the authors verify that switching across Claude Code, RooCode, and non-thinking settings yields a tight band between 72% and 74%. On SWE-bench Multilingual, V3.2 reaches 70.2%, substantially ahead of GPT-5-High (55.3%) and Kimi-K2-Thinking (61.1%), reflecting the eight-language container training pipeline covered in Chapter 15.
Thinking vs. Non-Thinking across agent benchmarks
Appendix C (tables/nonthink.tex) compares DeepSeek-V3.2 in Thinking versus Non-Thinking mode under matched scaffolds across seven agent benchmarks:
| Benchmark | Non-Thinking | Thinking | Gain from Thinking (percentage points) |
|---|---|---|---|
| Terminal Bench 2.0 (Claude Code) | 37.1 | 46.4 | +9.3 |
| SWE-bench Verified | 72.1 | 73.1 | +1.0 |
| SWE-bench Multilingual | 68.9 | 70.2 | +1.3 |
| -bench | 77.2 | 80.3 | +3.1 |
| MCP-Universe | 38.6 | 45.9 | +7.3 |
| MCP-Mark | 26.5 | 38.0 | +11.5 |
| Tool-Decathlon | 25.6 | 35.2 | +9.6 |
Look at where <think> blocks make the biggest difference: on SWE-bench Verified and Multilingual, non-thinking mode already captures ~98.5% of the full thinking performance (72.1% vs. 73.1%), making non-thinking mode an attractive low-latency option for standard repository repair. On unfamiliar, multi-constraint MCP tool suites (MCP-Mark +11.5 points, Tool-Decathlon +9.6 points, Terminal Bench +9.3 points, MCP-Universe +7.3 points), explicit multi-turn <think> planning drives nearly a 10-point jump in task resolution.
Environment details: -bench, MCP harnesses, and redundant verification
Three additional protocol details in Section 4.1 help put the general tool-use numbers in context:
- -bench category breakdown and user simulator: On -bench, the evaluation uses the tested model itself as the simulated user agent. DeepSeek-V3.2-Thinking scores 63.8% on Airline, 81.1% on Retail, and 96.2% on Telecom, whose unweighted average is (reported as 80.3%).
- Internal MCP environment alignment: For MCP-Universe and MCP-Mark, all models in Table 2 are evaluated inside DeepSeek's internal sandbox environment (where search API and Playwright browser configurations differ slightly from the official upstream harnesses) with tool outputs strictly formatted in the
"tool"role. - Context exhaustion from redundant self-verification: While V3.2 narrows the gap with proprietary frontier models across tool benchmarks, it still trails GPT-5-High on MCP-Mark (38.0% vs. 50.9%) and Gemini-3.0-Pro on MCP-Universe (45.9% vs. 50.7%). Investigating the failure traces, the authors note that on complex stateful tasks—particularly MCP-Mark GitHub and Playwright—V3.2 frequently gets stuck in redundant self-verification steps, inflating trajectory lengths until the transcript overflows the 128K context window and fails the task.
That trade-off between giving a model room to verify its work and keeping token trajectories within bounds becomes even starker when we examine DeepSeek-V3.2-Speciale in Chapter 21.
Sources: Report §4.1 and Appendix C (sections/02-post.tex, tables/eval_main.tex, tables/nonthink.tex). Continue with Speciale and competition-level reasoning.
21. Speciale and Competition-Level Reasoning
What happens if you take the DeepSeek-V3.2 post-training pipeline, strip out general chat and tool-use constraints, relax the length penalty during GRPO, and fold in a dedicated mathematical proof-verification reward? The result is DeepSeek-V3.2-Speciale—a specialized reasoning checkpoint built to test how far extended test-time thinking can push Olympiad math and competitive programming.
Evaluating Speciale requires separating two things: how the checkpoint itself trades token volume for single-attempt accuracy on standard benchmarks, and how the multi-candidate competition harness (parallel sampling, sample-test filtering, and iterative self-verification) turns that checkpoint into a gold-medal system on IMO, CMO, IOI, and ICPC.
How Speciale's training recipe differs from the main model
DeepSeek-V3.2-Speciale shares the exact same 671B DSA architecture and base checkpoint as the main model, but diverges during post-training in three ways:
- Reasoning-only RL mixture: Speciale trains exclusively on reasoning data during its RL stage, omitting multi-turn agent tool use and general conversational alignment (and consequently does not support tool calling in the released weights).
- Relaxed length penalty: Lowering the length penalty coefficient allows GRPO to reinforce much longer exploratory chains, case analyses, and inline sanity checks.
- DeepSeekMath-V2 proof dataset and reward: To handle full natural-language mathematical proofs rather than just
\boxed{}short answers, Speciale incorporates the theorem-proving dataset and self-verification reward method from DeepSeekMath-V2.
Accuracy vs. token consumption: Main V3.2, Speciale, and Gemini-3.0-Pro
Table 4 of the report pairs benchmark scores with average generated output length (in thousands of tokens) across eight reasoning benchmarks:
| Benchmark | DeepSeek-V3.2 (Main) Score / Tokens | DeepSeek-V3.2-Speciale Score / Tokens | Gemini-3.0-Pro Score / Tokens |
|---|---|---|---|
| AIME 2025 (Pass@1) | 93.1 / 16K | 96.0 / 23K | 95.0 / 15K |
| HMMT Feb 2025 (Pass@1) | 92.5 / 19K | 99.2 / 27K | 97.5 / 16K |
| HMMT Nov 2025 (Pass@1) | 90.2 / 18K | 94.4 / 25K | 93.3 / 15K |
| IMOAnswerBench (Pass@1) | 78.3 / 27K | 84.5 / 45K | 83.3 / 18K |
| LiveCodeBench (Pass@1-CoT) | 83.3 / 16K | 88.7 / 27K | 90.7 / 13K |
| Codeforces (Rating) | 2,386 / 42K | 2,701 / 77K | 2,708 / 22K |
| GPQA Diamond (Pass@1) | 82.4 / 7K | 85.7 / 16K | 91.9 / 8K |
| HLE (Text-only Pass@1) | 25.1 / 21K | 30.6 / 35K | 37.7 / 15K |
Comparing the three columns highlights both the power and the cost of test-time length scaling:
- Beating Gemini-3.0-Pro on competition math: Speciale improves over the main V3.2 checkpoint on every single benchmark—and overtakes Gemini-3.0-Pro across all four mathematical reasoning benchmarks: 96.0% on AIME 2025, 99.2% on HMMT Feb 2025, 94.4% on HMMT Nov 2025, and 84.5% on IMOAnswerBench, while pulling within 7 rating points on Codeforces (2,701 vs. 2,708).
- The token-efficiency gap: Those gains come at a steep increase in output length. Compared to the main V3.2 model, Speciale generates 1.4 to 2.3 more tokens per problem—reaching 45K tokens on average for IMOAnswerBench and 77K tokens on average for Codeforces (nearly 3.5 Gemini-3.0-Pro's 22K average). As the authors state candidly in Section 4.2, Speciale's token efficiency remains significantly behind Gemini-3.0-Pro, which is precisely why the main V3.2 release enforces stricter length penalties for everyday serving.
Gold-medal Olympiad and World Finals results
In Table 5 and Appendix D, the authors evaluate DeepSeek-V3.2-Speciale on four premier 2025 human competitions in mathematics and informatics:
| Competition | Score / Solved | Per-problem breakdown | Equivalent medal / rank |
|---|---|---|---|
| IMO 2025 (Math) | 35 / 42 points | Gold Medal threshold | |
| CMO 2025 (Math, English version) | 102 / 126 points | Gold Medal threshold | |
| IOI 2025 (Informatics) | 492 / 600 points | Gold Medal (10th place overall) | |
| ICPC World Finals 2025 | 10 / 12 problems | 10 solved within submission limits | Gold Medal (2nd place overall) |
Notice that on IMO 2025, Speciale achieves a perfect on the first five problems and on Problem 6. Because these evaluations model full contest participation (up to 50 submissions per problem in IOI, multi-submission penalty rules in ICPC, and multi-hour proof drafting in IMO/CMO), Appendix D documents the exact test-time search and filtering harnesses used for each contest. (All generation runs at a 128K token limit without external tools or internet access during model inference.)
The IOI 2025 and ICPC World Finals 2025 selection harnesses
In competitive programming contests, the official grading environment allows multiple submissions per problem and provides public sample test cases. DeepSeek-V3.2-Speciale uses a three-stage sample–filter–rank funnel:
- Parallel candidate sampling: For each IOI 2025 problem, the system generates 500 independent candidate solutions in parallel (for ICPC World Finals 2025, it generates 32 candidates per problem).
- Sample-test and refusal filtering: The harness executes each candidate program against the problem's public sample tests, discarding any candidate that fails the sample tests or exceeds code-length limits. Next, DeepSeek-V3.2-Exp acts as an automated judge to filter out candidates whose text explicitly states an inability to solve the problem or refuses the task.
- Ranking by thinking-trace length: From the surviving valid candidates for each IOI problem, the harness selects the 50 candidates with the longest
<think>traces and submits them under IOI's official 50-submission rule (where a contestant's score on each subtask is the maximum score achieved across their submissions).
Notice how clever Step 3 is: once broken code is filtered out by sample tests, longer <think> traces correlate with deeper edge-case analysis and more complete algorithmic derivations, making thinking-trace length a zero-cost proxy for solution quality among passing candidates.
In ICPC World Finals 2025, using the same filtering funnel on 32 candidates per problem, Speciale solves 10 out of 12 problems—solving 8 problems on the very first filtered submission, 1 problem on the 2nd submission, and 1 problem on the 4th submission.
The IMO 2025 and CMO 2025 self-verification loop
Unlike IOI and ICPC, mathematical Olympiads provide no executable sample tests to filter out flawed proofs. Instead, for IMO 2025 and CMO 2025, Speciale uses the generate–verify–refine loop developed in DeepSeekMath-V2:
- The model drafts a candidate proof for the problem.
- Using its trained proof-verification capability, the model critiques and scores its own proof for logical gaps, unproved lemmas, or invalid case reductions.
- The model iteratively revises the proof based on those self-verification critiques until the proof achieves a perfect self-evaluation score or reaches the maximum revision cap.
To allow independent inspection of the final mathematical proofs and competition code, the authors released the full text of Speciale's final IMO, CMO, IOI, and ICPC submissions in the official repository.
Sources: Report §3, §4.2, and Appendix D (sections/02-post.tex, sections/06-high.tex, sections/appendix.tex); official model card and competition submission archive. Continue with understanding the released implementation.
22. Understanding the Released Implementation
The open-weights release of DeepSeek-V3.2 ships with a clean, self-contained reference implementation (inference/model.py, inference/config_671B_v3.2.json, and encoding/encoding_dsv32.py). Reading those files alongside the paper bridges the gap between the compact mathematical notation in Section 2 and the exact tensor shapes, RoPE coordinate layouts, and mixed-precision quantization rules required to run the checkpoint faithfully.
Reconciling ModelArgs defaults with config_671B_v3.2.json
If you open inference/model.py and look only at the Python @dataclass class ModelArgs, you will see small placeholder defaults (dim = 2048, n_layers = 27, n_routed_experts = 64, max_seq_len = 4096 * 4) intended for unit testing on a single node. When loading the actual 671B checkpoint, those defaults are overwritten by inference/config_671B_v3.2.json (and the Hugging Face root config.json).
| Parameter | ModelArgs dataclass default |
config_671B_v3.2.json / config.json |
|---|---|---|
dim / hidden_size |
2,048 | 7,168 |
n_layers / num_hidden_layers |
27 | 61 |
n_dense_layers / first_k_dense_replace |
1 | 3 |
n_heads / num_attention_heads |
16 | 128 |
n_routed_experts |
64 | 256 |
n_activated_experts / num_experts_per_tok |
6 | 8 |
index_n_heads |
64 | 64 |
index_head_dim |
128 | 128 |
index_topk |
2,048 | 2,048 |
Always initialize memory calculators and kernel configurations from config_671B_v3.2.json or config.json, never from the bare ModelArgs defaults.
Code map of inference/model.py and encoding/encoding_dsv32.py
| Class / Function | File | What to inspect |
|---|---|---|
ModelArgs |
inference/model.py |
Runtime configuration fields, YaRN parameters, and FP8 block size (block_size = 128) |
Linear / linear() |
inference/model.py |
Blockwise FP8 weight storage with dynamic per-token activation quantization |
apply_rotary_emb() |
inference/model.py |
interleaved=True (MLA) vs. interleaved=False (Indexer) RoPE coordinate pairing |
rotate_activation() |
inference/model.py |
Fast Hadamard Transform (hadamard_transform(x, scale=dim**-0.5)) prior to FP8 quantization |
Indexer |
inference/model.py |
Query/key projections, LayerNorm, Hadamard rotation, FP8 cache, fp8_index, and torch.topk |
MLA |
inference/model.py |
Low-rank Q/KV compression, RoPE split, FP8 KV simulation, and top- masking |
Gate & MoE |
inference/model.py |
Sigmoid affinity scoring, 8-group top-4 group selection, route_scale = 2.5, and all-to-all dispatch |
Block & Transformer |
inference/model.py |
Pre-norm residual loop across 3 dense layers + 58 MoE layers, YaRN frequency precomputation |
encode_messages() |
encoding/encoding_dsv32.py |
Rendering OpenAI-style message arrays into DeepSeek-V3.2 prompt strings |
drop_thinking_messages() |
encoding/encoding_dsv32.py |
Stripping <think> blocks prior to last_user_idx while retaining tool history |
Crucial numerical detail 1: Interleaved vs. non-interleaved RoPE
One of the easiest places to introduce a silent numerical bug when porting DeepSeek-V3.2 to a new inference engine is RoPE coordinate layout. Look at apply_rotary_emb(x, freqs_cis, interleaved) in inference/model.py:
- Interleaved layout (
interleaved=True): Pairs adjacent coordinates as the real and imaginary components of each 2D rotation plane:x.view(*x.shape[:-1], -1, 2). Main MLA (MLA.forward) usesinterleaved=Trueforq_peandk_pe. - Non-interleaved layout (
interleaved=False): Splits the 64-dimensional vector into its first 32 coordinates and last 32 coordinates viatorch.chunk(x, 2, dim=-1). The lightning indexer (Indexer.forward) usesinterleaved=Falsefor its rotary slicesq_peandk_pe.
In fact, the official DeepSeek-V3.2-Exp repository history includes a November 2025 commit specifically fixing a mismatch where the reference indexer script accidentally defaulted to interleaved RoPE. If an engine applies interleaved RoPE to the indexer keys, the dot products scramble the learned positional bias and degrade top-2,048 token selection without raising any runtime shape errors.
Crucial numerical detail 2: Mixed precision and blockwise FP8
Calling DeepSeek-V3.2 an "FP8 checkpoint" is shorthand for a carefully partitioned mixed-precision execution graph configured in config.json (quantization_config):
- Linear weights ( blockwise FP8): Large projection and expert matrices store weights in
float8_e4m3fnwith block scales (using theue8m0power-of-two scale format specified inconfig.json), multiplied against dynamically quantized per-token FP8 activations viafp8_gemm. - Indexer keys and scores: Inside
Indexer, historical keyskare quantized to FP8 (act_quant(k, block_size=128)) and stored ink_cache(float8_e4m3fn) alongside 4-bytefloat32scales ink_scale_cache. Meanwhile, the small head-weight projectionweights_proj() is kept in unquantized floating point (float32inmodel.py, stored asbfloat16in the checkpoint) because 64 outputs are narrower than a single 128-element quantization block. - Simulated vs. physical FP8 MLA cache: In the reference
MLA.forwardscript,kvis passed throughact_quantand immediately dequantized back tobfloat16(dequant_fp8_kv_cache) before being written intoself.kv_cache. As the inline comment explains, this round-trip simulates the quantization noise of the production FP8 KV cache while keeping the reference PyTorch attention math in BF16. Production engines (vLLM, SGLang, TensorRT-LLM) store the physicalkv_cachetensor directly in FP8 and dequantize on the fly inside the sparse FlashMLA kernel. - Normalization and router gates: All
RMSNormlayers, the indexer'sLayerNorm(k_norm), and the MoE routerGateaccumulate infloat32to prevent precision loss before discrete top- selection.
Sizing multi-node GPU memory for deployment
Even with 1-byte FP8 weights, storing ~671B parameters requires roughly 671 GB of raw weight memory before adding block scales, BF16 embeddings/norms/gates, KV caches, and activation buffers. A standard production deployment therefore shards the model across at least 880 GB (640 GB, tight/offloaded) or 8141 GB H200 / 1680 GB H100/H800 GPUs using a combination of Tensor Parallelism (TP), Expert Parallelism (EP), and Data-Parallel Attention (DP-Attention):
- Because MLA in MQA mode shares a single 576-element cache entry per token across all 128 heads, tensor-parallel shards that split query heads across GPUs would duplicate the shared KV cache if run naively; production servers typically pair Data-Parallel Attention (where each rank processes full head groups for different requests) with Expert Parallelism (distributing the 256 routed experts per layer across GPUs via high-speed NVLink/InfiniBand all-to-all dispatch).
Chat encoding and developer role constraints
When integrating encoding/encoding_dsv32.py into a serving gateway, keep three interface rules in mind:
- Recommended sampling parameters: Both the paper and the official model card recommend temperature and top- for general and reasoning workloads.
- Search-only
developerrole: The encoder supports a specialrole: "developer"message branch designed specifically for internal search-agent prompts; the model card notes thatdeveloperis not accepted on standard general-purpose API endpoints and should not be treated as an alias for"system". - Strict tool-output ordering: When the assistant emits parallel tool calls inside a single
<|tool▁calls▁begin|>block, the next messages in the conversation list must be correspondingrole: "tool"messages in exact order, which the encoder wraps inside a single<|tool▁outputs▁begin|>...<|tool▁outputs▁end|>block before appending the next<think>or answer prompt.
In the next chapter, we trace a single multi-turn agent request through every layer of this stack—from encode_messages through the lightning indexer, MLA, MoE routing, tool execution, and GRPO training replay.
Sources: Pinned official inference/model.py, config.json, inference/config_671B_v3.2.json, encoding/encoding_dsv32.py, and README.md; Report §2 and Appendix A; DeepSeek-V3.2-Exp repository commit history. Continue with one request through the whole system.
23. One Request Through the Whole System
The preceding chapters examined DeepSeek-V3.2's subsystems one at a time. To see how message encoding, sparse attention, Mixture-of-Experts routing, tool state, context management, and GRPO training fit together in practice, let us trace a single multi-turn repository-repair request from the initial user prompt all the way through inference and offline RL replay.
The task
Suppose a developer submits the following request inside an agentic coding session:
Repair the CSV parser bug where an empty quoted field (
"") is silently dropped. Preserve existing behavior for escaped quotes and custom delimiters, add a regression test, and run the test suite.
The agent harness exposes three tools—read_file, edit_file, and run_bash—and the conversation already contains a lengthy repository architecture guide plus several prior tool outputs totaling 40,000 tokens.
Step 1: Message encoding and <think> boundary checks
Before a single GPU kernel runs, encode_messages in encoding/encoding_dsv32.py serializes the structured message list into a single prompt string:
- Tool schemas are formatted inside the system/developer header so the model knows the exact JSON signatures for
read_file,edit_file, andrun_bash. - Because this request arrives as a brand-new
role: "user"message,drop_thinking_messagesscans backward and strips all<think>...</think>blocks from earlier user turns, while retaining all prior<|tool▁calls▁begin|>and<|tool▁outputs▁begin|>blocks so the model still sees the files and commands inspected earlier in the session. - With
thinking_mode="thinking", the encoder ends the prompt string with an open<think>tag, cueing the model to begin reasoning before choosing its first tool action.
The tokenizer converts the rendered string into integer token IDs in , and the input embedding table maps each ID to a 7,168-dimensional vector.
Step 2: Prefilling the 40K prompt through MLA and the Lightning Indexer
As the 40,000-token prompt flows through the 61 transformer blocks (Block), each layer builds two historical caches in GPU memory:
- The MLA cache: Each token projects its normalized hidden state into a shared 512-dimensional content latent and a 64-dimensional interleaved RoPE key (576 coordinates total per layer).
- The Indexer cache: Each token also projects its hidden state into a 128-dimensional indexer key (with 64 non-interleaved RoPE coordinates), applies a LayerNorm and a Fast Hadamard Transform (
rotate_activation), quantizes the vector to 128 bytes of FP8 (float8_e4m3fn) plus one 4-bytefloat32scale, and stores them ink_cacheandk_scale_cache.
For every query position , the lightning indexer computes 64 heads of ReLU-gated FP8 dot products against all , combines them with query-dependent head weights , and selects the top token positions . Main MLA then gathers only those 2,048 shared latents and evaluates 128 query heads over that 2,048-token subset.
After attention, Layers 0–2 pass each token through a dense SwiGLU FFN, while Layers 3–60 route each token through 1 shared expert plus 8 out of 256 routed experts chosen by the group-limited sigmoid router (Gate).
Step 3: Autoregressive decoding of <think> and the first tool call
Once prefill finishes, the model decodes one token at a time at temperature , top-:
- At each decode step , the lightning indexer scans the cached FP8 indexer keys in time, picks the 2,048 highest-scoring positions, and hands those indices to MLA's absorbed MQA decode kernel.
- Inside
<think>, the model formulates its plan ("Locatecsv_parser.pyandtest_csv.py, inspect how""is tokenized..."), closes</think>, and emits:<|tool▁calls▁begin|><|tool▁call▁begin|>read_file<|tool▁sep|>{"path": "src/csv_parser.py"}<|tool▁call▁end|><|tool▁calls▁end|> - The runtime intercepts
<|tool▁calls▁end|>, pauses generation, readssrc/csv_parser.pyfrom the container filesystem, and appends the file contents as arole: "tool"message.
Step 4: Multi-turn tool loop with retained reasoning
When encode_messages runs for Step 2 of the turn, the newest message has role: "tool", not role: "user". Consequently:
- The
<think>block generated in Step 3 stays in the prompt. - The KV cache from Step 3 remains completely valid—the serving engine simply prefills the newly appended
<|tool▁outputs▁begin|>...<|tool▁outputs▁end|><think>tokens on top of the existing 40K cache instead of re-prefilling the entire conversation with stripped<think>blocks!
Across the next few tool turns, the model:
- Reads
src/csv_parser.pyand spots aif field == "": continuebug that strips empty quoted tokens after unquoting. - Calls
edit_fileto fix the condition and addtest_empty_quoted_field()totests/test_csv.py. (Note that this call mutates the container filesystem.) - Calls
run_bash("pytest tests/test_csv.py"). Suppose the first test run fails because a trailing comma at end-of-line now emits a spurious empty field. - Because the previous
<think>blocks and tool outputs are all retained in context, the model does not re-readsrc/csv_parser.py; its next<think>block immediately diagnoses the trailing-comma interaction, patches the state machine, re-runspytest, observes all tests passing (F2P = 1, P2F = 0), and writes a concise summary of the fix.
If the debugging loop had dragged on past 80% of the 128K window (~105K tokens), a context-management policy would have had to intervene—and because Step 2 mutated src/csv_parser.py on disk, a coding runtime would need a state-aware summary or git diff inspection rather than a blind Discard-all reset.
Step 5: Replaying the trajectory during offline GRPO training
Now suppose this trajectory was one of rollouts generated for this repository issue during the mixed RL stage. How does the training cluster turn this rollout into a stable gradient update?
- Outcome verification and advantage calculation: Inside the container, the test harness runs the JUnit test suite. This trajectory passed both the new regression test and all existing tests, earning (minus its small length penalty). Subtracting the group mean gives a positive advantage for every model-generated token in the trajectory.
- Action masking: All prompt tokens and all
<|tool▁outputs▁begin|>...<|tool▁outputs▁end|>environment observations are masked out of the GRPO loss sum; only the assistant's<think>,<tool_call>, and final-answer tokens receive gradients. - Keep Routing replay: At every generated token and every MoE layer , the training forward pass loads the exact 8 expert IDs logged by the inference server during rollout decoding, preventing expert-flip discontinuities in .
- Keep Sampling Mask replay: The training pass applies the saved top- vocabulary mask from the inference engine before normalizing , ensuring is computed over the exact same vocabulary support.
- Unbiased K3 KL and Sequence Masking: The KL penalty is evaluated with the importance-weighted K3 estimator (keeping inside the autodiff graph), while any failed rollout in the group () whose sequence log-ratio drift exceeds has its surrogate loss zeroed out by .
Subsystem summary across the lifecycle of a request
| Subsystem | What it does during this request |
|---|---|
Chat Encoder (encoding_dsv32.py) |
Strips <think> from prior user turns, preserves <think> across tool turns, wraps tool calls/outputs |
Lightning Indexer (Indexer) |
Scans 40K+ FP8 cached keys with 64 ReLU heads, selects top 2,048 token indices per query |
Multi-Head Latent Attention (MLA) |
Caches 576-dim shared latent + RoPE key per token; gathers only the 2,048 selected entries in MQA mode |
MoE Router & Experts (Gate, MoE) |
Evaluates 1 shared + 8 routed SwiGLU experts (out of 256) per token using group-limited sigmoid routing |
| Container Runtime & Verifier | Executes file edits and pytest, grading final container state via JUnit |
| GRPO Stabilization Stack | Replays MoE routes and top- masks, masks stale negative trajectories, and applies importance-weighted K3 KL |
Sources: Integrated walkthrough synthesized from Report §§2–4 and the pinned repository artifacts (inference/model.py, encoding/encoding_dsv32.py). Continue with limits, practical choices, and research questions.
24. Limits, Practical Choices, and Research Questions
In Section 5 of the report, the authors candidly lay out three areas where DeepSeek-V3.2 still trails frontier proprietary models like Gemini-3.0-Pro and GPT-5-High. Pairing those acknowledged limitations with our structural analysis of DSA, off-policy GRPO, and synthetic agent environments clarifies both how to deploy the released checkpoints today and what open research questions remain.
Three limitations highlighted by the authors
- Breadth of world knowledge vs. total pre-training FLOPs: On encyclopedic and long-tail factual benchmarks such as MMLU-Pro (85.0% vs. 90.1%) and text-only HLE (25.1% vs. 37.7%), DeepSeek-V3.2 lags Gemini-3.0-Pro. The authors attribute this gap to spending fewer total pre-training FLOPs than the largest proprietary frontier runs, and note plans to scale pre-training compute in future generations. (When paired with live search tools, V3.2's HLE score jumps from 25.1% to 40.8%, confirming that external retrieval compensates for much of the parametric knowledge gap.)
- Token efficiency in long-horizon reasoning: Achieving parity with Gemini-3.0-Pro on competition math and coding requires generating substantially more tokens. While DeepSeek-V3.2-Speciale overtakes Gemini-3.0-Pro on AIME, HMMT, and IMOAnswerBench, it burns 23K to 77K tokens per problem compared to Gemini-3.0-Pro's 15K to 22K tokens—meaning the model relies on longer serial search chains where a more token-efficient policy reaches the same deduction in half the steps.
- Complex multi-turn task execution and redundant verification: On long-tail agent suites like MCP-Mark (38.0% vs. GPT-5-High's 50.9%), V3.2 still falls short, frequently getting trapped in redundant self-verification loops that exhaust the 128K context window on GitHub and Playwright browser tasks.
Architectural boundaries of DeepSeek Sparse Attention
Beyond those empirical benchmark gaps, the mechanics of DSA impose three concrete systems boundaries:
- The indexer remains in prefill and per decode step: Because the lightning indexer scans every prefix token to pick the top 2,048 entries, scaling context length from 128K to 1M+ tokens will eventually make the FP8 indexer scan itself the dominant bottleneck unless hierarchical or block-pruned indexing is introduced.
- Full KV cache memory is still : Selecting 2,048 tokens saves memory bandwidth during MLA reads, but the engine must still store all historical MLA latents (576 elements/token/layer) plus all historical FP8 indexer keys (132 bytes/token/layer) in GPU memory.
- Hard top- cutoff on diffuse attention: If a task requires aggregating diffuse signals across 10,000 distinct positions simultaneously (for instance, counting or averaging a property across thousands of records scattered throughout a 128K prompt), a hard cap of tokens per query imposes an explicit information bottleneck at each layer.
Practical deployment guide: choosing between V3.2 variants and modes
When deploying the open-weights checkpoints in production, match the checkpoint and mode to your workload's tool requirements and latency budget:
| Workload profile | Recommended checkpoint & mode | Why |
|---|---|---|
Interactive multi-turn coding, search, or MCP agents (in frameworks with native tool roles) |
DeepSeek-V3.2 (Main) — Thinking mode | Retains <think> state across tool calls; delivers +7 to +11.5 point gains on complex MCP and terminal benchmarks |
Latency-sensitive repository repair or legacy agent scaffolds (e.g., Terminus / Roo Code that emit user messages for tool outputs) |
DeepSeek-V3.2 (Main) — Non-Thinking mode | Avoids re-reasoning overhead when scaffolds strip <think> on fake user turns; retains 72.1% vs. 73.1% on SWE-bench Verified |
| Offline competition math, theorem proving, and hard algorithmic puzzles (no tool calls needed) | DeepSeek-V3.2-Speciale | Trained with relaxed length penalty and DeepSeekMath-V2 proof verification; highest reasoning accuracy, no tool-calling support |
Open research questions and follow-up experiments
Because the technical report introduces several major interventions simultaneously without full factorial ablations, it opens up five concrete research directions for the open-source community:
- Mapping the top- sensitivity curve of DSA: Since the released checkpoint allows changing
index_topkat runtime, how does accuracy on multi-needle retrieval, repository QA, and math reasoning vary as sweeps from without retraining? Where does top- recall of dense attention mass begin to break down? - Factorial ablation of the off-policy GRPO stack: Holding the MoE checkpoint and rollout staleness fixed, how much stability comes from Keep Routing versus Keep Sampling Mask, Off-Policy Sequence Masking (), and the unbiased K3 KL gradient individually?
- Training adaptive stopping to cure redundant self-verification: Can step-level tool-call penalties or marginal-information rewards teach an agent to stop re-running passing tests on MCP-Mark and SWE-bench before overflowing the 128K context window?
- **State-aware context compaction for mutating agents:**On read-only web search (BrowseComp), wiping 100% of tool history at 80% capacity (
Discard-all) beat summarization by +7.4 points. What is the right analog for stateful coding and database agents, where the workspace persists across context resets—for instance, pairingDiscard-allwith an automatically injectedgit status/git diffstate header? - Auditing synthetic verifier correlation: In automated environment synthesis (Chapter 14), both
solution()andverify()are written by the same LLM from the same prompt. Quantifying the rate of correlated specification bugs—and testing whether generatingsolution()andverify()with independent models or formal property checkers improves transfer—would sharpen synthetic RL pipelines further.
Sources: Report §5 (sections/02-post.tex) and synthesis of Chapters 3–22. Continue with the glossary, equations, and source atlas.
25. Glossary, Equations, and Source Atlas
This reference chapter consolidates the paper's source file locations, revision checksums, architectural constants, key equations, and technical glossary in one place.
Primary sources and revision checksums
The primary paper is DeepSeek-AI, DeepSeek-V3.2: Pushing the Frontier of Open Large Language Models (arXiv:2512.02556v1, submitted 2 December 2025). The unmodified TeX source archive is preserved at ../2512.02556v1-source.tar.gz with SHA-256 checksum:
ebac277dba6a19100bec4fc921e6716157bf96d48b2f417e27cc4289a3d61c7d
Its top-level entry point is ../main.tex (as specified in ../00README.json), accompanied by the section files under ../sections/, tables under ../tables/, and original figures under ../figures/.
Official open-weights configuration, inference, and encoding files are preserved under ../_sources/ from the DeepSeek-V3.2 Hugging Face repository pinned at commit:
a7e62ac04ecb2c0a54d736dc46601c5606cf10a6
and cross-checked against the DeepSeek-V3.2-Exp GitHub repository at commit:
87e509a2e5a100d221c97df52c6e8be7835f0057
Per-file SHA-256 digests are recorded in ../_sources/source-manifest.json.
TeX source map
All paths below are relative to papers/dsv32/:
| Topic | TeX source file & lines | Book chapters |
|---|---|---|
Title and model-name macros (\dsv, \dsr, etc.) |
main.tex, lines 75–98 |
1, 25 |
| Abstract | sections/00abs_new.tex |
1 |
| Introduction and core motivation | sections/01-0-intro.tex |
1, 24 |
| DSA formulation and MLA MQA instantiation | sections/01-method.tex, lines 2–42 |
3–5 |
| Dense warm-up and sparse training stages | sections/01-method.tex, lines 44–73 |
6 |
| Architectural parity check (Terminus vs. V3.2-Exp) | sections/01-method.tex, lines 75–83 |
6, 19 |
| Computational complexity and H800 cost curves | sections/01-method.tex, lines 86–109 |
7 |
| Specialist distillation, mixed RL, and Speciale recipe | sections/02-post.tex, lines 3–27 |
8, 12, 21 |
| GRPO objective, K3 KL, and off-policy stability | sections/02-post.tex, lines 29–94 |
9–11 |
| Thinking with tools and cold-start bootstrapping | sections/02-post.tex, lines 97–126 |
13 |
| Agent task table and environment synthesis pipelines | sections/02-post.tex, lines 129–296 |
14–16 |
| Main benchmark protocol and harness notes | sections/02-post.tex, lines 298–317 |
19–20 |
| Main reasoning & agent evaluation table (Table 2) | tables/eval_main.tex |
19–20 |
| Speciale token efficiency and Olympiad results (Tables 4–5) | sections/06-high.tex |
19, 21 |
| Synthetic-task difficulty audit and RL transfer curves | sections/05-thinking-with-tool.tex, tables/synthesis-eval.tex |
17 |
| BrowseComp context-management scaling study | sections/03-seach-agent.tex |
18 |
| Conclusion and limitations | sections/02-post.tex, lines 328–end |
24 |
| Appendix A: MLA MHA vs. MQA execution diagrams | sections/appendix.tex, lines 3–22 |
4 |
| Appendix B: Cold-start prompt templates | sections/appendix.tex, lines 38–143 |
13 |
| Appendix C: Thinking vs. Non-Thinking agent table | tables/nonthink.tex |
20 |
| Appendix D: IOI, ICPC, IMO, and CMO competition protocols | sections/appendix.tex, lines 149–160 |
21 |
Official code and configuration map
| Preserved artifact | Key symbol or section | Location |
|---|---|---|
_sources/config.json |
Hugging Face model dimensions, YaRN, FP8 config | Full file |
_sources/inference-config.json |
config_671B_v3.2.json overrides for ModelArgs |
Full file |
_sources/model.py |
ModelArgs dataclass |
Line 18+ |
_sources/model.py |
apply_rotary_emb (interleaved flag) |
Line 405+ |
_sources/model.py |
Indexer class (DSA lightning indexer) |
Line 435+ |
_sources/model.py |
MLA class (Multi-head Latent Attention) |
Line 498+ |
_sources/model.py |
Gate class (group-limited sigmoid router) |
Line 646+ |
_sources/model.py |
MoE class (shared + routed SwiGLU experts) |
Line 747+ |
_sources/model.py |
Block class (pre-norm transformer layer) |
Line 807+ |
_sources/model.py |
Transformer class (top-level model) |
Line 854+ |
_sources/encoding_dsv32.py |
drop_thinking_messages |
Line 254+ |
_sources/encoding_dsv32.py |
encode_messages |
Line 270+ |
_sources/encoding_dsv32.py |
parse_message_from_completion_text |
Line 341+ |
_sources/model-card.txt |
Official README.md usage notes and chat template guide |
Full file |
(Backbone parameter counts of ~671B total and ~37B active per token trace to the inherited DeepSeek-V3 architecture in ../dsv3/main.tex, arXiv:2412.19437.)
Master table of architectural and training specifications
| Quantity | Value | Notes |
|---|---|---|
| Total / active parameters | ~671B / ~37B | Inherited V3 MoE backbone scale |
Vocabulary size (vocab_size) |
129,280 | Embedding and output LM head |
Hidden dimension (dim) |
7,168 | Residual stream width |
Transformer layers (n_layers) |
61 | 3 initial dense FFN layers + 58 MoE layers |
MLA query heads (n_heads) |
128 | Logical query heads per layer |
| Query / KV LoRA ranks | 1,536 / 512 | q_lora_rank / kv_lora_rank |
| Head widths (NoPE / RoPE / V) | 128 / 64 / 128 | qk_nope_head_dim / qk_rope_head_dim / v_head_dim |
| MoE routed / active / shared experts | 256 / 8 / 1 | Per MoE layer (moe_inter_dim = 2048, route_scale = 2.5) |
| Lightning indexer heads / width | 64 / 128 | index_n_heads / index_head_dim (64 RoPE + 64 NoPE) |
DSA selected KV budget (index_topk) |
2,048 | Selected token indices per query |
| Stage 1 (Dense warm-up) | 1,000 steps | , seqs/step tokens (backbone frozen) |
| Stage 2 (Sparse adaptation) | 15,000 steps | , seqs/step tokens |
| Context length (Paper / HF / Demo) | 128K / 163,840 / 16,384 | Evaluated window () / max_position_embeddings / ModelArgs default |
| Synthesized General Agent sandboxes | 1,827 environments | Yielding 4,417 retained general-agent tasks () |
| Code / Search / Interpreter tasks | 24,667 / 50,275 / 5,908 | Real execution environments; total across all 4 families tasks |
| BrowseComp accuracy (Thinking) | 51.4% 67.6% | Unmanaged 128K window with Discard-all at 80% capacity |
| SWE-bench Verified (Thinking / Non-Thinking) | 73.1% / 72.1% | Internal framework (72–74% across Claude Code and RooCode) |
| Terminal Bench 2.0 (Claude Code) | 46.4% / 37.1% | Thinking / Non-Thinking (Non-Thinking in Terminus ) |
| Speciale Olympiad scores | IMO 35/42, CMO 102/126, IOI 492/600, ICPC 10/12 | Gold-medal performance across all four 2025 competitions |
| H800 cost benchmark baseline | US$2 / GPU-hour | Reference hardware rental assumption for Figure 2 cost curves |
Key equations quick reference
- Lightning Indexer relevance score (Equation 1):
- Sparse top- MLA read:
- Indexer KL alignment loss (Equations 2–3):
- GRPO group mean-centered advantage and importance ratio (Equation 5):
- Importance-weighted K3 KL estimator (Equation 6):
- Masked GRPO objective with Off-Policy Sequence Masking (Equations 7–8): where if and , and otherwise.
Technical glossary
| Term | Definition |
|---|---|
| Absorbed projection | Folding MLA's per-head key/value up-projections into the query and output projections so the shared 512-dim latent is read directly in MQA mode |
| Action support | The subset of vocabulary tokens assigned nonzero probability after top- or top- truncation |
| DSA (DeepSeek Sparse Attention) | Two-stage attention pairing a 64-head FP8 lightning indexer with top-2,048 token selection over MLA |
| F2P (Fail-to-Pass) | A repository test case that fails on the base commit and passes after applying the candidate patch |
| GRPO (Group Relative Policy Optimization) | Critic-free RL algorithm that normalizes trajectory rewards against the mean of rollouts sampled for the same prompt |
| Hadamard rotation | Multiplying activations by an orthogonal Walsh-Hadamard matrix ( scaled) before FP8 quantization to smooth out channel outliers |
| Keep Routing | Recording the exact 8 routed MoE expert IDs per layer during rollout inference and enforcing those same expert paths during training replay |
| Keep Sampling Mask | Recording the rollout sampler's top-/top- vocabulary truncation mask and applying it to during training updates |
| Lightning Indexer | Lightweight 64-head ReLU scoring module (, shared FP8 keys) that ranks historical positions for DSA |
| MLA (Multi-head Latent Attention) | Attention architecture that compresses per-token KV states into a shared 512-dim latent plus a 64-dim decoupled RoPE key |
| Off-Policy Sequence Masking | Zeroing the policy-gradient surrogate () on negative-advantage trajectories () whose average log-ratio drift exceeds |
| P2F (Pass-to-Fail) | A regression test that passed on the base commit and fails after applying a patch (must be for valid coding environments) |
| Specialist checkpoint | Full 671B model trained via domain-specific RL to generate distillation trajectories for the unified V3.2 student model |
Frequently asked questions
Is DeepSeek-V3.2 trained from scratch with sparse attention?
No. It initializes from the dense DeepSeek-V3.1-Terminus 128K base checkpoint, trains the lightning indexer for 1,000 steps (2.1B tokens) with the backbone frozen, and then co-adapts all weights under top-2,048 sparse selection for 15,000 steps (943.7B tokens).
Does DSA make the whole model over a prompt of length ?
No. Main attention drops from to (), but the lightning indexer still scans all causal pairs in time—just with a smaller arithmetic constant in FP8.
Does selecting 2,048 tokens shrink the KV cache in GPU memory?
No. Because future tokens can select any earlier position , all historical MLA latents and FP8 indexer keys must remain resident in HBM. DSA reduces memory bandwidth read per step, while adding ~1.06 GB of indexer key cache per 128K sequence.
Do the lightning indexer scores weight the values inside MLA?
No. The indexer scores are used strictly to pick the top-2,048 index set (and to compute the auxiliary KL alignment loss during continued pre-training). Once is selected, all 128 MLA heads compute their own standard softmax attention weights over .
Why does placing tool outputs in role: "user" hurt agent accuracy?
Under DeepSeek-V3.2's chat template (encoding_dsv32.py), a new "user" message signals the end of the previous user turn and strips all prior <think> blocks, whereas "tool" messages preserve <think> blocks across steps. Frameworks like Terminus or Roo Code that wrap tool outputs in "user" messages inadvertently wipe the agent's working plan after every tool execution.
Is DeepSeek-V3.2-Speciale just the main model with a higher max_tokens limit?
No. Speciale is a distinct checkpoint trained on reasoning-only RL data with a relaxed length penalty and the DeepSeekMath-V2 proof-verification reward; it learns fundamentally longer exploratory strategies and omits tool-calling support.
Return to the table of contents to jump to any chapter.