Type at least 2 letters. Enter opens the first result, Esc closes.

    Reinforcement Learning · Lesson 9 · Trust regions, language models and planning

    Trust regions, PPO and RL for language models

    Advanced 95 min 5 interactive figures 4 videos Colab notebook

    Before this lesson: lesson 07 (the policy gradient theorem, REINFORCE and baselines), lesson 08 (advantages, GAE and the soft-greedy policy π∝exp⁡(Q/α)\pi \propto \exp(Q/\alpha)) and the importance ratio of lesson 04. KL divergence: information theory 03 and, for forward vs reverse KL, information theory 06. The Fisher matrix and natural gradient (optional): optimization 10. The full LLM training pipeline (SFT, reward models, DPO) is outside this track. Time: about 95 minutes, plus the notebook.


    Why this matters #

    • PPO is the default on-policy deep RL algorithm. It is simple, works with shared actor-critic networks, and reuses each batch for several epochs. It trained OpenAI Five (Dota 2) and many robotics and game agents.
    • RLHF. InstructGPT (Ouyang et al., 2022) fine-tuned GPT-3 with PPO on the score of a reward model learned from human preferences, plus a per-token KL penalty to the supervised model. This recipe made chat assistants follow instructions.
    • RL with verifiable rewards. GRPO (DeepSeekMath, 2024) removes the critic and uses a group of sampled answers as the baseline. As of 2025 it and its variants (Dr. GRPO, DAPO and others) are a standard way to train reasoning models such as DeepSeek-R1 on math and code, where a program checks the answer.
    • One idea behind all of them: distribution shift. The trust region (TRPO, PPO), the KL penalty (RLHF) and the behaviour constraint of offline RL (lesson 06) all keep the policy where the data, or the reward model, can be trusted.

    1. Predict first #

    2. The picture #

    Why big steps fail. Think of climbing a hill in fog. You can see the slope only near your feet. A small step uphill is safe. A long jump in the same direction can land you lower than before. In RL the "fog" is the data: every sample was collected by the old policy πold\pi_{\text{old}}. To judge a new policy πθ\pi_\theta with old samples, we reweight each sample by the probability ratio

    ρt(θ)=πθ(at∣st)πold(at∣st),\rho_t(\theta) = \frac{\pi_\theta(a_t \mid s_t)}{\pi_{\text{old}}(a_t \mid s_t)} ,

    the importance weight of lesson 04. This corrects for the actions. It does not correct for the states: a new policy also visits other states, and the old batch has no information about how often. This error is small for small steps and large for large steps.

    A small example where this matters. An agent has two states, s1s_1 (the start) and s2s_2, and three actions. It cannot tell the two states apart (they look the same to it), so one softmax policy π=softmax(θ)\pi = \mathrm{softmax}(\theta) with θ∈R3\theta \in \R^3 acts in both. This is the normal situation with function approximation: one parameter vector serves many states. Rewards and next states, with γ=0.9\gamma = 0.9:

    a1a_1 (forward) a2a_2 (wait) a3a_3 (back)
    s1s_1 +1+1, go to s2s_2 +0.2+0.2, stay in s1s_1 00, stay in s1s_1
    s2s_2 −1-1, stay in s2s_2 00, stay in s2s_2 00, go to s1s_1

    The old policy is uniform (θold=0\theta_{\text{old}} = 0). It spends a lot of time in s2s_2, where "back" is very good (advantage +0.96+0.96). So the policy gradient says: more "back", less "forward". But "back" is slightly bad in s1s_1 (advantage −0.09-0.09). A policy that almost always goes back never reaches s2s_2 again, so it spends all its time in s1s_1, where "back" earns nothing.

    Interactive figure: loading…

    Predict, then slide. Move the step size tt along the policy gradient. The blue curve is the true improvement J(πnew)−J(πold)J(\pi_{\text{new}}) - J(\pi_{\text{old}}), computed exactly. The violet curve is the surrogate LL, the improvement predicted from old data. Near t=0t = 0 they agree (same value, same slope). Far away the surrogate keeps rising while the true improvement falls below zero. The lower chart shows the KL from the old policy (solid) and its Fisher approximation 12t2u⊤Fu\tfrac12 t^2 u^\top F u (dashed). The shaded band is the trust region KL≤δ\mathrm{KL} \le \delta.

    This answers question 1. The first small steps help almost as predicted: at t=0.25t = 0.25 the surrogate predicts 0.460.46 and the true gain is 0.380.38. But the true gain peaks near t=0.72t = 0.72 (about 0.620.62) and becomes negative after t≈2.03t \approx 2.03, while the surrogate keeps growing to above 2.52.5. A trust region of size δ=0.05\delta = 0.05 stops at t=0.56t = 0.56, with a true gain of 0.600.60, close to the best possible on this line.

    PPO's rule, as a picture. PPO does not compute any KL during the update. For each sample it looks at ρt\rho_t and the advantage estimate A^t\hat A_t (from GAE, lesson 08). If A^t>0\hat A_t > 0, the update wants to make the action more likely, so ρt\rho_t grows. Once ρt>1+ε\rho_t > 1 + \varepsilon, PPO stops rewarding further growth: that sample's gradient becomes zero. If A^t<0\hat A_t < 0, the same happens once ρt<1−ε\rho_t < 1 - \varepsilon. Here ε\varepsilon (typically 0.20.2) is the clip range; it is not the exploration rate of earlier lessons.

    Interactive figure: loading…

    Drag the orange point along the curve (or use the ρ\rho slider), then switch the sign of A^\hat A. The solid orange curve is PPO's per-sample objective min⁡(ρA^,clip⁡(ρ,1−ε,1+ε)A^)\min(\rho \hat A, \operatorname{clip}(\rho, 1-\varepsilon, 1+\varepsilon)\hat A); the dashed line is the unclipped ρA^\rho \hat A. In the magenta region the curve is flat, so the gradient is zero. Notice that the flat part is only on one side: a sample that moved the wrong way keeps its full gradient.

    Quick check

    PPO with ε=0.2\varepsilon = 0.2. Which sample gives zero gradient?

    3. Definitions and main results #

    3.1 Setup and notation #

    We use the notation of the track. J(π)=Es0∼p0[Vπ(s0)]J(\pi) = \mathbb E_{s_0 \sim p_0}[V^\pi(s_0)] is the expected discounted return from the start distribution p0p_0. Aπ=Qπ−VπA^\pi = Q^\pi - V^\pi is the advantage. The discounted visitation of a policy is

    dπ(s)=∑t≥0γtPr⁡π(st=s),∑sdπ(s)=11−γ.d^\pi(s) = \sum_{t \ge 0} \gamma^t \Pr\nolimits_\pi(s_t = s), \qquad \sum_s d^\pi(s) = \frac{1}{1 - \gamma}.

    It is unnormalised; (1−γ)dπ(1 - \gamma) d^\pi is a probability distribution. Three policies appear in this lesson. Keep them apart:

    Symbol What it is Where it appears
    πθ\pi_\theta the policy we are training everywhere
    πold\pi_{\text{old}} the policy that collected the current batch; fixed during one update in the ratio ρt\rho_t
    πref\pi_{\text{ref}} a frozen copy of the starting model (in LLMs: the supervised model) in the KL penalty of RLHF

    3.2 The performance difference lemma #

    The first result says exactly how much better a new policy π′\pi' is than an old policy π\pi, using the old advantages.

    Theorem (performance difference lemma; Kakade and Langford, 2002). For any two policies π\pi and π′\pi', with bounded rewards and γ<1\gamma < 1,

    J(π′)−J(π)=Eτ∼π′[∑t≥0γtAπ(st,at)]=∑sdπ′(s)∑aπ′(a∣s) Aπ(s,a).J(\pi') - J(\pi) = \mathbb E_{\tau \sim \pi'}\Big[\sum_{t \ge 0} \gamma^t A^\pi(s_t, a_t)\Big] = \sum_s d^{\pi'}(s) \sum_a \pi'(a \mid s)\, A^\pi(s, a).

    In words: run the new policy, and add up the old policy's advantages of the actions it takes.

    Why this is true (intuition). Aπ(s,a)A^\pi(s, a) measures how much better action aa is than following π\pi from ss. The new policy is a sequence of such "deviations" from π\pi, one per step. Each deviation changes the return by its advantage, and the changes add up.

    Proof.

    1. Fix a start state s0s_0 and a trajectory s0,a0,r0,s1,…s_0, a_0, r_0, s_1, \dots of π′\pi'. Because VπV^\pi is bounded and γ<1\gamma < 1, the sum ∑t≥0γt(γVπ(st+1)−Vπ(st))\sum_{t \ge 0} \gamma^t \big(\gamma V^\pi(s_{t+1}) - V^\pi(s_t)\big) telescopes (neighbouring terms cancel) and equals −Vπ(s0)-V^\pi(s_0). Write out the first terms to see it: (γV1−V0)+(γ2V2−γV1)+(γ3V3−γ2V2)+⋯=−V0(\gamma V_1 - V_0) + (\gamma^2 V_2 - \gamma V_1) + (\gamma^3 V_3 - \gamma^2 V_2) + \dots = -V_0.
    2. Vπ′(s0)=Eτ∼π′[∑tγtrt]V^{\pi'}(s_0) = \mathbb E_{\tau \sim \pi'}[\sum_t \gamma^t r_t] is the expected return of π′\pi'. Add the zero-sum identity of step 1 inside the expectation: Vπ′(s0)−Vπ(s0)=Eτ∼π′[∑t≥0γt(rt+γVπ(st+1)−Vπ(st))]V^{\pi'}(s_0) - V^\pi(s_0) = \mathbb E_{\tau \sim \pi'}\big[\sum_{t \ge 0} \gamma^t \big(r_t + \gamma V^\pi(s_{t+1}) - V^\pi(s_t)\big)\big].
    3. Condition on (st,at)(s_t, a_t). The next state comes from the environment, st+1∼P(⋅∣st,at)s_{t+1} \sim P(\cdot \mid s_t, a_t), which does not depend on the policy. So E[rt+γVπ(st+1)∣st,at]=Qπ(st,at)\mathbb E[r_t + \gamma V^\pi(s_{t+1}) \mid s_t, a_t] = Q^\pi(s_t, a_t), and term tt has expectation E[γt(Qπ(st,at)−Vπ(st))]=E[γtAπ(st,at)]\mathbb E[\gamma^t (Q^\pi(s_t, a_t) - V^\pi(s_t))] = \mathbb E[\gamma^t A^\pi(s_t, a_t)].
    4. Average over s0∼p0s_0 \sim p_0. Then group the terms by state: the weight of state ss is ∑tγtPr⁡π′(st=s)=dπ′(s)\sum_t \gamma^t \Pr_{\pi'}(s_t = s) = d^{\pi'}(s), and the action there is drawn from π′(⋅∣s)\pi'(\cdot \mid s). ■\blacksquare

    The lemma is exact, but it has a problem: it needs states from dπ′d^{\pi'}, the new policy's visitation. We cannot sample those before we have chosen π′\pi'.

    3.3 The surrogate objective and TRPO #

    Replace dπ′d^{\pi'} by dπd^\pi and write the inner sum with importance weights. This gives the surrogate objective

    Lπ(π′)=∑sdπ(s)∑aπ′(a∣s)Aπ(s,a)=∑sdπ(s) Ea∼π(⋅∣s)[π′(a∣s)π(a∣s)Aπ(s,a)].L_\pi(\pi') = \sum_s d^\pi(s) \sum_a \pi'(a \mid s) A^\pi(s, a) = \sum_s d^\pi(s)\, \mathbb E_{a \sim \pi(\cdot \mid s)}\Big[\frac{\pi'(a \mid s)}{\pi(a \mid s)} A^\pi(s, a)\Big].

    Every term can be estimated from the old batch: states and actions come from π\pi, and π′\pi' only appears in the ratio. In practice LL is the sample mean of ρtA^t\rho_t \hat A_t (up to the constant 1/(1−γ)1/(1-\gamma)).

    Theorem (first-order agreement). For a differentiable policy πθ\pi_\theta with π=πθold\pi = \pi_{\theta_{\text{old}}}: Lπ(πθold)=0=J(πθold)−J(π)L_\pi(\pi_{\theta_{\text{old}}}) = 0 = J(\pi_{\theta_{\text{old}}}) - J(\pi), and ∇θLπ(πθ)∣θold=∇θJ(πθ)∣θold\nabla_\theta L_\pi(\pi_\theta)\big|_{\theta_{\text{old}}} = \nabla_\theta J(\pi_\theta)\big|_{\theta_{\text{old}}}.

    Proof.

    1. Value: ∑aπ(a∣s)Aπ(s,a)=Vπ(s)−Vπ(s)=0\sum_a \pi(a \mid s) A^\pi(s, a) = V^\pi(s) - V^\pi(s) = 0 for every ss, so Lπ(π)=0L_\pi(\pi) = 0.
    2. Gradient: ∇θL=∑sdπ(s)∑a∇θπθ(a∣s) Aπ(s,a)\nabla_\theta L = \sum_s d^\pi(s) \sum_a \nabla_\theta \pi_\theta(a \mid s)\, A^\pi(s, a).
    3. Since ∑aπθ(a∣s)=1\sum_a \pi_\theta(a \mid s) = 1, we have ∑a∇θπθ(a∣s)=0\sum_a \nabla_\theta \pi_\theta(a \mid s) = 0, so we may replace AπA^\pi by Qπ=Aπ+Vπ(s)Q^\pi = A^\pi + V^\pi(s) without changing the sum.
    4. ∑sdπ(s)∑a∇θπθ(a∣s)Qπ(s,a)\sum_s d^\pi(s) \sum_a \nabla_\theta \pi_\theta(a \mid s) Q^\pi(s, a) is exactly ∇θJ\nabla_\theta J by the policy gradient theorem of lesson 07. ■\blacksquare

    Why replacing dπ′d^{\pi'} by dπd^\pi is a second-order error. The difference between the lemma and the surrogate is ∑s(dπ′(s)−dπ(s))∑aπ′(a∣s)Aπ(s,a)\sum_s \big(d^{\pi'}(s) - d^\pi(s)\big) \sum_a \pi'(a \mid s) A^\pi(s, a). Both factors are zero when π′=π\pi' = \pi, and both grow linearly with a small change of θ\theta. Their product grows like the square of the step. So LL is accurate near π\pi and can be badly wrong far away, as the first figure showed.

    Theorem (TRPO lower bound; Schulman et al., 2015, Theorem 1). With C=4γmax⁡s,a∣Aπ(s,a)∣(1−γ)2C = \dfrac{4 \gamma \max_{s,a} |A^\pi(s,a)|}{(1-\gamma)^2},

    J(π′)−J(π) ≥ Lπ(π′)−Cmax⁡sKL(π(⋅∣s) ∥ π′(⋅∣s)).J(\pi') - J(\pi) \ \ge\ L_\pi(\pi') - C \max_s \mathrm{KL}\big(\pi(\cdot \mid s) \,\|\, \pi'(\cdot \mid s)\big).

    The right side is 00 at π′=π\pi' = \pi. So if each update maximizes the right side, the true JJ never decreases (a minorize-maximize scheme). We do not prove the bound here; the proof is in the TRPO paper (§3 and Appendix A).

    In practice CC is huge (in the example above C=4⋅0.9⋅0.98/0.01≈353C = 4 \cdot 0.9 \cdot 0.98 / 0.01 \approx 353), and the penalized steps would be tiny. TRPO therefore solves a constrained problem with a chosen radius δ\delta (for example 0.010.01):

    max⁡θ E^t[ρt(θ) A^t]subject toE^t[KL(πold(⋅∣st) ∥ πθ(⋅∣st))]≤δ.\max_\theta\ \hat{\mathbb E}_t\big[\rho_t(\theta)\, \hat A_t\big] \quad \text{subject to} \quad \hat{\mathbb E}_t\big[\mathrm{KL}\big(\pi_{\text{old}}(\cdot \mid s_t) \,\|\, \pi_\theta(\cdot \mid s_t)\big)\big] \le \delta .

    Here E^t\hat{\mathbb E}_t is the average over the batch, and the max over states is replaced by an average.

    The KL is locally a quadratic form. Near θold\theta_{\text{old}}, with Δ=θ−θold\Delta = \theta - \theta_{\text{old}},

    KL(πθold ∥ πθ)≈12 Δ⊤F Δ,F=Ea∼πθold[∇θlog⁡πθ(a) ∇θlog⁡πθ(a)⊤],\mathrm{KL}\big(\pi_{\theta_{\text{old}}} \,\|\, \pi_\theta\big) \approx \tfrac12\, \Delta^\top F\, \Delta, \qquad F = \mathbb E_{a \sim \pi_{\theta_{\text{old}}}}\big[\nabla_\theta \log \pi_\theta(a)\, \nabla_\theta \log \pi_\theta(a)^\top\big],

    where FF is the Fisher information matrix. The value and the gradient of the KL are zero at Δ=0\Delta = 0, so the first term of its Taylor series is the quadratic one, and its Hessian is FF. For a softmax over logits, ∇θlog⁡π(a)=ea−p\nabla_\theta \log \pi(a) = e_a - p and F=diag(p)−pp⊤F = \mathrm{diag}(p) - pp^\top.

    The natural gradient, conjugate gradient and line search

    Maximize the linear model g⊤Δg^\top \Delta (gg is the policy gradient) subject to 12Δ⊤FΔ≤δ\tfrac12 \Delta^\top F \Delta \le \delta. The Lagrangian condition gives Δ∝F−1g\Delta \propto F^{-1} g, the natural gradient, and the constraint fixes the length:

    Δ=2δg⊤F−1g  F−1g.\Delta = \sqrt{\frac{2\delta}{g^\top F^{-1} g}}\; F^{-1} g .

    For a network with millions of parameters, FF cannot be stored. TRPO computes x≈F−1gx \approx F^{-1} g with about 10 steps of conjugate gradient, which needs only Fisher-vector products FvFv (two backward passes, no matrix). Because the quadratic model is only approximate, TRPO then runs a backtracking line search: it halves the step until the true sample KL is at most δ\delta and the surrogate improves. For a softmax, FF is singular along (1,…,1)(1, \dots, 1) (adding a constant to all logits does not change pp), so one uses the pseudo-inverse or a small damping F+λIF + \lambda I.

    Numerical check. θ=(0.5,−0.2,0.1)\theta = (0.5, -0.2, 0.1), Δ=(0.03,−0.02,0.01)\Delta = (0.03, -0.02, 0.01): the exact KL is 1.918⋅10−41.918 \cdot 10^{-4} and 12Δ⊤FΔ=1.927⋅10−4\tfrac12 \Delta^\top F \Delta = 1.927 \cdot 10^{-4}. The natural gradient and K-FAC are in optimization 10 and optimization 12.

    3.4 PPO: the clipped surrogate #

    TRPO needs second-order machinery. PPO (Schulman et al., 2017) gets most of its benefit with first-order SGD. With ρt(θ)=πθ(at∣st)/πold(at∣st)\rho_t(\theta) = \pi_\theta(a_t \mid s_t) / \pi_{\text{old}}(a_t \mid s_t) and advantage estimates A^t\hat A_t:

    LCLIP(θ)=E^t[min⁡(ρtA^t, clip⁡(ρt,1−ε,1+ε) A^t)].L^{\text{CLIP}}(\theta) = \hat{\mathbb E}_t\Big[\min\big(\rho_t \hat A_t,\ \operatorname{clip}(\rho_t, 1 - \varepsilon, 1 + \varepsilon)\, \hat A_t\big)\Big].

    The derivative of ρtA^t\rho_t \hat A_t with respect to log⁡πθ(at∣st)\log \pi_\theta(a_t \mid s_t) is ρtA^t\rho_t \hat A_t, because ρt=exp⁡(log⁡πθ−log⁡πold)\rho_t = \exp(\log \pi_\theta - \log \pi_{\text{old}}). The four cases:

    Case Term chosen by the min Gradient w.r.t. log⁡πθ(at∣st)\log \pi_\theta(a_t \mid s_t)
    A^>0\hat A > 0, ρ≤1+ε\rho \le 1 + \varepsilon ρA^\rho \hat A ρA^\rho \hat A (push up)
    A^>0\hat A > 0, ρ>1+ε\rho > 1 + \varepsilon (1+ε)A^(1 + \varepsilon)\hat A, a constant 00
    A^<0\hat A < 0, ρ≥1−ε\rho \ge 1 - \varepsilon ρA^\rho \hat A ρA^\rho \hat A (push down)
    A^<0\hat A < 0, ρ<1−ε\rho < 1 - \varepsilon (1−ε)A^(1 - \varepsilon)\hat A, a constant 00

    Zero-gradient condition. The gradient is zero only when the sample has already moved by more than ε\varepsilon in the direction that helps (A^>0,ρ>1+ε\hat A > 0, \rho > 1 + \varepsilon or A^<0,ρ<1−ε\hat A < 0, \rho < 1 - \varepsilon). A sample that moved the wrong way keeps its full gradient.

    Pessimistic bound. Since min⁡(x,y)≤x\min(x, y) \le x, every term satisfies min⁡(ρA^,clip⁡(ρ)A^)≤ρA^\min(\rho \hat A, \operatorname{clip}(\rho)\hat A) \le \rho \hat A, so LCLIP≤E^[ρA^]L^{\text{CLIP}} \le \hat{\mathbb E}[\rho \hat A]. The clipped objective is a lower bound on the unclipped surrogate. It ignores gains beyond the clip range but keeps every loss. At ρ=1\rho = 1 (the start of each update) the two agree, and the gradient of LCLIPL^{\text{CLIP}} is the ordinary policy gradient E^[A^t∇log⁡πθ(at∣st)]\hat{\mathbb E}[\hat A_t \nabla \log \pi_\theta(a_t \mid s_t)].

    Quick check

    Why is LCLIP(θ)≤E^t[ρtA^t]L^{\text{CLIP}}(\theta) \le \hat{\mathbb E}_t[\rho_t \hat A_t] for every θ\theta?

    The full PPO update. A PPO iteration:

    1. Run πold\pi_{\text{old}} for TT steps in NN parallel environments. Store log⁡πold(at∣st)\log \pi_{\text{old}}(a_t \mid s_t) and Vϕ(st)V_\phi(s_t).
    2. Compute advantages with GAE and value targets R^t=A^t+Vϕ(st)\hat R_t = \hat A_t + V_\phi(s_t) (lesson 08).
    3. For KK epochs (typically 3–10), shuffle the batch into minibatches and take gradient steps on the loss below, with a value-loss weight cvc_v (for example 0.50.5) and an entropy bonus weight cec_e (for example 0.010.01).
    4. Set πold←πθ\pi_{\text{old}} \leftarrow \pi_\theta and repeat.

    The loss of step 3 is

    −LCLIP(θ)+cv E^t[(Vϕ(st)−R^t)2]−ce E^t[H(πθ(⋅∣st))].-L^{\text{CLIP}}(\theta) + c_v\, \hat{\mathbb E}_t\big[(V_\phi(s_t) - \hat R_t)^2\big] - c_e\, \hat{\mathbb E}_t\big[\mathcal H(\pi_\theta(\cdot \mid s_t))\big].

    Implementation details that matter (Huang et al., The 37 implementation details of PPO):

    • Advantage normalization per minibatch: (A^−mean)/(std+10−8)(\hat A - \text{mean}) / (\text{std} + 10^{-8}). The step size then does not depend on the reward scale.
    • Value loss, often clipped like the policy, with its own weight. Entropy bonus: keeps the policy from becoming deterministic too early.
    • Several epochs of shuffled minibatches: this data reuse is the reason to have a trust region.
    • Approximate-KL monitoring and early stopping: stop the epochs when the estimated KL passes a target (for example 0.010.01–0.020.02). The clip does not bound the KL (see below).
    • Global gradient-norm clipping (for example 0.50.5) and learning-rate annealing.

    Estimating the KL from samples. During the update we only have the sampled actions, drawn from πold\pi_{\text{old}}. With ρ=πθ(a∣s)/πold(a∣s)\rho = \pi_\theta(a \mid s) / \pi_{\text{old}}(a \mid s):

    k1=−log⁡ρ,k3=(ρ−1)−log⁡ρ.k_1 = -\log \rho, \qquad k_3 = (\rho - 1) - \log \rho .

    Both are unbiased for KL(πold ∥ πθ)\mathrm{KL}(\pi_{\text{old}} \,\|\, \pi_\theta). For k1k_1 this is the definition: KL(πold ∥ πθ)=Ea∼πold[log⁡(πold/πθ)]\mathrm{KL}(\pi_{\text{old}} \,\|\, \pi_\theta) = \mathbb E_{a \sim \pi_{\text{old}}}[\log(\pi_{\text{old}}/\pi_\theta)]. For k3k_3, add Ea∼πold[ρ−1]=∑aπθ(a∣s)−1=0\mathbb E_{a \sim \pi_{\text{old}}}[\rho - 1] = \sum_a \pi_\theta(a \mid s) - 1 = 0. Each k1k_1 term can be negative, but each k3k_3 term is ≥0\ge 0, because log⁡x≤x−1\log x \le x - 1. So k3k_3 usually has lower variance (Schulman's note "Approximating KL divergence").

    The clip does not bound the KL. The clip only removes the incentive for samples that are already outside the range in the helpful direction. Other samples keep moving the shared parameters, and those changes also move the clipped samples and the actions that were never sampled. Ratios often end far outside [1−ε,1+ε][1 - \varepsilon, 1 + \varepsilon], and the KL keeps growing with more epochs or a larger learning rate. The notebook shows this on a 10-action problem: after 10 epochs with ε=0.2\varepsilon = 0.2, over half of the ratios are outside [0.8,1.2][0.8, 1.2], the largest is 1.631.63, and the KL is more than ten times its value after the first epoch.

    Quick check

    You run PPO with ε=0.2\varepsilon = 0.2 for 10 epochs on one batch. What can you say about KL(πold∥πθ)\mathrm{KL}(\pi_{\text{old}} \| \pi_\theta) at the end?

    3.5 RL for language models #

    The token-level MDP. A language model πθ(yt∣x,y<t)\pi_\theta(y_t \mid x, y_{<t}) generates a response yy to a prompt xx one token at a time. As an MDP:

    • State st=(x,y<t)s_t = (x, y_{<t}): the prompt and the tokens so far.
    • Action at=yta_t = y_t: the next token. The action space is the vocabulary (for example 100 000 tokens).
    • Transition: deterministic, append the token. The episode ends at the end-of-sequence token or a length limit.
    • Reward: usually one number r(x,y)r(x, y) for the whole response, given at the last token, from a reward model or a checker. Usually γ=1\gamma = 1.

    Because the transition is known and deterministic, the same problem can also be seen as a contextual bandit: the context is xx, the action is the whole response yy, and πθ(y∣x)=∏tπθ(yt∣x,y<t)\pi_\theta(y \mid x) = \prod_t \pi_\theta(y_t \mid x, y_{<t}).

    A reward model from preferences. Humans compare two responses ywy_w (preferred) and yly_l to the same prompt. The Bradley–Terry model says Pr⁡(yw≻yl∣x)=σ(rϕ(x,yw)−rϕ(x,yl))\Pr(y_w \succ y_l \mid x) = \sigma\big(r_\phi(x, y_w) - r_\phi(x, y_l)\big), with the logistic function σ\sigma. The reward model rϕr_\phi (a language model with a scalar head) is trained by minimizing −log⁡σ(rϕ(x,yw)−rϕ(x,yl))-\log \sigma\big(r_\phi(x, y_w) - r_\phi(x, y_l)\big) over the comparisons. Only reward differences are learned, so rϕr_\phi is defined up to a constant per prompt.

    The KL-regularized objective (InstructGPT style):

    max⁡θ Ex∼D[Ey∼πθ(⋅∣x)[r(x,y)]−β KL(πθ(⋅∣x) ∥ πref(⋅∣x))],\max_\theta\ \mathbb E_{x \sim \mathcal D}\Big[\mathbb E_{y \sim \pi_\theta(\cdot \mid x)}\big[r(x, y)\big] - \beta\, \mathrm{KL}\big(\pi_\theta(\cdot \mid x) \,\|\, \pi_{\text{ref}}(\cdot \mid x)\big)\Big],

    with a KL coefficient β>0\beta > 0. The penalty keeps the policy near πref\pi_{\text{ref}}, where the reward model was trained and is reliable, and keeps the text fluent.

    The per-token reward, from the chain rule. Because log⁡π(y∣x)=∑tlog⁡π(yt∣st)\log \pi(y \mid x) = \sum_t \log \pi(y_t \mid s_t),

    KL(πθ(⋅∣x) ∥ πref(⋅∣x))=Ey∼πθ[∑tlog⁡πθ(yt∣st)πref(yt∣st)]=Ey∼πθ[∑tKL(πθ(⋅∣st) ∥ πref(⋅∣st))].\begin{aligned} \mathrm{KL}\big(\pi_\theta(\cdot \mid x) \,\|\, \pi_{\text{ref}}(\cdot \mid x)\big) &= \mathbb E_{y \sim \pi_\theta}\Big[\sum_t \log \frac{\pi_\theta(y_t \mid s_t)}{\pi_{\text{ref}}(y_t \mid s_t)}\Big] \\ &= \mathbb E_{y \sim \pi_\theta}\Big[\sum_t \mathrm{KL}\big(\pi_\theta(\cdot \mid s_t) \,\|\, \pi_{\text{ref}}(\cdot \mid s_t)\big)\Big]. \end{aligned}

    The second line takes, at each step tt, the expectation over the token yty_t given sts_t first.

    The sequence KL is the expected sum of per-token log-ratios (the chain rule for KL). So PPO-based RLHF gives every token the reward

    rt=−β(log⁡πθ(yt∣st)−log⁡πref(yt∣st)),plus r(x,y) at the last token.r_t = -\beta \big(\log \pi_\theta(y_t \mid s_t) - \log \pi_{\text{ref}}(y_t \mid s_t)\big), \quad \text{plus } r(x, y) \text{ at the last token}.

    The sum over the response is r(x,y)−βlog⁡πθ(y∣x)πref(y∣x)r(x, y) - \beta \log \dfrac{\pi_\theta(y \mid x)}{\pi_{\text{ref}}(y \mid x)}. A token-level critic and GAE then turn these rewards into per-token advantages.

    Interactive figure: loading…

    Pick a response and move the sliders. The tree shows a toy model that writes two tokens from {0,1}\{0, 1\}. Each edge shows the policy probability πθ\pi_\theta and the reference probability πref\pi_{\text{ref}}. For the chosen response, the panel lists the per-token log-ratios, the KL rewards −βlog⁡(πθ/πref)-\beta \log(\pi_\theta/\pi_{\text{ref}}) and the reward-model score. Check that the per-token rewards add up to r−βlog⁡(πθ(y)/πref(y))r - \beta \log(\pi_\theta(y)/\pi_{\text{ref}}(y)), and that the sequence KL equals the sum of the per-token KLs.

    Quick check

    In PPO-based RLHF with β>0\beta > 0, a token has πθ(yt∣st)=0.2\pi_\theta(y_t \mid s_t) = 0.2 and πref(yt∣st)=0.4\pi_{\text{ref}}(y_t \mid s_t) = 0.4. What is the sign of its KL reward rtr_t (ignore the final score)?

    The optimum of the KL-regularized objective has a closed form. Fix a prompt xx and allow any distribution π\pi over responses.

    Theorem. Let Z=∑yπref(y)exp⁡(r(y)/β)Z = \sum_y \pi_{\text{ref}}(y) \exp(r(y)/\beta). The unique maximizer of F(π)=Ey∼π[r(y)]−β KL(π ∥ πref)F(\pi) = \mathbb E_{y \sim \pi}[r(y)] - \beta\, \mathrm{KL}(\pi \,\|\, \pi_{\text{ref}}) is

    π∗(y)=1Z πref(y)exp⁡(r(y)/β),\pi^*(y) = \frac{1}{Z}\, \pi_{\text{ref}}(y) \exp\big(r(y)/\beta\big),

    and the maximum value is F(π∗)=βlog⁡ZF(\pi^*) = \beta \log Z.

    Proof.

    1. From the definition of π∗\pi^*, take logs: r(y)=βlog⁡π∗(y)πref(y)+βlog⁡Zr(y) = \beta \log \dfrac{\pi^*(y)}{\pi_{\text{ref}}(y)} + \beta \log Z for every yy.
    2. Put this into FF: F(π)=∑yπ(y)[βlog⁡π∗(y)πref(y)+βlog⁡Z−βlog⁡π(y)πref(y)]F(\pi) = \sum_y \pi(y) \Big[\beta \log \dfrac{\pi^*(y)}{\pi_{\text{ref}}(y)} + \beta \log Z - \beta \log \dfrac{\pi(y)}{\pi_{\text{ref}}(y)}\Big].
    3. The πref\pi_{\text{ref}} terms cancel: F(π)=βlog⁡Z−β∑yπ(y)log⁡π(y)π∗(y)=βlog⁡Z−β KL(π ∥ π∗)F(\pi) = \beta \log Z - \beta \sum_y \pi(y) \log \dfrac{\pi(y)}{\pi^*(y)} = \beta \log Z - \beta\, \mathrm{KL}(\pi \,\|\, \pi^*).
    4. KL(π ∥ π∗)≥0\mathrm{KL}(\pi \,\|\, \pi^*) \ge 0, with equality only for π=π∗\pi = \pi^* (Gibbs' inequality, information theory 03). ■\blacksquare

    So the KL-regularized optimum reweights the reference model by exp⁡(r/β)\exp(r/\beta). Small β\beta: almost all mass on the best response (but only among responses that πref\pi_{\text{ref}} can produce). Large β\beta: almost πref\pi_{\text{ref}}. With a uniform reference this is the soft-greedy policy π∝exp⁡(Q/α)\pi \propto \exp(Q/\alpha) of lesson 08, with α=β\alpha = \beta: the KL to a uniform distribution is log⁡∣A∣−H(π)\log |\mathcal A| - \mathcal H(\pi), so the KL penalty becomes an entropy bonus.

    Step 1 also says: at the optimum, the penalized reward r(y)−βlog⁡(π∗(y)/πref(y))r(y) - \beta \log(\pi^*(y)/\pi_{\text{ref}}(y)) equals βlog⁡Z\beta \log Z for every response. All responses look equally good, so every advantage is zero and the gradient vanishes.

    Interactive figure: loading…

    Move β\beta and drag the reward dots. Grey bars are πref\pi_{\text{ref}}; orange bars are the optimum π∗∝πrefexp⁡(r/β)\pi^* \propto \pi_{\text{ref}} \exp(r/\beta); the aqua dots are the rewards r(y)r(y). The lower chart shows, for every β\beta, the expected reward Eπ∗[r]\mathbb E_{\pi^*}[r] (aqua) and KL(π∗∥πref)\mathrm{KL}(\pi^* \| \pi_{\text{ref}}) (magenta). Predict first: what happens to π∗\pi^* when β→0\beta \to 0? Can π∗\pi^* put mass on a response with πref=0\pi_{\text{ref}} = 0?

    Direct preference optimization (DPO)

    Step 1 of the proof can be read backwards: for the optimal policy, the reward is r(x,y)=βlog⁡π∗(y∣x)πref(y∣x)+βlog⁡Z(x)r(x, y) = \beta \log \dfrac{\pi^*(y \mid x)}{\pi_{\text{ref}}(y \mid x)} + \beta \log Z(x). Put this into the Bradley–Terry model. The term βlog⁡Z(x)\beta \log Z(x) is the same for both responses and cancels:

    Pr⁡(yw≻yl∣x)=σ(βlog⁡π∗(yw∣x)πref(yw∣x)−βlog⁡π∗(yl∣x)πref(yl∣x)).\Pr(y_w \succ y_l \mid x) = \sigma\Big(\beta \log \frac{\pi^*(y_w \mid x)}{\pi_{\text{ref}}(y_w \mid x)} - \beta \log \frac{\pi^*(y_l \mid x)}{\pi_{\text{ref}}(y_l \mid x)}\Big).

    DPO (Rafailov et al., 2023) fits a policy πθ\pi_\theta in place of π∗\pi^* directly to the preference data by minimizing −log⁡σ(⋅)-\log \sigma(\cdot) of this expression. It needs no reward model, no sampling and no RL loop, only log-probabilities of fixed pairs. The cost: it learns only from the given pairs (it is an offline method), and it is exact only if the optimum is reachable.

    3.6 Critic-free methods: RLOO and GRPO #

    PPO for RLHF needs four large models in memory: the policy, the reference, the reward model and a value model about as large as the policy. The value model must assign credit to single tokens from one reward at the end, which is hard. LLMs offer a cheaper baseline: sample KK responses y1,…,yKy_1, \dots, y_K to the same prompt, with rewards r1,…,rKr_1, \dots, r_K, and compare them.

    • RLOO (REINFORCE leave-one-out; Ahmadian et al., 2024):
    Ai=ri−1K−1∑j≠irj=KK−1 (ri−rˉ),rˉ=1K∑jrj.A_i = r_i - \frac{1}{K - 1} \sum_{j \ne i} r_j = \frac{K}{K - 1}\,(r_i - \bar r), \qquad \bar r = \frac1K \sum_j r_j .

    The baseline of response ii does not use yiy_i; it depends only on the other, independent samples. So E[bi∇log⁡π(yi)]=E[bi] E[∇log⁡π(yi)]=0\mathbb E[b_i \nabla \log \pi(y_i)] = \mathbb E[b_i]\, \mathbb E[\nabla \log \pi(y_i)] = 0: this is unbiased REINFORCE with a per-prompt baseline (lesson 07). In the paper the KL penalty is part of the sequence reward, ri=r(x,yi)−βlog⁡(πθ(yi)/πref(yi))r_i = r(x, y_i) - \beta \log(\pi_\theta(y_i)/\pi_{\text{ref}}(y_i)).

    • GRPO (Group Relative Policy Optimization; Shao et al., DeepSeekMath, 2024):
    Ai=ri−rˉstd(r1,…,rK),A_i = \frac{r_i - \bar r}{\mathrm{std}(r_1, \dots, r_K)},

    the same advantage for every token of yiy_i. It is used inside a PPO-style clipped ratio per token, and the KL to πref\pi_{\text{ref}} is a separate loss term, not part of the reward. It is estimated per token with the k3k_3 form, πrefπθ−1−log⁡πrefπθ\frac{\pi_{\text{ref}}}{\pi_\theta} - 1 - \log \frac{\pi_{\text{ref}}}{\pi_\theta}. Dividing by the std is not unbiased: it gives more weight to prompts whose rewards vary little. As of 2025, variants differ: sample or population std, and Dr. GRPO (Liu et al., 2025) drops both the std and the division by the response length.

    Interactive figure: loading…

    Drag the reward bars, then compare the advantages. The aqua bars are the rewards of KK responses to one prompt. Below are three advantages per response: ri−rˉr_i - \bar r (grey), RLOO and GRPO. Try "one correct of four" and "all equal": when every reward is the same, every advantage is 0 and the prompt gives no learning signal.

    Why they fit LLMs. The dynamics are known and deterministic, so sampling several responses per prompt is cheap and needs no simulator. The reward comes once per sequence, so a per-prompt Monte Carlo baseline is a good baseline. No value network saves memory and removes a hard regression problem. Ahmadian et al. report RLOO matching or beating PPO for RLHF.

    RL with verifiable rewards (RLVR). For math and code, a program can check the final answer: the reward is 1 if correct and 0 if not. There is no reward model to over-optimize, only the risk of gaming the checker (for example, an answer format it accepts by mistake). GRPO with such rewards trained DeepSeek-R1 (2025).

    Quick check

    Four responses to one prompt get rewards (1,0,0,0)(1, 0, 0, 0). What are the RLOO advantages?

    3.7 Reward over-optimization #

    The reward model is only a proxy for what people want. If we optimize it hard, the policy finds responses that score high but are not better, for example longer answers or flattering text (reward hacking, an example of Goodhart's law). Gao et al. (2022) measured this with a large "gold" reward model playing the role of humans and smaller proxy reward models. With the distance d=KL(π ∥ πinit)d = \sqrt{\mathrm{KL}(\pi \,\|\, \pi_{\text{init}})} from the initial policy, the proxy reward keeps rising, while the gold reward rises and then falls. For RL they fit the gold reward as R(d)=d (a−blog⁡d)R(d) = d\,(a - b \log d), with constants a,ba, b that depend on the reward-model size.

    The KL penalty keeps the policy near πref\pi_{\text{ref}}, where the proxy is more reliable. It does not make the proxy correct. In Gao et al.'s setup, the penalty acted like early stopping: it changed how far training went, but not the gold reward reached at a given KL distance. Other protections: early stopping on held-out human or gold evaluations, larger or ensembled reward models, new preference data from the current policy, and verifiable rewards where possible.

    Answers to section 1. (1) No. The true improvement agrees with the surrogate only to first order. In the example, the gain grows more slowly than the step, peaks, and then becomes negative, while the surrogate keeps rising. (2) Yes. Clipping removes the incentive only for samples that are already outside the range in the helpful direction; other samples and shared parameters keep moving the policy. That is why PPO monitors the KL and stops early. (3) Lower. The log-ratio of that response is positive, so −βlog⁡(πθ/πref)<0-\beta \log(\pi_\theta/\pi_{\text{ref}}) < 0 is added to 0.80.8.

    4. Worked example #

    (a) PPO with ε=0.2\varepsilon = 0.2 on three samples (ρ,A^)(\rho, \hat A), with 1−ε=0.81 - \varepsilon = 0.8 and 1+ε=1.21 + \varepsilon = 1.2:

    Sample ρA^\rho \hat A clip⁡(ρ) A^\operatorname{clip}(\rho)\, \hat A min Gradient w.r.t. its log⁡π\log \pi
    (1.5,+1)(1.5, +1) 1.51.5 1.2⋅1=1.21.2 \cdot 1 = 1.2 1.21.2 (clipped constant) 00
    (0.6,+1)(0.6, +1) 0.60.6 0.8⋅1=0.80.8 \cdot 1 = 0.8 0.60.6 (unclipped) 0.6/3=0.20.6/3 = 0.2
    (1.1,−2)(1.1, -2) −2.2-2.2 1.1⋅(−2)=−2.21.1 \cdot (-2) = -2.2 −2.2-2.2 (inside the range) −2.2/3=−0.733-2.2/3 = -0.733

    LCLIP=(1.2+0.6−2.2)/3=−0.133L^{\text{CLIP}} = (1.2 + 0.6 - 2.2)/3 = -0.133. The unclipped mean is (1.5+0.6−2.2)/3=−0.033(1.5 + 0.6 - 2.2)/3 = -0.033. The clipped value is lower, as the pessimistic bound says. The first sample already moved enough and is ignored. The second sample was good but became less likely; its gradient pushes ρ\rho back up.

    (b) Per-token RLHF reward. A 4-token response has log-ratios log⁡(πθ/πref)=(0.2,−0.1,0.4,0.0)\log(\pi_\theta/\pi_{\text{ref}}) = (0.2, -0.1, 0.4, 0.0), β=0.05\beta = 0.05, and reward-model score 0.80.8.

    • Token 1: −0.05⋅0.2=−0.01-0.05 \cdot 0.2 = -0.01.
    • Token 2: −0.05⋅(−0.1)=+0.005-0.05 \cdot (-0.1) = +0.005.
    • Token 3: −0.05⋅0.4=−0.02-0.05 \cdot 0.4 = -0.02.
    • Token 4: −0.05⋅0+0.8=0.8-0.05 \cdot 0 + 0.8 = 0.8.

    Sum: −0.01+0.005−0.02+0.8=0.775-0.01 + 0.005 - 0.02 + 0.8 = 0.775. Check: the sequence log-ratio is 0.2−0.1+0.4+0=0.50.2 - 0.1 + 0.4 + 0 = 0.5, and 0.8−0.05⋅0.5=0.7750.8 - 0.05 \cdot 0.5 = 0.775.

    (c) RLOO and GRPO. Three responses with rewards (0.8,0.2,0.5)(0.8, 0.2, 0.5); mean rˉ=0.5\bar r = 0.5.

    • RLOO: 0.8−0.2+0.52=0.450.8 - \tfrac{0.2 + 0.5}{2} = 0.45;  0.2−0.8+0.52=−0.45\ 0.2 - \tfrac{0.8 + 0.5}{2} = -0.45;  0.5−0.8+0.22=0\ 0.5 - \tfrac{0.8 + 0.2}{2} = 0. Check: 32(0.3,−0.3,0)=(0.45,−0.45,0)\tfrac32 (0.3, -0.3, 0) = (0.45, -0.45, 0).
    • GRPO with the population std (0.09+0.09+0)/3=0.06=0.245\sqrt{(0.09 + 0.09 + 0)/3} = \sqrt{0.06} = 0.245: (1.22,−1.22,0)(1.22, -1.22, 0). With the sample std 0.18/2=0.3\sqrt{0.18/2} = 0.3: (1,−1,0)(1, -1, 0).

    (d) The closed-form optimum. Three responses with πref=(0.5,0.3,0.2)\pi_{\text{ref}} = (0.5, 0.3, 0.2), rewards r=(0,1,2)r = (0, 1, 2) and β=1\beta = 1.

    1. Weights πref(y)er(y)\pi_{\text{ref}}(y) e^{r(y)}: 0.5⋅1=0.50.5 \cdot 1 = 0.5,  0.3⋅e=0.8155\ 0.3 \cdot e = 0.8155,  0.2⋅e2=1.4778\ 0.2 \cdot e^2 = 1.4778.
    2. Z=0.5+0.8155+1.4778=2.7933Z = 0.5 + 0.8155 + 1.4778 = 2.7933, so π∗=(0.179,0.292,0.529)\pi^* = (0.179, 0.292, 0.529).
    3. Eπ∗[r]=0.292+2⋅0.529=1.350\mathbb E_{\pi^*}[r] = 0.292 + 2 \cdot 0.529 = 1.350 and KL(π∗∥πref)=0.323\mathrm{KL}(\pi^* \| \pi_{\text{ref}}) = 0.323.
    4. Objective: 1.350−0.323=1.027=log⁡Z=log⁡2.79331.350 - 0.323 = 1.027 = \log Z = \log 2.7933 ✓.
    5. Penalized reward of response 1: 0−log⁡(0.179/0.5)=1.0270 - \log(0.179/0.5) = 1.027; of response 3: 2−log⁡(0.529/0.2)=1.0272 - \log(0.529/0.2) = 1.027. The same for all responses, as the theorem says.

    With β=0.1\beta = 0.1 the optimum is almost (0,0,1)(0, 0, 1) with KL =1.609=log⁡5= 1.609 = \log 5 (all mass on response 3, which had πref=0.2\pi_{\text{ref}} = 0.2). With β=10\beta = 10 it is (0.465,0.308,0.227)(0.465, 0.308, 0.227), close to πref\pi_{\text{ref}}.

    (e) Sequence KL = sum of per-token KLs. A toy model writes two tokens from {0,1}\{0, 1\}. Policy: first token (0.7,0.3)(0.7, 0.3); second token (0.9,0.1)(0.9, 0.1) after a 0 and (0.4,0.6)(0.4, 0.6) after a 1. Reference: first (0.5,0.5)(0.5, 0.5); second (0.5,0.5)(0.5, 0.5) after a 0 and (0.2,0.8)(0.2, 0.8) after a 1.

    1. First-token KL: 0.7log⁡0.70.5+0.3log⁡0.30.5=0.08230.7 \log\tfrac{0.7}{0.5} + 0.3 \log\tfrac{0.3}{0.5} = 0.0823.
    2. Second-token KL after a 0: 0.9log⁡0.90.5+0.1log⁡0.10.5=0.36810.9 \log\tfrac{0.9}{0.5} + 0.1 \log\tfrac{0.1}{0.5} = 0.3681; after a 1: 0.4log⁡0.40.2+0.6log⁡0.60.8=0.10460.4 \log\tfrac{0.4}{0.2} + 0.6 \log\tfrac{0.6}{0.8} = 0.1046.
    3. Chain rule: 0.0823+0.7⋅0.3681+0.3⋅0.1046=0.37130.0823 + 0.7 \cdot 0.3681 + 0.3 \cdot 0.1046 = 0.3713.
    4. Directly over the four sequences, with πθ=(0.63,0.07,0.12,0.18)\pi_\theta = (0.63, 0.07, 0.12, 0.18) and πref=(0.25,0.25,0.10,0.40)\pi_{\text{ref}} = (0.25, 0.25, 0.10, 0.40): ∑yπθ(y)log⁡πθ(y)πref(y)=0.3713\sum_y \pi_\theta(y) \log \tfrac{\pi_\theta(y)}{\pi_{\text{ref}}(y)} = 0.3713 ✓.

    5. In code #

    NumPy checks of the worked examples. The notebook for this lesson has these cells and the exercises.

    import numpy as np
    from scipy.special import softmax
    
    # (a) PPO clipped objective and its gradient w.r.t. log pi
    rho, A, eps = np.array([1.5, 0.6, 1.1]), np.array([1.0, 1.0, -2.0]), 0.2
    terms = np.minimum(rho * A, np.clip(rho, 1 - eps, 1 + eps) * A)
    grad = np.where(rho * A <= np.clip(rho, 1 - eps, 1 + eps) * A, rho * A, 0.0) / len(rho)
    print(terms.mean(), (rho * A).mean())      # -0.1333 -0.0333
    print(grad)                                # [ 0.      0.2    -0.7333]
    
    # (b) per-token RLHF reward
    log_ratio, beta, score = np.array([0.2, -0.1, 0.4, 0.0]), 0.05, 0.8
    r_tok = -beta * log_ratio
    r_tok[-1] += score
    print(r_tok, r_tok.sum())                  # [-0.01  0.005 -0.02  0.8 ] 0.775
    
    # (c) RLOO and GRPO
    r = np.array([0.8, 0.2, 0.5]); K = len(r)
    print(K / (K - 1) * (r - r.mean()))        # [ 0.45 -0.45  0.  ]
    print((r - r.mean()) / r.std())            # [ 1.2247 -1.2247  0. ]   (population std)
    
    # (d) closed-form optimum of E[r] - beta KL(pi || pi_ref)
    p_ref, rew, beta = np.array([0.5, 0.3, 0.2]), np.array([0.0, 1.0, 2.0]), 1.0
    w = p_ref * np.exp(rew / beta); Z = w.sum(); p_star = w / Z
    kl = np.sum(p_star * np.log(p_star / p_ref))
    print(p_star, p_star @ rew - beta * kl, beta * np.log(Z))   # [0.179 0.2919 0.5291] 1.0272 1.0272
    print(rew - beta * np.log(p_star / p_ref))                  # [1.0272 1.0272 1.0272]
    
    # Fisher approximation of the KL for a softmax policy
    theta, delta = np.array([0.5, -0.2, 0.1]), np.array([0.03, -0.02, 0.01])
    p, q = softmax(theta), softmax(theta + delta)
    F = np.diag(p) - np.outer(p, p)
    print(np.sum(p * np.log(p / q)), 0.5 * delta @ F @ delta)   # 1.918e-04 1.927e-04
    
    # (e) sequence KL = sum of per-token KLs (toy two-token model)
    pol = {"first": np.array([0.7, 0.3]), "second": np.array([[0.9, 0.1], [0.4, 0.6]])}
    ref = {"first": np.array([0.5, 0.5]), "second": np.array([[0.5, 0.5], [0.2, 0.8]])}
    seq = lambda m, a, b: m["first"][a] * m["second"][a, b]
    kl = lambda u, v: np.sum(u * np.log(u / v))
    kl_seq = sum(seq(pol, a, b) * np.log(seq(pol, a, b) / seq(ref, a, b)) for a in (0, 1) for b in (0, 1))
    kl_tok = kl(pol["first"], ref["first"]) + sum(pol["first"][a] * kl(pol["second"][a], ref["second"][a]) for a in (0, 1))
    print(kl_seq, kl_tok)                      # 0.3713 0.3713
    

    6. Where it shows up #

    • Deep RL benchmarks and games. PPO with GAE is the default baseline in libraries such as Stable-Baselines3 and CleanRL, and trained OpenAI Five. Its clipped ratio also appears in multi-agent RL (MAPPO).
    • RLHF. InstructGPT and many later chat models: a reward model from human comparisons, then PPO with a learned value model and a per-token KL penalty to the supervised model.
    • Reasoning models and RLVR. GRPO and its 2025 variants (Dr. GRPO, DAPO) with rewards from answer checkers, unit tests or proof checkers; DeepSeek-R1 is the best-known example.
    • Preference optimization without RL. DPO and its variants use the closed-form optimum of the KL-regularized objective to fit preferences directly.
    • ML for science. Policy-gradient fine-tuning with a penalty for leaving a prior model steers generative models toward a computed property. REINVENT trains a molecule generator toward a scoring function (for example predicted activity) while keeping it close to the prior generator, and DDPO (Black et al., 2023) fine-tunes diffusion models with a PPO-style clipped ratio. The penalty has the same role as in RLHF: the property score is often a learned proxy, and the prior keeps samples realistic.

    7. Common mistakes #

    • Mixing up the three policies. πθ\pi_\theta is trained, πold\pi_{\text{old}} generated the batch and appears in the ratio, πref\pi_{\text{ref}} is the frozen starting model and appears in the KL penalty. In PPO-RLHF all three exist at the same time.
    • "Clipping bounds the KL." It does not. Measure the approximate KL and stop the epochs early.
    • Zero-gradient cases reversed. The gradient vanishes for A^>0,ρ>1+ε\hat A > 0, \rho > 1 + \varepsilon and for A^<0,ρ<1−ε\hat A < 0, \rho < 1 - \varepsilon. A sample that moved the wrong way keeps its gradient.
    • Forgetting that the surrogate uses the old states. The ratio corrects the action distribution, not the state distribution. This is why big steps are dangerous even with exact ratios.
    • Std normalization of an all-equal group. If all KK rewards are equal, all GRPO and RLOO advantages are 0 (GRPO needs a small constant in the denominator to avoid 0/00/0). Such prompts give no signal.
    • Counting the KL twice. PPO-RLHF puts it in the per-token reward; GRPO adds it as a separate loss term. Use one or the other.
    • Believing the KL penalty fixes reward hacking. It limits how far the policy moves; it does not make the reward model right.
    • Reward timing. We write rtr_t for the reward after (st,at)(s_t, a_t); Sutton and Barto write Rt+1R_{t+1}. In the token MDP the score r(x,y)r(x, y) belongs to the last token.

    8. Check yourself #

    1. Why can the surrogate use dπd^\pi instead of dπ′d^{\pi'}?
      AnswerBecause it agrees with the true improvement to first order at π′=π\pi' = \pi: the same value (0) and the same gradient (the policy gradient). The error is a product of two terms that both vanish at π′=π\pi' = \pi, so it is second order in the step, and TRPO's theorem bounds it by a multiple of the maximum KL. So the surrogate is accurate inside a small trust region.
    2. A sample has A^=−1\hat A = -1 and ρ=0.75\rho = 0.75, with ε=0.2\varepsilon = 0.2. Does it give a gradient?
      AnswerNo. ρA^=−0.75\rho \hat A = -0.75 and clip⁡(ρ)A^=0.8⋅(−1)=−0.8\operatorname{clip}(\rho)\hat A = 0.8 \cdot (-1) = -0.8; the min is −0.8-0.8, the clipped constant. The probability of this bad action has already fallen by more than ε\varepsilon, in the helpful direction.
    3. Show that the RLOO advantage equals KK−1(ri−rˉ)\frac{K}{K-1}(r_i - \bar r).
      Answer∑j≠irj=Krˉ−ri\sum_{j \ne i} r_j = K\bar r - r_i, so ri−Krˉ−riK−1=(K−1)ri−Krˉ+riK−1=K(ri−rˉ)K−1r_i - \frac{K\bar r - r_i}{K - 1} = \frac{(K-1) r_i - K\bar r + r_i}{K - 1} = \frac{K(r_i - \bar r)}{K - 1}.
    4. Prove that k3=(ρ−1)−log⁡ρk_3 = (\rho - 1) - \log \rho is an unbiased estimator of KL(πold∥πθ)\mathrm{KL}(\pi_{\text{old}} \| \pi_\theta) with a∼πolda \sim \pi_{\text{old}}, and that each term is non-negative.
      AnswerEπold[ρ]=∑aπold(a)πθ(a)πold(a)=1\mathbb E_{\pi_{\text{old}}}[\rho] = \sum_a \pi_{\text{old}}(a)\frac{\pi_\theta(a)}{\pi_{\text{old}}(a)} = 1, so E[ρ−1]=0\mathbb E[\rho - 1] = 0 and E[k3]=E[−log⁡ρ]=KL(πold∥πθ)\mathbb E[k_3] = \mathbb E[-\log\rho] = \mathrm{KL}(\pi_{\text{old}} \| \pi_\theta). Each term is ≥0\ge 0 because log⁡x≤x−1\log x \le x - 1 for x>0x > 0.
    5. For the KL-regularized objective with πref=(0.5,0.5)\pi_{\text{ref}} = (0.5, 0.5), rewards (1,0)(1, 0) and β=0.5\beta = 0.5, find π∗\pi^*.
      AnswerWeights 0.5e2=3.6950.5 e^{2} = 3.695 and 0.5e0=0.50.5 e^{0} = 0.5; Z=4.195Z = 4.195; π∗=(0.881,0.119)\pi^* = (0.881, 0.119). This is σ(r1/β−r2/β)=σ(2)\sigma(r_1/\beta - r_2/\beta) = \sigma(2) for the first response.
    6. What does the KL penalty not fix in reward over-optimization?
      AnswerThe proxy reward is still wrong; the penalty only limits how far the policy moves from πref\pi_{\text{ref}}. Gao et al. found that it acted like early stopping, with no better gold reward at a given KL distance.
    Recall cardsAnswer in your head first, then reveal. Add the cards to your review deck to see them again just before you would forget.
    1. State the performance difference lemma.

    2. What is the surrogate objective, and how does it differ from the exact improvement?

    3. Write PPO's clipped objective.

    4. For which samples is the PPO gradient zero?

    5. Why does PPO still monitor the KL?

    6. Give the k3k_3 estimator of KL(πold∥πθ)\mathrm{KL}(\pi_{\text{old}} \| \pi_\theta) and its two properties.

    7. What is the per-token reward in PPO-based RLHF?

    8. What is the maximizer of Eπ[r]−β KL(π∥πref)\mathbb E_\pi[r] - \beta\,\mathrm{KL}(\pi \| \pi_{\text{ref}})?

    9. Compute the RLOO advantages for rewards (1,0)(1, 0).

    10. What is the GRPO advantage, and what does Dr. GRPO change?

    Open the review →

    9. Interview angle #

    • "Walk me through PPO's loss." The ratio ρt\rho_t; the clipped surrogate with the min (a pessimistic bound; zero gradient only after enough movement in the helpful direction); the value loss; the entropy bonus; advantage normalization; several epochs of minibatches; KL monitoring and early stopping.
    • "Why not just take bigger policy-gradient steps?" The data come from the old policy. The performance difference lemma shows the surrogate uses the old state distribution, so it is only valid near the old policy; large steps can make the policy worse.
    • "TRPO vs PPO?" TRPO: a hard KL constraint, natural gradient by conjugate gradient, line search; more principled, harder to implement, awkward with shared actor-critic networks. PPO: first-order, clipped ratio, simpler and usually as good.
    • "PPO vs GRPO vs RLOO for LLMs?" PPO needs a value model and GAE for per-token credit. RLOO and GRPO use KK samples per prompt as the baseline; less memory, no critic to train, but more samples per prompt. RLOO is unbiased; GRPO's std division reweights prompts.
    • "Derive the optimal policy of the KL-regularized objective." Write F(π)=βlog⁡Z−β KL(π∥π∗)F(\pi) = \beta \log Z - \beta\,\mathrm{KL}(\pi \| \pi^*) with π∗∝πrefer/β\pi^* \propto \pi_{\text{ref}} e^{r/\beta}. Mention that DPO inverts this to get the reward from the policy.
    • "What is reward hacking, and what do you do about it?" Over-optimizing a proxy. KL penalty and early stopping, better or ensembled reward models, fresh human data, verifiable rewards.

    10. Practice #

    The notebook for this lesson runs in Colab. It has five exercises, each with a check cell and a folded solution:

    1. Write ppo_clip_objective and ppo_clip_grad, and check the gradient by finite differences.
    2. Write approx_kl (k1k_1 and k3k_3); show by sampling that both are unbiased and that k3≥0k_3 \ge 0.
    3. Run PPO for several epochs on one batch of a 10-action softmax problem and track the KL and the fraction of ratios outside the clip range; compare with the unclipped objective.
    4. Compute per-token KL rewards on the two-token toy model and check the chain rule (sequence KL = sum of per-token KLs).
    5. Write rloo_advantages, grpo_advantages and the closed-form optimum; train the toy model with RLOO plus a KL penalty and check that it converges to πrefexp⁡(r/β)/Z\pi_{\text{ref}} \exp(r/\beta)/Z.

    11. Watch and read #

    The surrogate from importance sampling, the KL trust region and the Fisher approximation, then PPO's clipped objective.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    The token-level view of PPO for language models: value model, GAE, importance ratio and clipping.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    From 14:10, how GRPO replaces the value model by a group baseline, and how it compares with PPO.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    The closed-form optimum of the KL-regularized objective and how DPO turns it into a classification loss on preference pairs.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play