RLHF (the InstructGPT recipe)
Reward models, PPO, and the three-stage pipeline that made LLMs follow instructions.
Why this matters
SFT teaches the model what to say. RLHF teaches the model what humans prefer. RLHF β Reinforcement Learning from Human Feedback β is the technique that made ChatGPT feel "polished" rather than just "instructed." Every major closed model (GPT-4o, Claude, Gemini) and most strong open models go through some preference-optimisation step.
This lesson explains the original RLHF recipe (InstructGPT, 2022) using PPO. The next lesson covers DPO/ORPO/KTO β newer, simpler alternatives that are now more common. You should understand the original even if you never run it; it is the conceptual ancestor of every preference method.
Learning objectives
- Explain the 3-stage RLHF pipeline (SFT β reward model β PPO).
- Train a small reward model from preference data.
- Understand the PPO loss in the language-model setting.
- Reason about KL constraints and reward hacking.
- Recognise why DPO largely replaced PPO for open-source post-training.
1. The InstructGPT pipeline (2022)
[base LM]
β
βΌ Stage 1: SFT
[SFT model]
β
βΌ Stage 2: Reward model β train on (prompt, chosen, rejected) pairs
[Reward model RM]
β
βΌ Stage 3: PPO β RL fine-tune SFT policy with reward = RM(prompt, response) - Ξ² KL(policy || ref)
[RLHF model β your chat assistant]This pipeline produced ChatGPT in 2022. Every later technique tweaks Stage 3.
2. Stage 2 β training a reward model
Data format
Each example is a pair of completions for the same prompt with a human-judged preference:
{"prompt": "Write a haiku about coffee.",
"chosen": "Mug warm in my hand / steam rises like whispered words / morning has begun.",
"rejected": "Coffee good. Drink coffee. Yes."}Public datasets: Anthropic/hh-rlhf, HuggingFaceH4/ultrafeedback, openbmb/UltraFeedback, lmsys/chatbot_arena_conversations.
Architecture
The reward model is the base or SFT model with a scalar head replacing the LM head:
class RewardModel(nn.Module):
def __init__(self, base):
super().__init__()
self.body = base
self.score = nn.Linear(base.config.hidden_size, 1, bias=False)
def forward(self, ids, mask):
h = self.body(ids, attention_mask=mask).last_hidden_state[:, -1, :]
return self.score(h).squeeze(-1)Loss β Bradley-Terry preference
P(chosen > rejected) = Ο(r_chosen - r_rejected)
loss = - log Ο(r_chosen - r_rejected)Train to maximise this likelihood. After ~1 epoch on 100k pairs, you have a usable RM.
loss = -F.logsigmoid(r_chosen - r_rejected).mean()trl.RewardTrainer does this.
3. Stage 3 β PPO
The crux: optimise the SFT policy to produce responses with high reward, without drifting too far from the SFT model (otherwise the policy will exploit the RM's flaws β "reward hacking").
The objective per token:
J(ΞΈ) = E_{x,y~Ο_ΞΈ} [ r(x,y) ] - Ξ² * KL( Ο_ΞΈ(y|x) || Ο_ref(y|x) )Ο_ref is the frozen SFT model. Ξ² is the KL coefficient (~0.05-0.2).
Why PPO?
PPO (Proximal Policy Optimisation; Schulman 2017) is the workhorse RL algorithm: keeps update steps "proximal" to the current policy via a clipped ratio. Stable, off-the-shelf.
PPO loss:
ratio = Ο_ΞΈ(y|x) / Ο_old(y|x)
clip = min(ratio * A, clip(ratio, 1-Ξ΅, 1+Ξ΅) * A) # Ξ΅=0.2
J = E[clip] - Ξ² * KLWhere A is the advantage (typically reward - value baseline; we estimate the value with a critic head).
Practical components
- Actor β your trainable policy (SFT model).
- Critic β value head; estimates expected return for a given prefix.
- Reward model β frozen.
- Reference model β frozen copy of SFT for the KL term.
- Roll-outs β sample completions from the actor.
- Update β backprop PPO loss.
You hold four copies of a 7B model in memory. PPO is expensive.
trl.PPOTrainer minimal example
from trl import PPOConfig, PPOTrainer
cfg = PPOConfig(model_name="my-sft", learning_rate=1e-6, batch_size=64,
mini_batch_size=8, kl_coef=0.05, init_kl_coef=0.05,
target_kl=6.0)
trainer = PPOTrainer(cfg, policy=actor, ref_policy=ref, reward_model=rm,
value_model=critic, train_dataset=prompts_ds, processing_class=tok)
trainer.train()4. The hard parts (and why DPO won)
Reward hacking
The policy finds adversarial responses the RM scores highly but humans dislike β verbose preambles ("Certainly! Here is a detailed answer..."), refusing borderline questions to be "safe," excessive politeness, sycophancy.
Mitigations:
- KL constraint (the Ξ² term).
- Better RM (more diverse data, larger RM).
- Reward shaping (combine with rule-based rewards: format, length penalty).
- Composite RMs (separate RMs for helpfulness, harmlessness).
Stability
PPO LM training is fragile. Tuning learning rate, KL coefficient, clip Ξ΅, and rollout temperature consumes most of an engineer's time.
Compute
You need 4Γ the model in memory and run RL roll-outs (slow autoregressive sampling) every step. RLHF on 70B is a serious infrastructure project.
This is why DPO (next lesson) β which eliminates the RM and the RL loop β exploded in 2023-2024. But:
- The biggest closed labs still use PPO (and variants like REINFORCE-style updates) at scale.
- Reasoning RL (DeepSeek-R1, o1) uses PPO/GRPO, not DPO.
5. RLHF variants you should know
- PPO β original; standard at OpenAI/Anthropic/Google for years.
- REINFORCE / RLOO (REINFORCE Leave-One-Out) β simpler; just gradient Γ reward. Re-emerged because PPO's clipping is overkill at language-modelling scale.
- GRPO (DeepSeek 2024) β Group Relative Policy Optimisation; estimate advantage by comparing within a group of N samples for the same prompt instead of a critic. No critic β 25% memory saving. Used in DeepSeek-R1.
- REINFORCE++ / RAFT β reject low-reward samples, fine-tune on the rest with cross-entropy. Cheap "best-of-N" SFT.
- SimPO / DPO / IPO / KTO / ORPO β preference methods that skip explicit RL (next lesson).
6. Mental model β RL vs SFT
SFT and RLHF differ in who knows the right answer:
| Method | Signal | Problem solved |
|---|---|---|
| Pretraining | Next token from corpus | "Speak fluently" |
| SFT | Imitation of demonstrated answers | "Answer like a helpful assistant" |
| RLHF / DPO | Pairwise human preference | "Among answers you can give, choose the one humans prefer" |
| RL with verifiable rewards (RLVR) | Programmatic correctness signal | "Solve maths / code correctly" |
RL becomes essential when you cannot demonstrate the right answer (hard reasoning tasks) but you can verify or rank outputs after the fact.
Hands-on lab (4 hours)
rlhf_lab.ipynb (use small models β Llama-3.2-1B is fine):
- Train a reward model on
Anthropic/hh-rlhfusingtrl.RewardTrainer. 1 epoch, 30k pairs. Plot accuracy on a held-out set (target: 65-70%). - Sanity-check the RM: feed a list of 5 candidate completions for a prompt and rank them. Discuss.
- Run a tiny PPO on
trlagainst your RM. Track KL divergence, reward, andmean_response_length. - Show the length bias: PPO with no length penalty produces verbose answers. Add a length penalty to the reward and rerun.
- Run GRPO instead of PPO for the same model+RM. Compare wall-time and final reward.
- Bonus: replace the RM with a rule-based reward (regex for format, exact match for short factuals) and run RL. This is the "RLVR" mode used in modern reasoning training.
Common pitfalls
- No KL constraint β policy collapses into degenerate high-reward outputs.
- Untrained / weak RM β RLHF amplifies the RM's biases.
- Too high LR in PPO β instant divergence.
- Sampling temperature = 0 during roll-outs β no exploration.
- Reward range explosion β standardise rewards (subtract group mean, divide by std).
- Forgetting to detach
ref_policyβ trainable params include the reference model. Painful debug.
Self-check
- State the three stages of RLHF.
- What does the KL term in the PPO loss prevent?
- What is reward hacking? Give two mitigations.
- Difference between PPO and GRPO?
- Why is RLHF more expensive than SFT?
References
- Christiano et al. (2017), "Deep Reinforcement Learning from Human Preferences."
- Stiennon et al. (2020), "Learning to Summarize from Human Feedback."
- Ouyang et al. (2022), "Training Language Models to Follow Instructions" (InstructGPT).
- Schulman et al. (2017), "Proximal Policy Optimization Algorithms."
- Bai et al. (2022), "Training a Helpful and Harmless Assistant with RLHF" (Anthropic).
- Shao et al. (2024), "DeepSeekMath" β introduces GRPO.
- HuggingFace TRL PPO docs.
Sign in to save your progress and earn badges.