Minimax m3 weight free export - #1317
Open
amarquic wants to merge 3 commits into
Open
Conversation
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
…oder Adds the checkpoint-key resolution, duplicate-submodule, lifted-constant, and dtype-promotion fixes needed to trace and export MiniMax-M3's decoder under torch.export/torch.onnx.export with weight_free=True (meta-device parameters, no real weights loaded at trace time): - checkpoint_key_resolver: resolve MiniMax's flattened block_sparse_moe.e_score_correction_bias checkpoint key (buffer sits one level shallower in the checkpoint than in the live module tree). - modeling_minimax_m3_vl: avoid duplicate nn.Module registration of MoEWeights (object.__setattr__ instead of plain assignment); avoid device-bound lifted scalar constants in shape/threshold comparisons; cast lm_head input to lm_head.weight.dtype consistently across all forward paths; use torch.clamp instead of torch.maximum/minimum against a device-bound constant; cast the sigmoid-router's top_k_weights back to the router's native dtype so a float32 MoE output doesn't leak into later float16-weighted layers (only visible once more than one MoE layer runs in sequence). - blocked_attention_forwards: compare start_index as a plain Python int (not a device-bound tensor) in blocked_kv_attention_forward_headpar_offline, scoped to the function MiniMax's kv_headpar blocking mode dispatches to. Validated by iteratively running examples/text_generation/minimax_m3_decode_only.py against the real MiniMax-M3 checkpoint and a local reproduction harness exercising the full 60-layer config without requiring real weights (weight-free export only needs the config at trace time). Signed-off-by: amarshar <amarshar@qti.qualcomm.com>
amarquic
force-pushed
the
minimax-m3-weight-free-export
branch
from
September 11, 2026 07:35
faac0f3 to
33a08dd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes weight-free (meta-device) torch.export/torch.onnx.export for MiniMax-M3's language decoder via QEFFAutoModelForImageTextToText. Each fix was
root-caused from a real export/compile failure surfaced by iteratively running examples/text_generation/minimax_m3_decode_only.py against the real
MiniMax-M3 checkpoint (and, for the final dtype-leak issue, a standalone repro harness that exercises the full 60-layer config directly —
weight-free export only needs the config at trace time, not real weights).
the MoE block) than the live module tree (nested under mlp.gate/block_sparse_moe.gate).
otherwise made torch.export emit duplicate gate/up/down initializers under two FQNs — only one of which promote_initializers_and_build_spec would
promote, leaving the other as an un-promoted meta tensor that fails at ONNX save().
dataless lifted constants that fail ONNX serialization.
torch.clamp(min=, max=), which accepts plain Python scalars directly.
fixing a float16/float32 Equal/matmul dtype mismatch the QAIC compiler rejected.
float32 for numerically-stable sigmoid scoring (matching upstream HF), but the derived top_k_weights was never cast back down, so moe_decode_bmm's
down * topk_weights silently promoted the MoE block's output to float32. This was invisible with --num-layers 4 (the MoE layer was the last layer
traced, and the lm_head cast mopped it up), but fatal on the real 60-layer model as soon as a later float16-weighted layer consumed the float32
activation.
compare start_index as a plain Python int rather than wrapping it in torch.tensor(start_index, device=query.device). The wrapped form traces to a
device-bound lifted tensor placeholder that has no data under meta-device tracing; the plain-int comparison traces to a scalar-comparison op with
the constant baked in as an attribute instead. Scoped to only this function, not the ~9 other occurrences of the same pattern elsewhere in the file
that back other (non-MiniMax) blocking modes.