Repository navigation
[Bugfix][SparseMLA] Fix piecewise cudagraph capture crash in index group - #56825
Merged
ZJY0516 merged 2 commits intoSep 15, 2026
Merged
Conversation
In piecewise cudagraph mode the sparse indexer runs inside a captured segment while SparseMLAIndexGroup._convert_once runs in the following eager break (unified_mla_attention_with_output is an eager break point). Recording logical_topk_ready inside the segment and waiting on it from the eager break hits cudaErrorInvalidValue, because an event recorded during stream capture is graph-local. Hybrid sparse-MLA models (e.g. GLM-5.3-Flash) capture decode batches piecewise and crashed at engine startup; non-hybrid models use FULL capture (record and wait both in-graph) and were unaffected. Skip the event in piecewise mode: set_logical_topk_ready does not record and _convert_once orders the side stream with wait_stream (identical to the existing has_indexer=False path). The same guard is applied to the HiSparse copy stream. Adds in_piecewise_cudagraph() to forward_context and a regression test covering record-in-segment + convert-in-eager-break under BreakableCUDAGraphCapture. Co-authored-by: Kimi Code <noreply@moonshot.ai> Signed-off-by: Jared Wen <jaredwen@inferact.ai>
JaredforReal
force-pushed
the
fix/mla-index-group-capture
branch
from
September 14, 2026 12:29
8cde071 to
771908b
Compare
ZJY0516
approved these changes
Sep 14, 2026
Member
|
/ci run |
ZJY0516
enabled auto-merge (squash)
September 14, 2026 12:49
|
✅ Triggered Buildkite CI #88820 for commit |
Member
|
/ci run |
|
✅ Triggered Buildkite CI #89001 for commit |
Contributor
Author
|
/ci retry |
|
✅ Queued 3 failed job(s) for retry in Buildkite CI #89001. |
1 task done
keneoneth
pushed a commit
to keneoneth/vllm
that referenced
this pull request
Sep 16, 2026
…oup (vllm-project#56825) Signed-off-by: Jared Wen <jaredwen@inferact.ai> Co-authored-by: Kimi Code <noreply@moonshot.ai>
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
Fix an engine-startup crash when a sparse-MLA model captures decode batches with piecewise cudagraphs (e.g. GLM-5.3-Flash, a hybrid KDA + sparse-MLA model):
Full startup traceback (4x GB300, TP4,
load_format=dummy; identical with real weights, the capture path does not read weights):Root cause
SparseMLAIndexGroupoverlaps the logical→physical topk conversion with the compute stream via thelogical_topk_readyevent: the indexer records it on the compute stream after computing topk, and_convert_oncewaits on it on the side stream.In piecewise cudagraph mode the indexer runs inside a captured graph segment, while the consumer runs in the following eager break (
unified_mla_attention_with_outputis an@eager_break_during_capturepoint, executed byadd_eager()after the segment'scapture_end()). An event recorded during stream capture is graph-local; waiting on it eagerly iscudaErrorInvalidValue.Minimal reproduction of the exact pattern (no vLLM involved):
Why only some models: FULL cudagraph capture (non-hybrid sparse MLA, e.g. DeepSeek-V3.2 decode) records and waits in-graph, which is legal; prefill-sized batches take the workspace-overflow branch of
_convert_once, which never touches the event. Hybrid models like GLM-5.3-Flash capture decode batches piecewise and hit the crash duringprofile_cudagraph_memory.Fix
In piecewise mode, skip the event entirely:
set_logical_topk_readydoes not record (a record inside a capture segment would be graph-local and unusable anyway), and_convert_onceorders the side stream withwait_stream(compute_stream)— identical to the existinghas_indexer=Falsepath, and correct because the convert is always invoked after the indexer on the same compute stream. FULL/eager modes keep the fine-grained event. The same guard is applied to the HiSparse copy stream. Addsin_piecewise_cudagraph()toforward_context.py.Tests
New regression test (record inside captured segment + convert in eager break under
BreakableCUDAGraphCapture); fails pre-fix atindex_group.py:133with the production error, passes post-fix:pytest tests/v1/attention/test_sparse_mla_backends.py -k piecewise_captureSparse MLA subset (convert / index_group / piecewise / hisparse): 47 passed
pytest tests/v1/attention/test_sparse_mla_backends.py -k "convert or index_group or piecewise or hisparse"E2E on 4x GB300, GLM-5.3-Flash real weights, TP4: engine starts with cudagraphs enabled (crashed at startup before), generation works.
Model evaluation
GSM8K, 5-shot, 1319 questions, GLM-5.3-Flash TP4 on 4x GB300 (this branch,
tests/evals/gsm8k/gsm8k_eval.py, no speculative decoding): 91.8% accuracy (invalid rate 0.0%).Notes
logical_topk_readyevent for the topk conversion (before it, the convert ran on the compute stream with no event). Verified empirically: its parent commit starts cleanly, it crashes at engine startup. Purely informational for locating the change — the piecewise interaction was easy to miss.