Repository navigation
feat: support Kimi Linear PD disaggregation with DCP - #32837
Conversation
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
/rerun-test test/registered/disaggregation/test_kimi_linear_pd_dcp4.py |
|
Results for 🚀 |
Transfer dense prefill MLA rows into rank-owned decode DCP layouts for Mooncake and NIXL. Support heterogeneous attention TP, matching DCP layouts, PP-aware layer mapping, exact partial-page token counts, and zero-owned transfer completion notifications. Co-authored-by: Yangmin Li <yangminl@nvidia.com>
eb6e3c9 to
1a4e550
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 🚀 |
74efd78 to
1a4e550
Compare
|
/rerun-test test/registered/disaggregation/test_kimi_linear_pd_dcp4.py |
|
Results for 🚀 |
|
/rerun-failed-ci |
| # msg[14:16] belong to the staging field below; DCP trails it. | ||
| dst_dcp_size=( | ||
| int(msg[16].decode("ascii")) if len(msg) > 16 and msg[16] != b"" else 1 | ||
| ), | ||
| dst_dcp_rank=( | ||
| int(msg[17].decode("ascii")) if len(msg) > 17 and msg[17] != b"" else 0 | ||
| ), | ||
| # Note: always put the staging field at the final | ||
| staging=StagingRegisterInfo.from_zmq_fields(msg, 14), |
There was a problem hiding this comment.
Could we reorder the fields' slice to 14, 15, 16? Staging register info should be physically placed at the end since it occupies several positions.
I think I should and will refactor the metadata interpretation part, many PRs miss this note.
There was a problem hiding this comment.
CC: @YAMY1234 I think putting this at the end will affect version compatibility while we append new fields, but the field number this StagingRegisterInfo contains is unclear from the name and has bad readability (that is the reason why I commented that it should be put at the last); should we unwrap it?
| dst_dcp_size, | ||
| dst_dcp_rank, |
There was a problem hiding this comment.
Then adjust the code here
| def requires_dcp_relayout(self, dst_dcp_size: int, dst_dcp_rank: int) -> bool: | ||
| if self.dcp_size == dst_dcp_size: | ||
| if self.dcp_rank != dst_dcp_rank: | ||
| raise RuntimeError( | ||
| "PD peers must connect matching DCP ranks, got " | ||
| f"prefill={self.dcp_rank}, decode={dst_dcp_rank}" | ||
| ) | ||
| return False | ||
|
|
||
| if ( | ||
| self.dcp_size == 1 | ||
| and dst_dcp_size > 1 | ||
| and (self.is_mla_backend or self.is_hybrid_mla_backend) | ||
| ): | ||
| return True | ||
|
|
||
| raise RuntimeError( | ||
| f"Unsupported PD DCP topology: {self.dcp_size} -> {dst_dcp_size}" | ||
| ) |
There was a problem hiding this comment.
I think we should not raise RuntimeError here. If requires_dcp_relayout fails, the transfer worker or metadata listener will crash. But in our design, this Prefill instance could pair with a DCP decode instance and a regular pure decode TP instance at the same time, so it could still process the requests from the latter one. We should mark this DCP topo not-match request as failed and print some warnings/error logging, or maybe add a try block here to avoid crashing the engine.
ShangmingCai
left a comment
There was a problem hiding this comment.
No other comments. Looks good. Once these nits have been addressed, it could be merged after CI passes.
|
Or we could fix them in a following PR, considering the GPU CI has passed now. |
|
Will address comments in a following PR |
Co-authored-by: Yangmin Li <yangminl@nvidia.com>
Co-authored-by: Yangmin Li <yangminl@nvidia.com>
Summary
Add PD disaggregation support for transferring dense prefill MLA rows into rank-owned decode DCP layouts.
Co-author
Supported topology
This is wider than only
TP -> DCP, but it is not the full Cartesian{TP, DCP} -> {TP, DCP}matrix.N != MPrefill and decode attention TP sizes may differ; the implementation uses the existing heterogeneous-TP rank mapping.
Pipeline parallelism
PP is supported within the existing PD topology rules:
PP=N-> decodePP=NPP=N-> decodePP=1, with decode gathering the applicable layers from all prefill stagesThe DCP path resolves destination entries by model-layer ID, so PP layer partitioning is composed with token relayout for both Mooncake and NIXL.
The following are not supported:
PP=1-> decodePP=NRuntime constraints
Implementation details
Validation scope
The registered 8-GPU acceptance test covers:
PP composition and the wider topology rules are implemented but are not all covered by the single registered end-to-end test.
Test plan
/rerun-test test/registered/disaggregation/test_kimi_linear_pd_dcp4.py)CI States
Latest PR Test (Base): ✅ Run #30590566763
Latest PR Test (Extra): ✅ Run #30590566001