Skip to main content
Modules: rllm.trainer.algorithms.advantage (advantage estimators) · rllm.trainer.algorithms.aux_loss (auxiliary losses) · rllm.trainer.algorithms.config (AlgorithmConfig)
In rLLM an RL “algorithm” is assembled from two composable, backend-agnostic pieces, both configured under rllm.algorithm:
  1. An advantage estimator — turns per-trajectory rewards into advantages (the GRPO family).
  2. Zero or more auxiliary losses — extra loss terms on tokens the policy gradient ignores (for example ECHO’s loss on environment-observation tokens).
The backend then applies a policy loss function (ppo, importance_sampling, …) using those advantages. The same registries feed all three training backends (verl, tinker, fireworks), so flipping algorithms is a one-line config change that works everywhere.

How advantages are computed

Advantages are computed on TrajectoryGroups, partitioned by group_role. The estimator hook is scalar reward per trajectory in, scalar advantage per trajectory out — the unified trainer broadcasts each trajectory’s advantage across its response tokens. This single contract is what lets the same estimator code serve every backend. Select the estimator with adv_estimator:
See Advantage estimator for the full data contract, per-role estimator maps, and what the scalar hook intentionally cannot express (GAE and other per-token / critic-based estimators — for those, see Pre-computing advantage).

Built-in advantage estimators

All six live in one registry and run on every backend. (The verl backend can also be pointed at its native estimators, but the rLLM-native set above is the portable path.)

ECHO and auxiliary losses

ECHO keeps GRPO’s advantage exactly and adds a cross-entropy auxiliary loss on the environment-observation tokens (tool / terminal output) that the policy conditions on but the policy gradient never trains. For tool-use and terminal agents — where rollouts are dominated by observation tokens and many rollouts fail — this turns every rollout, including the failures, into dense supervision at no extra rollout cost. adv_estimator=echo defaults the env-loss weight λ to the paper’s 0.05. Tune it explicitly (productive range 0.01–0.05; 0.0 reproduces plain GRPO):

The auxiliary-loss framework

env_loss_coef is shorthand for the general aux_losses mechanism. An auxiliary loss is a named loss applied to a token subset (a “mask”). These two configs are equivalent:
env_prediction is the one built-in client (length-normalized cross-entropy on observation tokens). You can list several aux losses; each is added to the policy loss with its own coef. The same config runs on every backend, with different mechanics and cost:
Because loss normalization differs across managed services, λ (the coef) may need per-backend retuning. Watch the metric above to confirm the auxiliary loss is actually falling.

Building custom RL algorithms

Both extension points are registries — register a function or a class and reference it by name from config. No backend code to touch.

A custom advantage estimator

Decorate a function with @register_rllm_adv_estimator("name"). It is scalar-per-trajectory in, scalar-per-trajectory out; **kwargs carries traj_groups when you need per-trajectory metadata.
The full contract, role-level estimator maps, and a complete worked example (porting OPO from verl) are in Advantage estimator.

A custom auxiliary loss

Subclass AuxiliaryLoss, choose a token mask, and register it. The default weighting is uniform (every masked token gets coef); override weight(ctx) to return a per-token tensor instead.
The same class runs on all three backends (verl folds it into the policy pass; tinker/fireworks add the extra cross-entropy pass). Dynamic per-token weights and auxiliary losses that need a separate model call (e.g. a teacher branch) are an in-progress extension — see the design note design/auxiliary-losses.md.
Need a per-token advantage signal (GAE, reward-to-go, a custom detector) that the scalar estimator hook can’t express? Compute it in your workflow and feed it through use_precomputed_advantage to bypass the estimator entirely.

Configuration quick reference

All under rllm.algorithm (full reference): Per-role estimator overrides are set via traj_group_adv_estimator_map on the AgentTrainer constructor — see Advantage estimator.

Next steps

Advantage estimator

The estimator hook contract, role-level maps, and the OPO worked example

Configuration

Every AlgorithmConfig field

Capability matrix

Which algorithms and losses each backend supports

Backends

verl vs tinker vs fireworks