Paper · 2025-10-02 · cs.LG, cs.AI, cs.CL
ExGRPO: Learning to Reason from Experience
Adds experience replay to RLVR for reasoning LLMs: correct rollouts are stored by success count, fully solved questions are retired, and half of each batch replays the lowest-entropy stored answer with a damped importance ratio. Author-reported: 48.3 vs 45.3 average on six math benchmarks (Qwen2.5-Math-7B, on-policy RLVR baseline).
Reinforcement learning with verifiable rewards (RLVR)Policy gradientImportance weightingExperience replayreinforcement-learningrlvrexperience-replaygrpollm-reasoning
arXivPDFCodeMarkdown17 min read
AI-compiled by claude-haiku-5-5 on 2026-10-19, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.
In plain words
To teach a language model to reason with reinforcement learning, the model tries several answers to each question, a checker marks each one right or wrong, and the model is nudged toward the right ones. The usual recipe uses each batch of attempts once and then throws it away. ExGRPO keeps the correct attempts, sorts the questions by how often the model got them right, and mixes some of those saved attempts back into later batches.
Questions the model always gets right are dropped from the saved set, so the replay effort goes to questions it solves some of the time. For each replayed question it keeps the saved answer the model is most confident about, which the authors found tends to be the cleaner reasoning. The replayed answer is also weighted by how far the current model has moved away from the one that wrote it, with a formula that amplifies the low-probability parts of that answer and damps the high-probability parts.
The aim is more learning from each attempt, and steadier training on models where the usual method breaks down. The paper's experiments are on maths and reasoning benchmarks, and the numbers are the authors' own.
TL;DR
- Method for RL with verifiable rewards (RLVR): mixes replayed correct rollouts into about half of each batch, using a bucketed buffer, a retired set, a lowest-entropy selection rule and a mixed-policy loss §4.
- Motivation from one 7B study: medium-difficulty questions and low-entropy correct trajectories were the most useful experience §3.2, fig. 1.
- Author-reported: +3.0 average over on-policy RLVR on Qwen2.5-Math-7B, and stable training on Llama-3.1-8B where on-policy RLVR collapses §5.2.
- Several details differ between the paper and the released code (bucket weighting, clipping in the mixed phase, loss normalisation, entropy term); read "Paper vs code" before implementing.
Problem
On-policy RLVR discards each batch of rollouts after one gradient update. The paper argues this wastes compute and blocks the model from learning again from its earlier successes §1. Experience replay addresses this in classic RL, but the paper says efficient replay for RLVR on large reasoning models is largely unexplored §1, §2. Prior LLM replay methods (ReMix, RePO, RLEP, RRL, ARPO) are discussed in §2. The open question is which stored experiences are worth replaying §1, §3.2.
Method
Preliminary findings §3.2, fig. 1. With on-policy RLVR on OpenR1-Math using Qwen2.5-Math-7B, the authors trained three models on questions of one difficulty band each. Medium-difficulty questions gave the largest gain on test accuracy. Correct trajectories had lower token entropy than incorrect ones, and the gap was measured with a Qwen3-32B judge of reasoning validity. The authors conclude: prioritise medium-difficulty questions, and pick low-entropy trajectories §3.2.
Setup of the objective §3.1. GRPO scores each rollout against its group. The paper follows Dr.GRPO: no standard-deviation scaling and no length normalisation of the loss. The reward is 1 for a correct final answer and 0 otherwise eq. 1.
Experience management §4.1, alg. 1:
- Collection. For each question in a batch, the rollout policy generates K answers. Every correct answer is stored under its question in buffer E, together with the question's correct count k.
- Partition. The buffer is bucketed by each question's latest correct count.
- Retired set. A question whose K answers are all correct is removed from E and never replayed again §4.1, alg. 1.
- Question sampling. A bucket is drawn with probability proportional to a Gaussian of its accuracy, centred at 0.5 with σ = 1. Then a question is drawn uniformly within the bucket (sampling without replacement) §4.1, alg. 2.
- Answer selection. For each sampled question, the stored answer with the lowest mean token entropy under the current policy is chosen. No external judge is used at training time §4.1.
The bucket weight in the paper, with accuracy k/K alg. 1:
p_k \propto \exp\!\left(-\frac{(k/K - 0.5)^2}{2}\right) \qquad [\text{alg. 1}],\ [\text{§4.1}]
Mixed batch §4.2, alg. 1. With batch size B and ratio ρ = 0.5, the number of replayed questions is min(⌊ρB⌋, |E|). The rest of the batch is fresh questions. A replayed question gets K−1 new rollouts from the current policy, and its stored answer joins them as the K-th member of the group. A fresh question gets K new rollouts. Advantages are normalised within the group §4.2, eq. 2; the code drops the std term (see Paper vs code). When the buffer is empty, the batch is all fresh alg. 1.
Mixed-policy objective §4.2, eq. 4. Let w = π_θ / π_old for fresh tokens and w* = π_θ / π_past for the replayed answer, where π_past is the policy that generated it:
\mathcal{J}(\theta) = (1-\rho)\,\mathbb{E}_{q}\!\left[\tfrac{1}{K}\sum_{i=1}^{K} \mathrm{CLIP}(w_i, \hat{A}_i)\right] + \rho\,\mathbb{E}_{q^*}\!\left[\tfrac{1}{K}\!\left( \mathrm{CLIP}(w^*, \hat{A}^*) + \sum_{i=1}^{K-1}\mathrm{CLIP}(w_i, \hat{A}_i) \right)\right] \qquad [\text{eq. 4}]
Two changes are made for the replayed answer §4.2:
- Policy shaping. The CLIP term for the replayed answer is replaced by f(w*) · Â, with f(x) = x / (x + β) and β = 0.1. The stated purpose is to amplify low-probability signal and damp high-probability signal in the replay §4.2. The paper reports that shaping alone in on-policy RLVR gives no improvement §6.2.
- Delayed start. ExGRPO is switched on only after the batch pass rate passes 35%. Before that, the run is plain on-policy RLVR §4.2, §5.1.
The paper gives the per-step complexity as O(BK) reward evaluations and O(BK) likelihood evaluations app. C. The extra cost is an entropy pass over the stored answers of the sampled questions only app. E.5.
Pseudocode (one training step, after alg. 1; the paper's pseudocode numbers its steps, which is not repeated here):
# One ExGRPO training step [alg. 1]
# Inputs: dataset, buffer E, retired set S, batch size B, K rollouts, rho
def training_step(policy, dataset, buffer, retired, B, K, rho):
# Phase 1: choose replayed questions from the buffer [§4.1]
n_replay = min(floor(rho * B), len(buffer))
# Bucket weight is a Gaussian over the bucket's accuracy [alg. 1]
replay_questions = bucket_sample(buffer, n_replay)
replay_answers = {}
for question in replay_questions:
# Keep the stored answer with the lowest entropy under the
# current policy; no judge is used [§4.1]
replay_answers[question] = pick_lowest_entropy(
policy, buffer[question]
)
# Remaining slots are fresh questions from the dataset [§4.2]
fresh_questions = sample(dataset, B - n_replay)
# Phase 2: rollouts [§4.2] [alg. 1]
groups = {}
for question in replay_questions:
# K-1 new samples; the stored answer is the K-th member [§4.2]
fresh = sample_rollouts(policy, question, K - 1)
groups[question] = [replay_answers[question]] + fresh
for question in fresh_questions:
groups[question] = sample_rollouts(policy, question, K)
for question, answers in groups.items():
num_correct = count_correct(answers)
# All K correct: retire the question [§4.1]
if num_correct == K:
retired.add(question)
# Some correct: store the correct answers in their bucket [§4.1]
elif num_correct > 0:
buffer.update(question, correct_only(answers), num_correct)
# Advantage: group mean subtracted, no std scaling [§3.1] [eq. 2]
# Update with the mixed objective [eq. 4]
update_policy(policy, groups)Per-token term for one mixed batch. Eq. 4 writes CLIP; the code's mixed phase does not clip, and the sketch follows the code (see Paper vs code):
# Per-token policy-gradient term for one answer [eq. 4] [§4.2]
# Shapes: logp_new, logp_old, advantage are (tokens,) for one answer
def token_term(logp_new, logp_old, advantage, is_replayed):
# Ratio of current to generating policy: pi_past for replayed
# answers (recorded log-probs), pi_old otherwise [§4.2]
ratio = exp(logp_new - logp_old)
# Replayed tokens use f(w) = w / (w + beta), beta = 0.1 [§4.2]
shaped = ratio / (ratio + 0.1)
weight = shaped if is_replayed else ratio
# Unclipped in the mixed phase, as in the code
# [code: ExGRPO/exgrpo/verl/verl/mix_src/mix_core_alg.py#L121-L127]
return -advantage * weightHyperparameters
Values for the Qwen2.5-Math-7B main run. "Code" column cites the released
script ExGRPO/exp_scripts/run_exgrpo.sh and config files, with paths relative
to the clone root raw/code/2510.02245/.
| Name | Value | Where | Notes |
|---|---|---|---|
| Rollouts per question K | 8 | §5.1 run_exgrpo.sh | Replayed questions: 7 new rollouts plus the stored answer §5.1 |
| Batch size B (questions per step) | 128 | §5.1 app. E.1 run_exgrpo.sh | |
| Mini-batch (questions) | 64 | §5.1 run_exgrpo.sh | Worker multiplies by K mix_fsdp_worker.py, so 512 responses per update and 2 updates per step (derived from code) |
| Experience ratio ρ | 0.5 | §4.2 §5.1 run_exgrpo.sh | ρ = 0.25 and 0.75 are worse app. E.4 |
| Shaping β | 0.1 | §4.2 mix_core_alg.py | |
| Bucket weight | Gaussian, μ = 0.5, σ = 1 | §4.1 alg. 1 | Accuracy units in the paper; count units in the code, see Paper vs code |
| Delayed-start threshold | batch pass rate > 35% | §4.2 §5.1 run_exgrpo.sh | Not applied for Llama base §5.1 |
| Replay selection | lowest mean token entropy, current policy | §4.1 experience_helpers.py | |
| Learning rate | 1e-6 | app. E.1 run_exgrpo.sh | Schedule not stated |
| Optimizer | AdamW | mix_fsdp_worker.py | Betas and weight decay not checked; paper does not state the optimizer |
| Training rollout temperature | 1.0 | §5.1 run_exgrpo.sh | |
| Validation temperature | 0.6 | §5.1 run_exgrpo.sh | |
| Max prompt / response length | 1024 / 8192 tokens | app. E.1 run_exgrpo.sh | Llama base uses a simplified prompt app. E.1 |
| Training steps | 700 (Qwen2.5-Math-7B), 500 (other models) | app. E.1 | Script sets 701 run_exgrpo.sh |
| Entropy coefficient | 0.001 | app. E.1 run_exgrpo.sh | Not in eq. 4; added to the loss in code mix_actor.py |
| PPO clip range ε | not stated | §4.2 | Code default 0.2 mix_ppo_trainer.yaml; used before the switch only |
| KL penalty | not stated | §4.2 | Disabled in code run_exgrpo.sh run_exgrpo.sh run_exgrpo.sh |
| Gradient clipping | not stated | §4.2 | Clip norm 1.0 mix_ppo_trainer.yaml; step skipped if norm > 500 run_exgrpo.sh mix_actor.py |
| Std scaling of advantage | off | §3.1 | Code: grpo_use_std=False run_exgrpo.sh |
| Token-mean normalisation | removed | §3.1 | Code: loss_remove_token_mean=True run_exgrpo.sh, see Paper vs code |
| Validation set | 2.2k test instances, every 10 steps | app. E.1 run_exgrpo.sh | |
| Training data | OpenR1-Math 45k subset | §5.1 | |
| Reward | Math-Verify | §5.1 main_mix_ppo.py | reward_impl_version=3 |
| Evaluation | AIME and AMC: Avg@32; others: Pass@1; top-p 1.0 | §5.1 | Answers extracted with Oat-evaluator §5.1 |
| Framework and hardware | verl, 8×H100 | §5.1 run_exgrpo.sh | |
| Seeds / repeat runs | not stated | §5.1 | Only the AIME and AMC protocol is described |
Results
Author-reported. Setup: Qwen2.5-Math-7B trained on OpenR1-Math 45k and tested on six in-distribution math benchmarks and three out-of-distribution tasks; the average over math is in the first "Avg." column §5.1, tab. 1. Baselines are described in app. E.2. The on-policy row is the comparison for the claims in §5.2.
Main table tab. 1
| Model | AIME24 | AIME25 | AMC | MATH-500 | Minerva | Olympiad | Avg. | ARC-c | GPQA* | MMLU-Pro | Avg. |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Qwen-Base | 11.5 | 4.9 | 31.3 | 43.6 | 7.4 | 15.6 | 19.0 | 18.2 | 11.1 | 16.9 | 15.4 |
| Qwen-Instruct | 12.5 | 10.2 | 48.5 | 80.4 | 32.7 | 41.0 | 37.6 | 70.3 | 24.7 | 34.1 | 43.0 |
| PRIME-Zero | 17.0 | 12.8 | 54.0 | 81.4 | 39.0 | 40.3 | 40.7 | 73.3 | 18.2 | 32.7 | 41.4 |
| Oat-Zero | 33.4 | 11.9 | 61.2 | 78.0 | 34.6 | 43.4 | 43.7 | 70.1 | 23.7 | 41.7 | 45.2 |
| GPG-Zero | 29.8 | 12.1 | 67.8 | 80.8 | 30.9 | 44.7 | 44.4 | 70.3 | 40.4 | 50.5 | 41.6 (see Pitfalls) |
| RePO-Zero | 19.8 | 10.2 | 54.0 | 76.8 | 34.2 | 40.1 | 39.2 | 73.8 | 24.2 | 42.5 | 46.8 |
| On-Policy (Dr.GRPO setup) | 24.9 | 15.5 | 59.2 | 84.8 | 38.2 | 49.3 | 45.3 | 82.6 | 37.4 | 49.2 | 56.4 |
| ExGRPO | 31.6 | 18.7 | 66.3 | 87.4 | 36.0 | 50.1 | 48.3 | 84.7 | 37.4 | 52.9 | 58.3 |
| SFT | 22.2 | 22.3 | 52.8 | 82.6 | 40.8 | 43.7 | 44.1 | 75.2 | 24.7 | 42.7 | 47.5 |
| SFT+RL | 25.8 | 23.1 | 62.7 | 87.2 | 39.7 | 50.4 | 48.2 | 72.4 | 24.2 | 37.7 | 44.8 |
| LUFFY | 29.4 | 23.1 | 65.6 | 87.6 | 37.5 | 57.2 | 50.1 | 80.5 | 39.9 | 53.0 | 57.8 |
| Continual LUFFY | 30.7 | 22.5 | 66.2 | 86.8 | 41.2 | 55.3 | 50.4 | 81.8 | 49.0 | 54.7 | 61.8 |
| Continual On-Policy | 24.8 | 17.8 | 67.5 | 88.4 | 38.6 | 55.3 | 48.7 | 81.9 | 47.0 | 53.3 | 60.7 |
| Continual ExGRPO | 32.3 | 25.7 | 65.6 | 87.6 | 40.1 | 57.0 | 51.4 | 83.6 | 42.4 | 54.5 | 60.2 |
Headline reading §5.2: ExGRPO is +3.0 on the math average over on-policy RLVR on Qwen2.5-Math-7B, with a larger gain on AIME24/25. In the continual setting on LUFFY, ExGRPO is below Continual LUFFY on the out-of-distribution average (60.2 vs 61.8) §5.2, tab. 1.
Other backbones app. E.3. Each row is the average over the benchmarks in its group. Gains are the authors' claim.
| Model | AIME24 | AIME25 | AMC | MATH-500 | Minerva | Olympiad | Avg. | ARC-c | GPQA* | MMLU-Pro | Avg. |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Qwen2.5-Math 1.5B Base | 7.2 | 3.6 | 26.4 | 28.0 | 9.6 | 21.2 | 16.0 | 3.1 | 3.0 | 2.3 | 2.8 |
| Qwen2.5-Math 1.5B On-Policy | 11.8 | 7.7 | 40.2 | 61.8 | 26.8 | 32.0 | 30.0 | 57.5 | 28.3 | 30.7 | 38.9 |
| Qwen2.5-Math 1.5B ExGRPO | 13.3 | 8.6 | 46.6 | 74.0 | 30.5 | 39.0 | 35.3 | 59.3 | 30.8 | 30.4 | 40.2 |
| Qwen2.5-7B Instruct | 11.7 | 7.5 | 43.8 | 71.8 | 30.9 | 40.4 | 34.4 | 84.7 | 24.7 | 54.7 | 54.7 |
| Qwen2.5-7B On-Policy | 14.1 | 8.3 | 43.5 | 74.0 | 33.8 | 37.6 | 35.2 | 91.4 | 19.2 | 57.6 | 56.0 |
| Qwen2.5-7B ExGRPO | 15.2 | 12.4 | 47.8 | 80.0 | 36.0 | 44.4 | 39.3 | 91.1 | 36.9 | 58.6 | 62.2 |
| Llama3.1-8B Base | 0.0 | 0.0 | 4.7 | 11.0 | 4.4 | 1.9 | 3.7 | 0.2 | 0.0 | 3.6 | 1.3 |
| Llama3.1-8B On-Policy | 0.4 | 0.4 | 2.9 | 9.2 | 5.1 | 2.8 | 3.4 | 0.6 | 0.0 | 3.0 | 1.2 |
| Llama3.1-8B ExGRPO | 0.7 | 0.1 | 6.6 | 12.0 | 10.7 | 6.5 | 6.1 | 59.0 | 7.1 | 26.2 | 30.8 |
| Llama3.1-8B Instruct | 4.0 | 0.3 | 15.7 | 39.8 | 18.0 | 13.3 | 15.2 | 42.4 | 0.0 | 40.5 | 27.6 |
| Llama3.1-8B Instruct On-Policy | 3.8 | 0.8 | 21.4 | 49.8 | 24.3 | 19.6 | 19.9 | 86.7 | 0.0 | 48.1 | 44.9 |
| Llama3.1-8B Instruct ExGRPO | 6.1 | 0.6 | 27.1 | 55.2 | 25.7 | 23.1 | 23.0 | 88.9 | 15.2 | 52.1 | 52.0 |
Within-backbone gains in math average: +5.3 (Qwen2.5-Math 1.5B), +4.1 (Qwen2.5-7B Instruct), +2.7 (Llama3.1-8B base), +3.1 (Llama3.1-8B Instruct), and +3.0 for Qwen2.5-Math-7B (computed from the tables above). The text reports that the Llama3.1-8B on-policy run collapses §5.2 §6.1, fig. 4.
Ablations app. E.4. All rows are on the six math benchmarks; the out-of-distribution columns are not in the table source.
| Variant | AIME24 | AIME25 | AMC | MATH-500 | Minerva | Olympiad | Avg. |
|---|---|---|---|---|---|---|---|
| On-Policy | 24.9 | 15.5 | 59.2 | 84.8 | 38.2 | 49.3 | 45.3 |
| ExGRPO | 31.6 | 18.7 | 66.3 | 87.4 | 36.0 | 50.1 | 48.3 |
| w/o Q. Selection | 26.9 | 17.2 | 63.9 | 86.4 | 38.6 | 47.6 | 46.7 |
| w/o T. Selection | 26.0 | 17.0 | 63.7 | 84.8 | 35.7 | 50.7 | 46.3 |
| w/o Q., T. Selection | 22.0 | 17.3 | 64.3 | 85.8 | 37.9 | 49.5 | 46.1 |
| w/o Shaping | 19.8 | 12.9 | 55.7 | 80.2 | 37.5 | 41.0 | 41.2 |
| w/o IS Correction | 25.9 | 19.8 | 63.2 | 87.0 | 37.9 | 49.0 | 47.1 |
| w/ Highest Entropy T. | 25.0 | 16.0 | 62.9 | 84.6 | 36.4 | 51.0 | 46.0 |
| w/ ρ = 25% | 27.2 | 16.3 | 62.9 | 85.4 | 39.0 | 47.6 | 46.4 |
| w/ ρ = 75% | 22.1 | 17.6 | 61.4 | 84.4 | 36.0 | 47.3 | 44.8 |
| ExGRPO^RE (RePO's setup) | 15.1 | 13.2 | 52.1 | 84.2 | 37.5 | 45.3 | 41.3 |
| RePO-Zero | 19.8 | 10.2 | 54.0 | 76.8 | 34.2 | 40.1 | 39.2 |
Retired-question replay (10% of retired examples every 25 steps) lowers both in- and out-of-distribution averages (ID 45.3 vs 48.4) app. E.4.
Bucket-weight sensitivity §6.2. Averages on the same six math benchmarks (ID) and three OOD tasks, with the paper's accuracy-unit parameters:
| Sampling | ID avg | OOD avg |
|---|---|---|
| On-Policy | 45.3 | 56.4 |
| ExGRPO (μ = 0.5, σ = 1) | 48.4 | 58.3 |
| Wider (σ = 1.5) | 46.2 | 58.2 |
| Narrower (σ = 0.5) | 46.2 | 54.8 |
| Hard-biased (μ = 0.25) | 46.3 | 58.2 |
Continuous-reward extension §5.3. A small preliminary study on 7k WildChat-IF prompts with Qwen2.5-7B-Base, one 8B reward model, and two epochs of on-policy training. Averages over ArenaHardV2, IFEval and IFBench: GRPO 20.0, ExGRPO 21.7. The authors call this preliminary.
Cost app. E.5. Qwen2.5-Math-7B on 8 GPUs: average step time 155.4 s on-policy vs 184.9 s with ExGRPO (+19.0%). Replay memory was about 1.77 GB for 202,011 stored trajectories. Qwen2.5-Math-1.5B: +2.1% average step time.
Paper vs code
Code citations are relative to the clone root raw/code/2510.02245/, which is
the LUFFY repository. ExGRPO lives in its ExGRPO/ folder. The paper's
abstract links this repository, which is the basis for using it. The repository
owner is not among the paper's authors, so treat its provenance with care.
Commit 01f4ae066249e6965ce0d5512ccdf99a12895c74. The ExGRPO-specific code
sits in a verl fork (Apache-2.0 license file at ExGRPO/exgrpo/verl/LICENSE),
with no separate license file for mix_src/.
-
Bucket weight scale differs. The paper weights buckets with N(k/K; 0.5, σ = 1), with accuracy k/K in [0,1] alg. 1 §4.1. The code uses the success count k directly, with mean K/2 = 4 and σ = 1 weighted_bucket_sampler.py selected by
exp_bucket_manager=normalrun_exgrpo.sh. Relative bucket weights for counts 1 to 7 are about 0.01, 0.14, 0.61, 1, 0.61, 0.14, 0.01. Under the paper's text, accuracy 0.5 gets weight 1 and accuracy 0 or 1 gets about 0.88, so the paper's sampler is almost uniform. The code's sampler is strongly peaked. In accuracy units, the code's σ = 1 (in counts) is σ = 1/8, so the code matches a much narrower sampler than the paper's text describes. The σ = 0.5 and σ = 1.5 runs in §6.2 are stated in accuracy units. Which scale produced the reported numbers is not stated. -
Clipping is removed in the mixed phase. Eq. 4 and §4.2 keep CLIP for both fresh and replayed tokens. In the code, the mixed-phase flag passes
loss_remove_clipfrom the script (True) mix_trainer_experience.py, and the loss skips the clip branch mix_core_alg.py. Before the switch, the flag is False and clipping stays on mix_trainer_experience.py. The appendix theory section assumes clipping is removed app. D, "Policy shaping via f(w)=w/(w+β) and removing clip". The main text does not say so. -
Loss normalisation is not the one the text describes. §3.1 says length normalisation is removed, but the GRPO clip definition still has a 1/|o| factor. The code, with
loss_remove_token_mean=Truerun_exgrpo.sh, sums token losses and divides by the padded response width of the micro-batch mix_core_alg.py, then divides by the gradient-accumulation count mix_actor.py. The effective normalisation therefore depends on micro-batch padding and on dynamic batching run_exgrpo.sh. The paper does not mention this. -
Entropy term is missing from eq. 4. The paper's objective has no entropy term, but its training table lists entropy coefficient 0.001 app. E.1. The actor subtracts entropy times that coefficient from the policy loss mix_actor.py.
-
Gradient handling is not in the paper. The code clips the gradient norm to 1.0 mix_ppo_trainer.yaml and skips the optimizer step when the norm exceeds 500 mix_actor.py run_exgrpo.sh. The skip threshold is set in the script; the 1.0 clip is the config default.
-
KL and reference model are disabled. The paper does not mention a KL term. The script sets its coefficient to 0, turns off the KL loss, and disables the reference model run_exgrpo.sh run_exgrpo.sh run_exgrpo.sh.
-
Training length. app. E.1 says 700 steps for Qwen2.5-Math-7B. The script sets
trainer.total_training_steps=701run_exgrpo.sh. Small, but it changes the schedule by one step. -
Replayed log-probs come from rollout time, as the paper says. The replayed answer's old log-probs are replaced with the recorded ones when
exp_is_correctis set, which is the default experience_trainer_ops.py mix_ppo_trainer.yaml. See Pitfalls for the fallback when no recorded value exists. -
Trajectory selection matches. Mean per-token entropy under the current policy, minimised experience_helpers.py experience_helpers.py. No discrepancy found.
-
Batch composition matches. Replayed count is int(B·ρ), capped by the buffer size experience_collate_fn.py. No discrepancy found.
-
Delayed-start metric.
batch/solvedis the share of correct responses in the batch mix_trainer_experience.py. It is checked after each step against 0.35, and once it passes, the mode is never switched back mix_trainer_experience.py. This matches §4.2. The Llama exception is not in the repo. -
Advantage and reward match. Std scaling is off run_exgrpo.sh. Math-Verify is used for
reward_impl_version=3main_mix_ppo.py. No discrepancy found. -
Only one run script is in the repo. The Llama, 1.5B and instruct-model settings (500 steps, simplified prompt, no delayed start for Llama) are not in the repository. They are not checked.
-
Analysis buckets differ from the method. The preliminary study uses accuracy bands (Easy [75%, 100%), Medium (25%, 75%], Hard (0, 25%]) §3.2. The method uses count buckets 1 to 7 experience_trainer_ops.py. Consistent with the paper, but a reader should not expect the analysis bands to appear in the code.
Pitfalls
- Bucket scale: see Paper vs code item 1. Implementing the paper's text gives an almost uniform question sampler. Implementing the code gives a sharp one. The paper's ablations do not say which.
- No trust region in the mixed phase. Without CLIP, a large ratio on either fresh or replayed tokens is not bounded. The f(w) term damps large ratios only on replayed tokens §4.2. The paper does not report a ratio-spread diagnostic for this.
- Silent fallback for replayed log-probs. The replacement only happens when the recorded log-prob sum is nonzero experience_trainer_ops.py. Otherwise the current policy's log-prob is kept, so the importance ratio for that answer becomes about 1 and the replay is treated like on-policy data with no correction. An implementation must record log-probs at rollout time and check for missing values.
- Shaping function is bounded. f(w) = w/(w+0.1) stays below 1 for any w, so large ratios on replayed tokens cannot raise their weight above 1. Near w = 0, f(w) ≈ 10w, so small ratios are scaled up about tenfold. The ablation without shaping drops to 41.2 app. E.4. The shape matters.
- Entropy scoring cost. The paper scores only the stored answers of the sampled questions, usually a few dozen app. E.5. A naive implementation that rescores the whole buffer each step will be much slower.
- Buffer memory. About 1.77 GB for 202k trajectories in the 7B run app. E.5. Stored answers include full token sequences, so memory grows with run length.
- Retired questions are never revisited. Reintroducing them every 25 steps lowers both averages app. E.4, so keep the retired set permanent.
- One-way switch. Once the batch pass rate passes 35%, ExGRPO stays on mix_trainer_experience.py. A run that later collapses will not fall back to on-policy.
- Continual setting trades OOD for ID. The paper reports that ExGRPO is below Continual LUFFY on OOD in the continual setting, which it attributes to less on-policy exposure §5.2.
- Llama base is not like-for-like. It uses a simplified prompt and no delayed start app. E.1 §5.1. The large OOD gain there (1.2 to 30.8) mixes the method with a different setup.
- Scope. Only verifiable tasks were studied. Open-ended tasks, valuable failures and other RL algorithms are not covered app. A.
- Averaging is not defined. Using the extension table and the main table, a plain mean over the five backbones gives +3.6 ID and +9.2 OOD, not the +3.5 and +7.6 in §1. The paper does not say how the averages are taken. Quote the per-backbone numbers.
- GPG-Zero OOD average does not follow its columns. Its three OOD columns (70.3, 40.4, 50.5) average 53.7, but the table reports 41.6 tab. 1. Verify before citing.
- Text-only RePO claim. §5.2 and app. E.4 quote an OOD average of 52.3 for ExGRPO^RE vs 46.8 for RePO. The ablation table has no OOD columns, and the OOD values are in commented-out source. Only the 46.8 matches the main table.
- Algorithm 1 typo. The argmin is written over e ∈ E, but it should range over the stored answers o_i of the sampled question alg. 1. The code does the per-question argmin experience_helpers.py.
- Seeds and variance. The paper does not state how many seeds were run. The Avg@32 protocol is for AIME and AMC only. Differences of 1 to 2 points, such as the 1.5B and bucket-width ablations, are not shown to be outside run-to-run noise.
- Continuous-reward section is a sketch. It uses one dataset, one reward model, two epochs, and a binned reward-variance difficulty rule §5.3. Do not rely on it.
Lineage
- Builds on: GRPO and Dr.GRPO for the advantage and length-normalisation choices §3.1. Prioritised experience replay (Schaul et al.) as cited in §2. The shaping function is "inspired by" the LUFFY off-policy method §4.2.
- Compared against: PRIME-Zero, Oat-Zero, GPG-Zero, RePO-Zero, SFT, SFT+RL and Continual LUFFY app. E.2 tab. 1. The closest replay baseline is RePO, which the paper says lacks experience management app. E.2.
- Superseded by: not stated; no later version is recorded in this wiki.
Source and license
Adapted from “ExGRPO: Learning to Reason from Experience” by Runzhe Zhan, Yafu Li, Zhi Wang, Xiaoye Qu, Dongrui Liu, Jing Shao, Derek F. Wong, Yu Cheng (arXiv:2510.02245), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/ElliottYan/LUFFY/tree/main/ExGRPO at commit 01f4ae066249 (Apache-2.0 (verl fork only; no license file for the ExGRPO code in mix_src)). Any quoted code is shown under that license.