refactor(rollout): seat colocated actor pools from the manager, not module state - #233
Closed
Rockdu wants to merge 1 commit into
Closed
refactor(rollout): seat colocated actor pools from the manager, not module state#233Rockdu wants to merge 1 commit into
Rockdu wants to merge 1 commit into
Conversation
…odule state rm_hub/core.py published the rollout placement group through a module global (set/get_manager_placement_group plus two aliases) because the reward pool is built lazily inside the rollout function, which has no handle on the manager. sft_rollout leaned on the same global and kept its encode actors in another. The pool outlives every rollout call, so RolloutManager now builds it in __init__ via rm_hub.create_reward_pool(args, pg); pickscore_rm's singleton lookup finds that seated instance. A colocated pool without seats raises at construction instead of pending in Ray forever, which is also the fail-fast for mixed GPU reward types. The SFT encode pool becomes a SingletonMeta class fed by a new optional placement_group kwarg that call_rollout_fn passes only to signatures declaring it, so custom rollout functions keep working unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019FxEmRysrrXzWUiQxxDR9k
Collaborator
Author
|
Closing: this belongs on top of #207's branch, not as a standalone PR. Re-basing there. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
miles/rollout/rm_hub/core.py(set_manager_placement_group/get_manager_placement_groupand theset/get_reward_placement_groupaliases) and the_encode_actorsglobal insft_rollout.py.RolloutManagernow seats the colocated reward pool itself in__init__(rm_hub.create_reward_pool(args, pg), keyed on--rm-type);pickscore_rmkeeps itsAsyncPickScorePool(args)lookup, which hits that singleton.AsyncRewardActorPooltakesplacement_group=explicitly. A colocated pool constructed without one raises immediately — this is also the fail-fast for mixed GPU reward types under--colocate-reward(previously the second pool's 0.05-GPU actor pended in Ray forever).call_rollout_fnpassesplacement_group=to rollout functions whose signature declares it (same pattern asevaluation=oncustom_generate);sft_rollout.generate_rolloutuses it to build aSftEncodePoolsingleton. Rollout functions without the kwarg are untouched.Why
The reward pool is built lazily inside the rollout function, which has no handle on the manager, so the placement group was smuggled through a module global. The pool outlives every rollout call — its owner is the
RolloutManager, whose__init__already decides where the engines sit (init_rollout_engines), so it is the one object that knows which bundles carry a rollout claim. #207 was about to add a second global (_reward_slots) on top of this one; seating pools from the manager gives that PR a place to hang its bundle accounting without any module state.GenerateStatewas deliberately not used as the owner: its lifecycle is one rollout call (reset()per call), while the pool is process-lifetime.Validation
pytest tests/fast/rollout/test_rollout_placement_group.py— 2 passed (kwarg is passed only to signatures that take it; an unseated colocated pool raises before creating actors).pre-commit runclean on the touched files.test_h3_t2va_grpo_2xGPU(H3 recipe,--colocate-reward --rm-type pickscore) covers it in this PR's CI; the three--colocate-rewardrecipes (H3, Cosmos3, Wan2.2 17-GPU) all use--rm-type pickscore, socreate_reward_poolhas a pool for each.Files
miles/rollout/rm_hub/core.py— drop the globals and aliases;placement_group=parameter; raise when colocated without seats.miles/rollout/rm_hub/__init__.py—create_reward_pool(args, placement_group).miles/rollout/rm_hub/pickscore.py— passplacement_groupthrough.miles/ray/rollout.py— seat the reward pool in__init__; passplacement_group=self.pgtocall_rollout_fn.miles/rollout/base_types.py—call_rollout_fnforwardsplacement_groupwhen the signature takes it.miles/rollout/sft_rollout.py—SftEncodePoolsingleton replaces the_encode_actorsglobal;generate_rolloutdeclaresplacement_group=.docs/user-guide/customization.md— document the optional kwarg and who seats the reward pool.tests/fast/rollout/test_rollout_placement_group.py— new.Follow-ups not in scope
sft_rollout._scheduler_gridis still a module-level cache (a derived constant, not placement state)._dispersal_order/ColocatedRewardSlots; with the pool seated by the manager, the remaining need is one actor per bundle, which the existing stride already gives.🤖 Generated with Claude Code
https://claude.ai/code/session_019FxEmRysrrXzWUiQxxDR9k