fix(rollout): pause generation before releasing offload memory#2015
Open
EazyReal wants to merge 2 commits into
Open
fix(rollout): pause generation before releasing offload memory#2015EazyReal wants to merge 2 commits into
EazyReal wants to merge 2 commits into
Conversation
f79613b to
5fd0e13
Compare
5fd0e13 to
f42364b
Compare
Contributor
Author
|
@zhuzilin could you review this one? It fixes a rollout offload race by making offload own the quiescence invariant: pause all engines and wait, flush all and wait, then release memory. I checked current verl: SGLang sleep/wake uses replica/server awaits; torch distributed barriers remain in backend weight/update paths where all ranks participate, which matches the layering here. |
bca9b24 to
1d59d18
Compare
# Conflicts: # slime/ray/rollout.py
1056161 to
e2bd101
Compare
Contributor
Author
|
@zhuzilin refreshed on latest main and checks are green. This pauses generation and flushes cache before releasing offload memory, then resumes generation after KV/CUDA graph onload; it reduces unsafe offload while requests are active. Could you review when you have bandwidth? |
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 changed
RolloutServer.offload()is now a three-phase quiescence transition across all offloaded engine groups: pause every engine and wait, flush every engine and wait, then release memory.RolloutServer.onload_kv()restores KV-cache/CUDA-graph memory before issuingcontinue_generation(). The newServerGrouphelpers keep the existing non-blocking Ray ObjectRef shape and skipneeds_offload=Falsegroups, matchingoffload()/onload().Why
offload()previously calledrelease_memory_occupation()without first making the rollout engines quiescent. The default rollout function is mostly safe today because it aborts in-flight requests until the server reports idle before returning, but that guarantee lives in the rollout function rather than at the offload boundary. A custom--rollout-function-pathor a multi-turn client paused between turns can return with pending work. In that state, the flush insiderelease_memory_occupation()can either spin untilTimeoutError("Timeout while flushing cache."), or it can succeed during a transient idle window while a newly admitted request races with memory release.Pausing first makes the offload boundary own the invariant: no new generation is admitted, all current generation is drained, and only then is memory released.
Coordination model
This PR uses Ray phase barriers at the rollout-manager boundary: all pause RPCs are acknowledged before any flush RPC is issued, and all flush RPCs are acknowledged before any release RPC is issued. That is the right layer for this transition because rollout offload/onload is driven by
RolloutManager, not by all Megatron ranks participating in a collective.This matches the current verl SGLang shape: SGLang sleep/wake is coordinated by awaiting the rollout server calls across replicas, while explicit
torch.distributedbarriers are used in backend paths such as TRT-LLM resume/update where all distributed training ranks participate and non-leader ranks may still be offloading. slime already uses that distributed-barrier pattern in the actor-side weight-update paths (update_weight_from_tensor.py,update_weight_from_distributed.py,update_weight_from_distributed_delta.py). This PR keeps those existing rank collectives in the weight-update layer and adds the missing rollout-engine phase barrier where the offload race occurs.Validation
uv run --no-project --with pytest --with requests --with pyyaml python -m pytest tests/test_rollout_offload_coordination.py -qpython3 -m py_compile slime/ray/rollout.py tests/test_rollout_offload_coordination.pygit diff --check upstream/main...HEADuv run --no-project --with jinja2 python .github/workflows/generate_github_workflows.pyleaves the generated workflow unchanged.