Skip to content

[MiniMax-M3.1] Native-MXFP8 Mono decode through S32 (stacked on #2686) - #2718

Draft
XiaobingSuper wants to merge 7 commits into
mainfrom
hattie/minimax-m31-native-mxfp8
Draft

XiaobingSuper wants to merge 7 commits into
mainfrom
hattie/minimax-m31-native-mxfp8

Conversation

@XiaobingSuper

@XiaobingSuper XiaobingSuper commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Stacked on #2686. This diff contains only the native-MXFP8/S32 kernel work; sparse-prefix and fixed-DSpark lifecycle changes remain in the base PR.

  • consume Quark QKV/O weights directly as row-major MXFP8 with row-major E8M0 scales, without a PTPC copy or module mutation
  • run the independent MXFP8 shared expert alongside MXFP4 routed experts without MXFP8-to-MXFP4 requantization
  • tile only the native M3.1 path through S32, serving fixed q=8 DSpark C1-C4; legacy MiniMax-M3 remains capped at S16
  • skip absent expert pairs in the S32 wide-MoE tail while keeping the launch CTA-uniform
  • preserve the default, PTPC/FSE, DSpark-off and legacy-M3 builders and ABIs

The native path is opt-in through ATOM_MONO_ENABLE=1. For the Quark export, keep attention/shared-expert weights native (ATOM_FUSE_MXFP8_SHARED_INTO_MXFP4=0, no ptpc_fp8 conversion), with TP4, FP8 KV/index cache, block 128 and fixed 7-draft DSpark.

Validation

Latest main plus #2686:

  • focused dispatch/layout/build-key/mailbox/resource suite: 183 passed
  • Black and Ruff: passed
  • official amd/MiniMax-M3.1-Flash-Quark-MXFP4: all four ranks report MiniMax-M3 mono decode on; width-8/16/24/32 builds and graph capture complete
  • q=8/C2 smoke: 8/8 requests successful
  • S32 gfx950 builds: zero private scratch and zero VGPR spill, LDS <= 160 KiB; one-index-head build measured at 219 VGPR / 156,992 B LDS
  • legacy M3/S16: 227 VGPR / 104 SGPR / 155,456 B LDS, zero scratch/spill; warm 8K/C16 remained within run-to-run noise

Historical preview2 accuracy for the same native layouts:

  • GSM8K robust 0.9629
  • AIME25 79.2 / 82.5 / 82.1%, mean 81.3%

Performance

Current PR head and amd/MiniMax-M3.1-Flash-Quark-MXFP4, 4xMI355X TP4, native MXFP8 attention/shared expert and fixed 7-draft DSpark. Baseline and Mono arms differ only in ATOM_MONO_ENABLE.

SA-style AgentX validation (inferencex-agentx-mvp, SemiAnalysis/Weka 256K traces, prefix cache, 900 s arms) with synthetic accepted length 4.0 to isolate target-path performance, Mono off -> on:

  • C1: output 137.83 -> 189.01 tok/s (+37.1%), p90 ITL 4.32 -> 2.92 ms (-32.4%), p99 context 243.4K -> 243.3K
  • C3: output 220.10 -> 264.58 tok/s (+20.2%), p90 ITL 4.91 -> 4.01 ms (-18.3%), p99 context 241.0K -> 242.5K
  • C4: output 246.32 -> 344.56 tok/s (+39.9%), p90 ITL 5.03 -> 4.62 ms (-8.2%), p99 context 221.5K -> 231.6K
  • no request errors or cancellations

These are 900-second PR-validation arms, not the 3600-second full InferenceX sweep. Synthetic acceptance is performance-only and is not used for accuracy claims.

S48/C6 was prototyped and excluded because the down path required private scratch, violating the persistent-kernel all-CTA residency requirement.

@XiaobingSuper
XiaobingSuper force-pushed the hattie/minimax-m31-mono branch from 4ac438c to ac8b0fb Compare October 26, 2026 10:01
@XiaobingSuper
XiaobingSuper force-pushed the hattie/minimax-m31-native-mxfp8 branch 2 times, most recently from b3c4cdf to 8953efb Compare October 28, 2026 01:59
Zhang and others added 3 commits October 28, 2026 19:13
…ules

M3.1's layers 0..2 are sparse attention + indexer + dense MLP, which neither
the mono dense kernels (full attention) nor the MoE kernels serve, so mono
refused every M3.1 deployment: "layers 0..2 must be dense full-attention
layers".

``dense_prefix_mono`` resolves the prefix's arm once at bind time from the
layer stack. M3's dense full-attention prefix keeps the fused dense kernels
and every launch it had; M3.1's runs on the original modules through the
``run_dense`` that was already there, which leaves the first mono layer the
same (ar, res) pair in ars[0]. A model with no mono arm for its prefix binds
no DenseLayer, builds no dense kernels and needs no swiglu parameters.

``run_dense`` takes its aux list the way ``run_dense_mono`` does rather than
defaulting it to None: it is the production prefix on M3.1, where an Eagle3
aux layer among 0..2 would have appended to the default.

The first layer mono runs still has to select its own sparse blocks. The
refusal now names the layer, because M3.1 numbers its sparse layers from 0
and an index_topk_freq schedule can land a reusing layer there.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@XiaobingSuper
XiaobingSuper force-pushed the hattie/minimax-m31-mono branch from 53b8065 to a3171ee Compare October 28, 2026 11:24
Zhang and others added 4 commits October 28, 2026 19:25
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@XiaobingSuper
XiaobingSuper force-pushed the hattie/minimax-m31-native-mxfp8 branch from 8953efb to 5f4ec52 Compare October 28, 2026 11:26
Base automatically changed from hattie/minimax-m31-mono to main October 28, 2026 11:51

This branch has not been deployed

No deployments
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.

1 participant