Repository navigation
[AMD][DeepSeek V4] Fix default FlashMLA sparse prefill off on ROCm/HIP - #29982
Conversation
#29775 flipped SGLANG_OPT_FLASHMLA_SPARSE_PREFILL to default-on for all DeepSeek-V4 runs. On AMD MI355X this regressed the DeepSeek-V4-Flash disaggregation nightly: the sparse prefill path returns garbage output (warmup emits near-all-zero token ids), the PD decode path then fails to serve and the GSM8K accuracy gate reports no result. DeepSeek-V4-Pro on the same nodes is unaffected, so the dense prefill path (the pre-#29775 default) remains correct on ROCm. Make the default platform-conditional using the existing _default_hip callable-default pattern: keep default-on for CUDA (preserving the #29775 optimization) and default-off for ROCm/HIP, restoring the behavior that was green on the MI355X nightly. Explicitly setting the env var still overrides this, so the sparse path stays available on ROCm for validation.
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
| # breaks the disaggregation nightly. Keep the previous (dense prefill) default | ||
| # on ROCm until the sparse kernel is validated for that variant. Explicitly | ||
| # setting SGLANG_OPT_FLASHMLA_SPARSE_PREFILL still overrides this. | ||
| SGLANG_OPT_FLASHMLA_SPARSE_PREFILL = EnvBool(lambda: not _default_hip()) |
There was a problem hiding this comment.
Please set this in python/sglang/srt/arg_groups/deepseek_v4_hook.py
There was a problem hiding this comment.
Done — moved the ROCm default-off into apply_deepseek_v4_defaults in deepseek_v4_hook.py and reverted environ.py back to EnvBool(True). It disables SGLANG_OPT_FLASHMLA_SPARSE_PREFILL by default only on ROCm/HIP and only when not explicitly set, mirroring the existing CP-based disable. Thanks!
Address review: instead of making the environ default platform-conditional, keep SGLANG_OPT_FLASHMLA_SPARSE_PREFILL=True in environ.py and disable it by default on ROCm/HIP inside apply_deepseek_v4_defaults (alongside the existing CP-based disable). An explicitly set env var still overrides the default.
|
Updated per review: reverted Validation run on the latest commit (
Will post per-job results here once it finishes. |
|
Correction: the manual Validation is instead being covered by the scheduled nightly on It runs the full DSV4 matrix (all Flash + Pro configs). I'll follow up here with the DeepSeek-V4-Flash results once it completes. |
|
Important correction on validation: this nightly runs sglang from the prebuilt Re-validating against the newer image Note: that same 07-02 image also shows a separate regression where |
|
Validation update — this change does not fix the DeepSeek-V4-Flash disagg nightly. Flagging so we can decide on a follow-up/revert. I verified against image Result: all 8 Why the fix is ineffective: the warmup request is tiny (4 prompt tokens), so even with Suggested next steps:
Apologies for the premature "fix" framing; I couldn't validate on hardware before merge due to the MI355X queue. |
|
@1am9trash @RolaoDenthu @kkHuang-amd - FYI. |
| # (MI355X), which breaks the disaggregation nightly. Keep the previous | ||
| # (dense prefill) behavior on ROCm until the sparse kernel is validated | ||
| # there; an explicit env var still overrides this. | ||
| if is_hip() and not envs.SGLANG_OPT_FLASHMLA_SPARSE_PREFILL.is_set(): |
There was a problem hiding this comment.
should we remove the not, or remove the second condition?
There was a problem hiding this comment.
Remove the second condition — it should just be if is_hip():.
The not ...is_set() guard was the bug in this PR: the SGLANG_OPT_FLASHMLA_SPARSE_PREFILL default gets materialized into os.environ, so is_set() is already True by the time the hook runs → the guard skipped the disable, sparse prefill stayed on, and DeepSeek-V4-Flash kept producing garbage. That's why this PR didn't actually fix the nightly. Removing the not instead would be worse (disable only when explicitly set).
This is already handled by #30237 (merged), which changed it to if is_hip(): — validated on image ...-mi35x-20260706: dsv4flash-fp8-1k1k-1p1d now passes the GSM8K gate, and an A/B run with sparse re-enabled still reproduces the exact [0, 0, 201, 0, ...] garbage, confirming FlashMLA sparse prefill was the root cause after all.
Small follow-up #30289 just cleans up the now-stale "set it explicitly to override" wording in the warning/comment (since the disable is now unconditional on ROCm/HIP). Full flash-matrix re-validation in flight: https://github.com/sgl-project/sglang/actions/runs/28817206537
Motivation
#29775 flipped
SGLANG_OPT_FLASHMLA_SPARSE_PREFILLto default-on for all DeepSeek-V4 runs. Starting with the firstmainnightly that included it, the AMD MI355X 1P1D disaggregation nightly (Nightly Test (AMD MI355X 2N 1P1D Disagg)) regressed for DeepSeek-V4-Flash while DeepSeek-V4-Pro stayed green.Failing run: #28565894749 (scheduled,
main, 2026-07-02). Everydsv4flashjob (fp8/fp4, base/mtp/dp8ep8) failed; everydsv4projob passed.Evidence it is the sparse prefill path
transformers5.12.1 bump ([Deps] Bump transformers to 5.12.1 #29393), ruling that out. The regression window is the commits merged between the 07-01 and 07-02 runs; [DeepSeek V4] Enable FlashMLA sparse prefill by default #29775 (merged 2026-07-01) is the DSV4-specific change that flips this default.output_ids: [0, 0, 201, 0, 410, 0, 12389, 0](near-all-zero). The subsequent PD/generatethen fails to serve (decode times out -> 500 -> router 502 ->PD path not serving; aborting), and the GSM8K gate reportsAccuracy: <not found in bench.log>.Modification
Make the default platform-conditional using the existing
_default_hipcallable-default pattern already used inenviron.py(e.g.SGLANG_DP_USE_REDUCE_SCATTER = EnvBool(_default_hip)):Explicitly setting
SGLANG_OPT_FLASHMLA_SPARSE_PREFILLstill overrides the default, so the sparse path remains available on ROCm for validation/opt-in.This is a conservative mitigation to unbreak the nightly; it does not touch NVIDIA behavior. cc @YAMY1234 — happy to flip ROCm back to default-on once the FlashMLA sparse prefill kernel is validated for the Flash variant on MI355X.
Accuracy Test
Checklist
CI States
Latest PR Test (Base): 🚫 Run #28626803369
Latest PR Test (Extra): ❌ Run #28626803260