Skip to content

[Core] Make sleep a pure memory-state transition - #53082

Draft
aoshen02 wants to merge 1 commit into
vllm-project:mainfrom
aoshen02:feat/sleep-pause-layering
Draft

[Core] Make sleep a pure memory-state transition#53082
aoshen02 wants to merge 1 commit into
vllm-project:mainfrom
aoshen02:feat/sleep-pause-layering

Conversation

@aoshen02

Copy link
Copy Markdown
Collaborator

Implements the end state of RFC #51476 §4 ("sleep/pause layering"). Draft, and deliberately breaking — posted as the concrete artifact for the RFC discussion; whether it lands directly or behind a deprecation cycle is exactly the feedback being sought there.

Purpose

sleep was born pure — #12987 introduced it as a memory-state transition only — and became entangled later: #33195 routed level 0 through pause_scheduler(), #34528 completed today's shape, sleep(level, mode) = pause_scheduler(mode) + executor.sleep(level). The entanglement has concrete costs:

  • sleep answers "what happens to the requests" — a question that belongs to pause — through a duplicated mode vocabulary with a policy default (abort). LLM.sleep's own docstring has always said "The caller should guarantee that no requests are being processed during the sleep period" — the contract was layered from day one; the implementation just started answering the question on the caller's behalf.
  • The standard RL flow pause → weight sync → sleep runs the DP quiescence consensus twice; the second run kick-starts every rank for up to 32 dummy forwards (~3.4 s measured; [Core] Sync DP state on the first step of a wave #52957 cuts it to ~0.2 s — mitigation, not removal). This PR removes it entirely: sleep no longer runs any consensus.
  • The internal re-pause cannot be guarded with "already paused → skip": the guard would read a local snapshot of a global in-flight property, and ranks landing on opposite sides of the consensus flip deadlock the gloo rendezvous. Which is why the only clean fix is the one below.

Change

Deleted (the core of the PR):

  • EngineCore.sleep loses the mode parameter, the internal pause_scheduler call, and the pause-future chaining. It is now: precondition check → _reset_caches()executor.sleep(level). Returns None, never a Future — nothing asynchronous is left.
  • mode is deleted from the whole client chain (LLM, LLMEngine, AsyncLLM, EngineClient protocol, all EngineCoreClient variants) and from the /sleep HTTP endpoint.
  • sleep(level=0) (a pause alias) loses its meaning; callers use pause_generation().

Added (what makes the deletion safe and usable):

  • The precondition: sleep raises EngineNotPausedError unless a pause has completed (is_scheduler_paused() and not has_work(); on DP, engines_running also rejects a pause whose consensus is still in flight, so kick-started ranks can never release memory early). A raise is distributively safe where a skip is not: a failed check never enters a collective — every rank either proceeds into the same protocol or errors out to the client as a retryable failure.
  • A pause door for the offline stack, which previously had no pause entry point at all: LLM.pause_generation() / LLM.resume_generation()LLMEngine → sync clients (InprocClient, SyncMPClient). Pure forwarders to the existing engine-side pause_scheduler / resume_scheduler; no new policy.

Migration (breaking surface):

before after
llm.sleep(level=1) llm.pause_generation() then llm.sleep(level=1)
llm.sleep(level=1, mode="keep") llm.pause_generation(mode="keep") then llm.sleep(level=1)
llm.sleep(level=0) / wake_up(tags=["scheduling"]) llm.pause_generation() / llm.resume_generation()
POST /sleep?level=1 POST /pause then POST /sleep?level=1
AsyncLLM.sleep(level, mode) pause_generation(mode=...) then sleep(level)

wake_up is unchanged: a full wake still resumes the scheduler; partial wakes still keep it paused. All in-tree callers (benchmarks/throughput.py prequeue, docs, and every sleep test) are migrated in this PR.

Test Plan

Three unit tests (no GPU): sleep on an un-paused engine raises and never touches the executor; sleep on a paused engine releases memory without touching request state (finish_requests / set_pause_state not called); sleep during an in-flight DP pause consensus (kick-started engines_running) is refused.

One DP e2e test: un-paused sleep is refused through the RPC chain; pause → sleep → wake → generate completes cleanly on DP=2+EP.

Regression: tests/v1/distributed/test_async_llm_dp.py -k "dp_pause or dp_sleep or prefill_schedule" (the existing pause/sleep suite, including the late-request pair from #51481, migrated to the explicit flow).

python -m pytest tests/v1/engine/test_engine_core.py -k sleep -v
python -m pytest tests/v1/distributed/test_async_llm_dp.py -k "dp_pause or dp_sleep or prefill_schedule" -v

Test Result

vllm/vllm-openai:nightly (2026-08-20 build), 2×H200 (this diff patch -p1-ed into site-packages, branch tests/ mounted):

suite result
test_engine_core.py -k sleep (3 new unit tests) 3 passed
test_async_llm_dp.py -k "dp_pause or dp_sleep or prefill_schedule" (12 migrated existing + 1 new e2e) 13 passed

Essential Elements

sleep() no longer embeds request-fate policy: the internal
pause_scheduler call, the mode parameter, and the pause-future
chaining are removed. Sleep now requires a completed pause and
raises EngineNotPausedError otherwise; pause_generation() /
resume_generation() are exposed on the offline LLM stack, which
previously had no pause entry point. Implements the layering
proposed in RFC vllm-project#51476.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

Signed-off-by: aoshen02 <aoshen@inferact.ai>
@mergify

mergify Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Documentation preview: https://vllm--53082.org.readthedocs.build/en/53082/

@mergify mergify Bot added documentation Improvements or additions to documentation frontend multi-modality Related to multi-modality (#4194) performance Performance-related issues labels Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation frontend multi-modality Related to multi-modality (#4194) performance Performance-related issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant