Skip to content

[rollout] fix: add missing RolloutConfig keys to rollout.yaml - #7430

Open
Nas01010101 wants to merge 2 commits into
verl-project:mainfrom
Nas01010101:fix/rollout-config-yaml-parity
Open

[rollout] fix: add missing RolloutConfig keys to rollout.yaml#7430
Nas01010101 wants to merge 2 commits into
verl-project:mainfrom
Nas01010101:fix/rollout-config-yaml-parity

Conversation

@Nas01010101

@Nas01010101 Nas01010101 commented Aug 15, 2026

Copy link
Copy Markdown

What does this PR do?

Seven RolloutConfig entries have no key in verl/trainer/config/rollout/rollout.yaml. Hydra composes the trainer config in struct mode, so a plain actor_rollout_ref.rollout.<field>=... override is rejected before training starts, even though every one of them is read at runtime:

entry read at
limit_images vllm_async_server.py — sets limit_mm_per_prompt for multi-image data
repetition_penalty vllm_async_server.py — default for the sampling parameter
enable_sleep_mode vllm_async_server.py, trtllm_async_server.py
standalone_gpu_memory_utilization fully_async_rollouter.py
moe_tensor_parallel_size trtllm_async_server.py
checkpoint_manager_class ray_trainer.py, separation/ray_trainer.py
server (ServerConfig) trtllm_rollout.pytimeout, max_attempts, retry_delay, max_connections

On main, each of them aborts the run:

$ python3 -m verl.trainer.main_ppo actor_rollout_ref.rollout.limit_images=4 ...
Could not override 'actor_rollout_ref.rollout.limit_images'.
To append to your config use +actor_rollout_ref.rollout.limit_images=4

limit_images shows the inconsistency most directly: reward/reward.yaml carries an inline rollout block with the same _target_: verl.workers.config.RolloutConfig, and it does list limit_images: null. So the same override works on the reward-model rollout and fails on the actor rollout, which is where multi-image training data needs it.

enable_sleep_mode defaults to True and gates if not self.config.enable_sleep_mode: in the vLLM async server, so there is currently no way to turn it off from the command line. server has no block at all, so the trtllm rollout's HTTP timeout and retry settings are pinned to their dataclass defaults for every run.

Same class as #7387 / #7426 (checkpoint config), on the rollout config.

Checklist Before Starting

Test

tests/special_sanity/test_rollout_config_parity.py compares fields(RolloutConfig) against the composed actor_rollout_ref.rollout node for both ppo_trainer and ppo_megatron_trainer. It fails on main:

AssertionError: ppo_trainer: RolloutConfig fields ['checkpoint_manager_class',
'enable_sleep_mode', 'limit_images', 'moe_tensor_parallel_size',
'repetition_penalty', 'server', 'standalone_gpu_memory_utilization'] have no key
in rollout.yaml, so actor_rollout_ref.rollout.<field>=... is rejected by Hydra.

and passes with this change. A second test asserts KNOWN_UNMAPPED does not go stale.

$ pytest tests/special_sanity/ -q
21 passed
$ bash scripts/generate_trainer_config.sh
All good

API and Usage Example

All seven become settable; composed defaults are unchanged because each key is added with its dataclass default.

python3 -m verl.trainer.main_ppo \
    actor_rollout_ref.rollout.limit_images=4 \
    actor_rollout_ref.rollout.repetition_penalty=1.05 \
    actor_rollout_ref.rollout.enable_sleep_mode=False \
    actor_rollout_ref.rollout.standalone_gpu_memory_utilization=0.9 \
    actor_rollout_ref.rollout.checkpoint_manager_class=my.pkg.MyManager \
    actor_rollout_ref.rollout.server.timeout=120 \
    actor_rollout_ref.rollout.server.max_attempts=5 \
    ...

Composing with no overrides gives limit_images=None, repetition_penalty=1.0, enable_sleep_mode=True, standalone_gpu_memory_utilization=None, moe_tensor_parallel_size=1, checkpoint_manager_class=None, and server at timeout=60.0, max_attempts=3, retry_delay=2.0, max_connections=1000, max_start_wait_time=300.0 — the dataclass defaults.

Design & Code Changes

  • verl/trainer/config/rollout/rollout.yaml: six scalar keys added next to their related settings, plus a server: block shaped like the neighbouring prometheus: block (with _target_). Every value is the dataclass default.
  • verl/trainer/config/_generated_*_trainer.yaml: regenerated via scripts/generate_trainer_config.sh (+13 lines each, additive).
  • tests/special_sanity/test_rollout_config_parity.py: new.

Left out, and why: custom, layer_name_map and sglang_engine_mode have no reader in the tree. All three are listed in KNOWN_UNMAPPED in the test so the exclusion is explicit rather than silent, and the second test fails if one of them later gains a YAML key.

Checklist Before Submitting

  • Read the Contribute Guide.
  • Apply pre-commit checks.
  • Add / Update the documentation. — the YAML comments are the documentation for these keys; no separate doc page lists them.
  • Add unit or end-to-end test(s) to the CI workflow. tests/special_sanity/ already runs in CI.
  • Once your PR is ready for CI, send a message in the ci-request channel.
  • recipe submodule — not touched.

Six RolloutConfig fields have no key in rollout.yaml. Hydra runs in struct
mode, so actor_rollout_ref.rollout.<field>=... is rejected before training
starts even though each field is read at runtime:

  limit_images                       vllm_async_server.py sets limit_mm_per_prompt
  repetition_penalty                 vllm_async_server.py sampling params
  enable_sleep_mode                  vllm_async_server.py, trtllm_async_server.py
  standalone_gpu_memory_utilization  fully_async_rollouter.py
  moe_tensor_parallel_size           trtllm_async_server.py
  checkpoint_manager_class           ray_trainer.py

limit_images is already present in the inline rollout block of
reward/reward.yaml, which builds the same RolloutConfig, so the same
override works on the reward model rollout and fails on the actor rollout.

Each key is added with its dataclass default, so composed values are
unchanged. The generated trainer configs are regenerated accordingly.

tests/special_sanity/test_rollout_config_parity.py compares the dataclass
fields against the composed node and lists the deliberate exclusions.
RolloutConfig.server (ServerConfig) has no block in rollout.yaml, so
actor_rollout_ref.rollout.server.timeout=... and the other four settings are
rejected by Hydra. The trtllm rollout reads timeout, max_attempts, retry_delay
and max_connections when it builds its HTTP client, so those values are fixed
at their dataclass defaults for every run.

The block is added with the dataclass defaults and follows the same shape as
the neighbouring prometheus block, including _target_.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant