Skip to content

Fix DeepSeek V4 loading with RunAI Model Streamer. - #30240

Merged
JustinTong0323 merged 5 commits into
sgl-project:mainfrom
Broduker:deepseek-v4-runai-streamer
Jul 30, 2026
Merged

JustinTong0323 merged 5 commits into
sgl-project:mainfrom
Broduker:deepseek-v4-runai-streamer

Conversation

@Broduker

@Broduker Broduker commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Motivation

Fix DeepSeek V4 loading with RunAI Model Streamer.

DeepSeek V4 performs a special FP8 dequantization pass for .wo_a.weight using the corresponding .wo_a.scale. The previous implementation first materialized the entire weights iterable with list(weights) and then dequantized from a dictionary. That is safe for normal local loading, but it breaks the streaming-loading contract used by runai_streamer.

In cluster validation with DeepSeek-V4-Flash on NVIDIA H20, the model could stream all tensors successfully, but the first decode failed with CUTLASS mixed dtype grouped GEMM / TMA descriptor initialization errors. Local loading of the same model did not reproduce the issue.

Fixes #30239

Modifications

  • Always use the streaming-safe DeepSeek V4 FP8 wo_a dequant path instead of materializing the full weight iterator.
  • Clone only pending RunAI Model Streamer tensors before retaining them across iterator steps.
  • Preserve the old missing-scale behavior: if no .wo_a.scale tensors exist, pass .wo_a.weight through unchanged; if any .wo_a.scale exists, unmatched .wo_a.weight still raises.
  • Add unit tests covering:
    • scale before weight and weight before scale
    • streaming output order versus legacy output order
    • cloned pending RunAI streamer tensors
    • missing-scale behavior

Accuracy Tests

No model-output accuracy change is expected. The patch only changes how DeepSeek V4 FP8 wo_a tensors are paired and dequantized during weight loading; the resulting tensor dtype remains bfloat16, matching the existing non-streaming path.

The streaming helper can yield a dequantized .wo_a.weight later than the legacy dict-based helper when .wo_a.weight appears before its .wo_a.scale. This does not change the model state because DeepSeek V4 loads tensors by parameter name. The unit tests compare legacy and streaming results by name and assert the tensor values match even when the yield order differs.

Speed Tests and Profiling

No throughput benchmark was run. This change avoids materializing the RunAI streamer weight iterator for DeepSeek V4 wo_a dequantization, so it should preserve the intended streaming-loading behavior and not affect steady-state inference speed.

Checklist


CI States

Latest PR Test (Base): ✅ Run #30328605916
Latest PR Test (Extra): ❌ Run #30328605785

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces streaming dequantization for FP8 weights in the DeepSeek-V4 model via the new _dequant_fp8_wo_a_streaming function, replacing the previous non-streaming implementation. It also adds a helper to clone RunAI streamed tensors to prevent issues during streaming. Comprehensive unit tests have been added to verify weight and scale pairing, correctness against the legacy implementation, cloning behavior, and error handling. There are no review comments, and the changes look solid.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@JustinTong0323 JustinTong0323 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebase onto the latest main and cover the DeepSeek V4 DSpark loader before merging.

@@ -2175,13 +2178,7 @@ def load_weights(self, weights: Iterable[Tuple[str, torch.Tensor]], is_nextn=Fal
raise ValueError("num_nextn_predict_layers is not in the config")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebase onto the latest main and use this streaming path in DeepseekV4ForCausalLMDSpark.load_weights too. PR #30261 added deepseek_v4_dspark.py with weights = list(weights), and DSPARK draft models inherit --load-format runai_streamer by default, so that path can still consume RunAI's reused buffers and load corrupted weights.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @JustinTong0323, I have updated it.

@Broduker
Broduker force-pushed the deepseek-v4-runai-streamer branch from 2442a04 to f67b35c Compare July 23, 2026 12:03
@JustinTong0323

Copy link
Copy Markdown
Collaborator

/tag-and-rerun-ci

@JustinTong0323

Copy link
Copy Markdown
Collaborator

/rerun-failed-ci

@JustinTong0323 JustinTong0323 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@JustinTong0323
JustinTong0323 merged commit b61cb5f into sgl-project:main Jul 30, 2026
216 of 234 checks passed
saturn-acc pushed a commit to saturn-acc/sglang that referenced this pull request Aug 16, 2026
jakki-amd pushed a commit to jakki-amd/sglang that referenced this pull request Sep 9, 2026
Atituiset pushed a commit to Atituiset/sglang that referenced this pull request Sep 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] DeepSeek V4 loading fails with RunAI Model Streamer during FP8 wo_a dequantization

2 participants