[None][perf] Default Minimax-m3 to unified draft-target kv manager + change CI test to GQA eagle head - #17835
Closed
zheyuf wants to merge 6 commits into
Closed
Conversation
4 tasks
zheyuf
force-pushed
the
perf/minimax-m3-agg-shared-draft
branch
2 times, most recently
from
August 18, 2026 05:32
c9593c9 to
c1aa316
Compare
Signed-off-by: Zheyu Fu <zheyuf@nvidia.com>
Both arms now run Inferact/MiniMax-M3-EAGLE3-GQA, the head production
is moving to: same training data as the MHA head with the drafter's
attention changed from 64 to 4 KV heads, so its draft KV cache is 16x
smaller and matches the target's head count.
Measured on this branch (4-GPU node, InferenceMAX eval + the shared
chat-GSM8K acceptance probe):
aggregated (separate draft manager) 3.515 / 0.838, accuracy 95.45
disaggregated (unified sub-page view) 3.369 / 0.790, accuracy 95.15
3.395 / 0.798, accuracy 95.45
The aggregated figure is indistinguishable from the MHA card's GSM8K
reference (3.518 / 0.839), which is why that reference stands in for
the GQA card's missing GSM8K entry; the two cards agree on the
benchmark they do share (MT-Bench 2.698 vs 2.668). The disaggregated
arm measures ~0.14 lower, so the rate floor drops 0.78 -> 0.76 for
headroom while the length floor stays at 3.3 — still between the
measured healthy range and the 3.33 plateau a drafter-KV transfer
regression produced on this workload.
Signed-off-by: Zheyu Fu <zheyuf@nvidia.com>
(cherry picked from commit af6ddb1)
zheyuf
force-pushed
the
perf/minimax-m3-agg-shared-draft
branch
from
August 18, 2026 05:56
c1aa316 to
a4c7a91
Compare
Make graph exit depend on the latest mutation of every in-place target, including void side effects that are not reachable from the FX return value. This prevents an auxiliary-stream Eagle hidden-state capture from racing the graph-external speculative worker. Add a structural scheduler test covering the event and wait inserted before graph output. Signed-off-by: Zheyu Fu <zheyuf@nvidia.com>
Signed-off-by: Zheyu Fu <zheyuf@nvidia.com>
Signed-off-by: Zheyu Fu <zheyuf@nvidia.com>
Signed-off-by: Zheyu Fu <zheyuf@nvidia.com>
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.
Description
MiniMax-M3 target KV uses P128 pages while the Eagle3 drafter consumes P32 pages. The existing non-owning sub-page view bridges that geometry, so every supported MiniMax-M3 one-model speculative configuration can use the unified target KV manager instead of owning a separate draft cache.
This PR:
_should_create_separate_draft_kv_cachegeneric and identical to the base-branch policy; MiniMax-M3 selects unified KV through_allow_separate_draft_kv_cache = Falseduring executor creation.MiniMax-M3-EAGLE3-GQA.test_minimax_m3_unified_draft_view.pyis byte-for-byte unchanged fromfeat/m3_with_msa.test_m3_agg_shared_draft_routing.pyandtest_auto_multi_stream.pyare absent from the final tree and PR diff.Unified KV policy
_should_create_separate_draft_kv_cacheremains the generic base-branch logic:should_use_separate_draft_kv_cache(speculative_config).MiniMax-M3 sets
speculative_config._allow_separate_draft_kv_cache = Falsebefore manager construction, budget accounting, attention metadata, and worker creation. It therefore uses unified KV for every supported one-model configuration, including draft lengths other than 3. Tree decoding and SA enhancer are not supported MiniMax-M3 modes, so this PR adds no branches for them and does not change other models' policy.Root causes and fixes
1. Unreturned multistream side effect
inplace_slice_copyrecords Eagle hidden states by mutating a buffer on an auxiliary CUDA stream and returns no FX value. The original multistream DAG joined operations reachable through returned dataflow, but this void side effect was not reachable from the graph output. The compiled context callable could therefore return while the auxiliarycudaMemcpy2DAsyncwas still writing, and the graph-external speculative worker could read stale or partially updated hidden states.The generic fix makes graph exit depend on the latest mutation of every in-place target. The scheduler consequently inserts the event/wait before FX output. Target accuracy can remain healthy during this race because verification rejects bad drafts; acceptance length is the sensitive signal.
2. Grouped-HND draft KV transfer
The shared draft layer has a P128 physical allocation, but its P32 view consumes that storage as four independently head-major token groups: logically
[group=4, local_head, 32, head_dim]. In the failing route, TP2 context has two local KV heads while attention-DP generation has four.The old HND head-mismatch mapper emitted one contiguous head slice per physical K/V buffer, as if the draft bytes were ordinary
[local_head, 128, head_dim]. That selects the correct logical heads only in the first P32 group and scrambles subsequent groups. NIXL copied exactly the requested ranges, but the requested ranges were semantically wrong.The page table now carries a backward-compatible
hnd_token_groupsfield (default 1). MiniMax-M3 marks shared draft K/V as four groups, peer matching validates the value, and the HND mapper emits one descriptor per(layer, K/V, token group). Ordinary HND and NHD paths remain unchanged.Included #17514 and base-branch fixes
Commit
a4c7a91eis patch-equivalent to #17514 headaf6ddb12: both Eagle3 CI arms use the GQA drafter. #17514 remains open, but this PR supersedes it, so only #17835 needs to merge.The plain
test_nvfp4[use_msa=True-eval_mode=inferencemax]case has no speculative model and therefore has no drafter head to switch.#17656, including the
blocks_in_primary_poolcorrection, is already infeat/m3_with_msa. This branch is based on it and does not duplicate that fix. A direct A/B showed the corrected bound modestly helps acceptance; it did not cause the regression.Acceptance and accuracy evidence
All acceptance rows use the same 200-question chat-GSM8K probe, greedy decoding, and 512 generated tokens.
The ADP->ADP control is indistinguishable from the fixed TP->ADP route, so the TP/ADP numerical topology boundary is not a systematic disaggregated-acceptance deficit.
For a real 249-token prompt, the fixed TP-context pre-send draft-layer KV and ADP-generation post-receive KV were reconstructed by logical layer/head. All eight layer-60 tensors (K/V x four heads) were bitwise equal: identical SHA-256, exact fraction 1.0, and max absolute difference 0. The same proof passed for ADP->ADP. TP-context and ADP-context arithmetic does produce expected numerical differences for an individual prompt, but transfer before/after is exact and the full-workload control above shows no systematic AL penalty.
A 64-token versus 1024-token generation budget produced bitwise-identical prompt traces and comparable complete-window acceptance, eliminating generation KV capacity as the cause.
CI calibration
The default
/metricsbuffers retain only the latest 1000 iteration records. Under attention DP that is roughly the tail 500 engine iterations and can bias the sample toward whichever requests finish last.The test now:
> 0.80and mean acceptance length> 3.4.The old mapper fails both floors (
0.780 / 3.339); all fixed complete-window runs pass with clear headroom.Performance evidence
The strict one-hour TP4/C35 paired comparison changed only separate versus shared draft-KV lifecycle ownership:
Both arms passed strict postprocessing with
submission_valid=true,was_cancelled=false, zero runtime fatal signatures, zero context overflow, and zero OSL mismatch. The full optimized AgentX sweep completed all 14 one-hour TP2, TP4, and TP8 points with strict QC; 12 of 14 points lie on the new-stack Pareto envelope.Validation
0.842 / 3.525(Slurm 767807).0.83178 / 3.49535(767842).0.82884 / 3.48652; old0.780 / 3.339and correctly rejected.git diff --check, DCO sign-offs, and a conflict-free merge-tree against the latestfeat/m3_with_msapassed.PR checklist