mirror of
https://github.com/kvcache-ai/sglang.git
synced 2026-11-05 01:07:39 +00:00
[PR #97] fix(kt): apply the KT GPU-expert remap when there is no expert-location metadata #97
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#97
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/97
Author: @05yuki
Created: 9/25/2026
Status: 🔄 Open
Base:
main← Head:fix/kt-gpu-expert-remap-no-metadata📝 Commits (1)
f3080b4fix(kt): apply the KT GPU-expert remap when there is no expert-location metadata📊 Changes
1 file changed (+28 additions, -19 deletions)
View changed files
📝
python/sglang/srt/layers/moe/fused_moe_triton/layer.py(+28 -19)📄 Description
Problem
With
--kt-num-gpu-experts Nand any placement other than logical experts0..N-1(--kt-expert-placement-strategy frequency,random, or a placement file), the resident GPU experts hold the wrong weights.FusedMoE.weight_loaderonly maps a logical expert to its KT GPU slot inside_weight_loader_physical, and that function is only reached whenget_global_expert_location_metadata()is set. When it isNone, which is the case for a plain KT launch, the loader does the global-to-local mapping and calls_weight_loader_impldirectly. Logical experteis then written into GPU slote, and experts past the slot count are dropped by the bounds check. The wrapper still routes its selected experts (logical_to_gpu_index) to those slots, so every token routed to a GPU expert is computed with another expert's weights.The
uniformplacement is unaffected, because its map is the identity. That is probably why this has not shown up.How it was found
GLM-5.3 (FP8 checkpoint, NVFP4 CPU experts, TP2, 2x RTX 5060 Ti on a dual EPYC 7452),
--kt-num-gpu-experts 4 --kt-expert-placement-strategy frequency. Perplexity rose with the share of routing that went to the GPU (hot-4 covers 12.3% of picks). I dumped the resident expert parameters inprocess_weights_after_loadingand compared them byte for byte with the checkpoint:After the fix, all four slots match the claimed experts' FP8 bytes (w13 and w2, both ranks).
Change
The KT remap moves into
FusedMoE._map_kt_gpu_expert_id()and is called from both branches: the existing_weight_loader_physicalpath, which behaves as before, and the no-metadata path, which now remaps too. Parameters marked_sglang_require_global_expertsare left alone on both paths, as before.The behaviour for fused shared experts does not change. Their local id is outside
gpu_experts_mask, so they are skipped under KT on both paths, as_weight_loader_physicalalready did.Results
Paired NLL over 7,664 tokens (fixed held-out text, teacher-forced, per-token comparison against the same server with 0 GPU experts). GPU prefill was off so that every token takes the hybrid path.
The small gain after the fix is expected: here the GPU experts run on the original FP8 while the CPU experts run on NVFP4. Decode with hot-4 goes from 17.2 to 18.5 tok/s (3 x 1,500-token completions each).
🤖 Generated with Claude Code
https://claude.ai/code/session_01R57AidCMwH17PTFpX7HfQ5
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.