Vibe Engines is free, interactive AI engineering & system design — runs in your browser. Pick a learning path →
PPO,
explained.
Reinforcement learning has a self-destruct button. Push the policy toward a good action too hard, off one noisy batch of experience, and it lurches somewhere terrible — and now every future batch is collected by a broken policy. The fix that made RL practical for hard problems, and later for aligning language models, is almost embarrassingly simple: clip the step. PPO measures how far the new policy has moved with a probability ratio, and refuses to reward moving too far. No second-order math, no hard constraint — just a min and a clip that keep every update inside a trust region. Here's the objective, and why that one clip is enough.
What changes against DQN: the policy is optimised directly
DQN learns what each action is worth and then acts greedily, which requires enumerating the actions to take a maximum over them. Policy-gradient methods skip the value and adjust the policy itself in the direction that increases expected return, so a continuous action space is no harder than a discrete one. The price is a failure mode DQN does not have: because the data is collected by the current policy, one over-large update can move the policy somewhere that collects useless data, and there is no way back — the policy has destroyed the source of its own improvement.
The existing fix was to constrain how far the policy may move per update, measured as a divergence between the old and new action distributions, and to enforce it as a hard constraint. That works and requires second-order information, which makes it awkward to implement and expensive to run. PPO's change is to get almost the same effect with first-order methods and a few lines of arithmetic.
The mechanism, in the units that matter: form the probability ratio between the new and old policy for each action actually taken, clip it to a narrow band around 1 (commonly ±0.2), and optimise the minimum of the clipped and unclipped objectives. Taking the minimum is what makes it work rather than merely bounded — it means the objective stops rewarding you for moving further once you have left the band, but still penalises you for a move that made things worse. Because the update is bounded, the same batch of experience can be reused for several epochs instead of one, which is where the sample efficiency over vanilla policy gradients comes from.
The self-destruct button
Policy-gradient RL learns by trial: run the current policy, see which actions did better than expected — a positive advantage A — and nudge the policy to make those actions more likely. Simple in principle, treacherous in practice. The advantage is estimated from data collected by the old policy, so it's only valid nearby. Take a big step and the new policy is a stranger to that data: the estimate no longer applies, and the update can send performance off a cliff. Worse, RL is on-policy — the broken policy now collects the next batch, so a single bad step can spiral.
The earlier fix, TRPO, solved this with a hard trust region: constrain each update so the new policy stays within a bounded KL distance of the old one. It works, but it needs heavy second-order optimization that's fiddly to implement and scale. PPO (Schulman et al., 2017) asked: can we get the same "don't step too far" safety with plain first-order gradient descent and a couple of lines of code? The answer — a clipped objective — is the reason PPO became the default RL algorithm, all the way up to the alignment of large language models.
Measure how much the policy changed with the ratio r = π_new/π_old, and maximize min(r·A, clip(r, 1−ε, 1+ε)·A) — so once the ratio leaves the band 1±ε in the helpful direction, the objective stops rewarding it and the step stays inside a soft trust region.
The probability ratio
To limit "how far the policy moved," PPO needs to measure it. The tool is the probability ratio: for a state-action pair, r = π_new(a|s) / π_old(a|s) — how much more (or less) likely the new policy is to take an action than the old policy that gathered the data. r = 1 is no change; r > 1 means the new policy now favors the action more; r < 1, less.
This ratio is the lever of the whole update. The surrogate objective — the thing plain policy gradients maximize — is r · A: push the ratio up for good actions (positive A), down for bad ones. But nothing stops r from running to 5 or 0.1 on a single batch, and a ratio far from 1 is exactly the danger sign: the policy has moved so far from the data that A is no longer trustworthy. PPO's entire contribution is a way to cap the reward for moving the ratio too far — to make the objective indifferent to steps that leave the safe neighborhood. That's the clip.
Clip the surrogate
PPO takes the surrogate r · A and pins the ratio inside a band [1−ε, 1+ε] (typically ε = 0.2), then takes the minimum of the clipped and unclipped versions. The min is the clever part — it makes the objective a pessimistic bound that only ever removes the incentive to over-step:
The result is a soft trust region built from a clip instead of a constraint. When the ratio is inside the band, PPO behaves like an ordinary policy gradient. When a good action's ratio tries to climb past 1+ε, the clipped term flattens — the objective stops improving, so the gradient for that sample is zero and the update stops pushing. The min ensures the clip only bites in the "helpful" direction, so it never accidentally encourages a large step. All of this is plain arithmetic on scalars — no KL constraint, no conjugate gradients, no line search. That simplicity, with TRPO-like stability, is the whole point.
The min objective
The clipped surrogate is a single expression. With ratio r, advantage A, and clip range ε:
At r = 1 it's just A. For A > 0, a large r is capped at (1+ε)·A. The min makes it pessimistic — it can only lower the objective relative to r·A, never raise it, so over-stepping is never rewarded.
Worked: with ε = 0.2, a good action whose ratio jumped to 1.5 is capped — but a bad action whose ratio rose to 1.5 is penalized in full, because the min picks the worse value:
Good action, big step up: capped at 1.2 (no runaway reward). Bad action, ratio drifted up: the full −1.5 penalty applies — the clip protects against over-eager increases, not against paying for mistakes. The runnable version below computes the ratio, the clipped objective, and when the ratio leaves the trust region.
The PPO loop: actors, advantage estimates, and several epochs per batch
PPO is an outer loop around a clipped loss. The loop matters as much as the loss, because the clip is what makes it safe to take more than one gradient step on a batch of fresh experience.
- Collect with N actors. Each of N parallel copies of the environment runs the current policy for T steps (T is much shorter than an episode), recording states, actions, rewards, the probability the policy gave each action, and the value network's estimate of each state. That gives a batch of N×T steps.
- Estimate advantages with GAE. For each step compute the one-step error δt = Rt + γV(st+1) − V(st), where Rt is the reward. The advantage is a decaying sum of these errors going forward in time: Ât = δt + (γλ)δt+1 + (γλ)^2δt+2 + … up to the end of the T-step window. With λ = 0 it uses a single step: low variance, but biased by whatever error the value network has. With λ = 1 it adds up the actual rewards: unbiased but noisy. The Atari and MuJoCo runs use γ = 0.99 and λ = 0.95.
- Freeze the old policy. Store the action probabilities under the policy that collected the batch. These are the denominators of the ratio rt = πθ(at|st) / πold(at|st). Right after collection, every ratio is exactly 1.
- Run K epochs of minibatch updates. Shuffle the N×T steps, split them into minibatches, and take Adam steps on the combined loss for K passes over the same data. The MuJoCo runs use K = 10 with minibatches of 64 and T = 2048. The Atari runs use K = 3, T = 128 and 8 actors. Each pass moves the ratios away from 1, and the clip is what stops them drifting far.
- Combine three terms in one loss. When the policy and value function share a network, the objective adds the clipped policy term, subtracts a squared-error loss for the value function, and adds an entropy bonus that keeps the policy from collapsing onto one action too early.
- Throw the batch away and repeat. The old policy is replaced by the new one, and fresh data is collected. PPO is still on-policy: data is reused for K epochs, not stored for later.
Why the clip and not a penalty
The paper also tries the obvious alternative: instead of clipping, subtract a penalty proportional to the KL divergence between old and new policies. The penalty weight β is adapted: if the measured KL after an update falls below the target divided by 1.5, halve β; if it rises above the target times 1.5, double β. That version works but needed a target to be chosen and was outscored by plain clipping in the authors' comparison.
What the advantage is doing
The advantage says how much better an action turned out than the value network expected. A positive value pushes that action's probability up. A negative one pushes it down. Because the estimate comes from data collected by the old policy, it is only trustworthy while the new policy stays close, which is exactly what the clip protects.
The combined PPO objective
L^CLIP— the policy term from the ratio r and advantage Â; ε is typically 0.2.L^VF— squared error between the value network and its target return; the minus sign makes it a loss when the objective is maximized.S[π]— the entropy of the policy at that state; the bonus discourages premature certainty.c1, c2— weights; the Atari runs use 1 and 0.01.δt— one-step error from the value network; GAE sums these with weights (γλ)^k.
Worked example: with ε = 0.2 and a ratio of 1.5, a good action (Â = +1) scores min(1.5, 1.2) = 1.2, so there is no extra reward for going further. A bad action (Â = −1) scores min(−1.5, −1.2) = −1.5, so the full penalty still applies.
Clipping versus penalties, and the MuJoCo and Atari comparisons
The main ablation compared surrogate objectives on seven simulated continuous-control tasks, three random seeds each, with the scores scaled so a random policy is 0 and the best result in the experiment is 1. Averaged over those runs:
| Objective | Setting | Normalized score |
|---|---|---|
| No clipping or penalty | plain surrogate | about −0.39 |
| Clipping | ε = 0.1 | about 0.76 |
| Clipping | ε = 0.2 | about 0.82 |
| Clipping | ε = 0.3 | about 0.70 |
| Adaptive KL penalty | best target tested | about 0.74 |
Two readings follow. The unconstrained version is worse than random on average, so the constraint is doing real work. And clipping at 0.2 beat every KL-penalty variant the authors tried, fixed or adaptive, even though the penalty is the more principled version.
On the continuous-control tasks over one million timesteps, PPO with clipping matched or beat the earlier trust-region method TRPO, the cross-entropy method, a vanilla policy gradient with adaptive step size, A2C, and A2C with a trust region on most tasks. On 49 Atari games trained for 40 million frames, PPO was compared with A2C and ACER. Counting games by average reward over all of training, PPO won 30, ACER 18 and A2C 1. Counting by the last 100 episodes, ACER won 28, PPO 19, A2C 1 and one game was a tie. So PPO learned faster, while the sample-efficient off-policy method often ended slightly higher.
What the authors admit, and what happened next
The paper presents the clip as a practical surrogate, not a proof: it does not guarantee the policy stays within a trust region, it only removes the incentive to leave one. That distinction is worth holding on to, because the failure mode it is defending against has not been eliminated, merely made unlikely under normal settings.
The larger finding came from outside. Reproducibility studies — Engstrom and colleagues, and Andrychowicz and colleagues, both around 2020 — took PPO apart and found that a substantial share of its measured advantage comes from implementation details rather than the clipped objective: advantage normalisation, observation and reward scaling, value-loss clipping, learning-rate annealing, orthogonal initialisation, the generalised advantage estimator's parameters. This is the most important caveat on this ladder, because it generalises: a reported delta between two algorithms can be a delta between two codebases.
How it held up: it became the default policy-gradient method and then found a second career that dwarfed the first. PPO is the optimiser in reinforcement learning from human feedback — the algorithm turning a reward model into a fine-tuned language model on the post-training ladder — and its cost there, four models in memory and a value network to train, is exactly what its descendant GRPO removes. A 2017 continuous-control paper is load-bearing for chat assistants, which is not a lineage anyone predicted.
The clipped objective, from scratch
PPO's whole trick is one expression: min(r·A, clip(r,1−ε,1+ε)·A), where r = π_new/π_old is the probability ratio and A is the advantage. At r=1 it equals the advantage. For a good action (A>0), a large ratio is capped at (1+ε)·A — no runaway step. For a bad action (A<0), the min applies the penalty in full. A ratio is "clipped" exactly when it leaves the trust region [1−ε, 1+ε]. Change the ratio, advantage, or ε and watch the objective flatten past the band.
Write the body of clipped_objective. Everything else in the file is
already written; this is the function the paper is about. Press ▶ Run to check it against
the 5 assertions below — they start red.
- At the on-policy point (r=1) the objective equals the raw advantage
- For a good action (A>0) a large ratio is capped at (1+eps)*A
- For a bad action (A<0) the min applies the penalty in full
- The ratio is pi_new / pi_old
- A ratio is clipped exactly when it leaves the trust region [1-eps, 1+eps]
The RLHF workhorse
PPO's second life is in aligning language models. RLHF — reinforcement learning from human feedback — fine-tunes a model to maximize a reward model's score, and that's an RL problem, optimized with PPO. InstructGPT and the RLHF pipelines that made chat assistants helpful and harmless used PPO as the optimizer, precisely because its clipped objective keeps the model from lurching too far from its previous behavior in any single update — exactly what you want when the "policy" is a giant, hard-won language model you don't dare destabilize.
That role made PPO one of the most consequential algorithms in modern AI, far outside its original control-and-games home. It's also a moving target: newer variants trim its machinery — GRPO drops the learned value network and estimates advantages from groups of sampled outputs, simplifying the RLHF stack that PPO defined, and it's central to reasoning-model training like DeepSeek-R1. But the core idea PPO crystallized endures across all of them: improve the policy from experience, and never let a single update wander outside the region where that experience is still trustworthy.
In RLHF, PPO's objective usually carries an extra KL penalty against the original (pre-RL) model on top of the clip — a second leash that keeps the fine-tuned policy from drifting too far from the base model's language, preventing reward-model "hacking" where the policy exploits quirks of the reward at the cost of coherent, on-distribution text.
Questions people ask about PPO
What is generalized advantage estimation in PPO?
Generalized advantage estimation, or GAE, estimates how much better an action was than expected by summing one-step errors going forward. The error at each step is reward plus gamma times the next state value, minus the current state value. Each later error is weighted by gamma times lambda raised to how far ahead it is. Lambda near 0 is low variance but biased; lambda near 1 is unbiased but noisy. PPO commonly uses gamma 0.99 and lambda 0.95.
What is the full PPO loss with value and entropy terms?
When the policy and value function share a network, PPO maximizes the clipped policy objective, minus a coefficient times the squared value error, plus a coefficient times the policy entropy. The value coefficient is 1 and the entropy coefficient is 0.01 in the Atari runs. The entropy bonus keeps the policy from becoming deterministic too early, and the value term trains the baseline used for advantages.
How many epochs does PPO run on each batch?
It depends on the task. The paper runs 10 epochs of minibatch updates on each batch of 2048 steps from one actor for continuous control, using minibatches of 64. In the Atari setup it uses 3 epochs on batches of 128 steps from each of 8 actors. In both cases, the same fresh data is used for several passes, then thrown away and recollected.
Is PPO's clipping better than a KL penalty?
In the authors' comparison on seven continuous-control tasks, clipping with epsilon 0.2 scored about 0.82 on a scale where random is 0 and the best result is 1. The adaptive KL penalty, which doubles or halves its weight depending on measured divergence, peaked at about 0.74. The penalty also needs a target divergence to be chosen, so clipping was both simpler and better in that test.
How does PPO compare with TRPO and A2C?
On the continuous-control benchmarks, PPO with the clipped objective matched or exceeded TRPO and A2C on most tasks within a million timesteps, while using only first-order optimization. On 49 Atari games it was compared with A2C and ACER: PPO won the most games on average training reward, while ACER won the most on the final 100 episodes. That split suggests PPO learns quickly but is not the most sample-efficient method at the end.
3 questions to test what you just read
Work each one out before you open it — a number, a prediction or a reason, not a definition. Producing the answer is what makes it stick. Your progress is kept on this device.
With ε = 0.2, what does the clipped term give for  = −2 and r = 0.7, and why?
Show answer
The unclipped value is 0.7 × (−2) = −1.4. The clipped ratio is 0.8, giving 0.8 × (−2) = −1.6. The minimum is −1.6. The ratio fell below 1 − ε for a bad action, so the objective is flat there: further decreases of the ratio earn nothing beyond this point.
Suppose λ = 0 in GAE. What does the advantage at step t reduce to?
Show answer
Only the first term survives, so the advantage equals δ_t = R_t + γV(s_{t+1}) − V(s_t). That is a one-step estimate: low variance, since it uses one real reward, but it inherits any error the value network has about the next state.
Right after collecting a batch, every ratio is exactly 1. Why does the clip not matter in the first epoch, but matters by epoch 10?
Show answer
At the start of the first epoch the new and old policies are identical, so every ratio is 1, inside the band, and the gradient is the ordinary policy gradient. Each Adam step moves the policy, so ratios spread out. After several passes some leave the band, and for those samples the gradient is zero, which prevents further drift.
Learning by trial and error
Reward, policy, search. The line from Atari to a Go engine that was never shown a human game — and the algorithm (PPO) that RLHF later borrowed wholesale.
- 1DQN2015
- 2PPO2017
- 3AlphaGo2016
- 4AlphaZero2018
- 5MuZero2020
Explore the topic
See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.
More Paper Breakdowns
- Attention Is All You NeedThe paper that introduced the Transformer — the architecture underneath GPT, BERT, Claude, and Gemini. Self-attention, Query/Key/Value, multi-head attention, positional encoding, and the real BLEU results, explained in depth with analogies and animated visuals, not just equations.Read →
- Word2VecHow words became math. Dense word vectors learned from the company a word keeps, so king − man + woman lands near queen. Skip-gram, CBOW, the distributional hypothesis, and the origin of every embedding model powering search and RAG.Read →
- ResNetThe skip connection that made deep learning deep. Why stacking layers made networks worse, and how residual learning let them reach 150+ layers and win ImageNet — the identity shortcut every Transformer still uses inside every block.Read →
- Vision Transformer (ViT)When an image became 16×16 words. Cut a picture into patches, treat each patch as a token, and feed them to a plain Transformer — no convolutions. Patch embeddings, the class token, and why data scale lets attention beat the CNNs that ruled computer vision for a decade.Read →
- Latent DiffusionThe paper behind Stable Diffusion. Compress an image into a small latent space with a VAE, run the diffusion denoising there instead of on pixels for a tens-of-times efficiency win, and steer it with text via cross-attention. The architecture that put text-to-image generation on consumer GPUs.Read →
- DDPMThe original denoising diffusion math — the paper that made diffusion work. A fixed forward process adds Gaussian noise over many steps; a U-Net learns the reverse. The masterstroke: train the network to simply predict the added noise with a plain MSE loss. The foundation under every modern image generator.Read →