Repository navigation
Commit 5d466ba
Fix QMoE SM80 FP4 init order: don't let the tactic seed throw (#32194)
### Description
<!-- Describe your changes. -->
Fix MXFP4 QMoE session initialization on Ampere by applying the SM80
grouped-GEMM routing decision **before** default tactic discovery.
The original failure was:
```text
TMA WS grouped MoE GEMM for SM80 is not compiled, and this QMoE configuration has no SM80 fallback
```
`CutlassMoeFCRunner` previously queried tactics before QMoE could call
`setUseSm80Fp4()`, so an SM80 MXFP4 runner queried the unavailable TMA
family with the provisional `false` flag.
Changes addressing the review:
- Add a defaulted `use_sm80_fp4` constructor argument and initialize
through the existing `setUseSm80Fp4()` helper, which selects both
default GEMM tactics.
- Pass the captured decision from both FP16 and BF16 primary MXFP4 QMoE
construction sites. Standard MoE, dense fallback, and other quantization
callers retain the default `false` behavior.
- Remove the blanket exception catch entirely. Unsupported
configurations and allocation failures propagate from initialization;
there is no suppressed failure or deferred error. With no remaining
`std::exception` reference, an `<exception>` include is unnecessary.
- Add six session-construction regressions covering FP16/BF16 with
`ORT_FP4_SM80_GEMM` unset, explicitly enabled, and disabled. Disable CPU
EP fallback in these regressions.
- Ensure A100 runs both the new initialization tests and the existing
parity/initializer-release tests. After merging current main, preserve
its expanded SM80+ eligibility, including SM120/121.
- Give the shared MXFP4 test graph builder explicit standard and
`com.microsoft` opset imports so the regression models also pass the
ONNX checker.
- Merge current main and resolve the two overlapping QMoE/test edits,
retaining main's new empty-tactic initialization check and expanded
architecture support.
#### Validation of this revision
Run from a neutral directory with the transformers helper directory on
`PYTHONPATH`, using the existing isolated Python environment:
```powershell
python -m pytest C:\Users\gnallasamy\Codes\onnxruntime-pr32194\onnxruntime\test\python\transformers\test_qmoe_fp4_cuda.py -q -rs -k 'TestFP4PackingUtility or TestQMoEFP4Sm80SingleWeightCopy'
```
**Result:** 4 passed, 15 skipped, 19 deselected. The skips are 14 CUDA
cases (including all six new initialization cases) and one unavailable
native packing binding. These skips are **not GPU validation**.
```powershell
lintrunner --take CLANGFORMAT,RUFF,RUFF-FORMAT onnxruntime\contrib_ops\cuda\llm\moe_gemm\moe_kernels.h onnxruntime\contrib_ops\cuda\llm\moe_gemm\moe_kernels.cu onnxruntime\contrib_ops\cuda\moe\moe_quantization.cc onnxruntime\test\python\transformers\test_qmoe_fp4_cuda.py
git diff --check
```
**Result:** both passed.
Additional focused runtime checks passed: Python syntax parsing, ONNX
checker validation of the actual FP16/BF16 regression graphs, acceptance
of SM80/86/89/90/100/119/120/121 and exclusion of SM79 by the regime
gate, and environment override/restoration for all three modes.
**Still required before merge:** build the revised CUDA provider and
execute the targeted tests on an SM80/A100 CUDA 12.8+ FP4-QMoE-enabled
build. This Windows validation environment has an SM86 RTX A1000,
CPU-only Python test packages, and no CUDA toolkit; it cannot compile or
execute the revised CUDA implementation. Also confirm the new-head CI
results and obtain maintainer approval.
#### Historical author-reported validation
The original revision was exercised on A100-80GB (SM80), using
`openai/gpt-oss-20b` MXFP4 with ONNX Runtime GenAI continuous batching.
The reported SM80 path initialized successfully, used 24,149 MiB peak
GPU memory versus approximately 49,800 MiB for the dequant fallback,
loaded in 4.56 s versus approximately 5.9 s, and had exact output
parity. This empirical run predates the constructor-plumbing revision
above and has **not** been repeated for it.
### Motivation and Context
<!-- - Why is this change required? What problem does it solve?
- If it fixes an open issue, please link to the issue here. -->
The SM80 MXFP4 grouped-GEMM path is selected by default on supported
GPUs, but tactic discovery during runner construction happened before
that selection was applied. This made the intended Ampere path
unreachable at session initialization.
Passing the decision into construction fixes the ordering at its source
without suppressing unrelated initialization failures in the shared MoE
runner. Regression coverage now includes the affected SM80 architecture
instead of skipping it.
---------
Co-authored-by: Gopalakrishnan Nallasamy <gopalakrishnan.nallasamy@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent 73b0fc6 commit 5d466ba
5 files changed
Lines changed: 39 additions & 19 deletions
File tree
- onnxruntime
- contrib_ops/cuda
- llm/moe_gemm
- moe
- test/python/transformers
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
671 | 671 | | |
672 | 672 | | |
673 | 673 | | |
674 | | - | |
675 | | - | |
676 | | - | |
677 | | - | |
| 674 | + | |
| 675 | + | |
678 | 676 | | |
679 | 677 | | |
680 | 678 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2216 | 2216 | | |
2217 | 2217 | | |
2218 | 2218 | | |
2219 | | - | |
| 2219 | + | |
| 2220 | + | |
2220 | 2221 | | |
2221 | 2222 | | |
2222 | 2223 | | |
2223 | 2224 | | |
2224 | | - | |
2225 | | - | |
2226 | | - | |
2227 | | - | |
2228 | | - | |
| 2225 | + | |
| 2226 | + | |
2229 | 2227 | | |
2230 | 2228 | | |
2231 | 2229 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
415 | 415 | | |
416 | 416 | | |
417 | 417 | | |
418 | | - | |
| 418 | + | |
| 419 | + | |
419 | 420 | | |
420 | 421 | | |
421 | 422 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
621 | 621 | | |
622 | 622 | | |
623 | 623 | | |
624 | | - | |
| 624 | + | |
625 | 625 | | |
626 | 626 | | |
627 | | - | |
| 627 | + | |
628 | 628 | | |
629 | 629 | | |
630 | 630 | | |
| |||
638 | 638 | | |
639 | 639 | | |
640 | 640 | | |
641 | | - | |
642 | | - | |
643 | | - | |
644 | | - | |
645 | 641 | | |
646 | 642 | | |
647 | 643 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
312 | 312 | | |
313 | 313 | | |
314 | 314 | | |
315 | | - | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
316 | 318 | | |
317 | 319 | | |
318 | 320 | | |
| |||
925 | 927 | | |
926 | 928 | | |
927 | 929 | | |
928 | | - | |
| 930 | + | |
929 | 931 | | |
| 932 | + | |
| 933 | + | |
930 | 934 | | |
931 | 935 | | |
932 | 936 | | |
| |||
969 | 973 | | |
970 | 974 | | |
971 | 975 | | |
| 976 | + | |
| 977 | + | |
| 978 | + | |
| 979 | + | |
| 980 | + | |
| 981 | + | |
| 982 | + | |
| 983 | + | |
| 984 | + | |
| 985 | + | |
| 986 | + | |
| 987 | + | |
| 988 | + | |
| 989 | + | |
| 990 | + | |
| 991 | + | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
| 995 | + | |
| 996 | + | |
| 997 | + | |
| 998 | + | |
972 | 999 | | |
973 | 1000 | | |
974 | 1001 | | |
| |||
0 commit comments