Skip to content

Algorithm Reference

Relax supports multiple policy gradient algorithms, all selected via the --advantage-estimator flag. This document covers PPO and the primary GRPO-family algorithms (for On-Policy Distillation, see the dedicated page).

GRPO, RLOO, CISPO, GSPO, SAPO, and M2PO share the same actor/rollout service topology, although RLOO is synchronous-only and enforces fixed batch invariants. PPO additionally requires a Critic model and an Advantages service; start from the PPO training recipe instead of only replacing GRPO_ARGS.

REINFORCE++ and REINFORCE++-baseline also reuse the GRPO service topology, but their return, global normalization and KL contracts are algorithm-specific. See REINFORCE++ Training before enabling either estimator.


GRPO

GRPO (Group Relative Policy Optimization) is the default algorithm in Relax. It broadcasts the group-relative scalar reward to every token and uses a standard PPO-Clip objective.

Reference: DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models.

How It Works

The GRPO objective is the standard PPO-Clip:

JGRPO(θ)=E[min(rt(θ)A^t, clip(rt(θ), 1ε, 1+ε)A^t)]

where rt(θ)=πθ/πθold, and A^t is the group-relative advantage (reward minus group mean, normalized by group standard deviation). Gradients are zeroed out when the ratio exceeds the clipping bounds.

Key Parameters

ParameterDefaultDescription
--advantage-estimator grpodefaultEnable GRPO
--eps-clip0.2Clipping margin (ratio range = [1-ε, 1+ε])
--eps-clip-highsame as --eps-clipUpper clipping margin; can be set differently for asymmetric clipping
--clip-gradGradient clipping norm

Quick Start

GRPO is the default algorithm — no parameter changes needed. Just run the training script directly:

bash
MODEL_DIR=/path/to/model \
DATA_DIR=/path/to/data \
EXP_DIR=/path/to/exp \
bash scripts/training/text/run-qwen3-4B-8xgpu.sh

RLOO

RLOO (REINFORCE Leave-One-Out) uses the other samples for the same prompt as an unbiased baseline. Relax implements synchronous RLOO with an unclipped REINFORCE policy loss; it does not use PPO ratios or clipping.

Reference: Back to Basics: Revisiting REINFORCE Style Optimization for Learning from Human Feedback in LLMs.

How It Works

For a prompt with G sampled responses and scalar rewards ri, the leave-one-out baseline and advantage are:

bi=1G1jirj,Ai=ribi=GG1(rir¯)

Unlike GRPO, RLOO does not divide by the group standard deviation. The token loss is:

Li,t=stopgrad(Ai)logπθ(yi,tx,yi,<t)

Each sample's scalar advantage is broadcast to its response tokens. Relax masks padding and normalizes the summed loss by the global number of valid response tokens Neff:

LRLOO=1Neffitmi,tstopgrad(Ai)logπi,t

This global-token reduction does not apply a separate 1/Ti weight to each response. train/pg_clipfrac is always 0 because RLOO uses no clipping.

Requirements and Parameters

ParameterRequirementDescription
--advantage-estimator rloorequiredEnable RLOO
--n-samples-per-promptat least 2Group size G; larger groups provide a more stable LOO baseline at higher rollout cost
--rollout-batch-size × --n-samples-per-promptequals --global-batch-sizeExactly one optimizer update per rollout
--num-steps-per-rolloutunset or 1Reusing the same rollout for multiple unclipped updates is rejected
--calculate-per-token-lossenabledUse global valid-token normalization; per-response token means would reweight unequal-length responses by 1/Ti
--kl-coef0Reward-side KL shaping is not implemented for RLOO; with a valid --ref-load <checkpoint>, use --use-kl-loss --kl-loss-coef <value> for the supported direct KL penalty
--max-staleness0Stale rollouts are rejected because the unclipped objective has no importance-ratio correction
reward normalizationenabledRLOO's group transformation runs in the normalized-reward path
--normalize-advantagesdisabledPost-DP whitening would change RLOO semantics and make results partition-dependent
--fully-async, --hybrid, --partial-rollout, --use-dynamic-global-batch-sizedisabledRLOO currently requires synchronous, fixed-size rollout batches

The batch sizes are hardware-tunable as long as their equality is preserved. For example, ROLLOUT_BATCH_SIZE=4, N_SAMPLES=8, and GLOBAL_BATCH_SIZE=32 retain one update per rollout while reducing per-step memory relative to 16 × 8 = 128.

Diagnostics

Training rollout logs publish the following final metric names:

  • rollout/rloo/baseline_mean: mean LOO baseline (equal to the mean group reward; retained as an explicit baseline trace)
  • rollout/rloo/adv_abs_mean: mean absolute RLOO advantage
  • rollout/rloo/no_signal_frac: fraction of effective loss tokens attached to zero-advantage samples
  • rollout/rloo/empty_response_frac: fraction of samples with a literally empty response
  • rollout/rloo/zero_adv_group_frac: fraction of complete groups with zero advantages throughout
  • rollout/rloo/dropped_group_frac: fraction of observed groups omitted from diagnostics because their size is incomplete

These diagnostics are training-only, purely observational rollout statistics; they do not affect the training path. Evaluation uses its own sampling group size and does not emit misleading eval/*/rloo/* values. They are also omitted when a custom reward post-processor or agentic custom-advantage hook replaces the standard RLOO signal, because raw rewards cannot reconstruct the optimizer input in those modes.

Quick Start

Use the dedicated Qwen3-0.6B GSM8K recipe. Its batch and rollout settings can be overridden with environment variables:

bash
MODEL_DIR=/path/to/models \
DATA_DIR=/path/to/data \
NUM_ROLLOUT=60 \
ROLLOUT_BATCH_SIZE=4 \
N_SAMPLES=8 \
GLOBAL_BATCH_SIZE=32 \
bash examples/algorithms/run-qwen3-0.6B-1xgpu-rloo.sh

Set ADVANTAGE_ESTIMATOR=grpo to run a control arm with the same recipe and seeds. The recipe writes normalized GSM8K data to a writable artifact cache (override with RLOO_DATA_CACHE_DIR) and appends an instruction to emit the final answer as \boxed{...}, matching the math reward parser contract.


PPO

PPO (Proximal Policy Optimization) is an actor-critic algorithm. Relax trains a separate Critic to predict token-level values, computes GAE advantages and returns, applies PPO-Clip to the Actor, and applies clipped value loss to the Critic.

Reference: Proximal Policy Optimization Algorithms.

How It Works

The temporal-difference residual and GAE recursion are:

δt=rt+γV(st+1)V(st)A^t=δt+γλA^t+1,R^t=A^t+V(st)

The Actor then uses the same clipped policy objective shown for GRPO, but with Critic-derived token-level advantages. The Critic minimizes the maximum of clipped and unclipped squared value errors.

Key Parameters

ParameterDefaultDescription
--advantage-estimator ppoEnable PPO and the Critic service graph
--gamma1.0GAE discount factor
--lambd1.0GAE lambda
--eps-clip0.2Actor clipping margin
--value-clip0.2Critic value clipping range
--num-critic-only-steps0Initial Critic-only warmup steps
--critic-lrsame as --lrCritic learning rate

Quick Start

PPO cannot be enabled by changing only the algorithm argument because its service graph requires critic and advantages resources. Fully-async PPO is not currently supported; use the dedicated synchronous colocate recipe:

bash
MODEL_DIR=/path/to/models \
DATA_DIR=/path/to/data \
EXP_DIR=/path/to/experiments \
bash scripts/training/text/run-qwen35-9B-8xgpu-ppo.sh

See PPO Training for the resource topology, checkpoint rules, and KL constraints.


CISPO

CISPO (Clipped Importance-ratio Soft Policy Optimization) preserves gradient signal for out-of-trust-region tokens instead of zeroing it out. It caps gradient magnitude via a stop-gradient'd coefficient while keeping the gradient direction alive.

Reference: MiniMax-M1: Scaling Test-Time Compute Efficiently with Lightning Attention.

How It Works

The CISPO objective is:

JCISPO(θ)=E(q,a)D, {oi}i=1Gπθold(|q)[1i=1G|oi|i=1Gt=1|oi|sg(r^i,t(θ))A^i,tlogπθ(oi,tq,oi,<t)]

where r^i,t(θ) is the clipped importance-sampling weight:

r^i,t(θ)=clip(ri,t(θ), 1εlowIS, 1+εhighIS)

and ri,t(θ)=πθ(oi,tq,oi,<t)/πθold(oi,tq,oi,<t). Gradients flow only through logπθ; both r^i,t and A^i,t are stop-gradient'd.

Key Parameters

ParameterDefaultRecommendedDescription
--advantage-estimator cispoEnable CISPO
--eps-clip0.20.2Lower clipping margin (ratio lower bound = 1 - eps_clip)
--eps-clip-highsame as --eps-clip10Upper clipping margin (ratio upper bound = 1 + eps_clip_high). Set to 10 to effectively unclamp the upper side
--kl-loss-coef0.00.001KL loss coefficient. Recommended: 0.001 to add a small KL penalty that constrains policy drift
--use-kl-lossoffonEnable KL loss computation (required for --kl-loss-coef to take effect)
--use-tisoffonToken Importance Sampling — recommended to enable with CISPO
--clip-grad1.0Gradient clipping norm

Quick Start

Use any existing GRPO training script and replace GRPO_ARGS with CISPO_ARGS:

bash
CISPO_ARGS=(
   --advantage-estimator cispo
   --use-kl-loss
   --kl-loss-coef 0.001
   --eps-clip 0.2
   --eps-clip-high 10
   --use-tis
)

GSPO

GSPO (Group-wise Sequence-level Policy Optimization) differs from GRPO in how KL divergence is computed: GSPO uses sequence-level KL instead of per-token KL. Every token in a sequence shares the same KL value (the mean over all tokens in that sequence), providing uniform constraint strength within a sequence.

How It Works

GSPO uses the same PPO-Clip objective as GRPO, but the ratio is computed from sequence-level KL:

KLseq=1|o|t=1|o|(logπθold(ot)logπθ(ot))

Every token's ratio is rt=exp(KLseq), rather than an independent per-token ratio.

Key Parameters

ParameterDefaultDescription
--advantage-estimator gspoEnable GSPO
--eps-clip0.2Clipping margin
--eps-clip-highsame as --eps-clipUpper clipping margin
--clip-gradGradient clipping norm

Quick Start

bash
GSPO_ARGS=(
   --advantage-estimator gspo
   --eps-clip 0.2
)

SAPO

SAPO (Soft Adaptive Policy Optimization) replaces hard clipping with a smooth sigmoid gate. The gate's steepness is controlled by a temperature parameter, implementing a differentiable trust region constraint.

How It Works

SAPO's core is a sigmoid gate centered at ratio=1:

f(r)=4τσ(τ(r1))

where σ is the sigmoid function, and τ is selected based on the advantage sign:

  • A>0: use τpos (default 1.0)
  • A0: use τneg (default 1.05, stronger suppression for negative tokens)

SAPO objective: JSAPO(θ)=f(r)A

Key Parameters

ParameterDefaultDescription
--advantage-estimator sapoEnable SAPO
--sapo-tau-pos1.0Temperature for positive advantages
--sapo-tau-neg1.05Temperature for negative advantages (higher = stronger suppression)
--clip-gradGradient clipping norm

Quick Start

bash
SAPO_ARGS=(
   --advantage-estimator sapo
   --sapo-tau-pos 1.0
   --sapo-tau-neg 1.05
)

M2PO

M2PO (Second-Moment Trust Policy Optimization) uses the second moment of the log importance ratio over harmful tokens as its trust-region constraint: it tightens clipping only when that second moment exceeds a budget, and keeps the token otherwise. Compared to fixed clipping, it retains more useful gradient and mitigates entropy collapse in off-policy (stale-data) regimes, making it purpose-built for mini-batch reuse and asynchronous training.

Reference: Prosperity before Collapse: How Far Can Off-Policy RL Reach with Reuse of Mini-Batch Data? (NeurIPS 2025).

How It Works

M2PO only constrains the "harmful" tokens that PPO would clip — those whose advantage sign aligns with the ratio's drift and would cause an over-update:

H={t:A^t>0, rt>1}{t:A^t<0, rt<1}

where rt=exp(KLt) and KLt=logπθold(ot)logπθ(ot). The second moment of the log-ratio over these tokens is:

M2=1|H|tH(logrt)2

Relax solves this statistic independently on each Megatron microbatch's local tokens. Logging preserves the existing aggregation: with --calculate-per-token-loss, train/ppo_kl_m2_before and train/ppo_kl_m2_after are weighted by the microbatch's loss-token count; otherwise, each microbatch scalar is summed unchanged and the framework divides by the sample count. The latter is not a sample-weighted mean. Neither mode pools all harmful tokens in the global batch. These logged diagnostics do not feed back into the loss.

  • If M2 kl2_budget: no clipping, all tokens are kept;
  • Otherwise, use water-filling to select the previous observed breakpoint. This gives a conservative trust-region radius τ whose capped sum does not exceed |H|kl2_budget, yielding the clip band [eτ, eτ].

The final clipping margin is ε=max(adaptive value, miniclip), so it is never tighter than the configured floor. Choose the floors to match the GRPO margins when that is the desired lower bound. ppo_kl_m2_after is the legacy solver diagnostic for the selected breakpoint before that floor is applied; in the first-breakpoint edge case it retains the uncapped local mean. It is not a recomputation after the final policy clip. The policy loss reuses the PPO-Clip pessimistic form from the GRPO section, with only the clip bounds solved adaptively.

Key Parameters

ParameterDefaultRecommendedDescription
--advantage-estimator m2poEnable M2PO
--m2po-kl2-budget0.010.010.04Second-moment budget per harmful token. Smaller = tighter/more-frequent clipping, larger = more off-policy tolerance (the paper uses 0.04)
--m2po-miniclip-low0.30.2Lower-side clip-margin floor (the margin is at least miniclip_low)
--m2po-miniclip-high0.50.28Upper clip-margin floor
--use-rollout-logprobsoffon for stale async dataUse the behavior-policy log probabilities that generated each token as M2PO's old policy
--use-tisoffoff with rollout log probsTIS is a post-loss correction and does not drive M2PO's adaptive threshold; it is mutually exclusive with --use-rollout-logprobs

M2PO derives its clip bounds adaptively, so it does not use --eps-clip / --eps-clip-high.

Existing implementation behavior

The registry refactor preserves M2PO's existing computation: reward processing passes through raw sample rewards, and the threshold solver does not filter tokens by the loss mask or aggregate its statistic across CP ranks. Its breakpoint comparisons still use host scalars. Registration does not establish equivalence to the paper. Because the clipping statistics are local, M2PO declares supports_context_parallel=False: startup requires --context-parallel-size 1 and dynamic context parallelism disabled. This validation leaves the algorithm's reward, solver and metric calculations unchanged.

When to Use

M2PO's benefit grows with how off-policy the training data is, so reach for it first in these scenarios:

  • Asynchronous training with large staleness: in fully-async mode the rollout weights lag noticeably behind the actor (--max-staleness of 32, 256, or higher), and stale samples inflate the importance ratio. Fixed clipping then either zeroes out many tokens (losing gradient) or lets them through (causing over-updates); M2PO uses the second moment to adaptively tighten only the genuinely "harmful" fraction, suppressing collapse while preserving the learning signal.
  • Mini-batch reuse / multi-step sampling: when the same rollout batch is reused across several update steps, the later steps effectively train on off-policy data too, and M2PO extends the usable lifetime of that batch.
  • Late-training entropy collapse or reward stagnation: when fixed clipping narrows the policy too quickly and starves exploration, M2PO's looser adaptive bounds help sustain entropy and delay collapse.

Conversely, under strictly on-policy synchronous training (--max-staleness 0 with per-step weight sync), M2PO's gain over GRPO is limited — start from GRPO as a baseline there.

M2PO is valid in true-on-policy mode, but then its importance ratio is exactly one and adaptive clipping does not engage. To evaluate its stale-data behavior, make sure the run supplies old-policy log probabilities rather than auto-enabling --true-on-policy-mode. For fully-async rollout staleness, pass --use-rollout-logprobs: --use-tis is applied only after M2PO has already chosen its clip bounds.

Quick Start

Use any existing GRPO training script and replace GRPO_ARGS with M2PO_ARGS:

bash
M2PO_ARGS=(
   --advantage-estimator m2po
   --m2po-kl2-budget 0.01
   --m2po-miniclip-low 0.2
   --m2po-miniclip-high 0.28
)

Algorithm Comparison

AlgorithmAdvantage ComputationPolicy LossKL Constraint
PPOCritic values + GAEPPO-Clip (hard clip)Disabled in the current synchronous topology
GRPOGroup-relative rewardPPO-Clip (hard clip)Optional KL loss
REINFORCE++Token KL-to-go return + global token normalizationPPO-Clip (hard clip)k1 KL in shaped reward
REINFORCE++-baselineInclusive group mean + global token normalizationPPO-Clip (hard clip)Separate k2 KL loss
CISPOGroup-relative rewardStop-gradient coefficientRecommended KL loss
GSPOGroup-relative rewardPPO-Clip + sequence-level KLSequence-level ratio
SAPOGroup-relative rewardSigmoid gateTemperature-controlled
M2PORaw sample reward broadcast to tokensAdaptive second-moment clipOptional KL loss (favor for large-staleness / off-policy)
RLOOLeave-one-out baselineUnclipped REINFORCEOptional KL loss (same as GRPO)

Next Steps

Released under the Apache 2.0 License.