8.1 Off-policy reuse and importance sampling
Let be the policy that sampled a batch and the policy after some updates. The objective is an expectation under , and the data come from . Importance sampling rewrites one expectation as the other (Appendix A.1): The trajectory weight looks as if it needs the environment’s transition probabilities. It does not. Both trajectory probabilities factor as in Equation (6.2) into policy tokens and everything else, and the “everything else” (prompt, template, tool outputs) has the same probability under both policies because the environment did not change. It cancels: This is Equation (8.1), the exact trajectory ratio, and is the per-token ratio. Differentiating gives , which at is REINFORCE again. So the exact correction exists and is unbiased. The question is its variance. We measure it. The base agent samples 320 episodes, the “old” batch. A copy of the base agent then takes REINFORCE steps on fresh batches, which moves it the way training would. For each we compute for every old episode, the effective sample size (the number of equally weighted samples the weighted batch is worth), the IS estimate of the new policy’s pass rate, and the pass rate measured on fresh samples.The per-token approximation
PPO does not use . It uses each token’s own ratio , which involves one token’s probabilities and stays near 1 when the policy changes little. The justification is the performance-difference identity (Kakade and Langford, 2002), here at the token level: The inner expectation reweights the action at each prefix, which one ratio does exactly. The outer expectation is over the prefixes that the new policy visits, and that is the part that needed the product of all earlier ratios. The surrogate replaces by , the prefixes in the batch: This is Equation (8.2). It is an approximation, and the book states it as such everywhere it appears: per-token ratios correct for the change in each action’s probability and ignore the change in which prefixes are visited. agrees with (up to a constant) to first order in , so it has the same gradient at , and its error grows with the distance between the two policies. Schulman et al. (2015) bound that error by a multiple of the maximum KL divergence between the policies, which is where the trust region of Section 8.3 comes from. We check the approximation on the same old batch: the surrogate estimate of the improvement, , against the improvement measured on fresh samples.8.2 The clipped surrogate
Maximizing Equation (8.2) with many gradient steps would drive the ratios as far as they can go, into the region where the surrogate is wrong. PPO’s clipped objective removes the incentive to go there: This is Equation (8.3). The minimum makes it a pessimistic bound on the unclipped surrogate, and its behavior depends on the sign of the advantage:- (the token should become more likely). The term is until reaches and then stays constant. Once a good token’s probability has grown by the factor , its gradient is zero. Below 1 the minimum keeps the unclipped term, so a good token whose probability fell is always pushed back up.
- (the token should become less likely). The term is until falls to and then stays constant. Above 1 the unclipped term, which is more negative, is kept: a bad token whose probability rose is always pushed back down, with a gradient that grows with .
aggregate_loss, and returns the statistics that Section 8.5 uses as diagnostics. A clipped token is one where the clipped branch is strictly smaller, which is exactly where the gradient is zero.
approx_kl statistic is the estimator of from samples of : , which is nonnegative token by token (Appendix A; Chapter 10 compares it with the other estimators). The gradient of the loss with respect to each token’s log-probability shows the per-sign behavior. Six tokens with ratios from 0.5 to 2, once with and once with ; seq_mean_token_sum over one row makes each token’s gradient its raw weight.
Dual clipping
The unbounded piece for is deliberate, but it has a failure mode. If a bad token’s ratio is very large, for example because the batch is stale or the sampler’s probabilities were wrong (Chapter 13), the term can dominate the whole batch’s gradient. Dual clipping (Ye et al., 2020) bounds the objective below by for a constant , usually 3:8.3 The trust-region view
Section 8.1 showed that the surrogate is accurate near . Trust Region Policy Optimization (TRPO; Schulman et al., 2015) turns that into an algorithm. Its analysis gives a lower bound of the form where here is the surrogate improvement and depends on the discount and on the largest advantage. Maximizing the right-hand side guarantees improvement. In practice TRPO maximizes subject to an average KL constraint , using the natural gradient: it solves for the Fisher information matrix by conjugate gradient with Fisher-vector products, scales the step to the constraint, and backtracks with a line search until the surrogate improves and the KL is inside the region. For a language model, each Fisher-vector product is a second-order pass through the whole network, and the line search needs extra forward passes. That is why TRPO itself is rarely used for LLMs, while its idea is everywhere. PPO replaces the constraint with clipping, which costs nothing beyond a first-order optimizer. The two are not equivalent. Clipping removes the incentive to push a token’s ratio past , but parameters are shared across tokens, so a step that helps other tokens can move a clipped token further, and nothing pulls it back. The block below takes one minibatch of the old batch and runs 40 Adam steps on the clipped loss and, for comparison, on the unclipped surrogate (the clip set to infinity), then reports the KL and the share of ratios outside .8.4 The value loss and the PPO loop
PPO as published trains a critic alongside the policy and uses GAE advantages (Section 7.3). The critic regresses on the value targets thatgae_advantages returns. Because the critic is also updated several times on the same batch, the same trust-region problem appears, and PPO2-style implementations clip it the same way: the new value may move at most away from the value recorded at sampling time before the clipped branch takes over,
The maximum makes it pessimistic, as the policy’s minimum does. Whether value clipping helps is disputed. In a large study of on-policy design choices on continuous-control tasks, Andrychowicz et al. (2021) found that “PPO-style value loss clipping hurts the performance regardless of the clipping threshold”; that evidence is not from language models. We implement it because it is the default in many LLM PPO stacks, with clip=None to turn it off.
The critic needs a head start
Section 7.4 measured how weak a TinyAgent critic is: explained variance 0.02 to 0.08 on fresh episodes. A critic whose new head starts from random weights is worse still, and with its errors enter the policy gradient directly (Figure 7.1). Two mitigations are standard, and we use both: warm up the critic on rollouts of the initial policy before the first policy update, and start with , where the critic is only a baseline and cannot bias the gradient.warm_critic is Chapter 7’s regression on Monte Carlo returns.
One PPO iteration
An iteration has two phases. The first freezes everything that defines : the log-probabilities of the sampled tokens, the critic’s values, and the GAE advantages and targets computed from them. Advantages are then whitened across the batch’s policy tokens (mean 0, standard deviation 1), as most PPO implementations do. The second phase runsepochs passes over the batch in shuffled minibatches, each with one policy step and one critic step, and records the statistics of each epoch.
Evidence. Measured here, one seed per setting, 30 iterations of 64 episodes. The comparison between and is within the noise of a single run and should not be read as a preference. What the run does support is the mechanism claim: with a critic this weak, GAE adds little, and the critic costs a second network and a second optimizer.
8.5 Diagnostics and early stopping
Three numbers tell an engineer whether reuse is safe, and every PPO-family trainer should log them per epoch.- Clip fraction: the share of policy tokens whose clipped branch is active. Near 0, the clip is idle and the update is plain policy gradient. Rising across epochs, the policy is reaching the edge of the trust region.
- Approximate KL between and , the estimate on the batch. It measures how far the policy has moved in the quantity the trust-region bound uses.
- Ratio statistics: the minimum and maximum ratio over policy tokens, which catch the few tokens the averages hide.
ppo_epochs already accepts target_kl; we rerun the setting with a target of 0.02 and count how many epochs each iteration used.
8.6 Design problems in practice
Problem: too many epochs. Symptom: the clip fraction and the KL climb across epochs, the policy’s entropy collapses or, after many epochs, jumps, and the training reward becomes erratic. Cause: each epoch moves the policy further from (Section 8.3), the surrogate’s error grows with that distance (Section 8.1), and the clip does not stop the drift. Options: (a) fewer epochs, which wastes less compute per sample than it seems because later epochs are mostly clipped. (b) Early stopping on a KL target, which adapts the number of epochs per batch. (c) A smaller learning rate, which makes each epoch cheaper in KL but slows learning. Default: 1 to 2 epochs for LLM agents, with early stopping as a guard, because rollouts are where the money goes but a corrupted policy wastes all of them. The block below updates one batch for 16 epochs and prints every fourth.
Problem: minibatch size versus staleness. Symptom: splitting a batch into more minibatches speeds learning per sample at first, then destabilizes it. Cause: minibatch of an epoch is evaluated under a policy that has already taken steps on the same batch, so later minibatches are more off-policy, even in the first epoch. Options: (a) fewer, larger minibatches, which are closer to on-policy but take fewer steps per sample. (b) More minibatches with a smaller learning rate. (c) Early stopping that counts minibatch steps rather than epochs. Default: 2 to 4 minibatches per batch, with clip fraction and KL logged per minibatch. The block below runs one epoch on the old batch with 1 to 16 minibatches and reports the KL seen by the last minibatch.
Problem:old_logpfrom the trainer or from the sampler. Symptom: a run whose clip fraction is high from the very first minibatch, or a run in which the clip never activates however many epochs it takes. Cause: must be the distribution that actually sampled the tokens. Recomputingold_logpwith the trainer’s forward pass is correct only if the trainer computes the same probabilities as the sampler. Recomputing it inside the update loop, from the current parameters, is a bug: every ratio is then exactly 1. Options: (a) recomputeold_logponce, before the first update, with the trainer, which is what this chapter and most open-source trainers do. (b) Use the sampler’s log-probabilities, which is exact about the behavior policy but makes ratios absorb any numerical mismatch between the engines. (c) Use both: the trainer’s for the PPO ratio and the sampler’s for an explicit mismatch correction (Chapter 13). Default: (a) in a single-process setting like this one, (c) in production. The block below compares Chapter 5’s storedsample_logpwith the trainer’s recomputation, then reproduces the bug.
old_logp taken from the current forward pass, every ratio is 1, the clip never binds, and the loss is plain REINFORCE no matter how many steps run. The dashboards show a clip fraction of exactly 0 and a KL of exactly 0, which is itself the signature.
Problem: asymmetric clipping. Symptom: entropy falls steadily during training, and rare actions that turn out to be good gain probability very slowly. Cause: the upper clip bounds the relative growth of a good token’s probability per batch by , so a token with can reach at most 0.012 with , while a token at 0.5 can reach 0.6. The lower clip bounds how fast probability can be removed from a bad token, and the removed mass flows mostly to the already-likely tokens. Both effects concentrate the distribution. Options: (a) clip-higher: raise (DAPO uses 0.28 with ; Chapter 9), which lets rare good tokens grow faster at the cost of a looser trust region. (b) An entropy bonus (Chapter 10). (c) Lower to slow the removal of mass. Default: symmetric 0.2 as the baseline, and clip-higher when entropy collapse is measured. The block below asks which tokens the upper clip actually stopped in the 16-epoch run, by their probability under .
Summary
- Reusing a batch after an update requires reweighting. The exact trajectory weight is a product of per-token ratios over policy tokens (the environment’s terms cancel), and its variance grows exponentially with the number of policy tokens: after three REINFORCE updates, 320 base-agent episodes were worth a third of their number, and the IS estimate of the new pass rate fell far below the truth.
- PPO’s surrogate uses per-token ratios. It corrects each action’s probability and ignores the change in which prefixes are visited, so it agrees with the true improvement to first order and loses accuracy as the policy moves: it predicted the improvement of one and three updates to within half a point and missed a sixth of ten updates’.
- The clipped objective removes the incentive to push a token’s ratio past in the direction its advantage asks for, and keeps the gradient that undoes moves in the wrong direction. It is a soft trust region: after 40 steps on one minibatch, 41% of ratios were outside the band, though the KL was 25 times smaller than without the clip. Dual clipping bounds the influence of very large ratios on negative-advantage tokens.
- PPO with a warmed-up critic learned the training tasks in 30 batches. The critic explained 12% to 26% of the variance of the returns, so it acted mostly as a baseline, and heavy reuse made the memorization of Chapter 6 worse on held-out tasks.
- Log clip fraction, approximate KL, and ratio extremes per epoch. Both grow with every epoch and every extra minibatch; early stopping at a KL target of 0.02 used about 63% of the gradient steps for the same training pass rate. Recompute
old_logponce before updating, never inside the loop.
Exercises
- Show that the environment’s factors cancel in Equation (8.1) even when the environment is stochastic, as long as both policies face the same environment. Which assumption fails when the tool outputs depend on wall-clock time or on a shared cache, and what happens to the ratio?
- Derive the performance-difference identity of Section 8.1 from the definition of by telescoping along a trajectory of . Where exactly does the per-token surrogate make its approximation?
- Change an assumption: repeat the IS table of Section 8.1 with self-normalized importance sampling, . Is it closer to the fresh-sample pass rate? It is biased; in which direction, and why is that bias often preferred?
- Implement the KL-penalty variant of PPO (“PPO-penalty”): no clipping, a term in the loss, and doubled or halved after each batch to track a KL target. Compare its per-epoch KL with the clipped version on the run of Section 8.4.
- Run Section 8.4’s PPO with
value_loss(..., clip=None)and withclip=0.05. Track the critic’s explained variance on fresh episodes. Does value clipping help or hurt this critic? - Measure the clip fraction separately for positive- and negative-advantage tokens in the 16-epoch run. Which side binds more often, and how does raising to 0.28 change the entropy after 16 epochs?
- Design review: a teammate proposes 8 epochs of 8 minibatches per batch “to make rollouts eight times cheaper”. Using the measurements of Section 8.6, list what you would expect on the dashboard, the experiment you would ask for, and the guard you would require before agreeing.