Skip to content

[Feature][Sleep] Preserve selected target and draft-private state across level-2 sleep - #18624

Open
Silas-Zeng wants to merge 4 commits into
vllm-project:mainfrom
Silas-Zeng:feature/port-sleep-wakeup-draft-state
Open

Silas-Zeng wants to merge 4 commits into
vllm-project:mainfrom
Silas-Zeng:feature/port-sleep-wakeup-draft-state

Conversation

@Silas-Zeng

@Silas-Zeng Silas-Zeng commented Oct 13, 2026 •

Copy link
Copy Markdown

What this PR does / why we need it?

Fixes #18641

Level-2 sleep discards weights, but a target-only weight update does not reload the draft model. This PR ports the following merged upstream changes to Ascend so selected target parameters and draft-private state survive this workflow:

The worker uses model_runner.get_draft_model() for MRV1 and MRV2, de-duplicates shared parameters, and restores saved parameters and buffers in place when waking weights. Snapshots remain available across KV-cache-only wakes and are cleared after tensor restoration succeeds.

Does this PR introduce any user-facing change?

Yes. Ascend now honors sleep_preserve_parameter_names during level-2 sleep, including draft.* for draft-private parameters. This allows users to retain selected weights while updating only the target model.

How was this patch tested?

Tested Qwen3-8B + DFlash serving with both MRV1 (VLLM_USE_V2_MODEL_RUNNER=0) and MRV2 on one Ascend 910B2 with CANN 9.1.

For each runner, generated a baseline response, ran sleep(level=2) → wake(weights) → target-only collective_rpc(reload_weights) → wake(kv_cache), then generated again. Both runs completed successfully with matching output, resumed draft generation, and /is_sleeping returning false.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces robust state preservation for Ascend NPU workers during level-2 sleep cycles. By porting upstream retention semantics, it ensures that critical target and draft model parameters and buffers are correctly snapshotted and restored, maintaining model state integrity across sleep and wake operations without disrupting existing allocator or cleanup flows.

Highlights

  • Parameter Preservation: Implemented logic to snapshot and restore selected target and draft-private parameters during level-2 sleep cycles.
  • Buffer Management: Extended snapshot and restore capabilities to include draft model buffers, ensuring state consistency across sleep and wake operations.
  • Parameter De-duplication: Added logic to de-duplicate shared parameters between target and draft models by object identity to prevent redundant storage.
  • Testing and Validation: Added comprehensive unit tests to verify parameter selection, buffer restoration, and lifecycle behavior, alongside hardware validation on Ascend 910B2.
New Features

🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@github-actions

Copy link
Copy Markdown
Contributor

👋 Hi! Thank you for contributing to the vLLM Ascend project. The following points will speed up your PR merge:‌‌

  • A PR should do only one thing, smaller PRs enable faster reviews.
  • Every PR should include unit tests and end-to-end tests ‌to ensure it works and is not broken by other future PRs.
  • Write the commit message by fulfilling the PR description to help reviewer and future developers understand.

If CI fails, you can run linting and testing checks locally according Contributing and Testing.


Tip

💡 Consider Linking a Related Issue or RFC

Your PR title contains the [Feature] tag, indicating a bug fix or new feature.

Linking a related issue or RFC in the PR description is strongly encouraged — it gives reviewers helpful context and speeds up the review. You can use any of these keywords:

  • Fixes #<issue_number>
  • Closes #<issue_number>
  • Resolves #<issue_number>
  • Refs #<rfc_or_issue_number> (for RFCs)

🙏 Thanks for helping us keep the project well-organized!

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Suggested PR Title:

[Ops][Feature] Support parameter and draft buffer preservation during sleep/wake cycles

Suggested PR Summary:

### What this PR does / why we need it?
This PR introduces parameter and draft buffer preservation during level-2 sleep and wake-up cycles in the NPU worker. It saves model parameters and draft model buffers to CPU memory before sleep and restores them upon wake-up, ensuring state preservation. It also adds comprehensive unit tests to verify these behaviors.

Feedback on the changes includes addressing a runtime AttributeError due to the use of non-existent is_cpu on PyTorch tensors, defensively handling missing get_draft_model attributes on the model runner, safely retrieving configuration patterns, and adding validation checks for missing parameters during wake-up.

### Does this PR introduce _any_ user-facing change?
No.

### How was this patch tested?
New unit tests were added in tests/ut/worker/test_sleep_wake_parameter_preservation.py and existing tests were updated.

Comment on lines +280 to +284
self._sleep_saved_parameters = {
name: parameter.detach().to("cpu")
for name, parameter in parameters.items()
if name in names and not parameter.is_cpu
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

In PyTorch, torch.Tensor (and nn.Parameter) does not have an is_cpu attribute. Attempting to access parameter.is_cpu will raise an AttributeError at runtime when saving sleep parameters. Check the tensor's device type instead using parameter.device.type != "cpu".

Suggested change
self._sleep_saved_parameters = {
name: parameter.detach().to("cpu")
for name, parameter in parameters.items()
if name in names and not parameter.is_cpu
}
self._sleep_saved_parameters = {
name: parameter.detach().to("cpu")
for name, parameter in parameters.items()
if name in names and parameter.device.type != "cpu"
}

Comment on lines +251 to +252
def get_draft_model(self) -> nn.Module | None:
return self.model_runner.get_draft_model()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Defensively check if self.model_runner implements get_draft_model before calling it. This prevents potential AttributeError crashes if a custom or mocked model runner is used.

Suggested change
def get_draft_model(self) -> nn.Module | None:
return self.model_runner.get_draft_model()
def get_draft_model(self) -> nn.Module | None:
get_draft_model_fn = getattr(self.model_runner, "get_draft_model", None)
if get_draft_model_fn is not None:
return get_draft_model_fn()
return None

Comment thread vllm_ascend/worker/worker.py
Comment thread vllm_ascend/worker/worker.py Outdated
Comment on lines +286 to +291
@torch.no_grad()
def _restore_sleep_parameters(self, model: nn.Module) -> None:
parameters = self._get_sleep_parameters(model)
for name, value in self._sleep_saved_parameters.items():
parameters[name].copy_(value)
self._sleep_saved_parameters.clear()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Add a check to ensure that all saved parameters are present in the model during wake-up, raising a descriptive RuntimeError if any are missing. This is consistent with how model and draft buffers are handled and prevents cryptic KeyError crashes.

Suggested change
@torch.no_grad()
def _restore_sleep_parameters(self, model: nn.Module) -> None:
parameters = self._get_sleep_parameters(model)
for name, value in self._sleep_saved_parameters.items():
parameters[name].copy_(value)
self._sleep_saved_parameters.clear()
@torch.no_grad()
def _restore_sleep_parameters(self, model: nn.Module) -> None:
parameters = self._get_sleep_parameters(model)
missing = set(self._sleep_saved_parameters) - set(parameters)
if missing:
raise RuntimeError(f"Saved model parameters are missing during wake-up: {sorted(missing)}")
for name, value in self._sleep_saved_parameters.items():
parameters[name].copy_(value)
self._sleep_saved_parameters.clear()

@Silas-Zeng
Silas-Zeng marked this pull request as draft October 13, 2026 17:33
@github-actions

Copy link
Copy Markdown
Contributor

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@Silas-Zeng
Silas-Zeng marked this pull request as ready for review October 13, 2026 20:30
@Silas-Zeng
Silas-Zeng force-pushed the feature/port-sleep-wakeup-draft-state branch from 9bdd5e5 to 2561108 Compare October 13, 2026 21:35
Silas-Zeng and others added 3 commits October 14, 2026 05:36
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Signed-off-by: Silas-Zeng <1784012765@qq.com>
@Silas-Zeng

Copy link
Copy Markdown
Author

Hi @Ronald1995, could you take a look at this sleep/wake change, or help route it to the appropriate reviewer?

I encountered this issue during RL rollout. This PR ports upstream #57891 and #61046 to Ascend, preserving selected target parameters and draft-private state across level-2 sleep and target-only weight updates.

I validated Qwen3-8B + DFlash on Ascend 910B2 with both MRV1 and MRV2; the workflow and results are described above. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: 支持在二级休眠中保留指定参数及草稿模型私有状态

1 participant