mirror of
https://github.com/kvcache-ai/sglang.git
synced 2026-11-05 01:07:39 +00:00
[PR #45] fix(v4-flash): make ExpertDistributionRecorder work for DeepSeek-V4-Flash #45
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
kvcache-ai/sglang#45
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/kvcache-ai/sglang/pull/45
Author: @yiqiliu2
Created: 5/8/2026
Status: 🔄 Open
Base:
main← Head:pr/expert-distribution-recorder-v4flash-fix📝 Commits (2)
5c3410efix(v4-flash): cuda-graph-safe + shape-safe ExpertDistribution recorder1e6496bfix: wrap deepseek_v4 forward layers with recorder current_layer ctx📊 Changes
2 files changed (+40 additions, -12 deletions)
View changed files
📝
python/sglang/srt/eplb/expert_distribution.py(+19 -6)📝
python/sglang/srt/models/deepseek_v4.py(+21 -6)📄 Description
Summary
Two coupled fixes that together make `--expert-distribution-recorder-mode stat` work end-to-end for V4-Flash.
1. `_SelectExpertsSinglePassGatherer.on_select_experts` cuda-graph-safe + shape-safe
The original used `scatter_add_` on `self._data[layer_idx, :]` and crashed with `Index tensor must have the same number of dimensions as self tensor` on V4-Flash routing tensors.
`_on_hook`'s `is_current_stream_capturing()` clause also lets the hook fire during cuda graph capture, but any host sync (`.item()`, boolean indexing, nonzero) inside the hook hits cudaErrorStreamCaptureInvalidated.
Rewrite uses pure GPU ops:
No host sync, no boolean indexing, no nonzero.
2. `deepseek_v4.py` forward loop wraps with `with_current_layer(i)` ctx
The forward loop iterated layers without the recorder context manager. Without this, every `on_select_experts` write lands in slot 0 of the gatherer's `_data` tensor → the dumped `logical_count.pt` only has data for layer 0 → `torch.topk` on it places all GPU experts on layer 0.
Other DeepSeek family models (`deepseek_v2`, `qwen2_moe`, `qwen3_moe`, `exaone_moe`, `llada2`, `longcat_flash`, `step3p5`) all wrap their forward loops with this context — V4 was an oversight on initial port.
Test plan
🤖 Generated with Claude Code
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.