GRPO Training
Group Relative Policy Optimization — derived from the policy gradient theorem, situated against PPO, DPO and RLOO, with its known biases stated and its memory footprint accounted for. Then a memory-efficient implementation on GSM8K with LoRA and DeepSpeed ZeRO-2.
Model: Qwen-1.5B (distilled) · Dataset: GSM8K · Target: 8 GB GPU
GRPO is frequently described — including in earlier versions of this page — as "eliminating the reference model, so no KL term is needed." This is wrong. The objective published in DeepSeekMath (Shao et al., 2024, Eq. 3) contains an explicit term and requires a frozen reference model.
What GRPO eliminates is the critic (value network) — a trainable model the same size as the policy. That is where the memory saving comes from, and it is a much stronger claim than dropping a frozen reference. The distinction is developed in §5.
1. Why Reinforcement Learning At All
An LLM is trained in stages, and each stage optimizes a different objective:
The reason RL is not redundant with SFT is a distribution mismatch. SFT is maximum likelihood on a fixed corpus of demonstrations — behaviour cloning. It trains the model on the demonstrator's state distribution, but at inference the model must act on states induced by its own previous tokens. Errors compound: this is the classic covariate-shift argument of DAgger (Ross et al., 2011), and in the sequence setting it is exposure bias.
More fundamentally, SFT can only imitate. If a correct answer is reachable by a reasoning chain no human wrote down, likelihood training on human chains cannot find it. RL optimizes — the quantity you actually care about — over the model's own output distribution, and can therefore discover behaviours absent from the demonstration set.
For mathematical reasoning this is especially compelling, because need not be learned at all: the answer is checkable. That is the regime GRPO was designed for.
2. From Policy Gradients to PPO
2.1 The policy gradient theorem
Treat generation as a finite-horizon MDP: state is the prompt plus tokens so far, action is the next token, and the policy is the LM itself, . We maximize
The score-function identity gives the REINFORCE estimator (Williams, 1992):
This is unbiased and essentially unusable on its own: its variance scales with the magnitude of and with sequence length. With tokens, a single scalar reward must be credited across 512 factors.
2.2 Baselines and why they are free
For any function that does not depend on the action,
So replacing with the advantage leaves the gradient unbiased while changing its variance. Choosing well is the entire game. This identity is the hinge of the whole page: PPO, GRPO and RLOO differ almost exclusively in how they construct .
| Method | Baseline | Cost |
|---|---|---|
| REINFORCE | None; variance is enormous | |
| Actor–critic / PPO | , a learned value network | A second trainable model of policy size |
| RLOO | Mean reward of the other samples | samples per prompt, no extra model |
| GRPO | Mean reward of the group, then divided by group std | samples per prompt, no extra model |
2.3 PPO
PPO (Schulman et al., 2017) fixes a second problem: a large policy step can collapse the policy, and the sampled data is only valid near . Define the importance ratio
and optimize the clipped surrogate — the objective the DeepSeekMath paper states as its Eq. 1:
The with a clipped copy creates a pessimistic bound: once the ratio moves beyond in the direction that would improve the surrogate, the gradient is cut off. Typically .
In RLHF, comes from GAE (Schulman et al., 2016) over a learned critic . That critic is the problem. It is initialized from the policy, is the same size, and is trained concurrently — so it carries a full of model states. It is also genuinely hard to fit: it must predict the expected future reward of a partial generation, from a sparse terminal signal, on a non-stationary distribution.
3. Direct Preference Optimization — the other escape route
DPO (Rafailov et al., 2023) takes a different exit. Under the KL-regularized RL objective the optimal policy has a closed form,
which can be inverted for the implied reward,
Substituting into a Bradley–Terry preference model, the intractable cancels between the two responses, leaving a supervised objective:
No rollouts, no reward model, no critic — DPO is a classification loss on a fixed preference dataset.
Its limitation is exactly what makes GRPO attractive for math. DPO is off-policy and offline: it can only learn from preference pairs already collected, cannot query a verifier during training, and cannot exploit a scalar reward that is cheap to evaluate on new samples. When you have a ground-truth checker, throwing it away to collect pairwise human preferences is a strange trade.
4. GRPO
4.1 The idea
Ask what the critic is for. It supplies a baseline: an estimate of the expected reward from state . But if you are willing to sample responses to the same prompt, you can estimate that expectation by Monte Carlo — directly, with no learned model:
Replace a learned function approximator with an empirical mean over a group of rollouts. That is GRPO in one sentence. It exploits a property special to LLM alignment: unlike a robotics episode, generating samples from the same prompt is cheap and embarrassingly parallel.
4.2 The objective
For prompt , sample a group and score each with . Under outcome supervision, every token of receives the same normalized advantage:
Writing , the GRPO objective (Shao et al., 2024, Eq. 3) is
Compare term by term with : the clipped surrogate is identical. Exactly two things changed.
- from a learned critic from group statistics.
- The KL penalty moved out of the reward and into the loss, as an explicit term with its own estimator.
Everything else — the ratio, the clip, — is PPO.
4.3 The KL estimator — why it is not what you would write
Naively, is estimated by the sample mean of . GRPO instead uses (Eq. 4):
This is Schulman's k3 estimator. Writing , the three candidates are
| Estimator | Form | Unbiased? | Variance | Sign |
|---|---|---|---|---|
| k1 | Yes | High | Can be negative | |
| k2 | No | Low | Always | |
| k3 | Yes | Low | Always |
k3 is unbiased and guaranteed non-negative, because for all real with equality only at . That non-negativity matters: k1 fluctuates in sign sample-to-sample, and a "penalty" that is sometimes a bonus is a poor regularizer.
A KL penalty written as kl = (old_log_probs - log_probs).mean() is k1 — high variance and sign-unstable. Prefer:
log_ratio = ref_logprobs - policy_logprobs # u
kl = torch.exp(log_ratio) - log_ratio - 1.0 # k3: unbiased, non-negative
4.4 Relation to RLOO
RLOO (Ahmadian et al., 2024) uses the leave-one-out baseline
Since excludes , it is independent of the action being scored and the baseline identity of §2.2 applies exactly — RLOO's advantage is strictly unbiased. GRPO's includes , so is weakly correlated with and carries an bias. Note the two differ only by the constant factor , which is absorbed into the learning rate — so before std-normalization, GRPO's advantage is RLOO's up to a scalar. The real divergence is the factor, and that turns out to be the contentious part.
5. What GRPO Actually Removes: A Memory Accounting
Use the mixed-precision Adam accounting from ZeRO Stages: a trainable model costs bytes of model states; a frozen model in BF16 costs .
| Component | PPO / RLHF | GRPO | DPO |
|---|---|---|---|
| Policy (trainable) | |||
| Critic (trainable) | — | — | |
| Reward model (frozen) | — a verifier | — | |
| Reference (frozen) | |||
| Total model states |
For : PPO 54 GB, GRPO 27 GB. GRPO halves model-state memory, and the entire saving is the critic. Dropping a frozen reference model would have saved — about 6% — which is why the "no reference model" framing both misstates the algorithm and undersells it.
Two caveats that keep this honest:
- GRPO's activation memory is worse than PPO's per optimizer step, because it holds rollouts per prompt rather than one. Model states fall; rollout buffers rise. Budget for both.
- With LoRA, only adapter parameters are trainable, so the terms collapse to . The critic's removal still matters, but proportionally less — and the reference model can often be obtained for free by disabling the adapters, since the frozen base weights are . See §8.
6. A Worked Numerical Example
Take GSM8K with binary verifier reward and group size .
Prompt. Janet's ducks lay 16 eggs per day. She eats 3 for breakfast and bakes muffins with 4. She sells the rest at $2 per egg. How much does she make daily? Ground truth: 18.
Rollouts and rewards.
| Final answer | ||
|---|---|---|
| 1 | 18 ✓ | 1 |
| 2 | 15 ✗ | 0 |
| 3 | 18 ✓ | 1 |
| 4 | 20 ✗ | 0 |
. The population standard deviation is
giving advantages
Every token of responses 1 and 3 is reinforced with weight ; every token of 2 and 4 is suppressed with weight . No critic was consulted, and the absolute scale of never entered.
torch.std uses Bessel's correction — this is a real bug sourcePyTorch's Tensor.std() defaults to unbiased=True, dividing by , not . On the same data:
A 13% smaller effective advantage than the paper's formula, i.e. a silently reduced learning rate — and the discrepancy grows as shrinks. Write rewards.std(dim=1, unbiased=False) (or correction=0) to match the published objective, and be aware that library implementations differ on this point.
6.1 The degenerate-group problem
Now suppose all four rollouts are correct: . Then , , and
The gradient is exactly zero. The prompt contributes nothing. The same holds if all four are wrong. This is not a numerical edge case — it is structural, and it governs how much of your compute does useful work.
Model each rollout as i.i.d. within a group, where is the model's per-sample success rate on that prompt. A group is degenerate iff all samples agree:
| 0.1 | 65.6% | 43.0% | 18.5% |
| 0.3 | 24.8% | 5.8% | 0.33% |
| 0.5 | 12.5% | 0.78% | 0.003% |
| 0.7 | 24.8% | 5.8% | 0.33% |
| 0.9 | 65.6% | 43.0% | 18.5% |
Three consequences worth internalizing:
- Signal is maximized at . GRPO learns most from problems the model solves about half the time — a formal statement of "train at the edge of competence."
- Success is self-defeating. As training drives , roughly two-thirds of groups at become degenerate. Throughput of useful gradient collapses precisely because the model improved. Reward curves flattening late in training often reflect this, not a converged policy.
- Group size is variance-reduction with sharply diminishing returns. Going at takes waste from 65.6% to 43.0%; takes it to 18.5%. Each doubling doubles rollout cost, and rollout dominates GRPO wall-clock.
The practical remedies follow directly: filter degenerate groups before the optimizer step (DAPO's dynamic sampling, Yu et al., 2025), curriculum toward problems near , and raise only once filtering is in place.
For a full simulation of this effect with runnable code, see the worked example page.
7. Known Biases: The Dr. GRPO Critique
Liu et al. (2025) show that two normalizers in the objective are not innocuous.
Length normalization . For a response with negative advantage, dividing the summed per-token loss by means a longer wrong answer receives a smaller per-token penalty. Gradient descent therefore finds it cheaper to be wrong at length, and incorrect responses grow monotonically during training — the widely-observed "length inflation" of R1-Zero-style runs, which is easy to misread as emergent deliberation.
Standard-deviation normalization . Under binary rewards , minimized when is near 0 or 1. Dividing by it up-weights questions that are nearly-always-solved or nearly-never-solved, and down-weights the informative middle — the opposite of the curriculum you want, and in direct tension with the §6.1 analysis.
Dr. GRPO removes both, using an unnormalized sum of token-level surrogates and a mean-only baseline:
The authors report matched reasoning accuracy at substantially better token efficiency, and RL-tuned Qwen2.5-Math-7B to state-of-the-art on MATH in 27 hours on 8×A100.
If you observe response length climbing while accuracy plateaus, suspect the term before you conclude the model is "learning to think longer." Both scale_rewards=False (drop std normalization) and length-normalization variants are exposed by TRL's GRPOConfig.
8. Implementation
8.1 Quick start
cd 03_huggingface/06_grpo
# SLURM (CoreWeave / HPC)
sbatch run_deepspeed.sh
# Direct (RunPod / single pod)
deepspeed --num_gpus=1 grpo_gsm8k_train.py
8.2 The verifier reward
def compute_reward(response: str, ground_truth: str) -> float:
"""Binary verifier reward: the answer follows '####' in GSM8K."""
extracted = extract_answer(response)
return 1.0 if extracted == ground_truth else 0.0
This is the whole reason GRPO suits math. has no parameters, cannot be reward-hacked in the usual sense, and never drifts — three failure modes of learned reward models eliminated by construction. (It can still be gamed: a model that emits a guessed integer with no reasoning scores 1 whenever it is lucky, which is what format and process rewards are for.)
8.3 Advantage computation
def compute_advantages(rewards: torch.Tensor, eps: float = 1e-8) -> torch.Tensor:
"""
Group-relative advantages, matching DeepSeekMath Eq. 5.
Args:
rewards: [batch_size, group_size]
Returns:
advantages: [batch_size, group_size]
"""
mean = rewards.mean(dim=1, keepdim=True)
# correction=0 -> population std, as in the paper. The PyTorch default
# (Bessel-corrected) shrinks advantages by sqrt((G-1)/G); see section 6.
std = rewards.std(dim=1, keepdim=True, correction=0)
return (rewards - mean) / (std + eps)
def nondegenerate_mask(rewards: torch.Tensor, tol: float = 1e-6) -> torch.Tensor:
"""Groups whose rewards are not all identical contribute zero gradient."""
return rewards.std(dim=1, correction=0) > tol
8.4 The loss
def grpo_loss(
logprobs: torch.Tensor, # [B, G, T] under pi_theta
old_logprobs: torch.Tensor, # [B, G, T] under pi_theta_old (detached)
ref_logprobs: torch.Tensor, # [B, G, T] under pi_ref (detached)
advantages: torch.Tensor, # [B, G]
mask: torch.Tensor, # [B, G, T] 1 for real tokens
epsilon: float = 0.2,
beta: float = 0.04,
) -> torch.Tensor:
"""Clipped surrogate plus a k3 KL penalty — DeepSeekMath Eq. 3 and 4."""
adv = advantages.unsqueeze(-1) # broadcast over tokens
ratio = torch.exp(logprobs - old_logprobs)
surrogate = torch.min(
ratio * adv,
torch.clamp(ratio, 1.0 - epsilon, 1.0 + epsilon) * adv,
)
# k3: unbiased AND non-negative. Do not use (ref - policy).mean() here.
log_ratio = ref_logprobs - logprobs
kl = torch.exp(log_ratio) - log_ratio - 1.0
per_token = surrogate - beta * kl
# Per-sequence mean, i.e. the 1/|o_i| of Eq. 3. Dropping this denominator
# in favour of a plain sum is the Dr. GRPO variant; see section 7.
per_seq = (per_token * mask).sum(-1) / mask.sum(-1).clamp(min=1)
return -per_seq.mean() # maximize -> minimize
8.5 LoRA
from peft import LoraConfig
lora_config = LoraConfig(
r=16, # rank
lora_alpha=32, # scaling; effective factor alpha/r = 2
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
is initialized Gaussian and to zero, so at step 0 and training starts exactly at the base model — essential in RL, where a perturbed initial policy produces garbage rollouts and a reward signal with no gradient.
is the base model. With LoRA the base weights are already resident and frozen, so disabling the adapters — with model.disable_adapter(): — yields logprobs with no second copy of the model. The reference term in §5 drops to zero. This, not the critic removal, is what actually gets 1.5B-parameter GRPO onto an 8 GB card.
8.6 DeepSpeed configuration
{
"bf16": { "enabled": true },
"zero_optimization": {
"stage": 2,
"offload_optimizer": { "device": "cpu", "pin_memory": true },
"contiguous_gradients": true,
"overlap_comm": true
},
"gradient_accumulation_steps": 8,
"train_micro_batch_size_per_gpu": 1,
"gradient_clipping": 1.0
}
| Setting | Rationale |
|---|---|
bf16 | Avoids FP16 loss-scaling entirely. RL losses are dominated by a small clipped surrogate plus a KL term; the dynamic loss-scale controller interacts badly with the resulting spiky gradients. Prefer BF16 for RL on Ampere+. |
stage: 2 | With LoRA, is tiny, so Stage 3 would pay of parameter-gather traffic on weights that never receive a gradient. Stage 2 is the right point. |
offload_optimizer | Moves the (small, LoRA-sized) Adam states off the GPU to leave room for rollout buffers. |
gradient_accumulation_steps: 8 | GRPO gradients are high-variance; a large effective batch is the primary stabilizer. |
train_micro_batch_size_per_gpu: 1 | Each micro-batch already holds rollouts, so the real activation load is this. |
gradient_clipping: 1.0 | Non-negotiable in RL — a single anomalous group can produce an enormous update. |
. The config above resolves to . Launching with a different --num_gpus without updating it aborts at startup.
8.7 Hyperparameters
| Parameter | Value | Note |
|---|---|---|
| Base LR | 5e-5 | LoRA tolerates ~10× the LR of full fine-tuning |
| LoRA rank | 16 | |
| Group size | 4 | Raise to 8–16 with degenerate-group filtering (§6.1) |
| Clip | 0.2 | PPO default; inherited unchanged |
| KL coefficient | 0.04 | Lower for verifiable rewards, where drift is less dangerous |
| Sampling temperature | 0.7–1.0 | Must be . Greedy decoding gives for every group |
| Gradient accumulation | 8 | |
| Epochs | 3 |
8.8 Memory ladder
| Configuration | GPU memory | System RAM |
|---|---|---|
| Full model | 24 GB | 32 GB |
| LoRA + ZeRO-2 | 12 GB | 32 GB |
| LoRA + offload | 8 GB | 64 GB |
9. Monitoring
metrics = {
"reward/mean": rewards.mean(),
"reward/std": rewards.std(),
"advantage/mean": advantages.mean(), # must be ~0 by construction
"advantage/std": advantages.std(), # ~1 with population std
"groups/degenerate": (rewards.std(dim=1, correction=0) < 1e-6).float().mean(),
"policy/entropy": entropy.mean(),
"kl/ref": kl.mean(), # k3, so must be >= 0
"ratio/clipfrac": ((ratio - 1).abs() > 0.2).float().mean(),
"completion/length": mask.sum(-1).float().mean(),
"accuracy": (rewards > 0).float().mean(),
}
Diagnostics, in order of how much they tell you:
groups/degenerate— the §6.1 quantity. Rising toward 1 means most compute is producing no gradient. Raise , filter, or rebalance the curriculum.advantage/mean— an arithmetic bug. It is zero by construction; a nonzero value means normalization is over the wrong axis.kl/refnegative — you are using k1, not k3. See §4.3.ratio/clipfrac> 0.3 — has moved too far from ; lower the LR or take fewer inner epochs per rollout batch.completion/lengthclimbing whileaccuracyis flat — the §7 length bias, not emergent reasoning.
Expected trajectory on GSM8K with this configuration:
Epoch 1: accuracy 0.35 -> 0.45
Epoch 2: accuracy 0.45 -> 0.55
Epoch 3: accuracy 0.55 -> 0.62
Final GSM8K accuracy ~62%, from a ~35% baseline
10. Troubleshooting
All advantages are zero. Temperature is 0 or too low, so every rollout in a group is identical. Set temperature >= 0.7, do_sample=True. Then check §6.1 — if the model is at , degenerate groups are expected and you need filtering, not a decoding change.
Reward rises, held-out accuracy does not. Reward hacking. With a verifier the usual culprit is format exploitation — the model emits a bare number with no reasoning and is right by chance. Add a format reward, or evaluate under a stricter extractor.
KL explodes and output degenerates. too low or LR too high. Raise , and verify you are using the k3 estimator; a sign-unstable k1 penalty will not hold the policy in place.
Training destabilizes late. Often the §7 std-normalization bias concentrating updates on extreme- questions. Try scale_rewards=False (Dr. GRPO).
Out of memory. GRPO's footprint is dominated by rollouts, not model states. Reduce or max_new_tokens before touching the ZeRO stage; enable gradient checkpointing. See the OOM diagnosis flow.
11. Summary
- GRPO is PPO with the critic replaced by a group mean. The clipped surrogate is unchanged.
- It does not remove the reference model or the KL term — it removes the critic, halving model states from to . Under LoRA, the reference is then free via adapter disabling.
- The KL uses the k3 estimator: unbiased and non-negative, unlike the naive log-ratio.
- Degenerate groups are the central practical constraint. ; signal peaks at and collapses as the model improves.
- Both normalizers are biased. inflates the length of wrong answers; up-weights uninformative questions. Dr. GRPO removes both.
- It excels wherever reward is verifiable — math, code, structured extraction — because then has no parameters and cannot drift.
Next Steps
Where GRPO sits in the alignment thread:
- RLHF and Reward Modeling — the four-model pipeline GRPO is cutting down. §2 below derives PPO; this page has the surrounding stages.
- Preference Optimization — DPO, IPO, CPO, KTO, ORPO, SimPO. §3 below sketches DPO; that page treats the whole family. Note the distinction: DPO removes the reward model, GRPO removes the critic.
- Online Preference Methods — GRPO's sampling loop with a judge instead of a verifier.
- Beyond GRPO — Dr. GRPO, DAPO and GSPO. §7 below opens the Dr. GRPO critique; that page has the full set of four biases and what to change.
Then:
- GRPO: Worked Numerical Example — full simulation of the degenerate-group and estimator-bias effects
- DeepSpeed ZeRO Stages — the accounting used in §5
- GPT-OSS Fine-tuning — larger models
- Multi-Agent — ensembles
References
GRPO and its analysis
- Shao, Z., Wang, P., Zhu, Q., Xu, R., Song, J., et al. (2024). DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models. arXiv:2402.03300 — introduces GRPO; Eq. 3 (objective), Eq. 4 (k3 KL), Eq. 5 (outcome-supervision advantage).
- DeepSeek-AI (2025). DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning. arXiv:2501.12948 — GRPO at scale with rule-based rewards.
- Liu, Z., Chen, C., Li, W., et al. (2025). Understanding R1-Zero-Like Training: A Critical Perspective. arXiv:2503.20783 — Dr. GRPO; the length- and std-normalization biases of §7.
- Yu, Q., Zhang, Z., Zhu, R., et al. (2025). DAPO: An Open-Source LLM Reinforcement Learning System at Scale. arXiv:2503.14476 — dynamic sampling for degenerate groups, clip-higher, token-level loss.
Policy gradient foundations
- Williams, R. J. (1992). Simple statistical gradient-following algorithms for connectionist reinforcement learning. Machine Learning, 8, 229–256. — REINFORCE.
- Sutton, R. S., McAllester, D., Singh, S., & Mansour, Y. (1999). Policy Gradient Methods for Reinforcement Learning with Function Approximation. NeurIPS 1999. — the policy gradient theorem and the baseline identity.
- Schulman, J., Wolski, F., Dhariwal, P., Radford, A., & Klimov, O. (2017). Proximal Policy Optimization Algorithms. arXiv:1707.06347
- Schulman, J., Moritz, P., Levine, S., Jordan, M., & Abbeel, P. (2016). High-Dimensional Continuous Control Using Generalized Advantage Estimation. ICLR 2016. arXiv:1506.02438
- Schulman, J. (2020). Approximating KL Divergence — the k1/k2/k3 estimators of §4.3.
Alternatives and context
- Ouyang, L., Wu, J., Jiang, X., et al. (2022). Training language models to follow instructions with human feedback. NeurIPS 2022. arXiv:2203.02155 — InstructGPT; the canonical three-stage RLHF pipeline.
- Rafailov, R., Sharma, A., Mitchell, E., Ermon, S., Manning, C. D., & Finn, C. (2023). Direct Preference Optimization: Your Language Model is Secretly a Reward Model. NeurIPS 2023. arXiv:2305.18290
- Ahmadian, A., Cremer, C., Gallé, M., et al. (2024). Back to Basics: Revisiting REINFORCE-Style Optimization for Learning from Human Feedback in LLMs. ACL 2024. arXiv:2402.14740 — RLOO; the leave-one-out baseline of §4.4.
- Ross, S., Gordon, G. J., & Bagnell, J. A. (2011). A Reduction of Imitation Learning and Structured Prediction to No-Regret Online Learning. AISTATS 2011. arXiv:1011.0686 — the covariate-shift argument of §1.
- Cobbe, K., Kosaraju, V., Bavarian, M., et al. (2021). Training Verifiers to Solve Math Word Problems. arXiv:2110.14168 — GSM8K.
- Hu, E. J., Shen, Y., Wallis, P., et al. (2022). LoRA: Low-Rank Adaptation of Large Language Models. ICLR 2022. arXiv:2106.09685