Skip to content

[1/4] Add MiniMax-M3 support - #4581

Merged
Zhichenzzz merged 7 commits into
mainfrom
zhichen/minimax-m3-support
Nov 1, 2026
Merged

Zhichenzzz merged 7 commits into
mainfrom
zhichen/minimax-m3-support

Conversation

@Zhichenzzz

@Zhichenzzz Zhichenzzz commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

MiniMax-M3 support: Megatron plugin, mbridge bridge, HF converter, launcher and a BF16 conversion tool.

Stack: #4581 (this) → #4582 → #4583 → #4584.

What

  • miles_plugins/models/minimax_m3: GQA with MSA block-sparse attention on the sparse layers (a frozen 4-head indexer picks each query's top-16 key blocks) and plain dense attention on the first three layers; swigluoai MoE with a sigmoid router and one shared expert.
  • miles/kernels/attention/qsa/block_sparse_attention.py: the tile map now covers key blocks wider than a tile (MiniMax uses 128-token blocks, the kernel walks 64/32-token tiles), with no host sync.
  • QSA block-sparse kernel tuning: launch configs per block width (qwen3.8-next's 4-token blocks vs MiniMax's 128-token blocks), and the dK/dV kernel splits a KV head's query heads over several programs.
  • miles/kernels/attention/msa: Triton per-block max-logit scores for the MiniMax indexer, replacing a per-sequence torch loop.
  • miles_plugins/mbridge/minimax_m3.py, megatron_to_hf/minimax_m3.py: weight mapping both ways.
  • scripts/run_minimax_m3.py: MiniMax-M3 (8 × 4 GB300, TP4/PP4/EP8, Adam state streamed through disk) and MiniMax-M3-4layer (one node).
  • tools/convert_minimax_m3_to_bf16.py: cuts a layer subset from a release, and dequantizes the MXFP8/NVFP4 MiniMax-M3.1 checkpoints to BF16 (used by [3/4]).

Depends on

SGLang must accept online weight updates into MiniMax-M3's fused q/k/v + index GEMM: sgl-project/sglang#47612 (into sglang-miles). Without it the first weight sync fails with IndexError: start out of range.

Validation (GB300, colocated, BF16 rollout, sglang with #47612)

  • MiniMax-M3-4layer, 3 steps: train/rollout log-prob abs diff 0.0050 / 0.0050 / 0.0050, --check-weight-update-equal passes after every update.
  • MiniMax-M3, 8 × 4 GB300, 10 steps: abs diff 0.0070–0.0096, dapo-math reward 0.52 → 0.79, 10–12 min per step after the first.
  • tests/fast/test_qsa_tile_index.py gains a blocks-wider-than-a-tile case: 16 of its cases fail on the previous two-tile _tile_mask and pass now.
  • pytest tests/manual/launch_scripts tests/fast/launch_scripts: the minimax cases pass; the remaining 19 failures / 4 errors are identical on main.

Kernel tuning (GB300, one GPU, 16k-token packs)

before after
qwen3.8-next attention fwd+bwd (12q/1kv, D256, block 4) 22.5 ms 16.4 ms
MiniMax-M3 attention fwd+bwd (16q/1kv, D128, block 128) 12.7 ms 6.7 ms
MiniMax-M3 attention fwd+bwd, one 32k sequence 38.6 ms 20.2 ms
MiniMax-M3 indexer select 5.0 ms 0.62 ms
MiniMax-M3 indexer select, one 32k sequence 16.3 ms 1.2 ms

Gradients match the previous configs to bf16 noise (rel ≤ 8e-3); the new select picks identical block sets on ≥ 99.997% of rows (the rest are near-ties). MiniMax-M3 4-layer e2e after tuning: abs diff 0.0050, weight check passes.

ci-sglang-pr: #47612

Megatron plugin, mbridge bridge, HF converter and launcher for MiniMax-M3: GQA
with MSA block-sparse attention on the sparse layers (a frozen 4-head indexer
picks each query's top-16 key blocks) and plain dense attention on the first
three, swigluoai MoE with a sigmoid router and one shared expert.

- miles_plugins/models/minimax_m3: the attention module and block spec; the
  sparse layers run the QSA block-sparse kernel, whose tile map now covers
  blocks wider than a tile.
- miles_plugins/mbridge/minimax_m3.py and megatron_to_hf/minimax_m3.py: weight
  mapping both ways.
- scripts/run_minimax_m3.py: the full model (8 x 4 GB300, TP4/PP4/EP8, Adam
  state streamed through disk) and a 4-layer cut for one node.
- tools/convert_minimax_m3_to_bf16.py: cuts a layer subset from a release and
  dequantizes the MXFP8/NVFP4 MiniMax-M3.1 checkpoints to BF16.
@Zhichenzzz
Zhichenzzz requested a review from fzyzcjy as a code owner October 31, 2026 09:55

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.

Tip: disable this comment in your organization's Code Review settings.

- block_sparse_attention: launch configs per block width (narrow = qwen3.8-next's
  4-token QSA blocks, wide = MiniMax-M3's 128-token MSA blocks), and the dK/dV
  kernel splits a KV head's query heads over several programs, each writing its
  own slice that the caller sums, instead of one program walking all of them.
- MiniMax-M3 indexer: the per-block max logits come from a Triton kernel
  (miles/kernels/attention/msa) and the init/local/causal rules and top-k run
  vectorized, replacing the per-sequence, per-query-chunk torch loop.

GB300, one GPU, 16k-token packs (fwd+bwd of the attention kernel; indexer select):
  qwen3.8-next (12 q / 1 kv head, D 256, block 4):    22.5 -> 16.4 ms
  MiniMax-M3   (16 q / 1 kv head, D 128, block 128):  12.7 -> 6.7 ms (32k: 38.6 -> 20.2 ms)
  MiniMax-M3 select: 5.0 -> 0.62 ms (32k: 16.3 -> 1.2 ms), identical block sets
  on >= 99.997% of rows (the rest are near-ties)
Gradients agree with the previous launch configs to bf16 noise (rel <= 8e-3).
MiniMax-M3 4-layer e2e: log-prob abs diff unchanged (0.0050), weight check passes.
Look the (forward, backward) configs up through one function instead of indexing two
bool-keyed dicts at each call site, and store dV with V's strides rather than relying on
K and V sharing a layout. No behavior change.
Runs the MiniMax-M3-4layer recipe on 4 H200s from a pre-cut BF16 checkpoint
(CharyZeng/MiniMax-M3-4layer: layers 0,1,3,4, two dense-attention and two sparse
MoE layers), with a deterministic pseudo-random reward so every weight sync
carries real deltas, and gates the train/rollout log-prob gap, grad norm and KL.
@Zhichenzzz

Copy link
Copy Markdown
Collaborator Author

/rerun-test tests/e2e/megatron/model_scripts/test_minimax_m3_4layer_ci.py

@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

⚪ tests/e2e/megatron/model_scripts/test_minimax_m3_4layer_ci.py cancelled on stage-c-4-gpu-h200 in 1h16m49s — workflow run

The run was cancelled.

@Zhichenzzz

Copy link
Copy Markdown
Collaborator Author

/rerun-test tests/e2e/megatron/model_scripts/test_minimax_m3_4layer_ci.py

@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

✅ tests/e2e/megatron/model_scripts/test_minimax_m3_4layer_ci.py passed on stage-c-4-gpu-h200 in 16m48s — workflow run

@Zhichenzzz

Copy link
Copy Markdown
Collaborator Author

/rerun-test tests/e2e/megatron/model_scripts/test_minimax_m3_4layer_ci.py

@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

❌ tests/e2e/megatron/model_scripts/test_minimax_m3_4layer_ci.py failed on stage-c-4-gpu-h200 in 35m18s — workflow run

The execution job failed; inspect the workflow run for the failing step.

@Zhichenzzz

Copy link
Copy Markdown
Collaborator Author

/rerun-test tests/e2e/megatron/model_scripts/test_minimax_m3_4layer_ci.py

@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

✅ tests/e2e/megatron/model_scripts/test_minimax_m3_4layer_ci.py passed on stage-c-4-gpu-h200 in 13m43s — workflow run

The check now also treats quick-GeGLU (MiniMax-M3's swigluoai) as a gated FC1, so the
test's backend namespace carries quick_geglu and gains that case.
@Zhichenzzz
Zhichenzzz enabled stacked auto-merge (squash) November 1, 2026 19:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants