[BugFix][Mamba] Overlap-safe state copies for align-mode block moves - #15592
[BugFix][Mamba] Overlap-safe state copies for align-mode block moves#15592Liears wants to merge 3 commits into
Conversation
Summary of ChangesHello, 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 addresses critical data corruption issues occurring during Mamba state moves on the NPU path. By introducing overlap-safe copy mechanisms and adding necessary synchronization barriers in the Triton kernels, the changes resolve race conditions that previously led to intermittent kernel crashes and memory corruption. These fixes restore stability for complex concurrent workloads and prefix caching scenarios. Highlights
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 AssistThe 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
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 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
|
The NPU path bound the upstream pointer-based collect_mamba_copy_meta and executed align-mode state moves through the Ascend triton batch_memcpy port, which dropped upstream's is_left_overlap guard. Same-pool moves can have overlapping src/dst ranges; without the guard the kernel is a program-order race whose corruption lands in the KV/mamba pools and is consumed by later kernels (drifting faulting-kernel signature, delayed manifestation, block-reuse dependence - the EZ9999 'MTE accesses an invalid GM address' family). Fix: collect tensor pairs alongside the pointer buffers (bind the torch collector on the NPU path) and copy via dst.copy_(src.clone()) - memmove semantics identical to upstream's guarded kernel. GLM53_BATCH_MEMCPY=1 restores the raw pointer kernel for A/B. Also add the upstream is_left_overlap + debug_barrier guard to the fused postprocess copy loops (defensive; today's conv shift fits one load-then-store block). Verified on GLM-5.3-Flash (hybrid KDA + spec=3 + align mode, TP8): the previously-100%-reproducible second-round block-reuse crash matrix (33.5k+15k concurrent, 3-way concurrent, 2000-token decode) passes with prefix caching enabled. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Liears <liears@users.noreply.github.com>
|
👋 Hi! Thank you for contributing to the vLLM Ascend project. The following points will speed up your PR merge:
If CI fails, you can run linting and testing checks locally according Contributing and Testing. Tip 💡 Consider Linking a Related Issue or RFCYour PR title contains the [BugFix] 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:
🙏 Thanks for helping us keep the project well-organized! |
There was a problem hiding this comment.
Code Review
This pull request introduces overlap-safe state copies for Mamba block moves on Ascend NPUs by adding overlap guards and debug barriers in the Triton postprocess kernel, and implementing a fallback tensor-pair copy path using PyTorch's clone and copy operations to handle overlapping memory ranges safely. Feedback on the changes highlights a critical correctness bug in the CPU fallback path where using input_batch.num_accepted_tokens_cpu instead of num_accepted_tokens_cpu_tensor ignores actual GPU accepted counts and risks using stale data. Additionally, the reviewer noted a style guide violation regarding the PR title and summary format, providing the correct compliant templates.
| # fallback consumes the snapshot. Keep this step's accepted counts | ||
| # independent from those mutable request rows. | ||
| num_accepted_tokens = num_accepted_tokens_cpu_tensor | ||
| num_accepted_tokens = input_batch.num_accepted_tokens_cpu |
There was a problem hiding this comment.
Critical Correctness Bug: Incorrect Accepted Tokens Used in CPU Fallback
In _postprocess_mamba_align_gpu_cpu_fallback, num_accepted_tokens has been changed to use input_batch.num_accepted_tokens_cpu instead of num_accepted_tokens_cpu_tensor.
This is a critical bug because:
num_accepted_tokens_cpu_tensoris the tensor that receives the actual accepted token counts copied from the GPU (num_accepted_tokens_gpu). By usinginput_batch.num_accepted_tokens_cpu, the actual accepted counts from the GPU are completely ignored, and stale/incorrect values are used instead.- As the deleted comment warned,
input_batchrows may be condensed or reused by async scheduling before this fallback runs, makinginput_batch.num_accepted_tokens_cpumutable and unsafe to use.
This will cause incorrect state copying and potential state corruption on 310P devices where this CPU fallback path is executed. Please revert this change to use num_accepted_tokens_cpu_tensor.
| num_accepted_tokens = input_batch.num_accepted_tokens_cpu | |
| num_accepted_tokens = num_accepted_tokens_cpu_tensor |
| # mypy: ignore-errors | ||
|
|
||
| import itertools | ||
| import os |
There was a problem hiding this comment.
Style Guide Violation: PR Title and Summary Format
The current Pull Request title and summary do not adhere to the repository's style guide. Specifically:
- The PR title format should be
[Branch][Module][Action] Pull Request Title. The current title[BugFix][Mamba] ...places the Action before the Module, and uses an invalid Module[Mamba]instead of[Ops]. - The PR summary should follow the specified markdown template.
Below are the suggested PR Title and PR Summary formatted according to the style guide:
Suggested PR Title:
[Ops][BugFix] Overlap-safe state copies for align-mode block movesSuggested PR Summary:
### What this PR does / why we need it?
This PR fixes a potential data corruption and crash issue (EZ9999) in the Mamba state copy path on Ascend NPUs. The Triton-based `batch_memcpy` port dropped the upstream `is_left_overlap` guard, which is unsafe for same-pool moves with overlapping src/dst ranges.
To fix this, the PR:
1. Binds the torch-based collector on the NPU path to collect tensor pairs and performs copies via `dst.copy_(src.clone())` to ensure safe memmove semantics.
2. Adds the `is_left_overlap` check and `tl.debug_barrier()` guard to the fused postprocess copy loops.
### Does this PR introduce _any_ user-facing change?
No.
### How was this patch tested?
Verified with GLM-5.3-Flash (hybrid KDA + spec=3 + align mode, TP8) under concurrent high-context decode and prefix caching scenarios.References
- The Pull Request Title must follow the format '[Branch][Module][Action] Pull Request Title'. The current title '[BugFix][Mamba] ...' violates this format by placing the Action before the Module, and using an invalid Module '[Mamba]' instead of '[Ops]'. (link)
| # fallback consumes the snapshot. Keep this step's accepted counts | ||
| # independent from those mutable request rows. | ||
| num_accepted_tokens = num_accepted_tokens_cpu_tensor | ||
| num_accepted_tokens = input_batch.num_accepted_tokens_cpu |
There was a problem hiding this comment.
This replaces the CPU snapshot (copied before the fallback runs) with a direct read of input_batch.num_accepted_tokens_cpu - the removed comment warned that input_batch rows can be condensed/reused by async scheduling before this fallback consumes them. Is the new field guaranteed to hold this step's values?
There was a problem hiding this comment.
Good catch — no, it is not guaranteed. Async scheduling can condense/reuse input_batch rows before this fallback consumes them, so reading the live field was wrong.
Fixed in 87906e2: the fallback now reads the per-step snapshot staged into num_accepted_tokens_cpu_tensor (copied from the GPU accepted counts right above), which is the same source of truth the fused kernel consumes. The preprocess_mamba reads of input_batch.num_accepted_tokens_cpu are untouched — those run before the scheduler can mutate the rows, matching upstream semantics.
The fallback read input_batch.num_accepted_tokens_cpu directly, but async scheduling can condense/reuse input_batch rows before the fallback consumes them, so the live field is not guaranteed to hold this step's values. The snapshot staged into num_accepted_tokens_cpu_tensor (copied from the GPU accepted counts just above) is the per-step source of truth the fused kernel also uses. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Liears <liears@users.noreply.github.com>
Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Liears <liears@users.noreply.github.com>
Problem
The NPU path binds upstream's pointer-based
collect_mamba_copy_metaand executes align-mode mamba state moves through the Ascend tritonbatch_memcpyport, which dropped upstream'sis_left_overlapguard (vllm/v1/worker/mamba_utils.py:639-652). Same-pool moves can have overlapping src/dst ranges; without the guard the kernel is a program-order race whose corruption lands in the KV/mamba pools and is consumed by later kernels — the EZ9999 "MTE accesses an invalid GM address" crash family:Fix
dst.copy_(src.clone())— memmove semantics identical to upstream's guarded kernel.GLM53_BATCH_MEMCPY=1restores the raw pointer kernel for A/B.is_left_overlap+tl.debug_barrier()guard to the fused postprocess copy loops (defensive; today's conv-state shift fits in a single load-then-store block iteration, so it is safe by construction).Verification (GLM-5.3-Flash, hybrid KDA + spec=3 + align mode, TP8)
🤖 Generated with Claude Code