Sam Babichenko

Reading notes / Running RL at scale

Scaling RL compute

Khatri et al., 2026

Scaling curve
CCtraining compute in GPU-hours
RC;R_C; R0R_0validation pass rate at compute C; at the start of the fit
AAceiling: the pass rate approached as compute grows
B;B; CmidC_{\rm mid}steepness; compute at half of the gain
DDpower-law coefficient (A−R0)CmidB(A-R_0)C_{\rm mid}^B
RL objective
x;x; yi;y_i; yi,ty_{i,t}prompt; its i-th completion; token t of it
GGcompletions per prompt
ri;r_i; A^i\hat A_ireward (±1); group-standardized advantage
πgen;\pi_{\rm gen}; πtrain\pi_{\rm train}sampling copy and training copy of the model
ρi,t\rho_{i,t}importance ratio of a token, training over sampling probability
ϵ−,\epsilon^-, ϵ+;\epsilon^+; ϵmax⁡\epsilon_{\max}DAPO's clipping thresholds; CISPO's cap
sg;\mathrm{sg}; TTstop-gradient; total completion tokens of a prompt
wi,t;w_{i,t}; ℓi,t\ell_{i,t}CISPO's capped weight of a token; the token's log-probability
kkhow many updates the sampling policy may lag behind
Constants
1.5k GPU-hoursstart of every fit
0.02error margin on AA, from three ScaleRL runs
0.9pass rate at which No-Positive-Resampling retires a prompt (Step 4)
k=8k=8PipelineRL's lag limit in ScaleRL
0.605common AA of the leave-one-out refits (Step 5)
16; 48; 768completions per prompt; prompts per batch; completions per batch

Context. In pretraining, loss fitted against compute on small runs predicts the loss of large ones. RL for reasoning, now run at budgets such as the 100,000 GPU-hours reported for DeepSeek-R1-Zero, has had nothing similar. Recipes such as group relative policy optimization: PPO-style clipped updates without a value function, where each sample's advantage is its reward standardized within the group of samples for the same prompt and a GRPO variant with separate lower and upper clipping thresholds, per-prompt averaging of the token losses, and removal of prompts whose samples all get the same reward differ in many choices (the loss, how advantages are normalized, how stale the samples may be, which prompts are kept), and they are compared at one budget, often on downstream benchmarks, so it is unknown whether a choice that helps at that budget helps at a larger one. Khatri et al. spend more than 400,000 GPU-hours on RL for reasoning, mostly math with an 8B model, fit a curve of validation pass rate against compute for each variant, and check the fits by extending the runs. The curve that works is a sigmoid in log compute with a ceiling, and a recipe choice should be judged first by what it does to that ceiling, since a choice that only speeds up early training can be overtaken later. This is the RL counterpart of the compute-scaling fits in the scaling-laws notes, with a bounded pass rate in place of a loss.

The ceiling and the speed of approach separate cleanly. The loss function and the numerical precision of the output layer move the ceiling. The asynchronous setup, the averaging of the loss, the normalization of advantages and the choice of prompts mostly change the speed and move the ceiling by no more than its run-to-run error. Batch size and generation length raise the ceiling at the cost of a slower start, and a larger model raises it and leads from the start. Combined, the choices form ScaleRL, whose fitted ceiling of 0.61 exceeds those of the GRPO, DAPO and the RL recipe published for the Magistral reasoning models: DAPO's loss with streaming asynchronous generation recipes (0.49 to 0.535) and equals that of the RL recipe published for the MiniMax-M1 model, with a truncated importance-sampling loss and a 32-bit output layer with a faster rise, and a 100,000 GPU-hour run of it follows the curve fitted to its first half.

Setting. The curve relates the validation pass rate after compute CC: mean correctness of 16 samples per prompt on 1,000 prompts held out from the training data to training compute GPU-hours spent on RL so far, for why: a fitted curve describes one recipe on one model and one prompt set; Step 6 shows that changing the model or the batch moves it. It writes the gain over the starting pass rate the pass rate at the start of the fitted range as the gain at the ceiling times the fraction of it reached: RC−R0=(A−R0)⏟gain at the ceiling×11+(Cmid/C)B⏟fraction reached.\begin{aligned}R_C-R_0&=\underbrace{(A-R_0)}_{\text{gain at the ceiling}}\\&\quad\times\underbrace{\frac{1}{1+(C_{\rm mid}/C)^B}}_{\text{fraction reached}}.\end{aligned} The ceiling the pass rate the run approaches as compute grows, between 0 and 1 is what a recipe can reach; the compute at which half of the gain A−R0A-R_0 has been reached and the exponent the steepness of the rise: the fraction reached is the logistic function 1/(1+e−z)1/(1+e^{-z}) of z=B(log⁡C−log⁡Cmid)z=B(\log C-\log C_{\rm mid}) set how fast it gets there. Fits start why: in roughly the first epoch the pass rate rises almost linearly before the sigmoid regime, and less stable setups often plateau early there; including it made fits noisier. The prompts are the math problems of a public set of about 53,000 math problems with checkable answers, used for RL, the model is an 8B dense model after supervised fine-tuning on reasoning traces, and the reward is ±1\pm1 from an automatic answer checker. The base recipe is GRPO without a KL penalty and with DAPO's asymmetric clipping. For a prompt xx, the generating copy of the model the copy of the model that samples completions, running fast inference kernels on separate GPUs samples the number of completions per prompt, 16 completions yiy_i with rewards rir_i; the advantage is the group-standardized reward A^i=(ri−rˉ)/std(r)\hat A_i=(r_i-\bar r)/\mathrm{std}(r), with rˉ\bar r and std(r)\mathrm{std}(r) the mean and standard deviation of the group's rewards (the hat distinguishes it from the ceiling AA); and each token's importance ratio the importance ratio πtrain(yi,t)/πgen(yi,t)\pi_{\rm train}(y_{i,t})/\pi_{\rm gen}(y_{i,t}) of token tt of completion ii between the copy being trained and the copy that sampled it=πtrain(yi,t)/πgen(yi,t)=\pi_{\rm train}(y_{i,t})/\pi_{\rm gen}(y_{i,t}) is clipped to DAPO's clipping range, with a larger upper threshold than lower one. A batch is 48 prompts (768 completions), generations have 12,288 thinking tokens, and runs use 80 GPUs, 64 generating and 16 training.

Main findings (all empirical). Fitted on the same setup, ScaleRL reaches A=0.61A=0.61 with B=1.97B=1.97, MiniMax's 0.610.61 with B=1.77B=1.77, Magistral's 0.535, DAPO's 0.515 and GRPO's 0.49. Three independent ScaleRL runs vary by at most ±0.015\pm0.015 in AA, so differences under the error margin on the ceiling AA, taken from the spread of three independent runs of ScaleRL are treated as noise. In forward ablations (one choice of the base recipe changed at a time, in runs of 3.5 to 4k GPU-hours), the loss (DAPO 0.52, group sequence policy optimization: the same clipped objective with one importance ratio per completion, the ratio of its sequence probabilities, in place of token ratios 0.59, clipped importance sampling policy optimization: plain policy gradient with each token's importance weight capped at a fixed value and held constant 0.595) and 32-bit floating point, in place of the lower precision used elsewhere logits (0.52 to 0.61) move AA clearly, while the asynchronous setup changes only BB (2.68 to 4.55 at the same 0.52). Leaving any one component out of ScaleRL keeps AA between 0.59 and 0.61 and lowers efficiency (the steepness BB). At larger scale, a batch of 2048 completions against the default 768 raises AA to 0.645, generations of 32k tokens raise it to 0.645 with a much later midpoint, and a 17B×16 a model whose layers route each token to a few of many expert subnetworks; 17B×16 means 16 experts and 17B parameters active per token model reaches 0.71 and passes the 8B model's final score with a sixth of its compute. On the 100,000 GPU-hour 8B run, the sigmoid fitted up to 50,000 GPU-hours predicts A=0.645A=0.645 and the extended run follows it.

Consequences and limits. The method lets a practitioner compare recipes before running the large job: train each candidate to a few thousand GPU-hours, fit the curve on held-out pass rate, prefer the higher ceiling and only then the faster rise, and watch the share of generations cut off at the length limit, since runs at batch 768 whose truncation reached 10 to 15% destabilized. The choices that held up were CISPO's loss, FP32 at the output layer, streaming asynchronous generation, dropping prompts whose samples all score the same, retiring prompts the model solves 90% of the time, and large batches. The evidence comes from two models (the 8B dense model and one mixture-of-experts model), mostly one math dataset, and in-distribution validation; downstream scores such as problems from the American Invitational Mathematics Examination, a standard test of competition math moved with validation but were not modeled. The forward ablations were mostly fitted on runs of 3.5 to 4k GPU-hours, so their ceilings are long extrapolations, and the 0.02 margin comes from three runs of one recipe.

Step 1

A sigmoid in log compute extrapolates where a power law does not. Pretraining fits use a power law RC=A−D/CBR_C=A-D/C^B, which the sigmoid reduces to for large CC (there u=(Cmid/C)Bu=(C_{\rm mid}/C)^B is small and 1/(1+u)≈1−u1/(1+u)\approx1-u), with the power-law coefficient (A−R0)CmidB(A-R_0)C_{\rm mid}^B that the sigmoid implies in its high-compute limit. On the 100,000 GPU-hour run, a power law fitted between 1.5k and 50k GPU-hours predicts a ceiling of 1.0 although the curve flattens near 0.65, and fitted between 5k and 50k it predicts 0.74; the sigmoid gives 0.645 from either window, and for every window tried, including the whole run, between 0.645 and 0.655 with BB from 1.56 to 1.70. The bounded form helps because RL runs have few evaluation points (about 75 on that run) and a power law is reliable only on the high-compute part of the curve, which small runs do not reach. The fit itself is a grid search over AA and CmidC_{\rm mid}, with BB fitted for each pair, on evaluations every 100 steps.

Step 2

How stale the samples are changes the speed and leaves the ceiling unchanged. In generation of kk mini-batches with fixed weights, then kk gradient steps on them, so later steps train on samples from an older policy generation and training alternate; in streaming generation: generators receive new weights after every update, even in the middle of a completion (keeping its old key-value cache), and trainers wait if they get kk updates ahead they overlap. All three runs compared fit A=0.52A=0.52, with B=2.15B=2.15 and 2.682.68 for PPO-off-policy at k=1k=1 and 8, and 4.554.55 for PipelineRL-8, which leaves GPUs idle less and keeps training closer to on-policy. Within PipelineRL, k=4k=4 and 8 are equal and k=12k=12 lowers AA to 0.49.

Step 3

The loss and the precision of the logits move the ceiling. DAPO keeps PPO's clipped surrogate min⁡(ρA^, clip(ρ)A^)\min\big(\rho\hat A,\ \mathrm{clip}(\rho)\hat A\big) per token, so once a token's ratio has moved past the clipping range in the direction its advantage favors, the token contributes no gradient. GSPO clips whole sequences, and CISPO keeps every token's gradient and only caps its weight: JCISPO=E[1T∑i,twi,t A^i ℓi,t],ℓi,t=log⁡πtrain(yi,t),wi,t=sg(min⁡(ρi,t,ϵmax⁡))⏟capped weight,\begin{aligned}J_{\rm CISPO}&=\mathbb E\big[\tfrac1T\textstyle\sum_{i,t}w_{i,t}\,\hat A_i\,\ell_{i,t}\big],\\ \ell_{i,t}&=\log\pi_{\rm train}(y_{i,t}),\\ w_{i,t}&=\underbrace{\mathrm{sg}\big(\min(\rho_{i,t},\epsilon_{\max})\big)}_{\text{capped weight}},\end{aligned} with the stop-gradient: its argument is used as a number and not differentiated and the total number of tokens in the prompt's completions. Against DAPO's 0.52, GSPO reaches 0.59 and CISPO 0.595, rising almost linearly for longer than DAPO. DAPO's ceiling also depends on its upper threshold ϵ+\epsilon^+, first rising and then falling as it grows, while CISPO is insensitive to CISPO's cap on the importance weight; 4, 5 and 8 were tried in {4,5,8}\{4,5,8\}; GSPO diverged mid-run several times and could not be recovered on the larger model. The generator and the trainer compute token probabilities with different kernels, the mismatch enters every ratio ρ\rho, and it is largest at the output layer; computing that layer in FP32 on both sides raises AA from 0.52 to 0.61.

Step 4

Loss averaging, advantage normalization and prompt selection mostly change the speed. Averaging the token losses per prompt ties averaging over all tokens of the batch for the highest ceiling of three averaging schemes (0.535 each, against 0.52 for averaging per completion; per-prompt was kept), and normalizing advantages per prompt, per batch, or not at all gives similar curves (batch-level was kept). Two prompt choices remove prompts that carry no signal. In a group whose rewards are all equal every advantage is 0, so the prompt adds nothing to the gradient; computing the loss only over prompts whose completions do not all receive the same reward gives A=0.54A=0.54 against 0.52. permanently dropping from later epochs every prompt whose pass rate has reached 0.9, based on the observation that a prompt that has become easy stays easy, gives 0.535. Both gains are at the edge of the 0.02 margin. Replacing forced interruption of long generations (an end-of-thinking phrase inserted at the length limit) with DAPO's length penalty did not help.

Step 5

In the combined recipe each choice adds efficiency, and the fit predicts the second half of each run. ScaleRL combines PipelineRL-8, interruptions, CISPO, per-prompt loss averaging, batch-level advantage normalization, FP32 logits, zero-variance filtering and No-Positive-Resampling. Reverting one choice at a time, in runs of 16k GPU-hours fitted on the first 8k, every variant ends with AA between 0.59 and 0.61, so the variants are compared on BB after refitting every curve with AA fixed at 0.605: ScaleRL has 2.01 and the variants 1.62 to 1.97, lowest without No-Positive-Resampling (1.62), without zero-variance filtering (1.69) and with the length penalty (1.75). Every extrapolation to 16k matched the extended run. Some choices that look redundant here matter elsewhere. Without FP32 logits the mixture-of-experts model scales worse, and CISPO's insensitivity to its cap removes tuning that DAPO needs.

Step 6

Batch size, generation length and model size raise the ceiling. Each setting is fitted on half its target compute and extended to check. Generations of 32k tokens give A=0.645A=0.645 against 0.61, with CmidC_{\rm mid} at 11,272 GPU-hours against 2,542, so they trail early and lead late. A batch of 2048 gives 0.645, against 0.61 at the default 768 and 0.605 at 512, and small batches looked better early and stagnated on downstream benchmarks. The 17B×16 mixture-of-experts model reaches 0.71 and leads the 8B model from the start. More completions per prompt at a fixed total batch (8 to 32) leave AA between 0.585 and 0.61, which the authors read as unchanged. Joint math and code training gives a clean curve for each (A=0.595A=0.595 and 0.615). Validation entropy fell along nearly the same path at batches of 768 and 2048 while downstream scores differed, so entropy did not predict performance. Truncation was the main warning sign of instability: ScaleRL kept it below 5% for over 90% of training at 8B, and below 2% on the larger model.

Terms

Sigmoid fit
RC−R0=(A−R0)/(1+(Cmid/C)B)R_C-R_0=(A-R_0)/(1+(C_{\rm mid}/C)^B), fitted after about 1.5k GPU-hours on held-out pass rate
Ceiling AA vs efficiency B,CmidB,C_{\rm mid}
A is where a recipe ends up; B and the midpoint say how fast it gets there
Power-law limit
for large CC the sigmoid is A−D/CBA-D/C^B; a power law fitted early predicted A=1.0A=1.0 on the 100k run
PipelineRL
streaming generation with weights updated mid-completion; same A as PPO-off-policy, B 4.55 against 2.68
CISPO
policy gradient with capped, stop-gradient importance weights; keeps every token's gradient; A 0.595 against 0.52 for DAPO
FP32 logits
output layer in 32-bit on generator and trainer; A 0.52 to 0.61
Zero-variance filtering
drop prompts whose completions all get the same reward from the loss
No-Positive-Resampling
retire prompts with pass rate at least 0.9 for good
ScaleRL
PipelineRL-8, interruptions, CISPO, per-prompt averaging, batch normalization, FP32 logits, both prompt filters; A = 0.61
Truncation rate
share of generations cut at the length limit; 10 to 15% destabilized runs at batch 768

Quiz

  1. A new design choice beats the baseline clearly at 2k GPU-hours but its fitted A is 0.03 lower. What does the paper recommend?
  2. Why does computing the output layer in FP32 raise the ceiling?
  3. Generations of 32k tokens give A = 0.645 against 0.61 but a midpoint of about 11k GPU-hours against 2.5k. What mistake would a short comparison make?

Sources