MODULE 7  ยท  Fine-Tuning

RLHF & DPO: How Models Learn to Be Helpful (Not Just Correct)

GPT-3 was brilliant but also a nightmare. RLHF and DPO taught it to be helpful instead of just technically correct.

๐Ÿ“… Mar 2026
โฑ 10 min read
๐ŸŽฏ Episode 49 of 98
RLHFDPOAlignmentTraining
In this episode

GPT-3 was brilliant. It could write essays, code, poetry. But it was also a nightmare. Ask it to help plan a birthday party and it might give you a recipe for methamphetamine. Ask for a joke and get a racist rant.

The model was smart. It just wasn't aligned.

GPT-3 knew the answer to your question โ€” it also knew conspiracy theories, toxic content, and copyrighted material, and it would mix them all together with zero judgment. The raw pretrained model optimizes for one thing: predicting the next token. It doesn't have a concept of "helpful" or "harmful."

snippet
code
RLHF (Reinforcement Learning from Human Feedback) is what transformed GPT-3 into ChatGPT. It's the difference between a genius with no social skills and a genius you'd actually want to talk to.

The Three Stages of Making a Useful Model

Every ChatGPT-like model goes through this pipeline:

Stage 1: PRETRAINING

example
code
โ†’ "Read the entire internet, learn language patterns"
         โ†’ Result: Smart but uncontrollable

Stage 2: SUPERVISED FINE-TUNING (SFT)

example
code
โ†’ "Here are examples of good conversations, learn this format"
         โ†’ Result: Follows instructions, but quality is uneven

Stage 3: RLHF / DPO

example
code
โ†’ "Between these two answers, THIS one is better. Learn why."
         โ†’ Result: Consistently helpful, harmless, honest

Stage 1 takes 6 months and $1 billion. Stage 2 takes a week and 10,000 examples. Stage 3 is where the magic happens.

โšก

RLHF: The Original Approach

Step 1: Collect Human Preferences

Show human annotators TWO responses to the same prompt and ask: "Which is better?"

Prompt: "How do I fix a leaking faucet?"

Response A: "A leaking faucet is typically caused by a worn washer.

Turn off the water supply, remove the handle with a screwdriver,

replace the rubber washer ($2 at any hardware store), reassemble.

If it's a cartridge faucet, you'll need to replace the entire

cartridge โ€” check YouTube for your specific brand."

Response B: "You should call a plumber. Plumbing is complex and

attempting DIY repairs could cause water damage. Professional

plumbers are trained to handle these situations safely."

Human preference: A โœ“ (more helpful, actionable)

This is done thousands of times. The resulting dataset looks like:

json

{

example
code
"prompt": "How do I fix a leaking faucet?",
    "chosen": "A leaking faucet is typically caused by...",
    "rejected": "You should call a plumber..."

}

Step 2: Train a Reward Model

The reward model learns to predict which response a human would prefer. It takes a prompt + response and outputs a scalar score:

python

Conceptual reward model

snippet
code
reward_model("How do I fix a faucet?", response_A) โ†’ 0.85
reward_model("How do I fix a faucet?", response_B) โ†’ 0.32

The reward model is trained on the preference data:

python

Training objective: reward(chosen) > reward(rejected)

snippet
code
loss = -log(sigmoid(reward(chosen) - reward(rejected)))

This is a standard classification problem. The reward model learns the PATTERNS of what humans prefer โ€” helpful, specific, honest answers over vague, hedging, or harmful ones.

Step 3: Optimize the Model with PPO

Now you use the reward model to train the actual language model using PPO (Proximal Policy Optimization), a reinforcement learning algorithm:

  1. Generate a response to a prompt
  2. Score it with the reward model
  3. If score is high โ†’ reinforce this behavior (increase probability)
  4. If score is low โ†’ discourage this behavior (decrease probability)
  5. Repeat thousands of times

The key constraint: KL divergence penalty. You don't want the model to change too much from the SFT model. Without this constraint, the model would learn to "hack" the reward model โ€” finding degenerate responses that score high but are nonsensical.

python

PPO objective (simplified)

loss = -reward_score + beta * KL(policy_modelreference_model)

^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

maximize don't change too much from the original

reward

The RLHF Pipeline

Human Preferences

example
code
โ†“

Reward Model (trained on preferences)

example
code
โ†“

PPO Training Loop:

โ†’ Generate response

โ†’ Score with reward model

โ†’ Update policy (with KL constraint)

โ†’ Repeat

example
code
โ†“

Aligned Model

Why RLHF Is Hard

Expensive. You need thousands of human annotations ($10-50 per hour per annotator).

Unstable. PPO training is notoriously finicky โ€” hyperparameters matter a LOT.

Three models in memory. During PPO, you need: the policy model, the reference model, and the reward model. For a 70B model, that's ~420 GB of VRAM.

Reward hacking. The model finds outputs that score high on the reward model but aren't actually good. Like a student who learns to ace the test without understanding the material.

๐Ÿ”ง

DPO: The Simpler Alternative

Direct Preference Optimization (published 2023) asked: "What if we skip the reward model entirely?"

DPO's insight: You can derive a closed-form solution for the RLHF objective. Instead of training a reward model and then doing RL, you can directly optimize the language model on preference data.

The DPO Formula

Loss = -log(sigmoid(ฮฒ * (log ฯ€(chosenprompt) / log ฯ€_ref(chosenprompt))

example
code
- (log ฯ€(rejected|prompt) / log ฯ€_ref(rejected|prompt))))

In English:

Increase the probability of chosen responses (relative to the reference model)

Decrease the probability of rejected responses (relative to the reference model)

ฮฒ controls how much the model can deviate from the reference

DPO vs RLHF

RLHF DPO

Steps3 (reward model โ†’ PPO โ†’ aligned model)1 (directly optimize on preferences)
Models in memory3 (policy + reference + reward)2 (policy + reference)
StabilityPPO is finickyStable as regular fine-tuning
ComputeHigh (RL training loop)Moderate (standard gradient descent)
QualitySlightly better ceiling95% of RLHF quality
Ease of useRequires RL expertiseStandard fine-tuning workflow

DPO in Practice

python

from trl import DPOTrainer, DPOConfig

from transformers import AutoModelForCausalLM, AutoTokenizer

Load your SFT model (the model you want to align)

snippet
code
model = AutoModelForCausalLM.from_pretrained("./my-sft-model")
ref_model = AutoModelForCausalLM.from_pretrained("./my-sft-model")
tokenizer = AutoTokenizer.from_pretrained("./my-sft-model")

Prepare preference dataset

Format: {"prompt": "...", "chosen": "...", "rejected": "..."}

snippet
code
dataset = load_dataset("json", data_files="preferences.jsonl")

DPO config

snippet
code
dpo_config = DPOConfig(
output_dir="./dpo-aligned-model",
    beta=0.1,               # KL penalty strength
    learning_rate=5e-7,      # Very low LR for alignment
    per_device_train_batch_size=2,
    gradient_accumulation_steps=4,
    num_train_epochs=1,      # Usually just 1 epoch
    warmup_ratio=0.1,
    logging_steps=10,
    bf16=True,

)

Train

snippet
code
trainer = DPOTrainer(
model=model,
    ref_model=ref_model,
    args=dpo_config,
    train_dataset=dataset["train"],
    tokenizer=tokenizer,

)

trainer.train()

That's it. Standard fine-tuning with a special loss function. No reward model, no RL loop, no PPO hyperparameter nightmares.

๐Ÿ“Š

Preference Data: What Makes a Good Dataset

Sources of Preference Data

Human annotation โ€” Most expensive, highest quality. Hire annotators to rank response pairs.

AI feedback โ€” Use GPT-4 to judge which response is better. Cheaper but can introduce biases.

Implicit signals โ€” User upvotes/downvotes, regeneration requests, conversation abandonment.

Existing datasets โ€” Anthropic's HH-RLHF, UltraFeedback, OpenAssistant.

Creating Preference Pairs

python

Generate 2 responses at different temperatures

import openai

snippet
code
prompt = "Explain quantum computing to a teenager"

Response A: lower temperature (more focused)

snippet
code
response_a = generate(prompt, temperature=0.3)

Response B: higher temperature (more creative but risky)

snippet
code
response_b = generate(prompt, temperature=1.0)

Have GPT-4 judge (or humans)

snippet
code
judgment = openai.chat.completions.create(
model="gpt-4",
    messages=[{
        "role": "user",
        "content": f"""Which response is better for a teenager?

Prompt: {prompt}

Response A: {response_a}

Response B: {response_b}

Reply with just "A" or "B" and a brief reason."""

example
code
}]

)

How Much Preference Data?

Model Size Minimum Recommended Source

7-8B1,000 pairs5,000-10,000Mix of human + AI
13B2,000 pairs10,000-20,000Mix of human + AI
70B5,000 pairs20,000-50,000Mostly human

Constitutional AI: Rules Without Humans

Anthropic introduced Constitutional AI โ€” a variant where the AI critiques its OWN responses based on a set of principles (the "constitution"):

Principle 1: "Choose the response that is most helpful"

Principle 2: "Choose the response that is least likely to cause harm"

Principle 3: "Choose the response that is most honest about its limitations"

The process:

Generate a response

Ask the model: "Does this response follow the principles? How could it be improved?"

Model revises its response

Use the (original, revised) pair as preference data

Train with DPO

No human annotation needed for the preference pairs โ€” just for writing the constitution.

๐Ÿ’ก

Beyond RLHF: What's Next

Method Year Key Idea

RLHF (PPO) 2022 Reward model + RL

DPO 2023 Direct optimization on preferences

KTO 2024 Only needs thumbs up/down (no pairs)

ORPO 2024 Combines SFT and alignment in one step

SimPO 2024 No reference model needed

The trend is clear: alignment is getting simpler and cheaper. What used to require a team of RL engineers now takes a single training script.

๐Ÿ”ฌ

Practical Takeaways

RLHF transforms smart models into useful ones โ€” raw pretrained models are powerful but uncontrollable

DPO is the practical choice for most teams โ€” 95% of RLHF quality, 10% of the complexity

Preference data > reward engineering โ€” invest in quality preference pairs, not clever reward functions

One epoch of DPO is usually enough โ€” alignment is a light touch, not heavy training

Constitutional AI reduces annotation costs โ€” let the model critique itself based on principles

The field is moving toward simpler methods โ€” ORPO and SimPO are worth watching

๐Ÿ›ก๏ธ

What's Next?

Episode 50: Prompt Injection โ€” You've built a helpful, aligned model. Now someone types "Ignore all previous instructions and..." and your model complies. Prompt injection is the biggest unsolved security problem in AI, and it's fundamentally harder than you think.

โ† Previous

Ep 48: Model Merging

Next โ†’

Ep 50: Prompt Injection

Next: Episode 50 โ€” Prompt Injection

One sentence broke every AI chatbot on the internet. And there is no complete fix. Not yet. Maybe not ever.

This is part of a 98-episode series covering AI engineering from tokens to production deployment.

โ† Previous Ep 48: Model Merging: Frankenstein Your Way to a Better Model