Skip to content

Guard RTN MoE quantization by expert layout - #2616

Merged
Ti-Tai Wang (titaiwangms) merged 2 commits into
mainfrom
moe-layout-guard-fix2
Aug 12, 2026
Merged

Guard RTN MoE quantization by expert layout#2616
Ti-Tai Wang (titaiwangms) merged 2 commits into
mainfrom
moe-layout-guard-fix2

Conversation

@titaiwangms

Copy link
Copy Markdown
Contributor

Problem

PR #2584 merged RTN MoE quantization (moe=True) support without a layout check on fused-expert weights. RTN's WeightQuantizer groups unconditionally along a tensor's last dimension, which is only correct when the fused expert weight is stored (num_experts, out_features, in_features) -- K last. Architectures such as gpt-oss store the transposed (num_experts, in, out) layout instead, and are silently mis-quantized (wrong axis grouped, no error) today on main when run through moe=True.

Fix

Adds olive/passes/pytorch/moe_support.py with check_moe_layout_support, gated into RTN's _run_for_config after prepare_model() and before finalize(). The check trusts transformers's own is_transposed attribute (set by the use_experts_implementation decorator, not derived from config/checkpoint data) directly:

  • Accept only experts modules that report is_transposed is False.
  • Reject anything where is_transposed is missing or not a bool (covers older transformers releases, undecorated architectures such as llama4/aria, and unrecognized implementations).
  • Reject is_transposed=True (e.g. gpt-oss).
  • Exempt classic per-expert nn.ModuleList experts (e.g. Mixtral/PhiMoE on older transformers) that carry no direct 3D parameter.

A trust_remote_code custom experts implementation that misreports its own is_transposed is out of scope: that is treated as user-introduced misuse of an explicitly opted-in trust boundary, not a layout Olive can independently verify. No architecture allow-list is used.

Only affects the moe=True path -- gated behind if qcfg.moe: and only runs when experts modules are actually detected, so non-MoE quantization is unaffected.

Testing

28/28 relevant tests pass (test/passes/pytorch/test_moe_support.py, test/passes/pytorch/test_rtn.py); lintrunner clean.

Note: PR #2610 (GPTQ MoE) will stack on top of this branch to reuse check_moe_layout_support and avoid duplicating the layout logic.

PR #2584 merged RTN MoE quantization (moe=True) support without a layout
check on fused-expert weights. RTN's WeightQuantizer groups unconditionally
along a tensor's last dimension, which is only correct when the fused
expert weight is stored (num_experts, out_features, in_features) -- K last.
Architectures such as gpt-oss store the transposed (num_experts, in, out)
layout instead, and would be silently mis-quantized (wrong axis grouped,
no error) if run through moe=True today.

Add olive/passes/pytorch/moe_support.py with check_moe_layout_support,
gated into RTN's _run_for_config after prepare_model() and before
finalize(). The check trusts transformers' own is_transposed attribute
(set by the use_experts_implementation decorator, not derived from
config/checkpoint data) directly:

- Accept only experts modules that report is_transposed is False.
- Reject anything where is_transposed is missing or not a bool (covers
  older transformers releases, undecorated architectures such as
  llama4/aria, and unrecognized implementations).
- Reject is_transposed=True (e.g. gpt-oss).
- Exempt classic per-expert nn.ModuleList experts (e.g. Mixtral/PhiMoE on
  older transformers) that carry no direct 3D parameter, since Olive's
  quantizer selection only ever groups a module's own 3D parameters and
  a bare ModuleList structurally cannot hold one.

A trust_remote_code custom experts implementation that misreports its own
is_transposed is out of scope: that is treated as user-introduced misuse
of an explicitly opted-in trust boundary, not a layout Olive can
independently verify.

Also documents the moe flag's layout contract in
docs/source/features/quantization.md and adds unit/integration tests
covering the accept/reject/exempt paths.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e10674c1-6909-4b09-9f5a-d41b28c89d2d
Copilot AI lite review requested due to automatic review settings August 11, 2026 23:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a fail-closed safety gate for PyTorch RTN MoE quantization to prevent silent mis-quantization of fused expert weights when the expert layout is transposed (K not last). It introduces a shared check_moe_layout_support helper and updates RTN to invoke it only for MoE quantization flows, with accompanying unit tests and user-facing documentation updates.

Changes:

  • Added olive/passes/pytorch/moe_support.py with MoeSupportError and check_moe_layout_support to validate fused-experts layout safety via is_transposed.
  • Wired the layout check into olive/passes/pytorch/rtn.py for moe=True runs (before finalize/save).
  • Added/updated tests and docs to cover/reflection the new fail-closed behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
olive/passes/pytorch/rtn.py Adds the MoE layout validation gate before finalizing RTN quantization.
olive/passes/pytorch/moe_support.py Implements shared layout-safety checks and a dedicated exception type for MoE quantization support.
test/passes/pytorch/test_rtn.py Adds end-to-end RTN tests ensuring layout rejection happens before finalize and that moe=False bypasses the gate.
test/passes/pytorch/test_moe_support.py Adds unit tests for check_moe_layout_support behavior (missing/invalid is_transposed, transposed layouts, ModuleList exemptions).
docs/source/features/quantization.md Documents the new MoE support constraints for fused experts and the fail-closed behavior.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread olive/passes/pytorch/rtn.py Outdated
@jambayk
Jambay Kinley (jambayk) dismissed their stale review August 12, 2026 07:06

copilot's comment looks reasonable

…vocation's request

prepare_model ORs a pre-existing checkpoint's moe flag into the merged qcfg.moe
(quant_utils.prepare_model), so re-running RTN with moe=False on an already
MoE-quantized checkpoint incorrectly re-triggered the fused-experts layout
safety check. Gate on the current invocation's own config.moe instead.

Addresses the automated Copilot review comment on PR #2616.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e10674c1-6909-4b09-9f5a-d41b28c89d2d
@titaiwangms

Copy link
Copy Markdown
Contributor Author

Jambay Kinley (@jambayk) Done! This is ready!

@titaiwangms
Ti-Tai Wang (titaiwangms) merged commit d2bc295 into main Aug 12, 2026
13 of 14 checks passed
@titaiwangms
Ti-Tai Wang (titaiwangms) deleted the moe-layout-guard-fix2 branch August 12, 2026 20:27
Ti-Tai Wang (titaiwangms) added a commit that referenced this pull request Aug 13, 2026
## Describe your changes

Extends the PyTorch `KQuant` pass to support quantizing fused MoE expert
weights, mirroring the layout-safety approach already applied to RTN in
#2616:

- Generalizes `kquant_find_qparams` to N-D tensors so fused expert
weights of
  shape `(E, OUT, K)` can be quantized directly.
- Adds an `allow_moe`/`moe` config flag, gated behind the shared
`check_moe_layout_support` guard from `moe_support.py` so quantization
fails
closed on transposed or unverifiable expert layouts instead of silently
  producing wrong results.
- Fixes the discovery loop to use `_iter_quant_info_params` (was
silently
  skipping non-`weight`-named MoE params before).
- Fixes the MoE gate to key off this invocation's own `config.moe`
request
  rather than the merged `qcfg.moe` (same bug independently found by the
Copilot automated reviewer on #2616 and fixed there; KQuant had copied
the
  same buggy pattern).

Based on `moe-layout-guard-fix2` (#2616) since this only depends on
`moe_support.py`, not on any GPTQ-specific work in #2610/#2612.

Real-model perplexity numbers for this pass (granite-3.0-1b-a400m-base,
OLMoE-1B-7B-0924, Qwen1.5-MoE-A2.7B) are in the "KQuant PPL (Δ, time)"
column
of the three-model benchmark table in #2612's PR description, alongside
the
existing RTN/GPTQ results for the same models.

## Checklist before requesting a review
- [x] Add unit tests for this change.
- [x] Make sure all tests can pass.
- [ ] Update documents if necessary.
- [x] Lint and apply fixes to your code by running `lintrunner -a`
- [ ] Is this a user-facing change? If yes, give a description of this
change to be included in the release notes.

## (Optional) Issue link

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e10674c1-6909-4b09-9f5a-d41b28c89d2d
Ti-Tai Wang (titaiwangms) added a commit that referenced this pull request Aug 13, 2026
…ized inference (#2620)

## Describe your changes

Documents a limitation surfaced while validating KQuant/RTN MoE
quantization on a real (locally-constructed) `Qwen3MoeForCausalLM`
model: `transformers` may auto-select the `"grouped_mm"` experts
implementation at inference time (even on CPU), which internally calls
`weight.transpose(-2, -1)` on the fused-experts weight before its matmul
kernel. Olive's 3D fused-expert `QuantTensor` is storage-only and cannot
represent a transpose without a lossy dequantize/re-quantize round trip,
so this raises a `RuntimeError` at inference time -- even for
architectures whose checkpoint layout (`is_transposed=False`) is already
fully supported for quantization by `Rtn`/`Gptq`/`KQuant`.

This reproduces identically for both `Rtn` (merged, #2616) and `KQuant`
(#2618), confirming it's a shared `QuantTensor` limitation rather than a
pass-specific bug.

Adds a short doc section next to the existing "`moe` and ONNX export"
note, documenting the workaround
(`model.set_experts_implementation("eager")` before running inference)
and linking the follow-up issue.

Follow-up issue: #2619 (tracks whether the deferred "transposed layout"
(`is_transposed=True`) `QuantTensor` design work could also resolve this
as a side effect, or whether it needs separate design).

Doc-only change, no code/test changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e10674c1-6909-4b09-9f5a-d41b28c89d2d
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.

3 participants