Repository navigation
[PD] Pack DCP1→DCP-N PD KV transfers into dest-contiguous RDMA blocks - #35762
Conversation
2e593f4 to
fcdc512
Compare
8fc1cc1 to
f77adfc
Compare
Cyclic DCP ownership made the relayout path emit one RDMA per token. Gather owned MLA rows on prefill first so Mooncake/NIXL can send page-sized or larger blocks. DSPARK is left to a follow-up. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep the feature description on the DCP page; the long-form design note stays local, not in the published docs. Co-authored-by: Cursor <cursoragent@cursor.com>
The packed-transfer design note is local-only; dcp.mdx does not need a docs update in this PR. Co-authored-by: Cursor <cursoragent@cursor.com>
Fold the duplicated Mooncake/NIXL ensure helpers into CommonKVManager and drop the unused lock. Each backend only registers the buffer with its transfer engine. Co-authored-by: Cursor <cursoragent@cursor.com>
Attach kv_data_tensors next to kv_data_ptrs when the MLA pool lines up, and skip the pointer reverse-lookup setter. Co-authored-by: Cursor <cursoragent@cursor.com>
Centralize lazy gather-stream ownership in StagingBuffer so DCP packing follows the existing staging synchronization path without redundant GPU IDs. Co-authored-by: Cursor <cursoragent@cursor.com>
Remove the rollout toggle so eligible DCP transfers consistently use the packed path while retaining the buffer-sizing override. Co-authored-by: Cursor <cursoragent@cursor.com>
Drop SGLANG_DISAGG_DCP_PACK_MAX_TOKENS; the pack buffer already cannot exceed a prefill chunk, so the env override was unused. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep KVArgs backend-neutral by moving DCP packing into a fused Triton KV-cache kernel that consumes registered addresses directly, while protecting NIXL's asynchronous source-buffer lifetime. Co-authored-by: Cursor <cursoragent@cursor.com>
Name the KV-cache kernel after its PD-to-DCP gather role so it is distinct from transfer orchestration. Co-authored-by: Cursor <cursoragent@cursor.com>
Reuse backend staging-memory hooks for DCP pack buffers and document the expected buffer footprint. Co-authored-by: Cursor <cursoragent@cursor.com>
Protect the descriptor-collapse benefit and clarify invalid KV item-length diagnostics. Co-authored-by: Cursor <cursoragent@cursor.com>
`_register_staging_memory` dropped its `gpu_id` parameter in favour of `self.kv_args.gpu_id`, but the test still passed it positionally and asserted the explicitly-passed value, failing with a TypeError. Drop the third argument at both call sites and expect the manager's own gpu_id (1), which also pins the new behaviour. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
6d29344 to
c18c9d3
Compare
|
/rerun-test test/registered/disaggregation/test_kimi_linear_pd_dcp4.py |
|
Results for 🚀 |
|
/rerun-test test/registered/disaggregation/test_kimi_linear_pd_dcp4.py |
|
Results for 🚀 |
ShangmingCai
left a comment
There was a problem hiding this comment.
Looks good to me, very clean. cc: @YAMY1234 for staging_buffer change review.
|
/rerun-group disaggregation |
|
/tag-and-rerun-ci |
|
Results for 🚀 🚀 🚀 🚀 🚀 🚀 🚀 🚀 |
YAMY1234
left a comment
There was a problem hiding this comment.
Staging buffer change LGTM!
|
Passed all based CI and PD disaggs test |
Resolved two conflicts introduced by upstream: * mori/conn.py: sgl-project#29133 landed an equivalent Mori ABORT handler (_TAG_ABORT / _handle_abort_message) that holds transfer_lock across the status read-modify-write and returns early on an already-Failed room. Kept upstream's handler and dropped this branch's _handle_abort_notification, which duplicated it without the lock. sgl-project#29133 also covers the Mori _submit_kv_transfer cleared-room guard this branch carried. * nixl/conn.py: kept the cleared-room guard's room_transfer_infos local alongside the packed_source_by_dcp_rank map added by sgl-project#35762; the two changes are adjacent but independent.
…ontract `send_kvcache_dcp` now returns one handle per transfer part (target + draft), and the worker extends its handle list with the result. The test merged from main (sgl-project#35762) still mocked a single string handle, so `extend` split it into characters and the chunk barrier polled 41 fake handles instead of 3. The fake `kv_args` also lacked `num_draft_entries`, which the pack path now reads. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Cyclic DCP ownership made the relayout path emit one RDMA per token. Gather owned MLA rows on prefill first so Mooncake/NIXL can send page-sized or larger blocks. DSPARK is left to a follow-up.
Motivation
DCP assigns KV ownership round-robin per token (
owned_offsets = arange(rank, num_kv_tokens, dcp_size)), so on a DCP1 -> DCP-N PD transfer the source indices are strided andgroup_concurrent_contiguouscannot merge them: the relayout emits one RDMA descriptor per token per layer (tokens x layersper chunk). The transfer becomes descriptor-bound rather than bandwidth-bound.Modifications
Accuracy Tests
test/registered/disaggregation/test_kimi_linear_pd_dcp4.pyon 8xB300: 6 passed, GSM8K 0.91 (threshold 0.88). Covers token + output-logprob parity against a monolithic TP4 reference at 9 chunk/virtual-page boundary lengths, and a 32k needle-in-a-haystack at depths 0.1/0.5/0.9.Speed Tests and Profiling
Setup. 8xB300,
Kimi-Linear-48B-A3B-Instruct.main@20621aa14bvs this PR @539b78567f, on both transfer backends.dcp=1(GPU 0-3) -> decode TP4dcp=4(GPU 4-7).tokenspeed_mla,fp8_e4m3KV,--page-size 64,--chunked-prefill-size 8192,--mem-fraction-static 0.80.sglang.benchmark.serving --pd-separated.4 x 31.5 MBpack buffers per prefill TP rank) and absent onmain.NIXL
Mooncake
Summary. Backend-dependent: NIXL -28% to -39% TTFT and up to 1.6x output throughput at ISL >= 32k; mooncake -9% to -14% and ~1.1x. Mooncake's baseline is already faster at every point, and packing converges the two to within ~3% -- per-token descriptors penalise NIXL far more, and this PR removes that penalty. ISL 4096 / conc 8 barely moves on either backend (~3.1-3.5 s in all conditions), so something other than descriptor count dominates there. Cost: 4 x 31.5 MB pack buffers per prefill TP rank, leaving the KV pool essentially unchanged.
Checklist
Review and Merge Process
/tag-and-rerun-ci,/tag-run-ci-label,/rerun-failed-ciCI States
Latest PR Test (Base): ✅ Run #33031619005
Latest PR Test (Extra): ✅ Run #33064293710
Latest PR Test (AMD ROCm 7.2): ❌ Run #33031619022