16.1 Off-policy and on-policy distillation
Let be the teacher and the student, both distributions over the same token vocabulary. There are two natural ways to make resemble on agent trajectories. Off-policy distillation samples episodes from the teacher and fine-tunes the student on them with the masked SFT loss of Section 15.1. Since the environment terms cancel, its expected loss is the forward KL between trajectory distributions, plus a constant. Forward KL is mode-covering: it penalizes the student wherever the teacher has mass and the student does not. The catch is in the subscript. The expectation is over the teacher’s episodes, so the student is trained only on prefixes the teacher visits. On-policy distillation samples episodes from the student, asks the teacher for its distribution at every student prefix , and minimizes a per-token divergence there. The book’s default is the per-token reverse KL, which is mode-seeking: the student is penalized for putting mass where the teacher has little. The prefixes now come from the student, including the observations its own mistakes produced, so the teacher’s corrections arrive exactly where the student will be at deployment. On-policy distillation is the soft-label version of DAgger, the imitation-learning algorithm that queries an expert on the states the learner itself visits (Ross, Gordon, and Bagnell, 2010). The same paper’s motivation applies: in sequential prediction, future inputs depend on past outputs, which breaks the i.i.d. assumption behind supervised learning. On-policy distillation only helps if the teacher knows what to do at the student’s prefixes, including bad ones. We therefore build a teacher that has seen mistakes.with_mistake wraps the oracle so that it makes one given mistake at one turn and then continues as if that turn had not happened. In the resulting demonstrations, the mistaken turn is masked out of the loss, so the teacher learns to recover from the mistake, not to make it.
clamp demonstration the mistake comes at turn 1: after reading, the expert applies fix_range_end, which leaves the source unchanged (no change), and then continues with the correct swap_minmax, a test, and a submit. Only the four tokens of the mistaken call are masked out of the loss. All 180 demonstrations end with reward 1.
The teacher is a full-size TinyAgent (157k parameters) trained on weak play for format, then on the oracle and recovery demonstrations. A second, clean teacher sees only the 20 oracle demonstrations; Section 16.4 uses it to show why the recovery data matters. The student is a smaller TinyAgent, with width 32 and one layer, trained on weak play only, the analog of a small pretrained model that knows the format but not the skill.
16.2 Per-token reverse KL as a dense signal
Outcome RL gives one number per episode. On-policy distillation gives one number per action token, , and it is available whether or not the episode succeeded. To use it, we need its gradient. Fix a prefix and write , . Then , and with , because the second sum is . This is a policy gradient for a single token with reward , the negative log-ratio, minimized instead of maximized. Two implementations follow. The sampled-token form uses only the token the student actually generated and the teacher’s log-probability of it, , as a per-token advantage in an ordinary policy-gradient loss. It needs one teacher number per token. The full-vocabulary form computes the sum over exactly and lets autograd differentiate it. It has no sampling noise at the token, but it needs the teacher’s whole distribution at every position. The derivation holds at a fixed prefix. The full objective also depends on through which prefixes the student visits, which adds a score-function term in which every token is credited with the KL of all later tokens (a return-to-go of per-token KLs). Practical recipes drop it. Thinking Machines’ implementation uses “a discount factor of zero”, so each token is credited only with its own KL (Section 16.6). GKD-style training computes the per-token divergence on student-generated sequences and does not differentiate through the sampling. We follow the same convention, and state it as an approximation: the student is pushed toward the teacher at the prefixes it visits, not toward prefixes on which the teacher would agree with it later. At the logit level, the two KL directions also differ. Differentiating with respect to the student’s logits , The reverse-KL gradient on a token is proportional to the student’s own probability . If the student gives the teacher’s preferred token almost no mass, reverse KL barely pulls it up; it mostly pushes down whatever the student currently prefers. Forward KL pulls the teacher’s token up with force regardless. The next block verifies the sampled-token identity by enumeration and prints both logit gradients for a student that misses the teacher’s mode.distill_loss saves the full-vocabulary version. It takes student and teacher logits at the same positions (aligned to the predicted positions, as everywhere in the book), detaches the teacher, computes the per-position divergence in either direction, and averages over the action mask.
16.3 Experiment: distillation versus outcome RL
We now train three copies of the student base for 40 steps each, with the same batch structure: 4 training tasks per step, 8 episodes each (32 episodes per step).- Off-policy distillation: the teacher samples the 32 episodes, and the student takes one
sft_lossstep on them. - On-policy distillation: the student samples the 32 episodes, the teacher scores every prefix in one forward pass, and the student takes one
distill_lossstep (reverse KL). - Outcome RL: the student samples, and REINFORCE with a per-task group baseline uses the hidden-test reward, as in Section 15.5. Chapter 9 gives the full treatment.
Evidence. Measured here: one seed, evaluations of 80 and 40 episodes, so differences below about 0.1 are noise. The ranking “distillation ≫ outcome RL at 40 steps” is far outside it. The teacher was given recovery demonstrations; Section 16.4 measures how much that matters.
16.4 Exposure bias and compounding errors
The average pass rate hides how a policy fails. Suppose the student makes a mistake at turn with probability when its history looks like the teacher’s, and that after its first mistake it is in a part of prefix space it was never trained on, where it fails with probability close to 1. Over turns its success rate is then about , and the expected number of turns spent off-distribution grows like rather than : an early mistake ruins every later turn. That is the classic analysis of behavior cloning in Ross, Gordon, and Bagnell (2010), and the quantity that separates off-policy from on-policy training is the second assumption: what does the student do after its own mistake?forced_rollout starts an episode with a given list of actions, injected through the same token path as a real rollout, and then lets the model continue. We inject the three mistake types and measure the success rate of the continuation.
- A teacher trained only on clean demonstrations cannot recover either. The clean teacher succeeds on every clean start (1.00), and after an injected mistake on 0.00 and 0.10 of tasks. A teacher is itself a policy trained on some distribution, and its behavior at prefixes it never saw is not expertise. On-policy distillation is only as good as the teacher at the student’s prefixes.
- The off-policy student inherits the teacher’s clean behavior, not its recovery. The full teacher recovers from both injected mistakes (1.00), but its own samples almost never contain mistakes, so off-policy distillation never shows the student a recovery. The off-policy student succeeds on 0.80 of clean starts and on 0.03 and 0.00 after a mistake, the same pattern as the clean teacher. This is exposure bias, measured.
- The on-policy student recovers from the mistakes it makes, and only those. After a no-op edit it succeeds 0.47 of the time, against 0.00 for the off-policy student, because the student base guesses ops and made such edits during training, so the teacher corrected them there. It does not recover from the unterminated call (0.00), because the student base, trained on well-formed play, almost never produces one, so that prefix never appeared in its training batches. On-policy distillation covers the student’s own error distribution, not all errors.
16.5 Full-vocabulary versus top-k teacher distributions
distill_loss needs the teacher’s full distribution at every position: numbers per batch, which for Qwen3’s 151,936-entry vocabulary is about 0.6 MB per token in fp32 (Section 3.6). When the teacher runs on a separate inference service, that has to cross the network. Systems therefore send only the top- teacher entries per position, or only the sampled token’s log-probability (the sampled-token form of Section 16.2). Truncation changes the objective, and how it changes depends on what is done with the missing mass:
- Renormalized top- restricts both distributions to the teacher’s top tokens and renormalizes. It ignores whatever mass the student puts outside that set, so a student that spreads mass on tokens the teacher rules out is not penalized for it. At the loss is identically 0.
- Top- plus a tail bucket keeps the teacher tokens and merges everything else into one “other” outcome, for both student and teacher. The divergence between the coarsened distributions is a lower bound on the full KL (the data-processing inequality), and the student is still penalized for the total mass it puts outside the teacher’s top .
tail_bucket returns normalized log-probabilities over outcomes, so distill_loss can consume them directly as logits. The loop compares both truncations at several .
Pitfall. Computing top- on the teacher and then calling a full-vocabulary loss with the teacher’s other logits set to gives an infinite reverse KL wherever the student has mass outside the top , which in floating point turns into nan gradients. Either restrict the student to the same support explicitly, or keep a tail bucket.
16.6 Recent work
The entries below are reported results from public sources, inspected 2026-10-13. None is reproduced here.- GKD (Agarwal et al., “On-Policy Distillation of Language Models: Learning from Self-Generated Mistakes”, v1 2023-06-23; abstract inspected). Names the train/inference mismatch of standard distillation and trains the student on its own generated outputs with teacher feedback. It allows divergences other than forward KL, for students that cannot represent the teacher, and can be combined with RL fine-tuning.
- MiniLLM (Gu et al., v1 2023-06-14; abstract inspected). Replaces forward KL with reverse KL so that the student does not overestimate low-probability regions of the teacher, and optimizes it on-policy. It reports lower exposure bias and better calibration on instruction following, from 120M to 13B parameters.
- Qwen3 Technical Report (Qwen Team, v1 2025-05-14; Section 4.5 and Table 21 inspected). Describes strong-to-weak distillation for the smaller models in two phases: off-policy distillation on teacher outputs, then on-policy distillation, in which “the student model generates on-policy sequences for fine-tuning” and is trained to minimize the KL divergence to the teacher’s logits. Table 21 compares, from the same off-policy-distilled Qwen3-8B checkpoint (AIME’24 55.0), RL at 17,920 GPU hours (67.6) with on-policy distillation at 1,800 GPU hours (74.4).
- On-Policy Distillation (Kevin Lu and Thinking Machines Lab, 2025-10-27; full text inspected). Uses the sampled-token form of Section 16.2: the per-token advantage is the negative reverse KL, computed from the teacher’s log-probabilities of the student’s sampled tokens, with “a discount factor of zero”. The post states that it does not use top- logit distillation. Starting from Qwen3-8B-Base after off-policy SFT on teacher reasoning traces (60% on AIME’24), on-policy distillation reports reaching 70% in about 150 steps, and estimates a 9 to 30 times compute reduction relative to extrapolated SFT, depending on whether teacher sampling is counted.
16.7 Design problems in practice
Problem: tokenizer mismatch between teacher and student. Symptom: the distillation loss is large and does not decrease, or decreases while the student gets worse. Cause: distill_loss compares distributions index by index. If teacher and student vocabularies are ordered differently, index means different strings, and if they segment text differently, position is a different prefix. Options: (a) use a teacher and student from one model family with a shared tokenizer, the common choice. (b) For vocabularies that share strings but not ids, map teacher entries to student ids, which is exact for a 1:1 map. (c) For different segmentations, distill at the sequence level (off-policy SFT on teacher text, retokenized by the student) or use an explicit alignment of token spans, both of which lose the per-token signal. Default: (a). The next block shows the first two failure modes.
Problem: teacher cost. Symptom: on-policy distillation steps are slower than RL steps, or the teacher service becomes the bottleneck of the cluster. Cause: on-policy distillation runs a teacher forward pass over every student token of every step, and the teacher is usually much larger than the student. Off-policy distillation pays the teacher once per episode, and its data can be reused across epochs and across students. RL pays no teacher at all but needs an environment and a verifier. Options: (a) score only action tokens (tool tokens need no target), which saves the most when observations dominate the context. (b) Return top- with a tail bucket instead of full distributions (Section 16.5). (c) Use the sampled-token form, one number per token. (d) Run off-policy distillation first and on-policy only for the final stage, as the Qwen3 report and the Thinking Machines post both do. Default: (d) with (a) and (c). The next block estimates the forward-pass cost per step from Section 16.3’s token counts.
Problem: the teacher is wrong on some families. Symptom: the student’s average score approaches the teacher’s, and one slice of the evaluation is at zero for both. Cause: a distillation loss measures agreement with the teacher, not correctness. Wherever the teacher is confidently wrong, the student is trained to be confidently wrong in the same way, with the same dense signal that makes distillation efficient. Options: (a) validate the teacher per slice with the verifier before distilling, and drop the teacher’s signal on slices where it fails. (b) Mix in an outcome reward, . (c) Fix or replace the teacher on the slice. Default: (a), and treat the dropped slices as an RL or data problem of their own. We inject the failure: a copy of the teacher fine-tuned on demonstrations that usehardcode_testson thezerofamily, the toy version of a teacher trained with a hackable reward on one task type.
zero completely. We distill it on-policy into the student base three ways: plain reverse KL; reverse KL plus the REINFORCE loss with weight on the same batch; and the same mixture gated by the per-family validation above, so that episodes from the failing family get only the RL signal and no teacher signal.
zero: 27 of its 32 samples there apply hardcode_tests, and its pass rate is 0. (Its compare score of 0.22 is a separate, single-seed effect of the short budget; the KL + RL run reaches 0.59 there.) Mixing in the outcome-RL term at equal weight does not repair the family within 40 steps, and the hack becomes even more common (29 of 32). The reason is the group baseline: on zero tasks the student’s eight samples are all the teacher’s hack, all fail, and all get advantage 0, so the RL term has nothing to push toward, while the KL term keeps pulling toward the hack. Gating the teacher off the family removes the hack, and the student’s most common behavior on zero becomes making no edit at all (11 of 32), but the pass rate is still 0, and this single run also lost accuracy on minmax (0.44): without a teacher signal and with no successful sample in its groups, nothing teaches it add_zero_guard. Figure 16.4 summarizes the four policies. A teacher’s error on a slice cannot be distilled away. It has to be detected with an independent check and then solved by a signal that can explore, which on this slice means paying RL’s cost with enough exploration to find a success (Exercise 6), or by new demonstrations.
Summary
- Off-policy distillation is SFT on teacher episodes and minimizes the forward KL between trajectory distributions on teacher prefixes. On-policy distillation minimizes a per-token divergence, by default reverse KL, on prefixes the student generates. It is DAgger with a soft teacher.
- At a fixed prefix, : a single-token policy gradient with reward . Practical recipes ignore the dependence of future prefixes on the current token (discount 0). Reverse-KL logit gradients scale with the student’s own probability, which slows the start when the student misses the teacher’s mode.
- At 40 steps of 32 episodes from the same small student, both distillation methods far outperformed outcome RL (measured here). The difference between them appeared in recovery, not average pass rate: the off-policy student inherited the teacher’s clean behavior and could not recover from mistakes, and the on-policy student recovered from the mistakes it made itself, but not from mistakes it never made.
- A teacher must itself be competent at the student’s prefixes. A teacher trained only on clean demonstrations could not recover from injected mistakes, so it could not have taught recovery.
- Top- teacher distributions bias the objective. Renormalized top- discards the student’s mass outside the teacher’s support and gives zero loss at . A tail bucket costs one number and stays close to the full gradient at every .
- A distillation signal measures agreement, not correctness. A teacher’s error on one family propagated exactly into the student, and neither an added RL term nor gating repaired it within the budget, because every group on that family had zero reward variance.
Exercises
- Implement the sampled-token form of on-policy distillation (per-token advantage , detached, in a REINFORCE loss) and compare its learning curve and its gradient variance with
distill_lossat matched steps. How many samples per prefix would the sampled form need to match the full-vocabulary gradient’s cosine with the true gradient of Section 16.5? - Change an assumption: give the student the same size as the teacher. Do off-policy and on-policy distillation still end in the same place? Then make the student smaller still (
d_model=16) and compare forward and reverse KL, explaining any difference in terms of mode covering and mode seeking. - Add the return-to-go term that practical recipes drop: weight each token’s score function by the sum of the per-token KLs after it (discount ), and compare , , and on the recovery measurement of Section 16.4.
- Inject the unterminated-call mistake into the student’s rollouts during on-policy distillation with probability 0.1 per turn (masking the injected tokens out of the loss), and measure recovery again. Relate this to DART-style noise injection and to the limitation found in Section 16.4.
- Run the top- measurement at teacher temperatures 0.5, 1, and 2 (divide the teacher logits before the softmax). How does the needed for a gradient cosine of 0.99 scale with the teacher’s entropy?
- Repair the
zerofamily of Section 16.7 by gating the teacher and raising the student’s rollout temperature on gated tasks only. What temperature makes the group reward variance nonzero often enough for RL to findadd_zero_guard, and what does that do to the other families? - Design review: you must post-train a 1.5B-parameter coding agent with a 32B teacher of the same family, a sandboxed test-based verifier, and a fixed GPU budget. Lay out the stages (data, off-policy distillation, on-policy distillation, RL), what you would measure to decide when to move from one stage to the next, and how you would detect a teacher that is wrong on one repository or language before the student copies it.