Repository navigation
[Feat] KVShard: PD transfer and e2e test - #38473
Merged
Merged
Conversation
Shunkangz
requested review from
ByronHsu,
Duyi-Wang,
Fridge003,
HaiShaw,
Qiaolin-Yu,
ShangmingCai,
Ying1123,
alphabetc1,
ch-wan,
fzyzcjy,
hanming-lu,
hebiao064,
hnyls2002,
huangtingwei9988,
hzh0425,
ispobock,
merrymercy,
sogalin,
xiezhq-hermann and
yizhang2077
as code owners
September 8, 2026 09:12
7 of 9 tasks
15 of 21 tasks
This was referenced Oct 7, 2026
test_page_interleave_shard.py: main (sgl-project#40925) added multi-GPU gather and DSA indexer tests to the file this branch extends. Keep both: the branch's CPU tests (TestShardedPoolFootprint, TestShardSendFilter) stay with the other CPU tests before main's multi-GPU section, the docstring lists CPU items 1-7 then main's GPU paragraph, and the imports are the union of both sides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
/rerun-failed-ci |
1 similar comment
Contributor
Author
|
/rerun-failed-ci |
_resolve_rank_mapping read info.enable_kv_cache_sharding before checking is_mla_backend. A non-MLA decode now stops at is_mla_backend, so it reads only the fields main reads. This fixes the hetero-TP SWA wire test, whose SimpleNamespace info has no sharding field. Behavior is unchanged for a real PrefillServerInfo, where the field defaults to False.
Contributor
Author
|
/rerun-failed-ci |
Collaborator
|
/rerun-failed-ci |
hzh0425
approved these changes
Oct 15, 2026
alphabetc1
reviewed
Oct 16, 2026
4 tasks done
AMD-yanfeiwang
pushed a commit
to AMD-yanfeiwang/sglang
that referenced
this pull request
Oct 18, 2026
Squashed dependency: the net change of sgl-project#38473 (open upstream) relative to main, squashed into one commit so this PR's own commits stand alone. Credit for this commit belongs to the sgl-project#38473 author; review it in sgl-project#38473. A sharded prefill rank holds only its stripe of every KV page, so each rank sends the pages it owns and decode pulls from every rank of the shard group. - disaggregation/utils.py: filter_kv_indices_for_shard_rank (logical page l lives on rank l % N as local page l // N). - disaggregation/common/conn.py: filter every send by the shard rank, skip empty non-final chunks, advertise enable_kv_cache_sharding through bootstrap; decode pulls from all prefill ranks of the shard group. - disaggregation/prefill.py: widen the bootstrap capacity bound by the shard size. - Read the sharding flag only on the MLA rank-mapping path. - Tests: send filter, empty-chunk skip, bootstrap payload, per-rank KV memory cut, and a 4-GPU PD E2E gating GSM8K accuracy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
5 of 6 tasks
…r fit
The PD bootstrap check rejected only prompts longer than N*T (N shard
ranks, T tokens per rank). Sharded PrefillAdder admission needs
prompt + 1 new token + one page per shard < N*T, strictly, so prompts in
[N*T - N*ps - 1, N*T - 7] passed intake and bootstrap but were refused
with NO_TOKEN on every pass, even on an empty pool. Under FCFS such a
request blocked the prefill queue until decode's 300 s KV-wait timeout
turned it into a 500. With tp=2, page 64 and 16384 tokens per rank, that
is 32639..32761.
The bootstrap check now rejects prompts longer than N*T - N*ps - 2
(32638 there) with a 400. Unsharded runs keep their limit.
Test: a CPU unit test drives the real sharded PrefillAdder on an empty
PageInterleavePoolAllocator and the real bootstrap check at the limit
and one past it, for N in {2, 4}.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sharding assigns whole logical pages to ranks; it does not split every page into per-rank stripes. Fix the comments and the E2E docstring that said otherwise. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sion path
With the radix cache disabled, PrefillAdder admits ignore_eos requests
through add_one_req_ignore_eos. That path rounds the prompt up to a page and
keeps 1 new token plus IGNORE_EOS_RESERVE_TOKENS spare, so on an empty pool
it admits only ceil_page(L) <= N*T - N*ps - 3. The previous limit,
N*T - N*ps - 2, still let [N*T - (N+1)*ps + 1, N*T - N*ps - 2] wait forever
(32577..32638 for tp=2, page 64, 16384 tokens per rank).
The limit is now floor_page(N*T - N*ps - 3), 32576 there. A sweep over
N in {2, 4, 8} and page sizes {2, 16, 64} matches the largest prompt both
real admission paths admit. The boundary test now also drives the
ignore_eos path.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
hzh0425
approved these changes
Oct 19, 2026
Collaborator
|
/rerun-group disaggregation |
Contributor
|
🚀 🚀 🚀 🚀 🚀 🚀 ⛔ |
AMD-yanfeiwang
pushed a commit
to AMD-yanfeiwang/sglang
that referenced
this pull request
Oct 20, 2026
Squashed dependency: the net change of sgl-project#38473 (open upstream) relative to main, squashed into one commit so this PR's own commits stand alone. Credit for this commit belongs to the sgl-project#38473 author; review it in sgl-project#38473. Each sharded prefill rank owns a subset of logical KV pages, so each rank sends the pages it owns and decode pulls from every rank of the shard group. - disaggregation/utils.py: filter_kv_indices_for_shard_rank (logical page l lives on rank l % N as local page l // N). - disaggregation/common/conn.py: filter every send by the shard rank, skip empty non-final chunks, advertise enable_kv_cache_sharding through bootstrap; decode pulls from all prefill ranks of the shard group. - disaggregation/prefill.py: widen the bootstrap capacity bound by the shard size, and reject at bootstrap any prompt that sharded prefill admission can never fit (bounded by the stricter ignore_eos path). - Read the sharding flag only on the MLA rank-mapping path. - Tests: send filter, empty-chunk skip, bootstrap payload, bootstrap limit vs sharded admission boundary, per-rank KV memory cut, and a 4-GPU PD E2E gating GSM8K accuracy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ShangmingCai
approved these changes
Oct 20, 2026
ShangmingCai
left a comment
Collaborator
There was a problem hiding this comment.
All changes are correct and safe, LGTM
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.
Motivation
The PR that makes the feature work end to end.
A sharded prefill rank holds only its stripe of every cached page, so the transfer changes on both ends: each prefill rank ships the pages it owns, and decode pulls from every rank of the shard group instead of one. Ownership is derived from the value (
owner = logical_page % N), not the position, so the filter stays correct under any allocator placement policy — and the wire value is already the owner's local page id, so the decode side needs no change.Validated PD-disaggregated on both arms: MLA sharded across attention-TP (GSM8K 0.82) and GQA under prefill CP sharded across attention-CP (GSM8K 0.935), both added here as registered E2E tests.
Modifications
Accuracy Tests
Speed Tests and Profiling
Checklist
Review and Merge Process
/tag-and-rerun-ci,/tag-run-ci-label,/rerun-failed-ciCI States
Latest PR Test (Base): ✅ Run #39209811480
Latest PR Test (Extra): ✅ Run #39209811542
Latest PR Test (AMD ROCm 10): ❌ Run #39209811722