Configuration structure
The configuration system is organized into three main components:- rLLM backend-agnostic configs: Core training settings shared across all backends
- Backend-specific configs: Settings specific to Tinker or Verl backends
- Forwarding mechanism: Allows backend-specific configs to override rLLM configs for backward compatibility
rllm/experimental/config/:
rllm/experimental/config/rllm/base.yaml: Backend-agnostic rLLM configurationsrllm/experimental/config/rllm/backend/tinker.yaml: Tinker-specific configurationsrllm/experimental/config/rllm/backend/verl.yaml: Verl-specific configurationsrllm/experimental/config/unified.yaml: Main entry point that combines all configs
rLLM backend-agnostic configurations
These configurations are defined inrllm/base.yaml and are used across different backends.
Agent configuration
Settings for the agent that interacts with the environment.Environment configuration
Settings for the environment where the agent operates.Workflow configuration
Settings for workflow-based training (alternative to agent-based training).Rollout configuration
Settings for trajectory rollouts during training and validation.These settings are primarily for logging purposes. The actual rollout behavior is determined by backend-specific configurations.
Trainer configuration
Core training loop settings.Algorithm configuration
RL algorithm and advantage estimation settings.Stepwise advantage configuration
Settings for computing advantages at each step in multi-step trajectories.Trajectory processing flags
Top-level flags for trajectory processing and filtering.Compact filtering configuration
Fine-grained filtering of trajectories based on various termination conditions.Rejection sampling configuration
Settings for rejection sampling to improve training data quality.SDK configuration
Settings for the rLLM SDK, including trace storage and proxy server.Episode logging configuration
Settings for logging full episode trajectories to disk.Backend-specific configurations
Tinker backend
Tinker-specific settings live inrllm/experimental/config/rllm/backend/tinker.yaml.
This file contains:
- Tinker service and execution settings
- Model/LoRA training settings
- Sampling and rollout-engine settings
- Tinker-native training/data blocks
- Forwarding into
rllm.*common config keys
Top-level Tinker-specific keys
Model block
Training block (Tinker-native)
Validation, sampling, rollout, and data blocks
Forwarding to common rllm.*
Tinker backend forwards group-size settings into backend-agnostic rollout config:
rllm.rollout.n <- training.group_sizerllm.rollout.n_val <- validation.group_size
Verl backend
Verl-specific settings live inrllm/experimental/config/rllm/backend/verl.yaml.
This file is intentionally thin and composes Verl’s native PPO config via:
verl.yaml only does two things:
- Sets a small number of required overrides for unified-trainer compatibility (e.g.
actor_rollout_ref.rollout.mode=async,actor.use_rollout_log_probs=True). - Pins one rllm-namespaced default that diverges from verl’s (
rllm.algorithm.rollout_correction.bypass_mode=False).
rllm.* namespace — happens at runtime via sync_config in rllm/experimental/verl/utils.py.
Key fields in verl.yaml
All other shared knobs (
algorithm.adv_estimator, actor.kl_loss_coef, trainer.total_epochs, …) live in their natural locations — verl-native keys come from ppo_trainer.yaml, rllm-namespace keys from base.yaml — and are reconciled at startup by sync_config.
Bidirectional config sync
For a fixed table of “shared keys” (the same value, different paths in the two namespaces),sync_config mirrors the value between the verl-native side and the rllm.* side at trainer startup. New configs should use the rllm.* path. Existing Verl-style CLI overrides still work for backward compatibility, but they log a deprecation warning.
Per-key precedence:
rllm.*value explicitly set on the Hydra CLI- Verl-native value explicitly set on the Hydra CLI
rllm.*value frombase.yaml(when non-null)- Verl-native value from
ppo_trainer.yaml
Two extra rules sit alongside this table:
actor.use_kl_lossis derived fromkl_beta: if you do not explicitly setactor_rollout_ref.actor.use_kl_losson the CLI,sync_configsets it to(kl_beta > 0). Settingrllm.algorithm.kl_betaalso mirrors intoactor_rollout_ref.actor.kl_loss_coef. Setting the Verl-native coefficient still backfillsrllm.algorithm.kl_betafor now, with a deprecation warning.clip_ratiofamily.rllm.algorithm.eps_clipmirrors toactor_rollout_ref.actor.clip_ratioandactor_rollout_ref.actor.clip_ratio_low. Ifrllm.algorithm.eps_clip_highis set, it mirrors toactor_rollout_ref.actor.clip_ratio_high; otherwise the upper bound mirrorseps_clip. Verl-nativeclip_ratio,clip_ratio_low, andclip_ratio_highstill backfill the rLLM values for now when the rLLM side is not set, with deprecation warnings.
/ppo_trainer resolves:
Config forwarding mechanism
The Verl backend uses bidirectional sync (described above): for any shared key, the preferred path isrllm.*, while legacy Verl-native shared-key CLI overrides still work with deprecation warnings. The Tinker backend does its own one-way forwarding from native group-size settings into rllm.rollout.{n,n_val} (see “Tinker backend” above).
Example: set the preferred shared knob
Setadv_estimator on the rllm.* side:
rllm.* value wins.
Example: KL-in-loss
Settingrllm.algorithm.kl_beta=0.01 is enough — actor.kl_loss_coef is mirrored and actor.use_kl_loss is auto-set to True:
Benefits
- Backward compatibility. Existing scripts that override on the verl-native side continue to work while logging deprecation warnings; the rllm-side value is mirrored automatically.
- Backend portability. New scripts can target the backend-agnostic
rllm.*namespace and run on either Tinker or Verl with the same flags. - Single source of truth at runtime. No
oc.selectinterpolation in the yaml; the merged config that goes to verl’s workers and rLLM’s trainer holds the same values on both sides.
Configuration best practices
- Use rLLM configs for new projects: If starting from scratch, use the rLLM backend-agnostic configs for better portability across backends.
-
Use rLLM paths for shared knobs: Existing Verl-native shared-key overrides still work for compatibility, but new configs should use
rllm.*. -
Check the unified config: The
unified.yamlfile shows how all configs are combined and is useful for debugging configuration issues. - Understand defaults hierarchy: Backend-specific configs override rLLM defaults, which in turn override Hydra’s base defaults.

