Repository navigation
[Fix] [NVIDIA] minimax-m3: Enable EAGLE3 verification on CUDA - #43804
thanhhao98 wants to merge 5 commits into
Conversation
TARGET_VERIFY reaches the sparse layers' forward_extend, which builds prefill metadata from extend_seq_lens. Verify batches carry none, so EAGLE3 fails at the FlashInfer autotune warm-up on CUDA. ROCm already runs a linear draft chain through the sparse decode kernels, one causal row per draft token; run that path on every non-NPU GPU, for EAGLE chains only (draft_is_chain_layout). The CUDA verify graph also took its score-buffer bound from the 1-token capture dummies, so replay at a real context would write past the buffer. Bound verify capture by the context length on every platform and count the draft rows in the eager bound. Rows past the context length are never committed; clamp them so the bound, and with it the decode top-k register bucket, stays at the context length. Verify rows skip MSA decode, whose plan covers decode batches only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@nvpohanh could you pls help to review this, thanks! |
nvpohanh
left a comment
There was a problem hiding this comment.
[by Claude Code] This review is done by agents. Please feel free to disagree if they do not make sense.
[by Claude Code] Severity: style | Confidence: High
Issue
The Accuracy Tests and Speed Tests sections give the model, GPUs, TP, image, and EAGLE3 settings, but no commands. Others cannot rerun the GSM8K, passkey, or TPOT numbers.
Fix
Add the exact server launch commands for the no-spec and EAGLE3 arms, the GSM8K and passkey eval commands, and the benchmark command behind the bs=1 TPOT table, including input/output lengths and how the prompt was cached.
…nd the ROCm verify test bound
|
These PRs should be reviewed first in the M3 PR series:
They will help to improve the performance. |
Motivation
MiniMax-M3 with an EAGLE3 draft does not start on CUDA: TARGET_VERIFY reaches the sparse layers'
forward_extend, which needs theextend_seq_lensthat verify batches lack, so the warm-up fails withAttributeError: 'NoneType' object has no attribute 'device'. #41497 fixed ROCm by verifying a linear draft chain with the sparse decode kernels, one causal row per draft token, but every gate it added isis_hip. This PR covers TP, not DP attention.Modifications
forward_extendhands verify toforward_decodeon a shallow copy, one row per draft token, so the dense layers keep their per-request metadata and the draft KV is stored once._init_rocm_linear_verify_metadatabecomes_init_linear_verify_metadata; the ROCm test only follows the rename.topk == 1) via the existingdraft_is_chain_layout; tree drafts and other algorithms raiseNotImplementedErrorat startup. ROCm keeps its rule: any draft withtopk == 1.bs × ndtrows._decode_score_kerneloverruns at replay); the eager bound counts the draft rows.context + ndt: those rows predict positions that are never committed (the scheduler capsmax_new_tokensbelow the context length and trims over-accepted drafts), and at 1M context the decode top-k stays in its 8192 register bucket.Accuracy Tests
MiniMax-M3-NVFP4, 4x GB300, TP4, 1M context, thinking enabled,
SGLANG_DISABLE_MSA=1,lmsysorg/sglang:nightly-dev-cu13-20261012-e6072935+ this patch; EAGLE3Inferact/MiniMax-M3-EAGLE3-GQA(3 steps, topk 1, 4 draft tokens, unquantized draft), real verification.--parallel 1(bs=1 decode graph)test_minimax_linear_verify.py(CUDA, H100 and B200 CI; MSA decode on, so verify must stay on Triton) compares verify rows with the same rows decoded alone: eager at prefixes 1000 and 5118 (crosses a block boundary) is bit-exact; a graph captured on 1-token dummies, replayed with one request two tokens short of a 64K context, matches inside the context and clamps rows past it.Speed Tests and Profiling
Mean TPOT at bs=1 (prompt cached, 256 output tokens, real acceptance), same build, one GB300 tray per arm:
Reproduce
Server, on
lmsysorg/sglang:nightly-dev-cu13-20261012-e6072935with this PR, 4× GB300 (the no-spec arm drops the--speculative-*flags):GSM8K (5-shot):
python3 -m sglang.test.few_shot_gsm8k --num-shots 5 --num-questions 1319, and--num-questions 40 --parallel 1for the bs=1 row.Passkey: one chat request per size whose prompt is filler text with a random 5-digit key at two thirds depth, sized to 131K / 524K / 990K tokens with the server's chat template; pass when the key is in the answer. bs=1 TPOT: on the same server, a follow-up "count upward" turn on that cached conversation, 256 tokens with
ignore_eos; the 8K row warms an 8K prefix first.Checklist
CI States
Latest PR Test (Base): ❌ Run #40291392525
Latest PR Test (Extra): ❌ Run #40291392550
Latest PR Test (AMD ROCm 10): ❌ Run #40291392514