The mechanism
Lesson 6 said the RL update in one line: score each try, subtract the average of its group, push the tries above average up and the ones below down. Every word of that line has a problem when the rows are production traces, and each of the three methods below answers it a different way. There is no group. A grouped update (GRPO,mode="rl", k rollouts
per prompt) takes the average over the k tries of the same ask. One try
per ask means the average is the try itself, the difference is zero, and
the update does nothing. The methods bring their own average, the field’s
word is baseline.
- The batch average. Take every trace in the update, whatever asks they came from, and subtract the mean of their scores. Cruder than a per-ask average, because a hard ask and an easy ask share it, but it exists, and it costs nothing. That is FlashReinforce.
- A learned average. Train a second, small head, the critic, to predict the score from the trace so far, at every word. The advantage of a word is the score minus what the critic expected at that point, so a hard ask (low expectation) and an easy ask (high expectation) are judged against their own bar. SAO and BPCO both do this; BPCO bounds the critic so it can never predict a score outside the range scores come in, and SAO skips the words the tools wrote when it hands credit backward through the trace.
trust; SAO masks a word
whose ratio leaves a band, (0.7, 6.0) by default; BPCO clips the ratio
to a range that widens for a rare word, so a word the old model almost
never wrote is not thrown away just for being rare.
Length. A long trace has more words, so a plain sum gives it more
say. FlashReinforce gives every admitted trace the same weight, one over
its length, the paper’s 1/T.
The same three mechanisms as the arithmetic update() performs, one
block per method with the papers’ equation numbers, are on the
methods reference page,
next to the group, preference and distillation losses they sit beside.
What each needs from a row is small, and it is the same four things:
the reward; the log-probability of every generated token under the
model being trained (logprobs); the same under the model that wrote
the trace (behavior_logprobs, what a serving stack returns as
token_logprobs if you ask for it); and, for a trace with tool calls,
an action_mask that is false on the tokens the tools wrote, so they
carry no gradient. SAO and BPCO add values, the critic’s prediction at
each token.
Run it
First, the baseline and the ratio by hand, on four traces. Made-up numbers; the arithmetic is the whole idea.defaults.py, and a bad value is refused on the
line that set it.
values list per trace from your critic, goes to
wai.SAO().update(batch) and wai.BPCO().update(batch), and each prints
the same kind of report.
Last, the trainer. Lesson 8 wrote a prime-rl config with
prime_rl_config, and the honest answer for these three methods is that
prime-rl cannot run them yet: its reward baselines are the group mean
(zero over a group of one) or a running average of past rewards, it hosts
no critic, and its losses mask single tokens rather than drop a whole
stale trace or clip a ratio. So the writer refuses, and the refusal says
what is missing and what to do instead, rather than writing a file that
would train a different method under this one’s name.
"rae",
REINFORCE against a running average of past rewards, and
wai.prime_rl_config(env, "rae", model=..., **{"orchestrator.group_size": 1})
writes it, with a warning that names the baseline it is.
When it fits, and when it does not
It fits when the rows are what this lesson opened with: one attempt per ask, a score that arrived after the fact, a world that cannot be replayed, and enough of them (hundreds at the least) that a batch mean is steady or a critic has something to fit. It also fits when the traces are a few model versions old; FlashReinforce is built for a lag of about eight updates between the model that wrote a trace and the one that trains on it, and the ratio and the trust region are what absorb the gap. It does not fit when you can replay the world. If the ask can be run again against the same state, run it four times and use lesson 6’s update: a per-ask average is a tighter baseline than any of these, and you keep the unanimous-group filter that tells you which asks teach nothing. It does not fit with a few dozen traces, because a batch mean over a few dozen scores is mostly noise. And it does not fit with a score you have not checked: a model trained on “the customer accepted the reply” learns whatever gets accepted, so lesson 3’s judge check and lesson 6’s reward scan come first, on the traces, before any of this runs. If the serving stack did not logtoken_logprobs, there is no
ratio to form; turn that on first and train on the traces that come
after.
What is proven, and what is not
Two things are checked, and they are different things. The update rules are checked in the test suite: each method’supdate() is applied to a toy policy, a table of probabilities with no
neural network behind it, and the tests watch the reward climb, the
stale trace get dropped or masked, and the tool tokens carry no
gradient. That proves the arithmetic is the paper’s arithmetic.
The papers’ claims were then put on a GPU, one recipe per method under
recipes/papers/, all three on the same protocol: Qwen2.5-1.5B-Instruct
on GSM8K, 512 training prompts and 120 held out, a program for the
reward, one rollout per prompt, and a sampler that lags the policy by up
to four updates. Each recipe arm runs the method against its own
ablation, on the same stale rollouts, for 40 steps, one training seed
per arm, under an hour and two dollars of GPU. None of the three showed
the gain its paper claims at this size. What each measured, pass@1 on
the held-out set, recipe against baseline with a 95% interval:
Every verdict is unresolved because one training seed per arm cannot
separate a method from run-to-run training variance (lesson 4; this
repository has watched a delta change sign between two seeds). The
reason the papers’ regime was not reached is on every recipe page: at a
learning rate of 1e-5 on a rank-16 adapter, four updates of lag leave
the rollouts barely stale, the ratio within a fraction of a percent of
1 and the sequence KL near 1e-4, so the trust gate, the band and the
clip had almost nothing to act on and the uncorrected baselines trained
just as well. The SAO recipe re-ran at ten times the learning rate: the
band then engaged, both arms gained 28 points, and they were still
equal. What the FlashReinforce delta measured instead was the
1/T
weighting against the token mean: the baseline shortened its replies
and gained, the recipe kept long failed replies alive. What did hold,
in all three: a model learns from one rollout per prompt with no group
to compare against, 2 to 8 points over the base in 40 steps.
The papers’ own numbers (a 30B model trained at a lag of eight updates
beating GRPO at a lag of one, in FlashREINFORCE; the reasoning and
coding gains in SAO and BPCO) were measured on the papers’ setups, at a
scale and a drift these recipes did not reach, and lesson 4’s rule
applies to them as to anything else. Each recipe’s README names the two
knobs that reach that regime, a second seed and a longer lag or a higher
learning rate, and the table on this page changes when one of them does.
Where it comes from
- Hu et al. FlashREINFORCE. NVIDIA, 2026. Critic-free REINFORCE with a
batch-mean baseline, one rollout per prompt, a sequence trust region
on the drift from the sampling policy, and
1/T. - Hou et al. SAO: Single-Rollout Asynchronous Optimization. arXiv:2607.07508, 2026. A value critic with length-adaptive GAE that skips observation tokens, and a token masked when its ratio leaves the band.
- Qi et al. BPCO: Best Practice Critic Optimization. arXiv:2608.23566, 2026. A critic bounded to the reward range through an arctangent, Monte Carlo value targets, and DPPO’s clip that widens for a rare token.
- Williams, R. J. Simple statistical gradient-following algorithms for connectionist reinforcement learning. Machine Learning, 1992. REINFORCE, and why subtracting a baseline changes the noise and not the answer.
- Schulman, J. et al. High-Dimensional Continuous Control Using Generalized Advantage Estimation. arXiv:1506.02438, 2016. GAE, the critic’s way of handing credit backward.
- Schulman, J. et al. Proximal Policy Optimization Algorithms. arXiv:1707.06347, 2017. The clipped ratio BPCO starts from.
- Lambert, N. Reinforcement Learning from Human Feedback. arXiv:2504.12501, 2025. Chapter Policy Gradient Algorithms: the baseline, the ratio and the clip in one place.