[None][feat] Page the DSpark drafter context through the draft KV cache manager - #18343
[None][feat] Page the DSpark drafter context through the draft KV cache manager#18343dc3671 wants to merge 1 commit into
Conversation
ab3b1c0 to
6f5df55
Compare
bd30278 to
3c6afb9
Compare
|
PR_Github #71140 [ run ] triggered by Bot. Commit: |
|
/bot run --stage-list "GB300-8_GPUs-2_Nodes-PyTorch-SingleNvlinkDomain-Post-Merge-1" |
|
PR_Github #71146 [ run ] triggered by Bot. Commit: |
|
PR_Github #71140 [ run ] completed with state |
|
PR_Github #71146 [ run ] completed with state
|
|
The new GB300 test was selected in L0 #58288 but failed before executing GSM8K: |
@ZhanruiSunCh Yes, I've added it in llm-models two days ago. But it seems hasn't been synced yet. |
|
[by Codex] @yizhang-nv Could you review this PR? Thanks! |
|
/bot run --stage-list "GB300-8_GPUs-2_Nodes-PyTorch-SingleNvlinkDomain-Post-Merge-1" |
|
PR_Github #71537 [ run ] triggered by Bot. Commit: |
|
PR_Github #71538 [ run ] triggered by Bot. Commit: |
|
PR_Github #71537 [ run ] completed with state |
|
PR_Github #71538 [ run ] completed with state
|
eb07ced to
6a4e7b0
Compare
|
/bot run --stage-list "GB300-8_GPUs-2_Nodes-PyTorch-SingleNvlinkDomain-Post-Merge-1" |
|
PR_Github #71828 [ run ] triggered by Bot. Commit: |
|
PR_Github #71828 [ run ] completed with state
|
yizhang-nv
left a comment
There was a problem hiding this comment.
Approving to unblock main: the disagg-gen slot collapse (AL 1.09) needs to land now,
and the arena sizing fixes are strictly better than what we have.
One note for the record, not blocking: we plan to remove the separate draft KV cache
manager entirely, and this PR makes it the memory owner of the drafter ctx cache and
adds disagg / attention-DP as new consumers of it. When that removal happens the
drafter will fall back to the dense arena unless we move first.
The direction I'd like to take in a follow-up is to append the drafter's L layers to
the unified target manager, the way MTP/Eagle3 already do via
_build_per_layer_num_kv_heads (external drafters only lack this because
get_num_spec_layers returns 0 for them). get_buffers(layer_offset + i, "HND")
gives the same per-layer view you bind today, the block table is
kv_cache_block_offsets directly, and the transceiver would carry those layers to
the disagg gen worker, giving the drafter prompt context instead of an empty slot —
which should close the 3.44 vs 4.32 AL gap. Happy to sync on that separately.
…he manager The standalone drafter kept a private context arena, dense in max_seq_len and allocated after the KV pool had been carved, so free_gpu_memory_fraction never bounded it: at max_seq_len 997696 with max_batch 8 it wants 21.4 GiB/rank and the worker cannot start. Read the already-funded draft pool through the manager's per-request block tables instead, so the footprint follows the sequences served, and size what remains from max_seq_len rather than the drafter's advertised max_position_embeddings (1048576 for K3, hundreds of GiB on its own). The pool index space differs between the V1 and V2 managers, so the block-table divisor is derived from stride(0) rather than assumed. Three gates kept an external drafter off that path, each written for a mode it does not describe: - attention DP: the bail suits MTP, whose draft layers are target-shaped and appendable to the target pool. An external drafter has its own architecture, so nothing is appended and it stayed on the arena -- which under attention DP is sized with KV heads unsharded (20480 vs 2560 B/token for K3). - disaggregation: nvbugs/5807902 reported an Eagle3 RMSNorm failure and was worked around by disabling the separate draft KV cache for every speculative mode. Keep the workaround where it was reported. - disagg slot allocation: _store_prefill_context was the only place that assigned a drafter slot, so a generation worker -- which receives prompt KV instead of prefilling -- collapsed every concurrent request onto the single dummy slot. A context-only worker also releases the target's IndexMapper slot after prefill; the draft mirror never got that call and saturated. Accuracy cannot detect a broken drafter: speculative decoding is lossless, so one producing garbage scores the same and only runs slower. The added test therefore asserts on acceptance length. That is not hypothetical -- the slot collapse showed up as AL 1.087 vs 3.441 (decode steps 123860 -> 39072 for the same output length) while every accuracy gate passed. Signed-off-by: Zhenhuan Chen <zhenhuanc@nvidia.com>
6a4e7b0 to
43befee
Compare
|
/bot run --stage-list "GB300-8_GPUs-2_Nodes-PyTorch-SingleNvlinkDomain-Post-Merge-1" |
|
PR_Github #71928 [ run ] triggered by Bot. Commit: |
|
PR_Github #71928 [ run ] completed with state |
|
/bot run |
|
PR_Github #71946 [ run ] triggered by Bot. Commit: |
|
PR_Github #71946 [ run ] completed with state
|
Description
The standalone DSpark/DFlash drafter kept its context KV in a private arena: dense in
max_seq_len, allocated after the KV pool was carved (sofree_gpu_memory_fractionnever bounded it), and sized frommax_position_embeddings(1048576 for K3). This pages it through the draft KV cache manager's per-request block tables instead.max_seq_lenmax_position_embeddingsmax_seq_lenThree gates kept an external drafter off that path, each written for a mode it does not describe:
_util.pyattention-DP bailpy_executor_creator.pynvbugs/5807902 WARTrue); standalone drafters exemptdflash.pyslot assignmentrelease_index_slotmirrored to the draft managerV1
get_buffers()returns a per-layer strided slice, V2 a dense view over interleaved pages, so the block-table divisor is derived fromstride(0). Guessing wrong is silent: ~20% acceptance, no error.Test Coverage
TestKimiK3DSpark::test_gsm8k_tep8, on the 2x4 GB300 post-merge stage from #18363 (l0_gb300_multi_nodes_node2_gpu8.yml). ItsSingleNvlinkDomainname forces--segment=2; straddling two NVL domains dies insymm_mem.rendezvous.Spec dec is lossless, so accuracy cannot detect a broken drafter — hence the AL assertion. That is how the slot collapse was found:
Measured on this branch, 8x GB300, 1319 samples, three runs. Target is the NVFP4 requant (nothing else covers K3 NVFP4 end to end), which also fixes the MoE backend: trtllm-gen ships SiTu cubins only for
W4A8_MXFP4_MXFP8.Not about this change, but this is the first real-model accuracy data on
MEGAMOE_CUTEDSL: it lands ~1.0 pt below CUTLASS on identical weights and is not reproducible across greedy runs (0.23 pt spread). AL is flat at 4.32-4.36 across all three, which is what this PR guards. The gsm8k reference stays at 96.5 so the kernel gap is not baked in; the hypothesis-testing threshold (93.297) absorbs it.min_al4.0: a collapse scores 1.09 with every accuracy gate green. AL figures of 5.2-5.9 quoted elsewhere are--apply_chat_templateruns (3.81 plain vs 5.52-5.88 chat, same drafter and samples).Also green on the embedded DSpark path (DeepSeek-V4-Pro DEP4 cutedsl, AL 4.436) — different drafter shape, same shared
kv_cache_manager_v2/py_executorcode.The drafter checkpoint is
RadixArk-Kimi-K3-DSparkon the CI model share (llm-models!596, merged; RadixArk and Inferact both publish a repo namedKimi-K3-DSpark, so both carry their vendor).Not covered: the VANILLA drafter attention backend still uses contiguous
flash_attn_with_kvcache.PR Checklist
Please review the following before submitting your PR:
PR description clearly explains what and why. If using CodeRabbit's summary, please make sure it makes sense.
PR Follows TRT-LLM CODING GUIDELINES to the best of your knowledge.
Test cases are provided for new code paths (see test instructions)
If PR introduces API changes, an appropriate PR label is added - either
api-compatibleorapi-breaking. Forapi-breaking, includeBREAKINGin the PR title.Any new dependencies have been scanned for license and vulnerabilities
CODEOWNERS updated if ownership changes
Documentation updated as needed
Update tava architecture diagram if there is a significant design change in PR.
The reviewers assigned automatically/manually are appropriate for the PR.
Please check this after reviewing the above items as appropriate for this PR.
GitHub Bot Help
To see a list of available CI bot commands, please comment
/bot help.