Skip to content

[KV Sharding][1/3] Transfer DSA target and draft indexer state over PD - #42969

Closed
HZY-Wade wants to merge 11 commits into
sgl-project:mainfrom
HZY-Wade:codex/kvshard-dsa-pd
Closed

HZY-Wade wants to merge 11 commits into
sgl-project:mainfrom
HZY-Wade:codex/kvshard-dsa-pd

Conversation

@HZY-Wade

@HZY-Wade HZY-Wade commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Page-sharded DSA prefill stores different indexer pages on each CP rank. The replicated-state shortcut must not suppress nonzero owners, and target/draft indexer pages must use the same source-position pairing as latent KV. Otherwise the decode worker can receive incomplete or incorrectly paired indexer state.

This increment extends Shunkang's existing PD transfer implementation:

  • Send DSA state from every page owner, convert source logical pages to owner-local pages, and filter destination pages by the same positions.
  • Reject mismatched state page counts instead of truncating them; retain the existing peer stride checks.
  • Preserve target/draft and skip-topk layer numbering while omitting empty RDMA descriptors.
  • Count only the sender's owned indexer pages in transfer metrics. Empty final KV chunks still carry the required state/completion protocol.

Stack and attribution

This is a draft, dependency-stacked PR based on upstream main 492dbd0807d21e0faa72a55a2c09f541cb4696b6. It includes the prerequisites from Shunkang's #40102, #38473, #40925 and #40929, retaining their author attribution and original commit references. A small test-consolidation commit reconciles their final tests with current main.

Review this increment: HZY-Wade/sglang@codex/kvshard-dsa-dependencies...codex/kvshard-dsa-pd

The functional increment is commit a22db8cd58. The broader Files changed view also contains the unmerged upstream dependencies; those are not new implementations claimed by this PR. DSA/MTP runtime activation follows in #42972 and CPU HiCache support in #42973. The stack will be rebased as its dependencies land.

Validation

  • 29 CPU tests and 46 subtests passed across the new DSA transfer tests and existing transfer metrics/batching tests.
  • Tests exercise the production owner filter and Mooncake descriptor builder using a CPU memory-copy transport. Coverage includes CP4/CP8 fragmented pages, complete 8448-byte packed key/scale pages, target plus draft buffers, empty owners, prefix-hit final chunks, skip-topk entries, mismatch rejection and unsharded compatibility.
  • Changed-code Ruff/isort and git diff --check passed.
  • GPU/RDMA end-to-end and full-model accuracy tests have not been run for this latest-main port. This draft does not claim production or accuracy qualification.

No changes to the non-sharded state-transfer path are intended.

Shunkangz and others added 11 commits October 7, 2026 20:52
Expose the flag only after scratch and scheduler contracts exist. Resolve supported configurations, reserve scratch HBM, select sharded pools and allocator, and require the rotation-aware cache together.

(cherry picked from commit 40fa526)
…ests

Last of four PRs for logical-page KV cache sharding; stacked on
"[kv-shard 3/4] Enable the feature". A sharded prefill rank holds only its
stripe of every cached page, so each prefill rank ships the pages it owns and
decode pulls from every rank in the shard group. UnifiedRadixCache preserves
the logical Full-KV page ids and rotation invariant consumed by this
tree-independent transfer path.

Contents:

- `disaggregation/utils.py`: add `filter_kv_indices_for_shard_rank`.
  Ownership comes from the value (`owner = logical_page % N`), independent of
  placement order. Owned entries go on the wire as `logical_page // N`, the
  owner's local page id. The contiguous destination slice becomes an explicit
  positions array for positional pairing.
- `disaggregation/common/conn.py`: resolve and advertise the prefill shard
  identity; make decode pull from all CP ranks or register every prefill TP
  rank as a real sender; reject decode layouts that would require DCP relayout.
- `disaggregation/nixl/conn.py`: emit a standalone notification when a rank
  owns no page in a non-final chunk, preventing a missing chunk id from
  stalling the receiver.
- `disaggregation/prefill.py`: widen the bootstrap capacity bound, require a
  page-aligned decode-cached prefix, retain scheduler-stage metrics, and run
  busy invariant checks in both disaggregated prefill loops.
- `disaggregation/mooncake/conn.py`: keep transfer metrics aligned with bytes
  actually sent when replicated state transfer is suppressed.

Tests cover the send partition and wire ids, Mooncake transfer accounting,
NIXL empty-chunk notification, and bootstrap flag propagation. The new 4-GPU
MLA and 8-GPU GQA/CP disaggregated E2Es exercise both shard axes; the GQA case
uses the canonical `--enable-prefill-cp --cp-strategy zigzag` configuration.

(cherry picked from commit 9f6b072)
Upstream sgl-project#41469 removed get_index_k_continuous and
get_index_k_scale_continuous (and IndexKeyCache.get_k_continuous /
get_k_scale_continuous) as orphaned. The sharded index cache still
overrode the IndexKeyCache pair, and the indexer test called the pool
pair, so CI on the main-merged branch failed with AttributeError.

Drop the two overrides and read through get_index_k_scale_buffer, which
still translates logical page IDs into the scratch plan and keeps the
skip-topk and begin_shard_extend assertions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit e33582f)
Since sgl-project#42178, slots_per_page = page_size // index_kpool, but the sharded
pool translates indexer locations in token units. With index_kpool > 1
that would address the wrong rows, so fail at construction instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 5a82ac9)
Preserve the final test coverage from Shunkangz/sglang PR sgl-project#40929 commits ea0efc1, 16c7162 and 156b0db while retaining current-main, PD and DSA tests. Keep current-main import boundaries in the pool implementations.

Co-authored-by: shunkangz <182541032+Shunkangz@users.noreply.github.com>
Extend the existing sharded Mooncake protocol to route packed DSA indexer pages by owner. Preserve source/destination positions, reject mismatched page counts, and exclude empty indexer layers from RDMA descriptors. Count each sender only for its owned state pages.

Add CPU byte-exact descriptor tests for CP4/CP8, target plus draft buffers, empty owners, prefix-hit final chunks, layout rejection and unsharded compatibility.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants