[Bugfix][Structured Output][Spec Decode] Fix async grammar bitmask alignment after draft trimming - #49738
[Bugfix][Structured Output][Spec Decode] Fix async grammar bitmask alignment after draft trimming#49738yanghui1-arch wants to merge 17 commits into
Conversation
Signed-off-by: dass90 <3053034939@qq.com>
|
cc @WoosukKwon @njhill @benchislett @yewentao256 @orozery |
|
@mgoin Can you review my PR? Thanks |
|
@ivanium Do you have free time to review my PR? Thanks a lot |
|
@yewentao256 @njhill Can you take a look this PR? Thanks |
|
Please take a look. Thanks for your review. @ApostaC @robertgshaw2-redhat |
|
@chaunceyjiang Can you help review this pr? Thanks |
|
This might need a review from @benchislett. |
|
Hi, can you help review this PR? Thanks for your help. @benchislett |
ok. Thanks |
|
Can you help review this pr? Thanks @yewentao256 |
yewentao256
left a comment
There was a problem hiding this comment.
Thanks for the work! I think @benchislett would be the best person to review this PR
|
Can you help review this pr? Thanks.... @benchislett |
|
cc @benchislett |
|
cc @benchislett |
|
Please take a look @benchislett |
|
Hello, please take a look @benchislett |
Related MTP async validation and a complementary alignment pathI completed an async structured-output stress run on MTP-3 that may be useful for this PR's test matrix. This is not a test of the PR branch: my local stack used a different but complementary scheduler-side change. The distinction as I understand it:
With that local behavior plus the reasoning-boundary and XGrammar termination fixes:
The approaches appear complementary because worker-side ngram/drafter trimming can still occur independently of grammar validation. Before proposing a separate MTP change, I plan to test four arms on current main: main, #49738, raw-draft preservation, and both together. If #49738 alone covers the MTP failure, I will not open another PR; otherwise I will document the materially different invariant and keep the follow-up narrowly scoped. Disclosure: AI-assisted analysis and comment posting; the runs and measurements were produced and verified by me on the hardware described. |
Purpose
Fixes #49694.
With async scheduling,
ngram_gpucan cause the engine core and model runner to observe different speculative-token lengths for the same request. The model runner trims invalid draft slots based on the GPU-side n-gram result, while the engine core constructs the structured-output grammar bitmask using the original scheduled span.Root cause
apply_grammar_bitmaskpreviously used the model runner's trimmed draft lengthfor both:
When a request's drafts were trimmed, the source offset became incorrect. Consequent requests in the same batch could receive bitmask rows belonging to the previous request, allowing grammar-invalid draft tokens to pass speculative verification. This explains why the failure rate increased with concurrency.
How does PR work
This PR records the engine core's per-request speculative-token count in
GrammarOutputand uses it to advance through the source grammar bitmask. Worker-side lengths are still used to locate the actual logits, keeping draft and bonus-token rows correctly aligned when the two lengths differ.Test Plan
Run the same structured-output serving workload before and after the fix using Qwen3.6-35B-A3B-FP8 with async scheduling, the
xgrammarbackend, andngram_gpuspeculative decoding with three speculative tokens.The reproduction script is available here.
Test Result
The following table compares the overlapping concurrency levels from the reproduction before the fix and the same workload after the fix.
After the fix, all 1,280 requests completed without HTTP, transport, or internal errors. All outputs had the expected constrained length of 225 characters, with no wrong or truncated outputs.