Skip to content

[dsv4] Trigger MHC prenorm prewarm at weight-load time with rank sync - #29988

Merged
Fridge003 merged 1 commit into
sgl-project:mainfrom
YAMY1234:dsv4-mhc-prewarm-lifecycle
Jul 3, 2026
Merged

Fridge003 merged 1 commit into
sgl-project:mainfrom
YAMY1234:dsv4-mhc-prewarm-lifecycle

Conversation

@YAMY1234

@YAMY1234 YAMY1234 commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Motivation

#27986 made the DSV4 MHC prenorm prewarm trigger lazily inside the first forward that carries tokens — per rank, uncoordinated. On wide-EP disaggregated prefill this is fatal: 0-token EP peers still launch deep_gemm.fp8_fp4_mega_moe every layer and wait for the compiling rank inside the kernel's NVLink barrier, which device-traps after 180 s. The 23-bucket burst (one DeepGEMM tf32_hc_prenorm_gemm + one TileLang big-fuse variant per bucket) measures 159–166 s on a cold JIT cache on GB200, so any >~15 s trigger stagger between ranks blows the budget:

DeepGEMM NVLink barrier timeout (180s): rank=2, counter=550, signal=7, target=8, phase=1, sign=0, tag=1
Assertion failed: .../deep_gemm/include/deep_gemm/comm/barrier.cuh:76
→ tvm.error.InternalError: CUDA driver error (sm100_fp8_fp4_mega_moe.hpp): 719 (CUDA_ERROR_LAUNCH_FAILED)

Reproduces deterministically on GB200 disagg 1p1d dep8-dep16 (8k1k); currently worked around by SGLANG_DSV4_MHC_PREWARM=0. Single-node dep4 setups pass only because their triggers happen to align (skew ≪ 180 s) — verified by a synthetic 4-rank repro where a single 200 s host stall reproduces the exact barrier-timeout signature.

Modifications

  • Trigger the same prewarm from the tail of DeepseekV4ForCausalLM.load_weights on every rank — before the memory pool, CUDA-graph capture, and any forward — then get_tp_group().barrier() so no rank proceeds while a peer is still compiling, and torch.cuda.empty_cache() (this now runs before init_memory_pool, so the multi-GB transient prewarm buffers must not skew KV-pool sizing).
  • Keep the in-forward trigger as a fallback for entry points that bypass load_weights (e.g. kernel unit tests); add prewarm duration + rank-sync logs.
  • Remove the orphaned prewarm_mhc_token_counts/_buckets pair (added by perf(dsv4): add MHC token-count prewarm #25810, removed by refactor(dsv4): route MHC prenorm through DeepGEMM wrapper #26238, resurrected without a caller by the [DeepSeek-V4] Add mhc_fused_post_pre kernel #25976 merge).

Accuracy Tests

No kernel/model math changes — the prewarm replays the existing _mhc_pre_impl path with dummy inputs at load time (same code the lazy trigger ran). Server responses validated on DSV4-Flash (TP4+DP4+deepep) and DSV4-Pro (disagg dep8/dep16).

Speed Tests and Profiling

A/B on GB200 disagg 2-node dep8 prefill + 4-node dep16 decode — same recipe, container, and base commit; the only difference is this patch:

without fix with fix
prewarm trigger 1 rank, mid-serving all 8 prefill ranks at load (153–173 s, rank sync +0.0 s)
NVLink barrier timeouts 16 (fields match production crash) 0
sa-bench (isl 8192 / osl 1024, conc 8) crash, no results completes, 80/80 requests, 464 tok/s output

Startup cost is unchanged (~160 s one-shot on a cold JIT cache; ~0 s warm — same as the lazy trigger paid, just moved off the serving path and aligned across ranks).

Checklist


CI States

Latest PR Test (Base): ❌ Run #28634631368
Latest PR Test (Extra): ❌ Run #28634631251

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@YAMY1234
YAMY1234 force-pushed the dsv4-mhc-prewarm-lifecycle branch 4 times, most recently from 46f352f to 40ed664 Compare July 3, 2026 01:22
@YAMY1234
YAMY1234 marked this pull request as ready for review July 3, 2026 01:29
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

Comment thread python/sglang/srt/models/deepseek_v4.py Outdated
The one-shot MHC prenorm prewarm (sgl-project#27986) triggers lazily inside the
first forward that carries tokens, per rank, uncoordinated. On wide-EP
disagg prefill (GB200 1p1d dep8) that is fatal: idle EP peers still
launch deep_gemm.fp8_fp4_mega_moe every layer and wait for the
compiling rank inside its NVLink barrier, which device-traps after
180 s ("DeepGEMM NVLink barrier timeout ... signal=7, target=8") and
poisons the context (CUDA error 719 on later launches). Measured on
GB200: the 23-bucket burst is 159-166 s on a cold JIT cache, so any
>15 s trigger stagger between ranks blows the barrier budget.

Fix: drive prewarm_mhc_pre() from the tail of load_weights on every
rank — before the memory pool, CUDA-graph capture, and any forward —
then barrier on the TP group so no rank proceeds while a peer still
compiles, and empty_cache so the transient prewarm buffers don't skew
KV-pool sizing.

With the trigger out of the forward path, the in-forward gate and the
mhc_pre/_mhc_pre_impl split (which existed only so the prewarm replay
would not re-enter mhc_pre) lose their reason to exist: remove them
and make mhc_pre the single implementation again. Also drop the
orphaned prewarm_mhc_token_counts/_buckets pair (added by sgl-project#25810,
removed by sgl-project#26238, resurrected without a caller by the sgl-project#25976 merge).
@YAMY1234
YAMY1234 force-pushed the dsv4-mhc-prewarm-lifecycle branch from 40ed664 to 4b2a43e Compare July 3, 2026 02:34
@Fridge003

Copy link
Copy Markdown
Collaborator

/rerun-test test/registered/models_e2e/test_deepseek_v4_flash_fp4_megamoe_b200.py test/registered/models_e2e/test_deepseek_v4_flash_fp8_h200.py test/registered/cp/test_deepseek_v4_flash_fp4_b200_cp.py test_mhc_kernels.py

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Results for /rerun-test test/registered/models_e2e/test_deepseek_v4_flash_fp4_megamoe_b200.py test/registered/models_e2e/test_deepseek_v4_flash_fp8_h200.py test/registered/cp/test_deepseek_v4_flash_fp4_b200_cp.py test_mhc_kernels.py:

🚀 4-gpu-b200 (2 tests): ✅ View workflow run

cd test/ && python3 registered/models_e2e/test_deepseek_v4_flash_fp4_megamoe_b200.py
cd test/ && python3 registered/cp/test_deepseek_v4_flash_fp4_b200_cp.py

🚀 8-gpu-h200 (1 test): ✅ View workflow run

cd test/ && python3 registered/models_e2e/test_deepseek_v4_flash_fp8_h200.py

🚀 1-gpu-h100 (1 test): ✅ View workflow run

cd test/ && python3 registered/kernels/test_mhc_kernels.py

@Fridge003
Fridge003 merged commit e81f05c into sgl-project:main Jul 3, 2026
92 of 106 checks passed
@YAMY1234
YAMY1234 deleted the dsv4-mhc-prewarm-lifecycle branch August 25, 2026 16:15
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