kl_estimate and entropy_bonus, together with the update, training loop, and sequence-KL helper that use them.
10.1 The reference policy
The reference policy is a fixed policy, in practice a frozen copy of the model at the start of RL (the SFT or base checkpoint). The KL-regularized objective is with the sequence KL decomposed into per-token terms along the policy’s own prefixes (Appendix A.6). Three reasons for it recur in the literature, and they are different reasons. First, in RLHF the reward is a learned model that is accurate only near the data it was trained on; the KL keeps the policy where the reward can be trusted. Second, the reference carries capabilities the reward does not measure (fluency, formatting, knowledge), and the KL limits how much of them the policy may trade away. Third, the KL is a cumulative trust region: PPO’s clip (Chapter 8) limits how far one update moves from , while the KL limits how far the whole run moves from . With a verifiable reward such as hidden tests, the first reason disappears, which is the core of the case for dropping the KL (Section 10.7). What does the regularized objective want? For a single decision (a bandit) the answer is in closed form. Write for a distribution over actions with rewards . Then where and . Since the KL is nonnegative and zero only at , the optimum is and the optimal value is . The optimum tilts the reference by the exponentiated reward: is a temperature that interpolates between () and the best action in the reference’s support (). An action the reference never takes stays at probability zero for every . The same derivation with uniform gives the entropy bonus, because : maximizing is a KL penalty toward the uniform distribution, with optimum . Chapter 15 uses the same closed form to derive DPO.10.2 Estimating KL from samples
The trainer never sees full distributions over sequences. It sees sampled tokens and two numbers per token, and . Write their difference as . John Schulman’s note Approximating KL Divergence (2020) compares three per-sample estimators of : is unbiased by definition and takes negative values on many samples. adds , which has mean zero under because ; it is with a control variate (Appendix A.3), unbiased and never negative since . is biased: a Taylor expansion shows that it matches the KL to second order in and overestimates beyond. Chapter 9 saved all three askl_penalty. Appendix A.7 sampled them at two distances; here we compute their exact mean and per-sample standard deviation by enumerating every outcome of a 50-way distribution, at four distances between policy and reference.
10.3 The gradient each estimator produces as a loss
A KL term in the loss is implemented by evaluating an estimator on the batch’s sampled tokens and adding times its mean to the loss. Autograd then differentiates the estimator through , with the sampled tokens held fixed. It does not differentiate through the fact that the tokens were sampled from . The expected gradient of such a loss is therefore , which is not : the score-function term of Chapter 6 is missing. Compute each one, with and . For , the per-sample gradient is , whose expectation is zero: a loss contributes only noise. For , the per-sample gradient is , and its expectation is the true gradient of the reverse KL, The biased estimator gives the unbiased gradient. For , the per-sample gradient is , and The unbiased, low-variance estimator gives the gradient of the forward KL, the other direction. Near the two directions agree to second order, so their gradients agree to first order, and the difference grows with the distance. We check all of this exactly by weighting each outcome by its (detached) sampling probability, which is the expectation a large batch of samples would approach.kl_penalty, which it calls for the values. It adds one thing: kinds ending in + use the straight-through construction g - g.detach() + v.detach(), whose forward value is the estimator (so the logged number is, say, ) and whose gradient is that of (so the loss pushes along the reverse-KL gradient). verl implements the same option under the same + suffix (core_algos.kl_penalty, commit 00094bd, inspected 2026-10-13), with a comment that and have the right expected value but not the right expected gradient.
k3+ has ‘s gradient exactly. How large is ‘s error at the distances training actually reaches?
low_var_kl, is closer to a forward-KL penalty. Section 10.5 shows why the direction matters, and Section 10.7 measures the difference on TinyAgent.
k3+), at any distance. No single estimator wins all three, which is why the straight-through combination exists.
Pitfall. Rows of a batch in a PPO-style update come from , not from the current , after the first minibatch. The derivations above assume on-policy samples. With the small ratios of Chapter 9’s default (clip fraction about 0.1%), this is a minor additional bias; with many epochs it is another reason the KL term’s gradient is only approximately what its name says.
10.4 KL in the reward versus KL in the loss
There are two places to put the penalty. KL in the reward subtracts times a per-token (the log-ratio) from the reward and lets the policy gradient handle it, as RLHF-style PPO does. KL in the loss adds times a per-token estimator to the loss, as GRPO does. For one token, the reward version is REINFORCE on the reward , whose gradient is ; this is exactly the negative reverse-KL gradient derived above, so for a single token, ” in the reward” and ” in the loss” agree. For sequences they do not. By Appendix A.6, the sequence KL is , where is the per-token KL at prefix . Its gradient has two parts: how each changes with the parameters at a fixed prefix, and how the choice of token changes which prefixes, and therefore which future KLs, are visited. A per-token loss captures only the first part, because each token’s loss term is a function of that token’s own log-probability. The policy gradient on the reward captures both, because each token’s log-probability is weighted by the KL of everything that follows it (the reward-to-go of Section 6.5). The difference is credit for future divergence: a token that steers the episode into a region where the policy and reference disagree is penalized by the reward version and not by the loss version. We check this on a two-token sequence model with a vocabulary of 4, small enough to enumerate all 16 sequences: the first token has its own logits, and the second token’s logits depend on the first.surrogate builds the expected loss that autograd would see for each placement. For the loss placements, each sequence contributes the estimator at both tokens. For the reward placement, each token’s log-probability is multiplied by the detached sum of from that token to the end.
algorithm.use_kl_in_reward with a penalty by default and an optional adaptive controller, and actor.use_kl_loss with kl_loss_type: low_var_kl (, clamped to ) and a default coefficient of 0.001 (commit 00094bd, inspected 2026-10-13). For agents, the future-divergence term matters more than for single-turn tasks, because the tokens of an early call decide which observations, and therefore which later contexts, the episode reaches.
10.5 Forward versus reverse KL
The reverse KL is an expectation under the policy. It is large wherever the policy puts mass that the reference does not, and indifferent to reference mass that the policy ignores. The forward KL is an expectation under the reference, and it is large wherever the reference has mass that the policy lacks. The first is called mode-seeking (or zero-forcing), the second mass-covering. Maximum likelihood and SFT minimize a forward KL from the data; on-policy distillation in Chapter 16 minimizes a reverse KL to the teacher. The difference is clearest when a simple family must approximate a distribution it cannot represent. We fit one discretized Gaussian to a mixture of two by gradient descent in each direction.10.6 Entropy collapse and the levers against it
Entropy collapse is the steady fall of the policy’s per-token entropy during RL, toward a policy that samples the same tokens every time. It is not a bug in any one component: it is what a policy gradient does to a softmax policy when its high-probability choices are rewarded. The mechanism fits in one line. For logits over tokens with and , differentiating gives , so a small logit change changes the entropy by using . Entropy falls when the update raises the logits of tokens that are already likely, and rises when it raises the logits of unlikely ones. Cui et al., The Entropy Mechanism of Reinforcement Learning for Reasoning Language Models (2025-05-28), derive this covariance form for policy-gradient and natural-gradient updates and report that, without intervention, entropy and validation performance trade off along a fitted curve. One policy-gradient step on a sampled token with advantage changes the logits by . Four cases cover the possibilities.- An entropy bonus adds to the loss, whose gradient on the logits is per token: it raises every token whose log-probability is below and lowers the likely ones. Over a vocabulary of 316 words (or 151k tokens for Qwen3), “every unlikely token” is mostly tokens the policy should never emit. Section 10.1 showed the same thing in closed form: the entropy bonus is a KL penalty toward the uniform distribution.
- A KL penalty pulls each token’s distribution toward the reference’s, which has the reference’s entropy. It resists collapse only as far as the reference is uncertain, and, as a reverse KL, it does not penalize dropping alternatives the reference had (Section 10.5).
- Clip-higher (DAPO) raises . With , PPO’s clip removes a token’s gradient once , so the absolute increase a token can receive before the clip binds is : 0.18 for a token at 0.9, and 0.002 for a token at 0.01. The upper clip therefore binds on rare tokens with positive advantage, which are exactly the updates that raise entropy in the table above. DAPO’s stated reason is the same: “the probability of an unlikely ‘exploration’ token is too tightly bounded to be uplifted”, and it raises from 0.2 to 0.28. The lever works only if the clip binds, which requires the policy to move within a batch (several minibatches or epochs).
- Sampling temperature samples from . Because the trainer computes log-probabilities at the same (Chapter 9’s
rl_updatedivides the logits bycfg.temperature), the optimized policy is the tempered one, and the network can sharpen to undo any fixed . A higher temperature delays collapse rather than preventing it; ProRL reports that with raised rollout temperature “entropy continues to decline steadily as training progresses”. Evaluating at a lower temperature than training is then a separate, deliberate choice (Chapter 17).
train_rl has no hook for an extra loss term, and Chapter 9’s functions must not change. We therefore save entropy_bonus and a regularized version of Chapter 9’s update and loop, built from the same saved pieces (sample_step, behavior_stats, compute_advantages, policy_loss). entropy_bonus is the masked mean of the full-vocabulary entropy at policy positions; unlike the KL estimators, it is exact at each visited prefix rather than a one-sample estimate, because the logits for the whole vocabulary are already computed.
regularized_update is Chapter 9’s rl_update with two differences: the loss subtracts entropy_coef times the entropy bonus, and the KL term uses kl_estimate, so cfg.kl_kind may be 'k3+'. The logged entropy is the bonus’s value at each minibatch, computed before the step.
train_regularized is train_rl without periodic evaluation, plus the reward placement of Section 10.4. With kl_in_reward=True, each episode’s reward becomes , computed from the sampler’s log-probabilities and the reference before the advantages, and the loss carries no KL term. sequence_kl computes that sum.
train_rl, so three steps of each from the same start should give identical parameters.
train_rl only by the regularizer it switches on.
Clip-higher on one batch
Whether the upper clip binds depends on how far the policy moves within a batch, and Chapter 9’s default (one epoch, two minibatches) clipped 0.13% of tokens, too few for to matter. To see what the clip does when it binds, we take one batch of 64 episodes from the RL base agent and run 8 full-batch steps on it with at 0.2, at DAPO’s 0.28, and effectively unbounded. After the 8 steps we count the positive-advantage policy tokens whose ratio exceeds , and how many of them started below probability 0.5.10.7 Comparing the regularizers on TinyAgent
We now train the default configuration for 40 steps (where Chapter 9’s run still had headroom) under nine settings: no regularizer; KL penalties in the loss with the correct gradient (k3+) at of 0.05, 0.3, and 1.0; the GRPO-style loss at 0.3; the KL in the reward at 0.3 (Section 10.4); entropy bonuses of 0.03 and 0.1; and a sampling temperature of 1.3. Each run starts from the same RL base agent with seed 0. Besides held-out pass@1 we measure diversity. For a task with passing attempts out of , the probability that attempts drawn without replacement contain a pass is ; Chapter 17 derives this estimator and saves it, so here it is a local helper. We also count distinct action sequences among the 16 attempts at each task, and estimate the per-token KL from the starting policy with .
- Entropy. Without a regularizer the policy-token entropy fell from 0.52 to 0.12 in 40 steps. Every regularizer except the weakest KL slowed the fall, roughly in proportion to its strength: a KL coefficient of 0.3 held it at 0.28, 1.0 held it where it started (0.54), and the entropy bonus of 0.03 at 0.31. The bonus of 0.1 drove the policy to the uniform distribution: 5.707 nats against , six malformed calls per episode, and zero pass rate.
- pass@1 against pass@8. The unregularized run had a pass@1 of 0.725 and a pass@8 of only 0.80: two held-out tasks were never solved in 16 attempts, because the collapsed policy repeated the same wrong procedure on them. The weakest KL (0.05) left entropy unchanged at 0.124 and still reached pass@8 of 1.000, with the best pass@1 of the table, 0.80; at one seed we cannot separate that from noise. Stronger KL bought diversity with pass@1: at the distinct action sequences per task doubled (8.3 against 4.3) and pass@8 reached 0.99, while pass@1 fell to 0.59. At , reading did not take over (0.53 reads per episode) and pass@1 was 0.23, close to the blind ceiling of 0.2, with pass@8 still 0.90 because the near-reference policy samples many different guesses.
- Estimator. The loss and the
k3+loss at ended at nearly the same entropy (0.294 and 0.284), pass@1 (0.594 and 0.588), and distance from the start. At these per-token KLs (about 0.1), Section 10.3 puts the gradient difference near 25%, and one seed does not resolve its effect. - Placement. The KL in the reward at the same was much stronger than either loss placement: pass@1 0.34, reads 0.48, and the smallest distance from the start apart from (0.059). This is the scale difference of Section 10.4: the reward version sums the log-ratio over the episode’s 12 to 14 policy tokens instead of averaging it, and then enters an advantage normalized by each group’s spread.
- Entropy bonus and temperature. Both kept entropy higher while moving the policy further from the start than no regularizer (KL 0.325 and 0.517 against 0.237), and both raised malformed calls (0.28 and 0.25 per episode against 0.04). The entropy bonus spreads mass onto tokens no policy should emit; the temperature run’s network sharpened its logits to compensate for , so evaluated at it is further from the start policy than any setting except the collapsed entropy bonus. Its training-time entropy, measured at , still fell from 0.78 to 0.47.
k3+ loss at the same coefficient (the two green curves, one in each column); and the KL in the reward holds entropy highest and reward lowest. No regularizer improved the training reward at 40 steps on this gym, which has one correct procedure per task: what they buy is diversity in the samples, at a cost in pass@1 that grows with their strength.
Evidence. Measured here: one seed per setting, 40 steps, 64 episodes per step, evaluation on 10 held-out tasks with 16 attempts each. Differences in pass@1 smaller than about 0.08 are within the noise of this evaluation (Chapter 9 measured a spread of 0.71 to 0.81 across three seeds for the default run). The qualitative ordering by strength (entropy, distinct sequences, distance from the start) is the mechanism being demonstrated.
The case for dropping the KL
DAPO removes the KL term, arguing that when training long reasoning, “the model distribution can diverge significantly from the initial model, thus this restriction is not necessary” (DAPO, Section 2.3, 2025-03-18). The public coding-agent recipes in Chapter 20 (DeepSWE, SkyRL-Agent) also report no KL loss and no entropy loss. The argument from Section 10.1 supports this when the reward is a verifier: there is no learned reward to exploit, so the first reason for a reference disappears, and the remaining reasons (preserving unmeasured capabilities, a cumulative trust region) can be handled by evaluation on other tasks and by PPO’s per-step clip. The counter-position is ProRL (2505.24864, 2025-05-30), which trains for more than 2,000 steps and reports that “explicit regularization via a KL divergence penalty provides a stronger and more stable solution”, helping “maintain entropy”, while noting that over time “the KL term may increasingly dominate the loss, leading to diminishing policy updates”. Its answer is to reset the reference, which Section 10.8 reproduces. Both are reports from single-turn reasoning at large scale, not controlled evidence for agents.10.8 Design problems in practice
Problem: entropy collapse early in training. Symptom: the policy-token entropy halves within the first tenth of the run while the reward is still low, the share of zero-advantage groups climbs, and pass@ on held-out tasks approaches pass@1. Cause: the covariance of Section 10.6: in each group, the successful attempts are mostly the policy’s already-likely tokens, so most positive-advantage updates sharpen the distribution, and the step size (learning rate, epochs) sets how fast. Options: (a) lower the learning rate or the number of epochs, which slows learning too; (b) a KL penalty to the starting policy, which holds entropy near the reference’s at a cost in pass@1; (c) an entropy bonus, with a small coefficient and a watch on malformed outputs; (d) clip-higher, which helps only if the clip binds; (e) a higher sampling temperature, which delays collapse. Default: the book’s recommendation is to log entropy and pass@ from the first step, and to treat collapse as a problem only when pass@ falls or a known-good behavior disappears; try (b) with the k3+ gradient before (c). The histories show how fast the default run collapses and what (b) and (c) change.
Problem: a KL coefficient that is too strong or too weak. Symptom: too strong, the logged KL stays near zero, reward plateaus early, and a behavior the reference rarely shows (here, reading) never takes over; too weak, the KL grows without bound and the term does nothing measurable. Cause: at the optimum of Section 10.1, the policy tilts the reference by , so must be compared with reward differences, and the per-token KL must be compared with per-token advantages. The scale also depends on placement: a per-token mean in the loss and a per-episode sum in the reward differ by the number of policy tokens (about 13 here, thousands for agents). Options: (a) sweep on a log grid while logging the KL; (b) an adaptive controller that adjusts toward a target KL (verl’sAdaptiveKLController); (c) no KL, with a held-out regression suite. Default: (c) for verifiable rewards, following the public coding-agent recipes; (b) when a learned reward or judge is in the loop. The KL logs of the threek3+runs show the regimes.
Problem: the memory and compute cost of the reference model. Symptom: enabling a KL term runs the trainer out of memory or adds a large share to step time. Cause: the reference is a second full model that must produce log-probabilities for every training token. It needs only its weights (no gradients or optimizer state), but it adds one forward pass to a step that otherwise consists of the trainer’s log-probability pass for (Chapter 9 recomputes it) and one forward and backward pass. Options: (a) compute reference log-probs on the inference fleet during rollout and ship them with the batch; (b) offload or shard the reference separately; (c) with LoRA training, use the base model with adapters disabled as the reference, at no extra memory; (d) drop the KL. Default: (d) when the reward is verifiable, otherwise (c) or (a). The arithmetic for a few model sizes, assuming bf16 weights and gradients with fp32 master weights and Adam moments (16 bytes per trained parameter):
Problem: resetting the reference. Symptom: with a KL penalty, the logged KL settles at a plateau while the reward stops improving; the penalty, not the task, has become the binding constraint. Cause: the reference is the starting policy, so the further training has to go from the start, the more of each update the KL gradient cancels. Options: (a) lower ; (b) hard-reset the reference to the current policy (and, as ProRL does, the optimizer state), which keeps the KL as a local trust region rather than an anchor to the start; (c) drop the KL. Default: if a KL is used at all, reset on a schedule tied to a validation plateau, as ProRL reports doing. We continue the run for 20 steps twice, once anchored to the start and once with the reference reset to the current policy; both restart the optimizer.
Summary
- The KL-regularized objective has the closed-form optimum : the reference tilted by the exponentiated reward, never leaving the reference’s support. An entropy bonus is the same objective with a uniform reference.
- Of Schulman’s estimators, and are unbiased values and has by far the lowest spread at small KL. As losses, they give different gradients: gives zero in expectation, gives the reverse-KL gradient, and gives the forward-KL gradient, with an error against the reverse direction that grows with the distance.
kl_estimate(..., 'k3+')logs and differentiates as . - For sequences, a per-token KL loss ignores how a token changes the KL of the tokens after it; KL in the reward, through the policy gradient, gives the exact sequence gradient. On TinyAgent the reward placement at the same was a much stronger penalty, because it sums over tokens and enters the advantage.
- Reverse KL is mode-seeking and forward KL mass-covering; a reverse-KL penalty does not by itself preserve the reference’s alternatives.
- Entropy falls when updates raise already-likely tokens, . On TinyAgent the unregularized run went from 0.52 to 0.12 nats in 40 steps and never solved two of ten held-out tasks in 16 attempts; KL penalties and an entropy bonus slowed the collapse and raised pass@8 at a cost in pass@1, an entropy bonus of 0.1 destroyed the action format, and clip-higher had no measurable effect on entropy. These are one-seed mechanism demonstrations.
- With verifiable rewards, dropping the KL (DAPO, DeepSWE) removes a reference model and a tuning knob; keeping it (ProRL) trades pass@1 for entropy and needs reference resets to stop anchoring training to its start.
Exercises
- Show that adding the missing score-function term to a loss, , gives the reverse-KL gradient, and that the same correction applied to also does. Check both with
expected_loss_grad-style enumeration. Why does nobody implement the corrected instead ofk3+? - Expand to third order in and predict the bias column of Section 10.2 for small KL. At what KL does your approximation fail?
- Change an assumption: rerun Section 10.7 for 80 steps instead of 40, with the unregularized and
KL k3+ 0.05settings only. Does the unregularized run’s pass@8 fall below the regularized one’s once its entropy reaches Chapter 9’s 0.08? Report the difference against the spread of three seeds. - Extend the two-token model of Section 10.4 to three tokens and implement a loss placement that is exact: the per-token loss plus a REINFORCE term carrying each token’s future KL. Verify it against the exact gradient, then explain which part a GRPO trainer would have to add to its loss to implement it.
- Implement an adaptive KL coefficient ( per step) in a copy of
train_regularized. Which target KL lets TinyAgent learn to read while keeping pass@8 at least as high as the unregularized run? - Restrict the entropy bonus to the first policy token after each tool observation (the positions ARPO identifies as high-entropy; Chapter 20). Compare malformed calls and pass@8 with the uniform bonus at a matched mean entropy.
- Design review: a team trains a SWE agent with verl’s defaults,
use_kl_loss=True,kl_loss_type=low_var_kl,kl_loss_coef=0.001, on a test-execution reward. The loggedkl_lossis 0.02 and policy entropy has fallen by 70% in 200 steps. Using this chapter, argue whether the KL term is doing anything, which gradient it computes, what you would log next, and what you would change if the reward were an LLM judge instead of tests.