Repository navigation
[CUDA] Fix packed-INT QMoE expert-counting capture and consume - #32942
Merged
Merged
Conversation
(cherry picked from commit 1f57e92)
Exercise INT2 SwiGLU GEMV with a dense-dequantization scratch cap, deterministic expert-dependent outputs, duplicate selections, repeated invocations, and changed routing. Verify counters are lost when packed-path capture and consume are omitted. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Copilot review overview
π’ Approval recommended
The narrow lifecycle fix matches neighboring paths and is covered by targeted numerical and counter assertions.
Review effort: Balanced
Findings: None
What changed in this PR
Fixes CUDA QMoE packed-INT GEMV expert counting and adds focused regression coverage.
Changes:
- Captures and consumes routed expert snapshots using the established lifecycle.
- Tests repeated and changed routing while preventing CPU/dense fallback.
| File | Description |
|---|---|
onnxruntime/βcontrib_ops/βcuda/βmoe/βmoe_quantization.cc |
Repairs expert snapshot handling. |
onnxruntime/βtest/βframework/βmoe_expert_counting_test.cc |
Adds packed-INT counting regression. |
π‘ Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Tianlei Wu (tianleiwu)
previously approved these changes
Sep 29, 2026
aciddelgado
enabled auto-merge (squash)
September 29, 2026 22:38
Contributor
Author
|
Copilot resolve the merge conflicts in this pull request |
β¦ed_int_expert_counting # Conflicts: # onnxruntime/test/framework/moe_expert_counting_test.cc Co-authored-by: aciddelgado <139922440+aciddelgado@users.noreply.github.com>
Contributor
Merged |
Prathik Rao (prathikr)
approved these changes
Sep 29, 2026
Baiju Meswani (baijumeswani)
approved these changes
Sep 29, 2026
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.
Description
Fix the CUDA QMoE packed-INT GEMV path's remaining reference to the removed
routing_recordAPI and add a focused expert-counting regression.before the packed-INT path returns, using the same lifecycle as the neighboring
paths. Preserve the existing non-plugin/non-minimal guards.
MoeExpertCountingTest.CudaQMoEPackedIntGemv: FP16, INT2, fused SwiGLU,three rows, four experts, top-k 1, 512-wide hidden/intermediate dimensions,
and block size 64.
duplicate routes
[0, 0, 2], a repeated invocation, then changed routes[1, 1, 1]. Expected counters are[0.1, 0, 0.1, 0],[0.19, 0, 0.19, 0], and[0.171, 0.1, 0.171, 0].successful run cannot silently use the dense fallback.
Only
moe_quantization.ccandmoe_expert_counting_test.ccchange. Routingselection and GEMV arithmetic are unchanged; no WebGPU/PagedAttention changes
are included.
Validation
Built and executed locally on NVIDIA A100-SXM4-80GB (SM80), CUDA 12.8.93,
GCC 11.4, cuDNN 9.10.2.21, Release, warnings-as-errors, QUICK_BUILD=OFF.
The existing CUDA build tree was reconfigured from SM86 to SM80, recompiling
the CUDA targets. This is not a claim of CUDA 13/GCC 14 CI validation.
After configuring with the same options plus
--update, the following buildcommand passed:
source /workspace/venv/bin/activate python tools/ci_build/build.py \ --build_dir /workspace/onnxruntime/build/cuda-ci-20260929 \ --config Release --build --parallel 16 --cmake_generator Ninja \ --build_shared_lib --build_wheel --enable_onnx_tests --use_cuda \ --use_binskim_compliant_compile_flags --nvcc_threads 4 --flash_nvcc_threads 4 \ --cuda_version=12.8 --cuda_home=/usr/local/cuda-12.8 \ --cudnn_home=/workspace/venv/lib/python3.11/site-packages/nvidia/cudnn \ --enable_cuda_profiling --skip_tests --allow_running_as_root \ --targets onnxruntime_test_all onnxruntime_provider_test \ --cmake_extra_defines CMAKE_CUDA_ARCHITECTURES=80 \ onnxruntime_BUILD_UNIT_TESTS=ON \ onnxruntime_ENABLE_CUDA_EP_INTERNAL_TESTS=ON \ onnxruntime_BUILD_CUDA_QUANT_PREPROCESS=ONTests were run from the build output directory:
Negative control: temporarily omitted both packed-path
CaptureandConsume, rebuilt withcmake --build build/cuda-ci-20260929/Release --target onnxruntime_providers_cuda --parallel 16,and ran
./onnxruntime_test_all --gtest_filter='MoeExpertCountingTest.CudaQMoEPackedIntGemv'.It failed as intended: outputs still matched, but seven counter assertions
failed because all counters remained zero (first failure: expert 0 expected
0.1, actual 0). Restored the repair, rebuilt the provider, and reran both
focused suites: all five tests passed. No negative-control edits are committed.
Motivation and Context
The expert-counting migration in #32738 left a stale
routing_record->CaptureTilecall in the packed-INT GEMV early-return path. This prevents ordinary built-in
CUDA compilation on current main; simply deleting that call would compile but
silently omit expert counts for this path.
This separates the repair originally included in #32808, following
the scope/coverage review comment.
The production patch is carried unchanged from commit
1f57e92abe; the newregression verifies the runtime counting behavior as well as compilation.
After this lands, merging main into #32808 will remove the unrelated MoE file
from that PR's diff.