GRPO and Verifiable Rewards

Module FT14 · Course 3 — LLM Fine-Tuning Masterclass

90 minutes · Pillar 4 — the flagship 2025–2026 module. Reasoning models (o1 / R1 / Qwen3) are trained via RL on verifiable rewards.

FT13's DPO learns from fixed preference pairs. GRPO generates, verifies, and learns from its own attempts — on-policy exploration that offline DPO structurally cannot do. Verifiable rewards (math, code, tools) are what make it possible.

Pillar 4 — Reasoning Models

The decision: DPO vs GRPO

The most important judgment in this module. It comes down to one question.

Can you write a verifier? A deterministic function that returns correct/incorrect for a given response.
Reward typeExamplesMethod
Verifiablemath correctness, code execution, tool-use successGRPO / RL — on-policy exploration
Preference onlystyle, helpfulness, toneDPO family (FT13) — offline
Reasoning is verifiable. A math answer is right or wrong — you can run the check. The moment you have a verifier, the right move is to let the model generate, check, and learn from its own attempts. That is on-policy exploration. DPO cannot do it.

Why DPO is wrong for reasoning

DPO — offline preference

Fixed (chosen, rejected) pairs. Model re-scores, never generates. Learns from someone else's attempts. The curriculum is frozen before training begins.

GRPO — on-policy RL

Model generates N attempts per prompt, verifier scores each. Learns from the distribution of its own errors — including errors your fixed dataset never contained.

The analogy. Teaching long division: DPO shows 1,000 pre-labeled good/bad worked examples. RL lets the student attempt it N times and checks each against the answer key. For verifiable skill, RL is strictly more informative — the verifier generates an infinite curriculum of labeled attempts tailored to this model's weak spots.

GRPO: drop the critic

GRPO (Group Relative Policy Optimization, DeepSeek — DeepSeekMath, arXiv:2402.03300). The key move: eliminate the learned value function from PPO.

PPOGRPO
Policyyes (trainable)yes (trainable)
Critic / valueyes — ~same size as policyNO — dropped
Reference (KL)yes (frozen)yes (frozen)
Baselinelearned estimategroup mean of N samples
Models in memory~3~2 → ~half the memory
Per prompt: sample N responses (e.g. 8/16) → score each with the verifier → advantage A_i = (r_i − mean(r)) / std(r) → clipped PPO update + KL anchor. The group is the baseline. No critic to train.

The clarification: GRPO ≈ RLOO

GRPO is essentially RLOO (REINFORCE Leave-One-Out) with a slightly different advantage computation. Both sample N responses per prompt and use a group/leave-one-out baseline. Not fundamentally different algorithms.

RLOO (Kool et al. 2019): baseline for response i = mean of the other N−1. GRPO: baseline = mean of all N (including i). A small bias/variance tradeoff, not a different family.

FamilyBaselineCritic?
PPOlearned value function (estimates expected reward from state)yes (trained)
GRPO / RLOOMonte Carlo mean over N samplesno
This is why TRL ships GRPOTrainer and RLOOTrainer side by side — they behave nearly identically. Siblings, not strangers.

The GRPO++ landscape

GRPO works. Production recipes patch specific failure modes. (Cameron Wolfe's survey is the map.)

VariantFailure it fixesThe patch
DAPO (ByteDance)exploration stalls; zero-variance groups waste computeclip-higher (decouple ± clip) + dynamic sampling (skip all-correct/all-wrong groups)
Dr. GRPOlength bias (per-token avg favors short sequences)remove the length bias in advantage averaging
GSPOnoisy credit assignment on long CoTsequence-level importance weighting (one weight per sequence)
In production: mix & match. "GRPO with clip-higher and dynamic sampling" = GRPO + DAPO patches. OLMo 3 (2025) is the open-data production reference — cite it as the reproducible counterpoint to R1/Qwen3.

The DeepSeek-R1 pipeline (canonical)

R1-Zero proved reasoning emerges from RL alone. R1 fixes the readability with a 4-stage pipeline. (arXiv:2501.12948 + Nature s41586-025-09422-z.)

R1-Zero — the proof

Pure RL on the base (DeepSeek-V3-Base), no SFT cold start. Self-verify, backtrack, long CoT emerge — selected for by the correctness reward. Problem: poor readability, mixed languages.

R1 — the 4 stages

(1) Cold-start SFT → readable CoT scaffold. (2) Reasoning RL (GRPO). (3) Rejection-sampling SFT → generate, filter by reward, retrain (→ FT15). (4) Final RL (alignment).

Distillation surprise. 6 dense students distilled from R1 via SFT only (no RL) on ~800K curated CoT samples. R1-Distill-Qwen-32B beats OpenAI o1-mini. This made CoT distillation a standard technique — the subject of FT15.

The Qwen3 pipeline (the other canonical reference)

Qwen3 technical report (arXiv:2505.09388, May 2025). Industrializes the R1 recipe.

#StageWhat it does
1Long-CoT cold startSFT on long chain-of-thought — sets a prior toward thorough reasoning
2Reasoning RLGRPO-style on verifiable rewards (large-scale)
3Thinking mode fusionMerge thinking (long CoT) + non-thinking (fast) into ONE model, mode-flagged
4General RLBroad capability + alignment; preserves reasoning from 2–3
Pretraining: 36T+ tokens — among the largest openly disclosed. Scale matters: RL amplifies what the base can do. Thinking budget (runtime): bound the "thinking" compute per query — short budget for easy, long for hard. Adaptive latency/accuracy trade.

The reward-verification loop

The heart of the method. The verifier is the load-bearing component — its quality bounds the whole run.

  1. Generate N responses per prompt from the current policy
  2. Verify each: parse answer → execute/check (run the code, compare the math answer, validate the tool output) → scalar reward
  3. Advantage: A_i = (r_i − mean(r)) / std(r) — group-relative, no critic
  4. Update policy toward high-advantage responses, with a KL anchor to the reference
Reward hacking. A weak verifier (substring match, leniency) → the model finds the shortcut, scores high, outputs wrong. Fix: a verifier, not a judge. Execute the code; compare the parsed answer exactly; validate structure. Your reasoning RL is bounded by your verifier quality — the analog of "your data matters more than your algorithm."

Tooling: TRL, verl, OpenRLHF

ToolUse it forNotes
TRL GRPOTrainerModerate scale — research, small models, learningIntegrates with transformers/peft/accelerate. Supply a Python reward function. Default starting point. The lab uses this.
verl (HybridFlow, ByteDance)Production-grade distributed RL on RaySeparates generation (rollout) from training. The standard for 30B+ on a cluster.
OpenRLHFFaster on some micro-benchmarksA masked_mean bug was found (silently wrong on padded long CoT). Consensus: "TRL or verl and you're fine."
Decision tree: single GPU, learning, small model → TRL. Cluster, large model, production → verl. OpenRLHF only with a specific reason + a check that the masked_mean issue doesn't affect your padding.

The verifiable reward function (math)

import re

def math_reward(prompts, completions, answer, **kwargs):
    """Verifiable: parse the model's \\boxed{} answer, compare exactly."""
    rewards = []
    for comp, gold in zip(completions, answer):
        # parse the last \\boxed{...} from the completion
        m = re.findall(r"\\\\boxed\{([^}]*)\}", comp)
        pred = m[-1].strip() if m else None
        rewards.append(1.0 if pred is not None and pred == gold.strip() else 0.0)
    return rewards
This is the load-bearing component. It parses the answer and checks it exactly — not a substring match, not a judge. For code rewards you'd exec the completion and check the output. The strength of your verifier is the ceiling on your RL run.

Anti-patterns

  • DPO for reasoning — forfeits on-policy exploration on a verifiable task. Use GRPO + a verifier.
  • No reward verification (reward hacking) — a hackable reward (substring, leniency) → model games it, scores high, outputs wrong. Use a verifier, not a judge.
  • Skipping the cold-start SFT — the R1-Zero path can work but produces readability problems. Give the model a CoT scaffold first (one SFT stage).
  • Ignoring the readability problem of pure-RL — RL optimizes correctness, not human-facing format. Plan the readability layer (cold-start SFT, rejection-sampling SFT).
  • Treating GRPO variants as interchangeable — "use GRPO" is underspecified. Mid-training stalls often need a specific patch (clip-higher, length-debias, sequence-level weighting). Know which failure each patch addresses.

The lab — "GRPO on a Math Task"

Run TRL GRPOTrainer on a small base with a verifiable math reward (GSM8K-style correctness checked by a Python reward function). Watch the reward curve climb.

The reward

Parse the model's \\boxed{} answer, compare to ground truth exactly. Verifiable — no judge. This is what makes GRPO the right tool (vs DPO).

The loop

Load base → write reward function → configure GRPO (N samples, KL) → train → eval on held-out math. Heavy lab — single consumer GPU; cloud GPU stretch goal.

Default: Qwen/Qwen2.5-1.5B-Instruct. Watch the reward climb step-over-step — that is on-policy exploration working. Stretch: swap in verl for scale, or a code-execution reward.

Next: FT15 — CoT Distillation & Rejection-Sampling FT

What you can now do

  1. Explain why RL, not DPO, for reasoning — verifiable rewards enable on-policy exploration offline DPO cannot do.
  2. State the GRPO mechanism — N samples, group-relative advantage, no critic → ~half the memory — and that GRPO ≈ RLOO.
  3. Map the GRPO++ landscape (DAPO, Dr. GRPO, GSPO) to the failure each patches; name OLMo 3 as a production recipe.
  4. Recite the DeepSeek-R1 pipeline (R1-Zero → 4-stage R1 → distillation) and the Qwen3 4-stage pipeline + thinking budget.
  5. Choose between TRL GRPOTrainer (moderate) and verl (production), and state the OpenRLHF caveat.
  6. Write a verifiable reward function and explain why verifier quality bounds the whole run.

DPO taught you preference. Now you have exploration — the tool that builds reasoning models.