Repository navigation
Add UnstackGatheredMatMulWeights graph surgeon for static-unroll MoE - #2739
Open
Oke Iyanuoluwa Enoch (Iyanuoluwa007) wants to merge 4 commits into
Open
Oke Iyanuoluwa Enoch (Iyanuoluwa007) wants to merge 4 commits into
Oke Iyanuoluwa Enoch (Iyanuoluwa007) wants to merge 4 commits into
Conversation
Static-unroll MoE blocks keep all expert weights in one [E, K, N] initializer and select one expert per MatMul with Gather(W_all, k, axis=0), optionally followed by Squeeze(axes=[0]). OnnxKQuantQuantization only quantizes MatMuls whose weight is an initializer, so every per-expert MatMul stayed in full precision. The new surgeon replaces gathered weights that use a constant index with 2-D initializers holding W_all[k], so a following weight-only quantizer picks them up. Gather/Squeeze nodes and stacked initializers left without consumers are removed. MatMuls with a runtime expert index are unchanged. Fixes microsoft#2489
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Generated names can collide with existing values, and overridable defaults can be incorrectly frozen during rewriting.
2 open issues
What changed in this PR
Adds a graph surgery that exposes static MoE expert weights as initializers, enabling existing weight-only quantizers to process them and addressing #2489.
Changes:
- Materializes constant expert slices and removes unused graph components.
- Adds output-equivalence and k-quant integration tests.
- Documents configuration and recommended pass ordering.
| File | Description |
|---|---|
| test/passes/onnx/test_graph_surgeries.py | Tests rewriting, cleanup, negative indices, and quantization. |
| olive/passes/onnx/graph_surgeries.py | Implements UnstackGatheredMatMulWeights. |
| docs/source/features/onnx-transformations.md | Documents the surgeon and usage. |
Review effort: Balanced
Refactor conditions to improve clarity and handle graph inputs. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
Commenter does not have sufficient privileges for PR 2739 in repo microsoft/Olive |
Contributor
Author
|
/azp run |
|
Commenter does not have sufficient privileges for PR 2739 in repo microsoft/Olive |
…dMatMulWeights - Pick new initializer names from the whole value namespace (initializers, graph inputs, graph outputs and node outputs) instead of only initializers, so an existing value named like W_all_0 can't collide with the new weight. - Skip stacked weights, expert indices and Squeeze axes that are graph inputs. Those are overridable defaults, so materializing a slice would freeze them and inference-time overrides would stop having an effect.
5 tasks
This branch has not been deployed
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.


Describe your changes
Static-unroll MoE blocks (for example the mobius Gemma 4 fallback MoE in #2489) keep the weights of all experts in a single
[E, K, N]initializer and pick one expert perMatMul:OnnxKQuantQuantizationonly quantizesMatMulnodes whose weight is an initializer, so all of these expertMatMulnodes stayed in fp16.This PR implements option B from the issue as a new graph surgeon,
UnstackGatheredMatMulWeights, which keeps k-quant focused on its job:MatMulwhose weight comes fromGather(3-D initializer, constant index, axis=0), optionally throughSqueeze(axes=[0])(axes given as an input or, for opset < 13, as an attribute), the weight is replaced with a 2-D initializer holdingW_all[k]. The same expert slice is created only once if severalMatMulnodes use it. Negative indices are supported.Gather/Squeezenodes and stacked initializers that are no longer used are removed withRemoveUnusedNodesPass.MatMulnodes whose expert index is only known at runtime are left unchanged.Usage: run
GraphSurgerieswith{"surgeon": "UnstackGatheredMatMulWeights"}beforeOnnxKQuantQuantization. The surgeon is documented indocs/source/features/onnx-transformations.md.Packing experts into a 3-D
MatMulNBitsstyle op (option A in the issue) needs ONNX Runtime kernel support and is not part of this PR.Checklist before requesting a review
Squeeze, and runtime-index experts.MatMulNBitsbefore the surgery and 2 after it.pytest test/passes/onnx/test_graph_surgeries.py: 92 passed. The 3 failures in my env needonnxruntime_genai, which is not installed, and are unrelated.)lintrunner -a(ruff 0.15.11 check and format on changed files)New
UnstackGatheredMatMulWeightsgraph surgery lets weight-only quantizers such as k-quant quantize per-expert MatMuls in static-unroll MoE models.(Optional) Issue link
Fixes #2489