[XPU] Route INC WNA16 MoE to oracle backend instead of bf16 dequant - #48555
sgurwinderr wants to merge 4 commits into
Conversation
|
👋 Hi! Thank you for contributing to the vLLM project. 💬 Join our developer Slack at https://slack.vllm.ai to discuss your PR in PRs do not trigger a full CI run by default. Once the PR is approved and ready to go, your PR reviewer(s) can run CI to test the changes comprehensively before merging. To run CI, PR reviewers can either: Add If you have any questions, please reach out to us on Slack at https://slack.vllm.ai. Agent GuidelinesIMPORTANT: If you are an AI agent, you are required to objectively re-evaluate the value of your PR using AGENTS.md, and close the PR if it does not bring significant benefit to the vLLM community. Failure to do so may result in an immediate ban. 🚀 |
INCWna16Scheme.get_moe_method returned UnquantizedFusedMoEMethod for XPU, materializing every expert as full bf16. On a 24GB card an int4 AutoRound MoE (e.g. Qwen3-30B-A3B) OOMs at load. XPU already has a working quantized MoE path (the WNA16 oracle -> XPUExpertsWNA16, added in vllm-project#41426), reached via _resolve_gptq_moe -> MoeWNA16Method, so the dequant fallback is both wasteful and broken on memory-constrained cards. - Drop XPU from the dequant early-return (keep CPU, which lacks a quantized MoE path) so sym-int4 GPTQ/AutoRound flows to _resolve_gptq_moe. - Gate use_marlin off for XPU in _resolve_gptq_moe: check_moe_marlin_supports_layer is platform-agnostic, but Marlin is CUDA-only (torch.ops._C), so XPU must take the MoeWNA16Method path, not AutoGPTQMoEMethod. Verified on Arc Pro B60 with Intel/Qwen3-30B-A3B-Instruct-2507-int4-AutoRound: - Before: OOM at load ('not enough GPU memory', UnquantizedFusedMoEMethod). - After: loads and generates correctly via the XPU WNA16 backend. Fixes vllm-project#47937. Signed-off-by: gurwinderintel <gurwinder.singh@intel.com>
|
Verified on Arc Pro B60 (BMG): with The |
|
@yiliu30 Can you take a look this change? |
| # CPU does not support quantized MoE yet; fall back to dequantized bf16. | ||
| # XPU is supported via the WNA16 oracle backend (routes through | ||
| # _resolve_gptq_moe -> MoeWNA16Method -> XPUExpertsWNA16), so it must | ||
| # NOT take this dequant fallback, which OOMs materializing bf16 experts. | ||
| if current_platform.is_cpu(): |
There was a problem hiding this comment.
Hi @sgurwinderr, this part looks good to me. Thanks for the fix!
There is a similar fix in #47124.
| # Marlin is a CUDA-only path; XPU uses the WNA16 oracle backend instead | ||
| # (check_moe_marlin_supports_layer is platform-agnostic, so gate it here). | ||
| use_marlin = ( | ||
| layer_config.bits, | ||
| layer_config.sym, | ||
| ) in gptq_type_map and not current_platform.is_xpu() |
There was a problem hiding this comment.
For this part, do we really need this gate? AutoGPTQMoEMethod should support XPU as well, right?
Can we leave it as is and leverage AutoGPTQMoEMethod to construct the WNA16 method for XPU?
There was a problem hiding this comment.
Vllm-xpu-kernels uses XPUExpertsWNA16, so here is expected.
|
LGTM. |
|
Hey guys alarm! I was experimenting with MoE model on the Intel Arc B70 with the main code + this PR and found something - it will break the code (and I have a fix). It looks like this branch was started before #44120 has landed With a Qwen3.5-MoE-35B checkpoint quantized via auto-round (--format auto_round, W4A16, group_size=64, sym) -> so a different model family and group size than tested here -> stock main OOMs at load exactly as described (Using XPU Unquantized MoE backend-> bf16 experts). With this PR applied, the experts route to the WNA16 oracle and the model loads at 18.7 GiB. On current main (anything including ec59c15 / #44120, merged Jul 21 after this PR's validation), the MoeWNA16Method route crashes at the first MoE forward: What I found finally: @sgurwinderr feel free to fold this into the PR or if the maintainers prefer, it can go as a separate bugfix against #44120 since the breakage is independent of this PR. I tried main code + this PR + my patch - Qwen3.6 35B A3B with Intel's Autoround int4 finally fits 32GB |
|
@mayuyuace I guess bug is here as well (another one probably), check patch from my previous comment - after refactoring there are now checks in the code for MoeWNA16Config. I have main code + this branch + my patch - everything works on Intel B70. Without my patch on top it doesn't. (Qwen3.6 35B int4 autoround / mxfp4) |
The XPU gate added to _resolve_gptq_moe was unnecessary: AutoGPTQMoEMethod never dispatches to Marlin on XPU, since select_wna16_moe_backend's _get_priority_backends() returns [WNA16MoEBackend.XPU] and MarlinExperts._supports_current_device() requires CUDA. The gate also broke test_resolve_gptq_moe_uses_auto_gptq_when_supported, which patches both Marlin checks but not is_xpu. Revert it; _resolve_gptq_moe is now identical to main. Removing the blanket bf16 dequant in get_moe_method makes the MoeWNA16Method route newly reachable on XPU, which is broken: the oracle's XPU branch feeds weights to _process_weights_xpu, whose documented contract is AutoGPTQ's K-first int32 layout, while MoeWNA16Method registers N-first uint8. Pre-check the same conditions _resolve_gptq_moe uses to select AutoGPTQMoEMethod and keep the bf16 fallback otherwise, so only the working route is taken. This is load-bearing at TP>=4 for the target model, where a sharded intermediate size of 192 is not a multiple of the group size. Add tests for get_moe_method, which had no coverage. Signed-off-by: sgurwinderr <sgurwinderr@users.noreply.github.com>
|
Thanks all — I've reworked this. Summary of what changed and why: Removed the XPU gate in intel-ci was my fault, and this fixes it. Build 7457's @urakozz — #44120 diagnosis confirmed, taking it separately. The oracle's XPU branch is the only backend branch with no source-layout check (TRITON checks positively at Added a guard so this PR can't newly reach that broken path. Removing the blanket bf16 dequant makes @lkk12014402 — #47124 contains this PR's first hunk verbatim and the opposite of the gate I just removed. Suggest landing this smaller one first and rebasing yours. Known gap, not fixed here: the Xe2 arch check in @jikunshang — diff changed materially since your approval, could you re-review? |
|
@sgurwinderr It looks like my catch was taken care of in #50209, thx for double checking and confirming! |
|
This pull request has merge conflicts that must be resolved before it can be |
|
After PR #47124 is merged, INC model will choose AutoGPTQConfig/AutoAWQConfig for MOE backend. Bug is fixed. @sgurwinderr @urakozz |
|
Closing this — #47124 landed first and supersedes it. Thanks @lkk12014402; your PR carries the same For the record, the reworked version of this PR did go green: intel-ci #7715 passed, and Thanks @yiliu30, @mayuyuace, @urakozz and @jikunshang for the reviews. One loose end I've raised on #50209 rather than here — I don't think the |

Purpose
On XPU, loading an INC (AutoRound) int4 MoE checkpoint OOMs at model load because
INCWna16Scheme.get_moe_methodreturnsUnquantizedFusedMoEMethod, materializing every expert as full bf16. For example,Intel/Qwen3-30B-A3B-Instruct-2507-int4-AutoRoundfails to load on a 24GB card (Arc Pro B60). XPU already has a working quantized MoE path — the WNA16 oracle backend (XPUExpertsWNA16, added in #41426) — so the dequant fallback is both wasteful and broken on memory-constrained cards.Root cause
get_moe_methodshort-circuited withif current_platform.is_xpu() or current_platform.is_cpu(): return UnquantizedFusedMoEMethod(...)before reaching_resolve_gptq_moe, which builds theMoeWNA16Methodthat dispatches through the oracle toXPUExpertsWNA16. Separately,_resolve_gptq_moecomputesuse_marlinviacheck_moe_marlin_supports_layer, which is platform-agnostic — so even after falling through, XPU could pickAutoGPTQMoEMethod(Marlin,torch.ops._C, CUDA-only).Fix
_resolve_gptq_moe.use_marlinoff for XPU in_resolve_gptq_moeso XPU takes theMoeWNA16Method(oracle →XPUExpertsWNA16) path rather than the CUDA-only Marlin method.Test plan
Verified on Arc Pro B60 (BMG) with
Intel/Qwen3-30B-A3B-Instruct-2507-int4-AutoRound,--enforce-eager,max_model_len=2048:Failed to load model - not enough GPU memory ... Using XPU Unquantized MoE backend."The capital of France is Paris. ...") via the WNA16 oracle backend.The kernel dependencies for the XPU WNA16 path (vllm-xpu-kernels moe_align/silu fixes) are satisfied by the pinned kernels version.
Risk
XPU-only behavior change, gated by
current_platform.is_xpu()/is_cpu(). CPU keeps its existing dequant fallback; CUDA/ROCm Marlin selection is unchanged. The XPU path it routes to is the one already used for AWQ/GPTQ MoE on XPU.Fixes #47937.