Enhanced Off-Policy Async Rollout with Staleness Control and Partial Rollout Support - #1781
Enhanced Off-Policy Async Rollout with Staleness Control and Partial Rollout Support#1781huang3eng wants to merge 8 commits into
Conversation
…ndow-evict policies
|
@zhuzilin @Zhuohao-Li Please help review it~ |
|
Can we break this PR into smaller ones, e.g. staleness version control, and lifecycle hooks can be seperative. |
|
@Zhuohao-Li For sure |
- Replace fully_async_rollout.py with PR#1781's implementation (1061 LOC): CompletedSampleRecord store, staleness control, window eviction, pause-for-staleness, sample annotation with weight version - Add lifecycle hooks to RolloutManager: before_weight_update, after_weight_update, _call_generate_rollout_hook - Add policy_version tracking to train_async.py - Backup original v0.3.0 fully_async_rollout as .v030.bak Based on: THUDM#1781
|
Thanks for driving the broader #1800 work and for publishing the proposed split. I independently explored a smaller, deterministic alternative and have pushed the three review layers for comparison: main...0z5a:codex/policy-version-metrics. The scope is intentionally narrower than this PR:
It deliberately does not implement partial-rollout resume, fragment relabeling, I will open it as a draft comparison PR rather than claim that it supersedes this work. I am happy to close, rebase, or reduce it further if maintainers prefer the direction here. Update: the draft comparison is now available as #2278. |
Background
The existing off-policy modes in slime (
one_step_offandfully_async) have significant limitations:train_async.pydid not havebefore_weight_update/after_weight_updatehooks to coordinate rollout and training weight synchronizationWhat's New
This PR introduces two new buffer policies for fully async rollout with comprehensive staleness control and partial rollout support:
1.
legacy_backpressure(staleness_partial mode)Inspired by VERL's fully async implementation, this policy:
2.
window_evict(window_partial mode)Inspired by MiniMax Forge's sliding-version-window eviction, this policy:
[current_version - W, current_version]Feature Comparison
legacy_backpressurewindow_evictPartial Rollout & Off-Policy Masking
When
--partial-rolloutis enabled:--mask-offpolicy-in-partial-rollout, off-policy tokens are masked during training loss computationLifecycle Hooks
Added
before_weight_update/after_weight_updatehooks totrain_async.pyandRolloutManager, enabling the async worker to:New CLI Arguments
--staleness-threshold--fully-async-buffer-policylegacy_backpressurelegacy_backpressureorwindow_evict.--fully-async-version-windowwindow_evict.--fully-async-max-completed-samples--fully-async-eviction-policydrop_oldest_versionwindow_evict.--fully-async-debug-version-trackingBenchmark Results
📊 Experiment Dashboard: wandb.ai/huang3eng-alibaba/slime-async-release
The benchmark script (
run-qwen3.5-4b-off-policy-benchmark.sh) demonstrates:staleness_partialandwindow_partialmodes show performance parity with the basefully_asyncmode while providing staleness/version controlQuick Start
Wandb Metrics
When enabled, the following metric groups are logged under a dedicated
fully_async/stepaxis:fully_async/count/*: stale samples processed, consumed, recycled, droppedfully_async/partial/*: partial rollout ratio and max version spanfully_async/window/*: completed store size, eligible samples, eviction countsFiles Changed
examples/fully_async/fully_async_rollout.py: Core async worker implementation with buffer policiesexamples/fully_async/run-qwen3.5-4b-off-policy-benchmark.sh: Multi-mode benchmark scriptexamples/fully_async/README.md: Comprehensive documentationtrain_async.py: Added lifecycle hooks integrationslime/ray/rollout.py: Addedbefore_weight_update/after_weight_updatehook forwarding inRolloutManagertests/test_fully_async_rollout.py: Unit tests for staleness control and version trackingtests/test_rollout_manager_fully_async_metrics.py: Tests for metrics loggingThis PR provides a flexible foundation for off-policy RL training with proper staleness control, enabling users to choose between backpressure-style control (VERL-inspired) and window-eviction-style control (Forge-inspired) based on their specific requirements.