Code Architecture: InstructGPT Notebook
Overview
The notebook implements a simplified but complete RLHF (Reinforcement Learning from Human Feedback) pipeline on a small GPT-style language model. It demonstrates all three steps from the InstructGPT paper: (1) supervised fine-tuning (SFT) on instruction-response pairs, (2) reward model (RM) training on human preference rankings, and (3) PPO policy optimization against the reward model. The notebook compares outputs before and after RLHF to show the alignment effect.
Section-by-Section Breakdown
1. Setup & Imports
- Import PyTorch, torch.nn, torch.nn.functional, and standard utilities.
- Set random seeds for reproducibility.
- Configure device (GPU/CPU).
- Install any pip dependencies (transformers tokenizers if needed).
2. Toy Instruction Dataset
- Create a small synthetic dataset of instruction-response pairs (e.g., “Write a haiku about rain” → “Gentle drops fall down / Pattering on rooftops soft / Earth drinks deeply now”).
- Build a simple character or word-level tokenizer (kept minimal for self-containment).
- Data shapes: Input tokens
(batch, seq_len), target tokens(batch, seq_len), attention mask(batch, seq_len). - For the RM dataset: prompt + K response candidates with rank labels
(batch, K, seq_len).
3. Small GPT-Style Language Model (Pretrained Base)
- Key class:
MiniGPT(nn.Module)— a minimal GPT decoder with token embeddings, positional embeddings, N Transformer decoder blocks (causal multi-head self-attention + feedforward + residual + layer norm), and an LM head. - Configurable
d_model=128,n_heads=4,n_layers=4,vocab_size,max_seq_len=128. - This simulates the “pretrained” GPT-3 — we initialize it and do a brief unsupervised pretraining pass on a small text corpus so it has non-random weights.
- Forward shapes:
(batch, seq_len)→ embeddings(batch, seq_len, d_model)→ transformer blocks(batch, seq_len, d_model)→ LM head(batch, seq_len, vocab_size).
4. Step 1 — Supervised Fine-Tuning (SFT)
- Fine-tune MiniGPT on the instruction-response pairs using standard language modeling cross-entropy loss.
- Training: 20 epochs, cosine LR decay, dropout 0.1 (simplified from the paper’s 16 epochs / dropout 0.2 for faster convergence on toy data).
- Model selection: keep the checkpoint with lowest validation loss.
- Loss: standard next-token CE:
L_SFT = −Σ log P(y_t | y_<t, x). - Output:
sft_model— the fine-tuned model used as initialization for both RM and PPO.
5. Step 2 — Reward Model (RM) Training
- Key class:
RewardModel(nn.Module)— wraps the SFT model, replaces the LM head with a scalar output head (linear layer → single value). - Input: prompt + response concatenated; output: scalar reward score.
- Training data: for each prompt, K=4 responses from the SFT model (with varying quality — some are good, some are deliberately degraded). A “human” ranking is simulated by scoring responses using a heuristic (e.g., response length, keyword matching, or a held-out quality function).
- Loss (pairwise ranking, from the paper):
loss = −1/C(K,2) · Σ log(σ(r(x, y_w) − r(x, y_l)))All C(K,2) pairs from one prompt are computed in a single batch element.
- Normalization: After training, normalize RM so that SFT demonstrations achieve mean reward 0.
- Output:
reward_model— used as reward function and value function for PPO.
6. Step 3 — PPO Policy Optimization
- Key class:
PPOTrainer— orchestrates the PPO training loop. - The RL policy is initialized from the SFT model. The environment is a bandit: sample a prompt → generate a response → get reward from RM → episode ends.
- Key mechanism: KL penalty. At each token, penalize the policy for diverging from the SFT model:
reward_total = r_θ(x, y) − β · log(π_RL(y|x) / π_SFT(y|x)) - PPO update: Compute advantages using the RM as value function. Clip policy ratio to [1−ε, 1+ε]. Optimize the clipped surrogate objective.
- Training: 50 PPO steps, batch size 16, β=0.1, ε=0.2, lr=1e-5.
- Output:
ppo_model— the final aligned model.
7. Before/After Comparison
- Generate responses from the base (untrained) model, the SFT model, and the PPO model on a set of test prompts.
- Print side-by-side comparisons to show the improvement in instruction-following quality.
- Plot reward model scores across the three model versions to show the RLHF improvement.
- Plot training curves: SFT loss, RM accuracy, PPO reward over time.
Key Functions/Classes
| Component | Class/Function | Purpose |
|---|---|---|
| Tokenizer | SimpleTokenizer | Character/word-level tokenizer for toy dataset |
| Language Model | MiniGPT | GPT decoder with causal attention, used as base for SFT/RM/PPO |
| SFT Training | train_sft() | Supervised fine-tuning loop with CE loss |
| Reward Model | RewardModel | SFT model + scalar head, trained on pairwise comparisons |
| RM Training | train_reward_model() | Pairwise ranking loss training loop |
| PPO Trainer | PPOTrainer | PPO optimization with KL penalty against SFT |
| Generation | generate() | Autoregressive sampling from any model |
| Comparison | compare_outputs() | Generate and display before/after responses |
Data Flow
Toy Instructions → SFT Training → sft_model
↓
┌─────────────────┴────────────────┐
↓ ↓
RewardModel PPO Policy (init from SFT)
(scalar head on SFT) KL penalty vs SFT
↓ ↓
RM Training PPO Training
(pairwise loss) (clipped surrogate + KL)
↓ ↓
reward_model ──────────────────→ ppo_model (aligned)
↓
compare_outputs(base, sft, ppo)
Deliberate Simplifications vs Full Paper
| Aspect | Paper | This Notebook |
|---|---|---|
| Model size | GPT-3 (1.3B–175B) | MiniGPT (~1M params, d_model=128, 4 layers) |
| Tokenizer | BPE (50K vocab) | Character-level (~100 vocab) |
| Dataset | 13K–33K human-labeled prompts | ~200 synthetic instruction-response pairs |
| Human feedback | 40 trained labelers | Simulated heuristic ranking function |
| RM model size | 6B parameters | Same MiniGPT backbone + scalar head |
| PPO iterations | Multiple rounds (RM→PPO→collect→repeat) | Single round of PPO |
| KL coefficient β | Tuned per model size | Fixed at 0.1 |
| Pretraining mix (PPO-ptx) | Mixed pretraining gradients | Omitted (pure PPO) |
| Model sizes for RM | Up to 175B | Single small model |
| Evaluation | Human evaluations, TruthfulQA, toxicity | Reward model scores + qualitative comparison |
These simplifications keep the notebook runnable within Kaggle’s 30-minute GPU limit while faithfully implementing the core RLHF algorithm (SFT → RM → PPO with KL penalty).