cs336 / lessons/17 · preferenceslesson 18 / 20

Part V — Alignment & inference

Preferences & rewards — RLHF, DPO, GRPO

SFT (lesson 16) taught the base model to imitate a demonstrated answer: it copies the response tokens it was shown and stops. But imitation has a ceiling. A demonstrator who writes a 7-out-of-10 answer trains a 7-out-of-10 model — the loss has no vocabulary for "this answer is better than that one," only "reproduce this exact one." This lesson installs the missing vocabulary: a comparison signal. We optimize the model to produce answers people (or a verifier) prefer, while a KL anchor stops it from wandering off into gibberish to game that signal. Three methods — RLHF, DPO, GRPO — are three points on one map.

The previous step left this broken
SFT minimizes −log π(response | prompt) over a fixed set of demonstrations. Three things it structurally cannot do. (1) It cannot say A is better than B — every demonstration is treated as the one correct continuation, so a merely-good answer and a great answer pull the model with equal force. (2) It cannot learn from cheap signal — writing a gold demonstration is expensive expert labor, while judging which of two model outputs is better is fast and reliable even for non-experts. (3) It cannot exceed its demonstrator — you can only imitate up to the quality you were shown. To get past all three you need a signal that ranks outputs rather than dictating them, and an optimizer that climbs that ranking.
Linear position
Forced by: SFT can only imitate fixed demonstrations — it cannot express relative quality, cannot learn from cheap comparisons, and cannot exceed the demonstrator.
New idea: optimize a preference / reward signal under a KL anchor to the SFT reference πref — three points on one map: RLHF (learn a Bradley-Terry reward model from comparisons, then PPO to maximize E[r] − β·KL(π‖πref)), DPO (the KL-regularized optimum is closed-form, so skip the reward model and rollouts and optimize one pairwise classification loss), GRPO/RLVR (when correctness is verifiable — math, code — sample a group, use its mean reward as the baseline, no value net).
Forces next: alignment finishes the model — but a trained model that costs too much per token to run is worthless. You must serve it cheaply. That forces inference, lesson 18.
The plan
Five moves. (1) Why a comparison signal beats a demonstration — humans rank more reliably than they write. (2) The RLHF pipeline: Bradley-Terry reward model → PPO on reward minus a KL penalty, and why that KL anchor is the load-bearing piece. (3) DPO: derive that the KL-regularized optimum is a reweighting of πref, reparameterize the reward through log(π/πref) so the partition function cancels, and collapse the whole pipeline into a pairwise loss. (4) GRPO/RLVR: a verifier reward and a group-mean baseline that deletes the value network — the engine of reasoning models. (5) The map: reward source × optimizer, and which cell to pick. Then drive the KL–reward trade-off yourself.

1 · Why a comparison, not a demonstration

Ask a person to write the ideal answer to a hard prompt and you get something slow, expensive, and noisy — two equally-skilled annotators produce different "ideal" answers, and an SFT loss treats every word of each as gospel. Ask the same person instead to compare two model outputs and say which is better, and three things change at once. The judgment is faster (seconds, not minutes). It is more reliable — people agree far more on "B is better than A" than on "here is the one true answer." And critically, the comparison can rank outputs the annotator could never have produced themselves: a domain expert who cannot write a flawless proof can still reliably tell which of two proofs is cleaner.

So we collect data of the form (x, yw, yl) — a prompt x, a winning response yw, a losing response yl, both sampled from the current model. The supervision is a single bit: yw ≻ yl. Everything in this lesson is a way to turn that bit into a gradient that makes the model produce more yw-like outputs and fewer yl-like ones — without forgetting how to write fluent, on-distribution text.

Demonstration (SFT)
"Here is the correct answer." Expensive to author, noisy, caps the model at the demonstrator's skill. Loss: imitate exactly.
Comparison (preference)
"This one is better." Cheap, reliable, can rank outputs the labeler couldn't write. Loss: shift probability mass toward the winner.
Verifier (RLVR)
"This answer is correct" — checked by a program (unit tests, a math grader). Free, exact, unbounded by any human. Only where correctness is checkable.

2 · RLHF — reward model, then PPO under a KL anchor

The original recipe (InstructGPT, the basis of ChatGPT) is a three-stage pipeline. SFT (lesson 16) gives the starting policy πref. Then:

1 · collect preferencesSample several responses per prompt from πref; humans rank them, yielding pairs (x, yw, yl).
2 · fit a reward modelTrain rφ(x, y) — a copy of the LM with a scalar head — to score winners above losers.
3 · PPOTreat the LM as a policy; reinforce responses that earn high reward, penalized for drifting from πref.

The reward model is Bradley-Terry. The Bradley-Terry model says the probability that yw beats yl is a sigmoid of their reward gap:

P(yw ≻ yl | x)  =  σ( rφ(x, yw) − rφ(x, yl) )

Fit rφ by maximizing the log-likelihood of the observed comparisons — i.e. minimize −log σ(rφ(x, yw) − rφ(x, yl)). Note this only ever uses reward differences: the reward is identified up to an additive constant, which is fine because the optimizer only cares about gaps. The output is a learned, differentiable proxy for "what humans prefer," dense enough to score any response the policy invents.

Then PPO optimizes the policy against that reward — minus a KL leash. The objective is:

maxπ   Ex, y∼π [ rφ(x, y) ]  −  β · KL( π(·|x) ‖ πref(·|x) )

The first term pushes the policy toward high-reward outputs. The second term — the KL anchor — is the entire reason this works. KL(π‖πref) measures how far the new policy has wandered from the SFT model; β is the price you charge per unit of wandering. Drop the anchor (β → 0) and the policy is free to chase the reward model anywhere, and it will: the reward model is an imperfect proxy trained on πref-like text, so far out of distribution it assigns garbage high scores. The policy discovers those exploits — repetitive sycophantic filler, degenerate token loops, a fixed phrase the RM happens to love — and reward-hacks them. Output reward soars; actual quality and fluency collapse. The KL term makes every step away from fluent, on-distribution text cost reward, so the policy only moves where the gain genuinely outweighs the drift. The sweet spot is an intermediate β: enough leash to improve, enough anchor to stay coherent. (PPO is the optimizer that maximizes this safely with clipped updates and a value network as a baseline; the mechanics live in reinforcement_learning/16 and reinforcement_learning/14.)

Why this is heavy
RLHF-with-PPO keeps four models in play at once: the policy, the frozen reference πref (to compute the KL), the reward model, and PPO's value/critic network. It requires online rollouts — generate, score, update, repeat — which is slow and finicky to tune. That cost is exactly what the next two methods attack.

3 · DPO — the reward model was never needed

DPO's insight is that the KL-regularized objective in §2 has a closed-form optimal policy, and that closed form lets you skip the reward model and the rollouts entirely. Here is the derivation in three steps.

Step 1 — the optimum is a Gibbs reweighting of πref. Maximizing E[r] − β·KL(π‖πref) over all distributions π (a constrained optimization solvable with one Lagrange multiplier for normalization) has a unique solution:

π*(y|x)  =  (1 / Z(x)) · πref(y|x) · exp( r(x, y) / β )

This is intuitive: start from the reference, and tilt it by exp(reward/β) — up-weight high-reward responses, down-weight low-reward ones, with β setting how aggressively. Z(x) = Σy πref(y|x)·exp(r(x,y)/β) is the partition function that renormalizes it back to a distribution. Z(x) is intractable — it sums over all possible responses — which is normally why you can't use this formula directly. DPO's trick is to never need it.

Step 2 — invert it: the reward is a log-ratio. Solve the equation above for r:

r(x, y)  =  β · log( π*(y|x) / πref(y|x) )  +  β · log Z(x)

Read this carefully: any reward function corresponds to some optimal policy, so we can express the reward of the policy we want purely in terms of that policy's log-probabilities relative to πref. The reward model is implicit — it is the policy, viewed through the lens β·log(π/πref).

Step 3 — the partition function cancels across a pair. Substitute this reward into the Bradley-Terry loss from §2. Bradley-Terry only ever uses the difference r(x, yw) − r(x, yl) — and the β·log Z(x) term is identical for both responses to the same prompt, so it cancels. What's left has no Z, no reward model, no rollouts — just a loss over the policy's own log-probs on the preference pair:

LDPO  =  − log σ( β · log(πθ(yw|x)/πref(yw|x))  −  β · log(πθ(yl|x)/πref(yl|x)) )

This is a plain pairwise classification loss: push the policy to assign relatively higher probability (vs πref) to the winner than to the loser. You compute four forward passes — πθ and the frozen πref, each on yw and yl — and step the gradient. No reward model to train, no sampling loop, no value net, no PPO clipping. The KL anchor is built into the loss through the πref ratios and the β that scales them — it is the same trade-off as §2, now compiled into a single supervised objective. This is why DPO became the default for offline preference tuning; the line-by-line view is in gpt_mini/05.

What DPO trades away
DPO is offline: it learns from a fixed set of pairs, never sampling fresh responses from the current policy. That makes it cheap and stable, but it can only re-rank responses near the data it was given, and it is sensitive to pairs going stale as the policy moves. Online variants re-sample to fix this — at which point you are paying rollout cost again, the thing GRPO embraces deliberately.

4 · GRPO / RLVR — when a program can grade the answer

For math and code, you don't need humans or a learned reward model: a verifier grades the answer exactly and for free. Run the unit tests; check the final numeric answer against the key. This is RLVR — RL from Verifiable Rewards — and the reward is a clean, un-hackable bit: r = 1 if correct, 0 otherwise. Because the signal is honest, you can push hard on it, and the model learns to reason — to spend more tokens deriving the answer — because longer correct chains earn reward. This is the engine behind the reasoning models (DeepSeek-R1 and kin).

GRPO is the optimizer that makes this cheap. Vanilla policy-gradient (REINFORCE) has high variance; PPO tames it with a learned value network that predicts the expected reward — a baseline to subtract. But a value net is a second large model to train and store. GRPO (Group Relative Policy Optimization) deletes it with one idea: for each prompt, sample a group of K responses (say K = 8), grade them all, and use the group's mean reward as the baseline. Each response's advantage is its reward minus the group mean (often divided by the group's standard deviation):

Ai  =  ( ri − mean(r1..K) ) / std(r1..K)

Responses that beat the group average get reinforced; below-average ones get suppressed. The mean is a free, unbiased baseline — no value network needed, removing one of PPO's four models; and because RLVR also swaps the learned reward model for a program verifier, GRPO/RLVR runs on just two (policy + frozen reference), halving PPO's model count and memory. A KL term to πref still rides along to keep the policy from collapsing into a single high-reward rut. GRPO is online (it samples each step) and so pays rollout cost, but it buys the unbounded ceiling of verifiable reward — the model can become far better at math than any demonstration it was shown. The full PPO→GRPO derivation and the reasoning-model story are in gpt_mini/06; the RL-side depth is in reinforcement_learning/14.

5 · The map — reward source × optimizer

All three methods optimize a comparison/reward signal under a KL anchor; they differ on where the reward comes from and how you optimize it. That is the whole map.

RLHF (PPO)DPOGRPO / RLVR
Reward sourceLearned RM from human prefs (Bradley-Terry)Implicit — the policy itself, via log(π/πref)Program verifier (unit tests / answer key)
Needs rollouts?Yes (online)No (offline, fixed pairs)Yes (online, K-sample groups)
Extra modelsRM + value net + frozen ref (4 total)Frozen ref only (2 total)Frozen ref only — no value net (2 total)
KL anchorExplicit penalty term, coeff βBaked into the loss via πref ratios & βExplicit KL-to-ref term
Quality ceilingHuman preference levelHuman preference level (offline)Verifier level — can exceed humans
Use whenGeneral helpfulness/safety, you'll iterate onlineCheap, stable offline alignment from a pref datasetCorrectness is checkable (math, code, tool use)

In practice the modern recipe stacks them: SFT → DPO (cheap broad alignment from preference data) → GRPO/RLVR (push reasoning where a verifier exists). RLHF-with-PPO is still used where the reward is genuinely a fuzzy human judgment and online iteration pays off, but DPO has eaten much of its offline territory and GRPO owns the reasoning frontier. Every one of them is the same sentence: climb a comparison signal, on a KL leash.

Safety and red-teaming

Everything above optimizes one axis: helpfulness / quality — answers people prefer, correctness a verifier confirms. Safety is a distinct axis, and a high preference score does not imply it. Safety means refusing requests that are genuinely harmful, staying robust when a user actively tries to jailbreak the model with adversarial or role-play prompts, and not emitting harmful or biased generations even when the prompt invites them. A model can be maximally helpful on the preference data it saw and still hand over dangerous instructions the moment someone phrases the ask cleverly — because "be helpful" and "be safe" pull in opposite directions exactly on the prompts that matter most.

The machinery is the same comparison-and-reward engine, pointed at this second axis. You collect safety-specific preference data (a refusal preferred over a compliant-but-harmful completion) and fold a safety reward into the RLHF objective alongside the helpfulness reward. The hard prompts to train on come from red-teaming: systematically hunting for inputs that make the model fail — human red-teamers probing by hand, plus automated attackers that generate adversarial prompts at scale — and feeding every discovered failure back as new preference pairs. To collect enough of this signal without an army of labelers, Constitutional AI / RLAIF has the model critique and revise its own outputs against a written set of principles (a "constitution"), turning those AI judgments into preference data — scaling preference collection with far fewer human labels. The KL anchor matters here too: β·KL(π‖πref) keeps the policy near a reference whose safety behavior you trust, so chasing reward cannot quietly erode the refusals and guardrails the SFT model already had (this is the "forgetting πref" failure in the table above, now read on the safety axis).

Be honest about the limits: safety is an open problem, not a solved checkbox. Jailbreaks keep being found against models that passed extensive red-teaming, automated attacks co-evolve with defenses, and — most fundamentally — aligning a model to preferences is not the same as making it safe: the reward is still a proxy, and a determined adversary optimizes against the gaps you did not anticipate. This track only sketches the shape of the problem; the dedicated RL machinery for reward modeling, PPO, and the safety/alignment pipeline lives in reinforcement_learning.

6 · Drive the KL–reward trade-off

The widget below makes the §2 objective tactile. The slider is β, the KL coefficient — the price of drifting from πref. As you lower β, the policy is allowed to chase the reward harder: the achieved reward rises. But the divergence from πref rises with it, and past a point the reward you're chasing is the reward model's blind spots, not real quality — so a reward-hacking / fluency-loss indicator climbs and a sample of the policy's output degrades into gibberish. Crank β too high and the opposite failure: the policy is leashed so tightly it never moves off πref — zero reward-hacking, but zero improvement either. The usable region is the middle. Push the slider to its far-left, β → 0 end: reward maxed, output collapsed.

KL–reward trade-off — set the leash, watch it hack
Lower β (the KL coefficient) buys more achieved reward but more drift from πref. The white curve is true quality (reward minus the hacking penalty); it peaks in the middle. The orange curve is the reward-model score the policy is actually maximizing — it keeps rising even as true quality falls, because low β lets the policy exploit the RM out of distribution. The knob that breaks: β → 0 maxes the RM score and destroys the output.
RM score (what π maximizes) true quality (reward − hacking) KL(π‖π_ref) — scaled ÷ a constant to fit the 0–1 axis; height is illustrative your β
Achieved RM reward
KL(π‖π_ref)
True quality
Regime

The shape of the white curve is the whole lesson in one picture: optimizing a proxy reward without a leash does not maximize the thing you actually want. The KL anchor is not a regularization afterthought — it is the mechanism that keeps "more reward" pointed at "better model" instead of at the reward model's failure modes.

Failure modes & checklist

Failure modes

  • KL coefficient too small. Reward soars, output degenerates. Signal: RM score climbing while human eval and fluency drop; repetitive or sycophantic text; the policy fixates on a phrase the RM over-rewards.
  • Reward model over-trusted. An RM is a proxy fit on limited data; pushing the policy far past the RM's training distribution rewards its blind spots. Signal: reward keeps rising long after quality plateaus — classic reward hacking.
  • Stale DPO pairs. Offline DPO on pairs sampled from an old policy mis-ranks responses the current policy now produces. Signal: DPO "improves" the loss but win-rate against the SFT model stops moving or regresses.
  • Gameable verifier. An RLVR verifier that checks only the final answer lets the model guess or hard-code, or pass tests without real reasoning. Signal: high pass rate on the graded set, no transfer to held-out problems.
  • Forgetting π_ref. Dropping or under-weighting the KL term (or letting π_ref drift) erases SFT's instruction-following and safety behavior. Signal: the aligned model loses formatting/refusal behavior the SFT model had.

Checklist

  • Always keep a KL anchor. Tune β to sit in the middle of the trade-off, not at either extreme.
  • Pick the reward source first. Verifiable task → RLVR/GRPO; fuzzy human judgment → RM+PPO or DPO; have a pref dataset and want cheap → DPO.
  • Watch true quality, not proxy reward. Track held-out win-rate / human eval alongside RM score; divergence between them is reward hacking.
  • Re-sample for DPO if the policy moved. Refresh preference pairs from the current policy to avoid staleness, or go online.
  • Harden the verifier. For RLVR, test on held-out problems and guard against shortcut exploits before trusting the reward.

Checkpoint

Try it
Open the widget and park β near the white curve's peak — true quality maxes out around β ≈ 0.25, well inside the "sweet spot — aligned" regime. Read off the three numbers there: RM reward, KL, true quality. Now slide β down toward 0 and watch the RM reward keep rising while true quality falls and the sample box degenerates — this is reward hacking made visible. Confirm that the β that maximizes true quality is nowhere near the β that maximizes RM reward. Then answer in one sentence each: why does DPO not need a separate β-penalty term even though it has the same trade-off, and why can RLVR push its reward far harder than RLHF without hacking?

Where this points next

The model is now done in every sense this course set out to deliver: a base model trained compute-optimally on quality data (parts I–IV), turned into an instruction-follower by SFT (14), and tuned to human preferences and verifiable correctness here (15). It is also, right now, useless — because a frontier-scale model that takes seconds and dollars to emit each token is a model nobody can deploy. The cost structure of generation is completely different from training: a single forward pass per token, re-reading every weight and a growing KV cache from HBM each step, memory-bandwidth-bound rather than compute-bound. Serving the model you paid to build is its own engineering problem, and it is the last link in the chain: lesson 18, Inference — serving the model you paid for.

Takeaway
SFT can only imitate; to express "A is better than B," learn from cheap comparisons, and exceed the demonstrator, you optimize a comparison/reward signal under a KL anchor to πref. RLHF fits a Bradley-Terry reward model from human preferences (σ of the reward gap), then runs PPO to maximize E[r] − β·KL(π‖πref) — and the KL term is load-bearing: drop it and the policy reward-hacks the imperfect RM into fluent gibberish. DPO notices the KL-regularized optimum is a Gibbs reweighting π* ∝ πref·exp(r/β); inverting it expresses reward as β·log(π/πref) + β·log Z, and the intractable log Z cancels across a preference pair in the Bradley-Terry loss — leaving a single pairwise classification loss with no reward model and no rollouts. GRPO/RLVR uses a program verifier (math/code) for an un-hackable reward and replaces PPO's value network with the mean reward of a K-sample group as the baseline — the cheap, high-ceiling engine of reasoning models. The map is one axis of reward source (human pref → learned RM → verifier) crossed with optimizer (PPO/DPO/GRPO); all three are the same sentence — climb a comparison signal on a KL leash. The model is finished; what remains is serving it cheaply, which forces inference.

Interview prompts