Fix DSpark + DeepSeek V4 prefill CP compatibility - #33865
Conversation
|
/tag-and-rerun-ci |
|
@whybeyoung We have shifted the CP implementation of DSV4 to CP_V2 in #33532. The older CP implementation will be deprecated soon. Can you please test how it works with DSpark Its usage should be: --attn-cp-size 8 \
--enable-prefill-cp \
--cp-strategy interleave \with flag SGLANG_ENABLE_CP_V2=1 |
…project#32035 sgl-project#33656 sgl-project#32183 sgl-project#33145) Applied PRs (latest from GitHub): sgl-project#33288 Indexer logits OOM fix sgl-project#30393 HiCache packed/sidecar draft caches sgl-project#31170 DPA prefix_affinity load balancing sgl-project#33795 DSpark compact ragged-verify CUDA graph JIT race sgl-project#32467 C128 plan-kernel warp barrier sgl-project#33865 DSpark x prefill CP unblock sgl-project#30371 SWA state pool sizing (storage page) sgl-project#33358 FlashMLA norm-rope K-tokens-per-block ILP sgl-project#33872 num_draft_tokens clamp + extend_len==0 skip (supersede sgl-project#32183) sgl-project#34002 Sidecar backup vacuously-successful fix (replaces sgl-project#33656, with tests) sgl-project#33862 Reclaim redundant host mirrors after storage backup sgl-project#31315 Avoid repeated Mooncake gets after stale hits sgl-project#32327 Q8KV8 sparse MLA prefill backend (flashmla_sparse_q8) sgl-project#31668 Fix sidecar pool life-time (use-after-free on prefetch abort) sgl-project#31195 TP0 verify-token-budget broadcast (adapted to get_schedule() API) Dropped (per user request or superseded): sgl-project#32771 IndexCache C4 top-k reuse — has bug sgl-project#32035 DSpark C128 online compressor — has bug sgl-project#33656 Superseded by sgl-project#34002 (same fix + unit tests) sgl-project#32183 Superseded by sgl-project#33872 (included in supersede PR) sgl-project#33145 Base f01f706 already has superior reasoning-effort profile system Conflicts resolved: sgl-project#31195: adapted to base get_schedule().disable_overlap_schedule API sgl-project#32327: path remapped jit_kernel/ -> kernels/jit/ and kernels/ops/attention/ sgl-project#31668: applied cleanly on top of sgl-project#30393+sgl-project#34002+sgl-project#33862 modifications
configure_tp_shard hard-coded attn_tp_group for the per-step all-gather, but under prefill CP (attn_cp_size == tp_size) attn_tp_group degenerates to world_size=1 while lm_head still shards over the full TP group, leaving the check failing and the gather a no-op. Pick the group that matches lm_head's own sharding: attn_tp_group when use_attn_tp_group is True, otherwise the full TP group. Store the group and use it in _apply_step_logits_sharded.
Drop the NotImplementedError blocking DSpark + CP and all-gather+rerange each dspark_aux_hidden_states tensor on the last PP rank with the same CP token split used for hidden_states, so downstream logits_processor indexing sees the global token layout.
TP=4 with attn_cp_size=4 and round-robin-split so attn_tp_group degenerates to size 1: exercises both fixes (markov_w2 TP-shard picking lm_head's shard group and DSpark aux hidden-state CP all-gather).
Under CP-v2 the model-level all-gather is skipped and hidden_states is gathered by _execute_extend_cp_v2 via cp_gather_after_forward. Do the same for aux_hidden_states so DSpark's per-layer captures land in the global token layout that logits_processor indexes with extend_seq_lens.
Per PR review: drop the standalone test file and add a DSPARK subtest inside test_deepseek_v4_flash_fp4_b200_cp.py using the CP-v2 flag set (--enable-prefill-cp --cp-strategy interleave, SGLANG_ENABLE_CP_V2=1).
f253193 to
174efc6
Compare
|
Addressed review comments and rebased on latest main: @Fridge003 - CP_V2 support:
@Fridge003 - test consolidation:
Rebased onto upstream/main; merge conflicts (with #33532) resolved. |
|
/tag-and-rerun-ci |
|
/rerun-test test/registered/cp/test_gqa_prefill_cp.py test/registered/cp/test_deepseek_v4_flash_fp4_b200_cp.py test/registered/cp/test_cp_strategy_unit.py test/registered/cp/test_dsa_prefill_cp.py test/registered/cp/test_deepseek_v3_cp_single_node.py |
|
Results for 🚀 🚀 🚀 🚀 |
|
/rerun-test test/registered/dcp/test_kimi_linear_dcp_dspark4.py |
|
Results for 🚀 |
Under DSV4 prefill CP, the CP hook auto-sets enable_dp_attention=True but dp_size stays 1 (no real DP sharding). The DSpark dp-attention validation (needs --enable-dp-lm-head, forbids attn_cp_size>1) targets real DP deployments; skip it when dp_size==1 so DSpark + CP can launch.
|
/rerun-test test/registered/cp/test_gqa_prefill_cp.py test/registered/cp/test_deepseek_v4_flash_fp4_b200_cp.py test/registered/cp/test_cp_strategy_unit.py test/registered/cp/test_dsa_prefill_cp.py test/registered/cp/test_deepseek_v3_cp_single_node.py |
|
/rerun-test test/registered/dcp/test_kimi_linear_dcp_dspark4.py |
|
Results for 🚀 🚀 🚀 🚀 |
|
Results for 🚀 |
|
Pushed a follow-up fix (64ac5ae) for the b200 CP failure. Root cause: in The CP-v2 code now mirrors the wrapper's contract: pass /rerun-test test/registered/cp/test_deepseek_v4_flash_fp4_b200_cp.py test/registered/dcp/test_kimi_linear_dcp_dspark4.py |
|
/rerun-test test/registered/cp/test_gqa_prefill_cp.py test/registered/cp/test_deepseek_v4_flash_fp4_b200_cp.py test/registered/cp/test_cp_strategy_unit.py test/registered/cp/test_dsa_prefill_cp.py test/registered/cp/test_deepseek_v3_cp_single_node.py |
|
/rerun-test test/registered/dcp/test_kimi_linear_dcp_dspark4.py |
|
Results for 🚀 🚀 🚀 🚀 |
|
Results for 🚀 |
When DSpark captures aux hidden states, DeepseekV4ForCausalLM.forward already passes hidden_states_before_norm=None so the logits processor returns packed aux tensors (shape [T, K*hidden]) to the DSpark KV injector. The CP-v2 path in _execute_extend_cp_v2 was still forwarding pre_hc_head (shape [T, mult*hidden]) as hidden_states_before_norm, which _get_hidden_states_to_store prefers over the packed aux buffer. The DSpark KV injector then handed main_proj a tensor whose last dim mismatched the ReplicatedLinear weight, tripping the fp8 matmul A.shape[-1] == B.shape[-1] assertion during prefill. Mirror the wrapper's contract: pass hidden_states_before_norm only when aux_hidden_states is None.
64ac5ae to
f50e1f5
Compare
|
/rerun-test test/registered/cp/test_gqa_prefill_cp.py test/registered/cp/test_deepseek_v4_flash_fp4_b200_cp.py test/registered/cp/test_cp_strategy_unit.py test/registered/cp/test_dsa_prefill_cp.py test/registered/cp/test_deepseek_v3_cp_single_node.py test/registered/dcp/test_kimi_linear_dcp_dspark4.py |
|
Results for 🚀 🚀 🚀 🚀 |
Summary
Two related fixes so DSpark speculative decoding works together with DeepSeek V4 prefill context parallelism (
--enable-nsa-prefill-context-parallel --nsa-prefill-cp-mode round-robin-split) at PD co-located deployment.Changes
deepseek_v4_dspark.py: use lm_head's shard group for markov_w2 TP-shardconfigure_tp_shardhard-codedattn_tp_groupfor the per-step all-gather. Under prefill CP (attn_cp_size == tp_size)attn_tp_groupdegenerates toworld_size == 1whilelm_headstill shards over the full TP group, so the geometry check failed and the gather (if forced through) would be a no-op leaving half the vocab missing. Now we pick the group that matcheslm_head's own choice:attn_tp_groupwhenuse_attn_tp_group=True, otherwise the full TP group.deepseek_v4.py: enable DSpark aux capture under prefill CPDrop the
NotImplementedErrorblocking DSpark + CP and all-gather + rerange eachdspark_aux_hidden_statestensor on the last PP rank with the same CP token split used forhidden_states, so downstreamlogits_processorindexing sees the global token layout.Test
Verified with:
No more
NotImplementedError; markov_w2 TP-shard geometry check passes.CI States
Latest PR Test (Base): ❌ Run #31455444987
Latest PR Test (Extra): ❌ Run #31455444860
CC @xu-yfei @ShangmingCai @Fridge003