THUDM / THUDM/slime

[Bug] GPT-OSS raw converter emits incorrect expert weight format, causing gibberish output with `--megatron-to-hf-mode raw`

Open
#1,840 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
8.5k
Forks
1.3k
Avg merge
5h 36m
Merged PRs (30d)
22

Description

Bug Description

convert_gpt_oss_to_hf has two bugs when using --megatron-to-hf-mode raw (non-colocate). After the first weight sync, SGLang produces gibberish (reward=0, 100% truncation).

  1. fc1: Emits separate gate_proj/up_proj per expert instead of fused interleaved gate_up_proj. SGLang expects fused 3D tensors via make_expert_params_mapping_fused().
  2. fc2: Missing transpose — Megatron (out, in) vs HF (in, out). Hidden in 20B where hidden == inter == 2880.

scripts/run-gpt-oss-20B.sh uses --megatron-to-hf-mode bridge --colocate, bypassing convert_gpt_oss_to_hf entirely, so this path was never tested.

Steps to Reproduce
  1. Use origin/main (verified at 8efb1166)
  2. Run GPT-OSS 20B GRPO with --megatron-to-hf-mode raw (non-colocate, 2-node: training TP=1/PP=2/EP=4, rollout SGLang TP=2/DP-attn=4)
  3. Observe rollout after first weight sync
Expected Behavior

Coherent responses, truncated_ratio < 1%, reward > 0

Actual Behavior
response_len/mean: 2048.0   (all hit max length)
truncated_ratio:   1.0       (100%)
reward:            0

Broken code:

# fc1 — separate unfused (wrong)
gate_weight, up_weight = param.chunk(2, dim=0)
return [
    (f"...experts.{expert_idx}.gate_proj.weight", gate_weight),
    (f"...experts.{expert_idx}.up_proj.weight", up_weight),
]
# fc2 — missing transpose
return [(f"...experts.{expert_idx}.down_proj.weight", param)]

Fix:

# fc1 — fused interleaved
gate, up = param.chunk(2, dim=0)
fused = torch.stack([gate, up], dim=1).reshape(-1, param.shape[-1])
fused = fused.transpose(0, 1).contiguous()
return [(f"...experts.{expert_idx}.gate_up_proj.weight", fused)]
# fc2 — transposed
return [(f"...experts.{expert_idx}.down_proj.weight", param.T.contiguous())]

After fix: response_len/mean: 427, truncated_ratio: 0.004, reward: 0.078, grad_norm: 0.377.

The weight sync pipeline also needs to accumulate per-expert 2D tensors into fused 3D [num_experts, ...] before sending to SGLang, since weight_loader_fused() only accepts 3D shapes.

Environment

slime version: origin/main at 8efb1166

  • Python version: 3.10
  • PyTorch version: 2.6.0
  • CUDA version: 12.8
  • GPU type and count: 16x H200
  • OS: Ubuntu 22.04 (Docker)
  • SGLang version: v0.5.9 (from slimerl/sglang:v0.5.9 base image)
  • Megatron-LM version: commit 3714d81d
Logs

Additional Context

No response

Pre-submission Checklist
  • I have read the CONTRIBUTING.md and understand the collaboration scope.
  • I have read the documentation and my issue is not addressed there.
  • I have searched for existing issues and this is not a duplicate.
  • I have provided a minimal, reproducible example.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in slime/backends/megatron_utils/megatron_to_hf/gpt_oss.py and compare the raw conversion path with SGLang's fused GPT-OSS expert mapping. Trace the weight sync pipeline to verify that per-expert tensors are accumulated into fused 3D tensors before sending them to SGLang. Done means raw non-colocate GPT-OSS sync produces the expected fused expert format, transposed fc2 weights, and coherent rollout metrics.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, pytorch
Domain
distributed-systems, machine-learning
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.