dp-attention: add prefix_match load balance for in-instance cache-aware routing - #26612
Closed
jianzhichun wants to merge 1 commit into
Closed
jianzhichun wants to merge 1 commit into
jianzhichun wants to merge 1 commit into
Conversation
…re routing Add a new --load-balance-method prefix_match for the single-instance Data Parallel controller. It hashes the first 4k input tokens (via blake2b on the leading 256-token window) and routes by hash % dp_size, so requests sharing a system+tools prefix consistently land on the same DP rank and hit that rank's radix cache. Motivation: round_robin gives a hard ~1/dp_size cache-hit ceiling on identical-prefix sequential requests, and total_tokens only approximates prefix locality (it picks whichever rank just finished and falls apart under concurrency). Existing cache-aware work (sgl-project#2114, sgl-project#6869, sgl-project#26046, sgl-project#26561) targets either the sgl-router gateway or P/D-disaggregated deployments and does not cover plain --enable-dp-attention --dp-size N serving where the tokenizer manager dispatches directly to workers. The decision is a pure function of the leading tokens, so concurrent requests with the same prefix all land on the same rank without any cross-rank coordination. Empty input_ids fall back to round-robin. The existing routed_dp_rank override is preserved. Adds a registered DP-attention integration test (GSM8K with --dp 2 --load-balance-method prefix_match, same 0.6 threshold as the sibling DP-attention tests) and a CPU unit test asserting same-prefix determinism, distinct-prefix spread, empty-input fallback, and external rank routing precedence.
jianzhichun
requested review from
Ying1123,
hnyls2002,
merrymercy and
xiezhq-hermann
as code owners
May 28, 2026 21:37
Contributor
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
Author
|
Hi maintainers 👋 The CI failures here are Summary:
Thanks for reviewing! |
21 tasks
Contributor
|
Thanks @jianzhichun. Closing this because it has had no updates in 102 days. Reopen it if the work is still relevant. Some directories moved recently, so an older branch may need retargeting: |
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.
Closes #26611.
Motivation
The single-instance DP controller currently ships only
round_robin / follow_bootstrap_room / total_requests / total_tokens. None of them route by request content, so when a single client sends many sequential turns over a shared system + tools prefix (agent serving), the radix cache on each DP rank gets a hit at best once everydp_sizerequests underround_robin.Existing cache-aware routing work targets either the
sgl-routerRust gateway (#2114, #6869) or P/D-disaggregated decode (#26046, #26561). Neither covers plain--enable-dp-attention --dp-size Nserving with no gateway in front: the tokenizer manager dispatches directly to workers, and the only knob is--load-balance-method.total_tokensaccidentally approximates prefix locality only because the just-finished rank tends to be the lowest-loaded, and only for strictly sequential traffic. It degrades under concurrency.Modifications
python/sglang/srt/managers/data_parallel_controller.pyLoadBalanceMethod.PREFIX_MATCHto the enum.dispatch_lookup.DataParallelController.prefix_match_scheduler(req): hashes the first 4k input tokens viablake2bover a 256-token window and routes byint.from_bytes(h) % dp_size. Emptyinput_idsfalls back to round-robin; the existingrouted_dp_rankoverride is preserved (viamaybe_external_dp_rank_routing).import hashlib.python/sglang/srt/server_args.py"prefix_match"to the--load-balance-methodargparsechoices.test/registered/dp_attn/test_dp_attention.pyTestDPAttentionPrefixMatchLoadBalance: launches the standard MLA test model with--enable-dp-attention --dp 2 --load-balance-method prefix_matchand asserts GSM8K accuracy stays above the same0.6threshold as the sibling DP-attention tests.test/registered/unit/managers/test_prefix_match_scheduler.pyrouted_dp_ranktakes precedence.The decision is a pure function of
req.input_ids, so concurrent requests with the same prefix all land on the same rank with no cross-rank coordination.Accuracy Tests
No inference output change; load balance method is a routing-only decision over which DP rank receives a request. The new registered DP-attention test (
TestDPAttentionPrefixMatchLoadBalance) exercises GSM8K through the new code path with--dp 2 --load-balance-method prefix_matchand asserts the samegsm8k_accuracy_thres = 0.6threshold as the existingTestDPAttentionDP2TP2/TestDPAttentionMixedChunktests.Speed Tests
Measured on a Qwen3-class MoE checkpoint,
tp_size=16 dp_size=16 ep_size=16, moe_a2a_backend=deepep, attention_backend=fa3, mem_fraction_static=0.78, schedule_policy=lpm. Workload: one client sending a 22,651-token shared prefix + a short user turn,temperature=0,chat_template_kwargs.enable_thinking=false.load_balance_methodround_robintotal_tokensprefix_match(this PR)That's 5.7x speedup vs
round_robinon the exact pattern that matters for agent serving. A 4-agent concurrent same-prefix bench (withenable_mixed_chunk=true) goes from c4 RPS 0.19 (round_robin) to 0.41 (prefix_match).Checklist
pre-commit run --filesCI States
Latest PR Test (Base): ❌ Run #26603772659
Latest PR Test (Extra): ❌ Run #26603772607