Skip to content

[ROCm][Perf] Use flydsl moe with Minimax-M3 mxfp8 weights on gfx950 and implemented moe-backend selection - #46184

Merged
tjtanaa merged 15 commits into
vllm-project:mainfrom
hongxiayang:flydsl-moe
Jun 27, 2026
Merged

[ROCm][Perf] Use flydsl moe with Minimax-M3 mxfp8 weights on gfx950 and implemented moe-backend selection#46184
tjtanaa merged 15 commits into
vllm-project:mainfrom
hongxiayang:flydsl-moe

Conversation

@hongxiayang

@hongxiayang hongxiayang commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

Purpose

[ROCm][Perf] Use flydsl moe with Minimax-M3 mxfp8 weights on gfx950

aiter's flydls moe has shown perf improvement on various scenrios on mxfp8 serving on gfx950. This PR is to integrate the
support, and also have the capability to fall back to triton mxfp8 dot-scaled implementation.

Implementation and usability decisions:

Reused moe-backend aiter and triton, and refactored the moe selection logic.

Gating (the usability decision): enable FlyDSL via

  • --moe-backend aiter (explicit, capability-gated, no env),

Reason is the AITER master flag can cause lots of env needing to be disabled.

For the triton backend, added support to choose triton-native dot-scaled backend via:
--moe-backend triton-native

Added ep support in the flydsl backend as well.

Note: To invoke this aiter's flydsl moe backend, it needs to have aiter to include flydsl commit (ROCm/aiter#3811).

Thanks for the feedback from Bowen and TJ.

Test Plan

  • use nightly as base, updated aiter.
    run benchmarking and accuracy.

  • regression:
    use nightly which does not have aiter's flydsl, make sure regression works.

  • added a unit test for expected backend selection behavior.

Test Result

Sample vllm serve command:

vllm serve /weights \
  --served-model-name mm3 \
  --tensor-parallel-size 4 \
  --gpu-memory-utilization 0.90 \
  --max-model-len 9472 \
  --max-num-seqs 256 \
  --block-size 128 \
  --attention-backend TRITON_ATTN \
  --no-enable-prefix-caching \
  --moe-backend aiter \
  --port 8011 \
  --compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}'

8k-in / 1k-out, sweep concurrency

for C in 1 32 64 128; do
  vllm bench serve --backend vllm --model mm3 --tokenizer /weights \
    --base-url http://localhost:8011 --dataset-name random \
    --random-input-len 8192 --random-output-len 1024 --ignore-eos \
    --num-prompts $((C==1?8:2*C)) --max-concurrency $C
done

**1k-in / 1k-out (decode-weighted) **

vllm bench serve --backend vllm --model mm3 --tokenizer /weights \
  --base-url http://localhost:8011 --dataset-name random \
  --random-input-len 1024 --random-output-len 1024 --ignore-eos \
  --num-prompts 128 --max-concurrency 64

eval

lm_eval --model local-completions \
  --model_args model=mm3,base_url=http://localhost:8011/v1/completions,num_concurrent=200,tokenized_requests=False,tokenizer_backend=None,timeout=5000,max_length=4096 \
  --tasks gsm8k --num_fewshot 5 --output_path /tmp/gsm8k

config throughput TPOT gsm8k (full)
TP8 1k/1k +13..16% -12..14% neutral (0.9075 vs 0.9105)
TP8 8k/1k +8..16% -8..14% --
TP4 8k/1k +12..20% -11..18% neutral (0.9105 vs 0.9113)

Essential Elements of an Effective PR Description Checklist
  • The purpose of the PR, such as "Fix some issue (link existing issues this PR will resolve)".
  • The test plan, such as providing test command.
  • The test results, such as pasting the results comparison before and after, or e2e results
  • (Optional) The necessary documentation update, such as updating supported_models.md and examples for a new model.

@hongxiayang
hongxiayang marked this pull request as draft June 19, 2026 19:01
@mergify mergify Bot added the rocm Related to AMD ROCm label Jun 19, 2026
@github-project-automation github-project-automation Bot moved this to Todo in AMD Jun 19, 2026
@hongxiayang
hongxiayang marked this pull request as ready for review June 19, 2026 19:29
Comment thread vllm/model_executor/layers/fused_moe/oracle/mxfp8.py
Comment thread vllm/model_executor/layers/fused_moe/oracle/mxfp8.py Outdated
Comment thread vllm/model_executor/layers/fused_moe/experts/flydsl_mxfp8_moe.py Outdated
@hongxiayang

Copy link
Copy Markdown
Collaborator Author

the backend selection test result:

Smoke prompt Q: 17 times 24?\nA: → expect 408.

# serve config backend selected (log) outcome
2a auto (no --moe-backend) AITER_MXFP8 (FlyDSL) ready 200, smoke 408 — PASS
2b --moe-backend aiter AITER_MXFP8 (FlyDSL) ready 200, smoke 408 — PASS
3a --enable-expert-parallel (ep=4) native CDNA4 … dot_scaled ready 200, smoke 408, no crash — PASS
3b EP + --moe-backend aiter — (rejected at init) clear startup ValueError, server refused to start (port→000), no mid-run crash — PASS

@hongxiayang

Copy link
Copy Markdown
Collaborator Author

@BowenBao Thanks for the review comments. I updated the code to address your comments. please check again.
cc @tjtanaa for additional insights.

@hongxiayang

Copy link
Copy Markdown
Collaborator Author

working to get ep support.

Comment thread vllm/model_executor/layers/fused_moe/experts/aiter_mxfp8_moe.py
Comment thread vllm/model_executor/layers/fused_moe/experts/flydsl_mxfp8_moe.py Outdated
Comment thread vllm/model_executor/layers/fused_moe/oracle/mxfp8.py Outdated
Comment thread vllm/model_executor/layers/fused_moe/oracle/fp8.py Outdated
Comment thread vllm/config/kernel.py Outdated
Comment thread vllm/config/kernel.py Outdated
Comment thread tests/kernels/moe/test_mxfp8_aiter_backend_selection.py
@tjtanaa tjtanaa added the ready ONLY add when PR is ready to merge/full CI is needed label Jun 22, 2026
@hongxiayang hongxiayang changed the title [ROCm][Perf] Use flydsl moe with Minimax-M3 mxfp8 weights on gfx950 [ROCm][Perf] Use flydsl moe with Minimax-M3 mxfp8 weights on gfx950 and implemented moe-backend selection Jun 22, 2026

@tjtanaa tjtanaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM.

@tjtanaa
tjtanaa enabled auto-merge (squash) June 23, 2026 09:34
@tjtanaa

tjtanaa commented Jun 23, 2026

Copy link
Copy Markdown
Member

@hongxiayang

can you try fixing this test?

CI #73688
it is related to the changes in new pr,

(EngineCore pid=2705) ERROR 06-23 09:51:21 [core.py:1229]     self.fused_experts.apply(
(EngineCore pid=2705) ERROR 06-23 09:51:21 [core.py:1229]   File "/usr/local/lib/python3.12/dist-packages/vllm/model_executor/layers/fused_moe/experts/rocm_aiter_moe.py", line 517, in apply
(EngineCore pid=2705) ERROR 06-23 09:51:21 [core.py:1229]     result = rocm_aiter_fused_experts(
(EngineCore pid=2705) ERROR 06-23 09:51:21 [core.py:1229]              ^^^^^^^^^^^^^^^^^^^^^^^^^
(EngineCore pid=2705) ERROR 06-23 09:51:21 [core.py:1229]   File "/usr/local/lib/python3.12/dist-packages/vllm/model_executor/layers/fused_moe/experts/rocm_aiter_moe.py", line 369, in rocm_aiter_fused_experts
(EngineCore pid=2705) ERROR 06-23 09:51:21 [core.py:1229]     return rocm_aiter_ops.fused_moe(
(EngineCore pid=2705) ERROR 06-23 09:51:21 [core.py:1229]            ^^^^^^^^^^^^^^^^^^^^^^^^^
(EngineCore pid=2705) ERROR 06-23 09:51:21 [core.py:1229]   File "/usr/local/lib/python3.12/dist-packages/vllm/_aiter_ops.py", line 2209, in fused_moe
(EngineCore pid=2705) ERROR 06-23 09:51:21 [core.py:1229]     return torch.ops.vllm.rocm_aiter_fused_moe(
(EngineCore pid=2705) ERROR 06-23 09:51:21 [core.py:1229]            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(EngineCore pid=2705) ERROR 06-23 09:51:21 [core.py:1229]   File "/usr/local/lib/python3.12/dist-packages/torch/_ops.py", line 1209, in __call__
(EngineCore pid=2705) ERROR 06-23 09:51:21 [core.py:1229]     return self._op(*args, **kwargs)
(EngineCore pid=2705) ERROR 06-23 09:51:21 [core.py:1229]            ^^^^^^^^^^^^^^^^^^^^^^^^^
(EngineCore pid=2705) ERROR 06-23 09:51:21 [core.py:1229]   File "/usr/local/lib/python3.12/dist-packages/vllm/_aiter_ops.py", line 186, in _rocm_aiter_fused_moe_impl
(EngineCore pid=2705) ERROR 06-23 09:51:21 [core.py:1229]     return fused_moe(
(EngineCore pid=2705) ERROR 06-23 09:51:21 [core.py:1229]            ^^^^^^^^^^
(EngineCore pid=2705) ERROR 06-23 09:51:21 [core.py:1229] TypeError: fused_moe() got an unexpected keyword argument 'swiglu_limit'
(EngineCore pid=2705) Traceback (most recent call last):

@tjtanaa

tjtanaa commented Jun 23, 2026

Copy link
Copy Markdown
Member

Taking a closer look, this PR will break existing code as swiglu_limit is not supported by fused_moe aiter API of v0.1.13.post1, we will have to wait till we upgrade aiter version before merging.

Comment on lines +124 to +127
# Re-tag the preshuffled weights: replace_parameter drops the
# is_shuffled flag, without which aiter picks a broken CK kernel.
w1.is_shuffled = True
w2.is_shuffled = True

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.

Is it really the correct place to do that?

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.

Should it not be the role of a function similar to

def convert_to_nvfp4_moe_kernel_format(
.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for pointing this out. I am current revising the existing design to see how we could best address this in vLLM framework.

Regarding to this, historically we do not need to modify the property of the parameter tensors.
So, if you look at the convert_to_nvfp4_moe_kernel_format and other variant of conversion functions, the kernels are returning tensors. Then in the last step of the weight loading process, we are copying the tensors back into a new set of tensor object torch.Parameters . So current abstraction is not fully bullet proof. There are a few PRs has been mentioning that tensor properties and even layout information are discarded and missing at the end of the parameter instantiation. So, for now, the safest place is to add this w1.is_shuffled = True here in function itself of mxfp8 path specifically.

Comment thread vllm/model_executor/layers/fused_moe/experts/aiter_mxfp8_moe.py Outdated
@@ -0,0 +1,170 @@
# SPDX-License-Identifier: Apache-2.0

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.

I think having a new experts class is fine.

It seems up to now https://github.com/vllm-project/vllm/blob/main/vllm/model_executor/layers/fused_moe/experts/rocm_aiter_moe.py was already eventually calling into rocm_aiter_ops.fused_moe through some if/elif/else.

@hongxiayang

hongxiayang commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator Author

Taking a closer look, this PR will break existing code as swiglu_limit is not supported by fused_moe aiter API of v0.1.13.post1, we will have to wait till we upgrade aiter version before merging.

the PR bumping aiter to v0.1.16.post2 #46692 has landed

@hongxiayang

Copy link
Copy Markdown
Collaborator Author

I have run the unit tests locally for the amd-kernels-quantization-test-1-mi325-1 and amd-kernels-quantization-test-2-mi325-1, which are all passed.
THe other test which failed before is an nvidia end-to-end test, which may related to infra-frakyness.

Don't think there is anything blocking this PR from merged.

cc @tjtanaa

auto-merge was automatically disabled June 27, 2026 03:36

Head branch was pushed to by a user without write access

Co-authored-by: Tan Pin Siang <tanpinsiang@gmail.com>
Signed-off-by: tjtanaa <tunjian.tan@embeddedllm.com>
@tjtanaa
tjtanaa enabled auto-merge (squash) June 27, 2026 10:10
@tjtanaa
tjtanaa merged commit 867fd5e into vllm-project:main Jun 27, 2026
109 of 110 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in AMD Jun 27, 2026
wincent8 pushed a commit to wincent8/vllm that referenced this pull request Jun 29, 2026
…nd implemented moe-backend selection (vllm-project#46184)

Signed-off-by: Hongxia Yang <hongxia.yang@amd.com>
Signed-off-by: tjtanaa <tunjian.tan@embeddedllm.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: TJian <tunjian.tan@embeddedllm.com>
Co-authored-by: Andreas Karatzas <akaratza@amd.com>
Co-authored-by: Tan Pin Siang <tanpinsiang@gmail.com>
rjrock pushed a commit to rjrock/vllm that referenced this pull request Jul 1, 2026
…nd implemented moe-backend selection (vllm-project#46184)

Signed-off-by: Hongxia Yang <hongxia.yang@amd.com>
Signed-off-by: tjtanaa <tunjian.tan@embeddedllm.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: TJian <tunjian.tan@embeddedllm.com>
Co-authored-by: Andreas Karatzas <akaratza@amd.com>
Co-authored-by: Tan Pin Siang <tanpinsiang@gmail.com>
InfoSage05 pushed a commit to InfoSage05/vllm that referenced this pull request Jul 1, 2026
…nd implemented moe-backend selection (vllm-project#46184)

Signed-off-by: Hongxia Yang <hongxia.yang@amd.com>
Signed-off-by: tjtanaa <tunjian.tan@embeddedllm.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: TJian <tunjian.tan@embeddedllm.com>
Co-authored-by: Andreas Karatzas <akaratza@amd.com>
Co-authored-by: Tan Pin Siang <tanpinsiang@gmail.com>
Signed-off-by: Ayushman Paul <ayushman@HP.>
noooop pushed a commit to noooop/vllm that referenced this pull request Jul 9, 2026
…nd implemented moe-backend selection (vllm-project#46184)

Signed-off-by: Hongxia Yang <hongxia.yang@amd.com>
Signed-off-by: tjtanaa <tunjian.tan@embeddedllm.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: TJian <tunjian.tan@embeddedllm.com>
Co-authored-by: Andreas Karatzas <akaratza@amd.com>
Co-authored-by: Tan Pin Siang <tanpinsiang@gmail.com>
Signed-off-by: wang.yuqi <yuqi.wang@daocloud.io>
Dao007forever pushed a commit to Dao007forever/vllm that referenced this pull request Jul 18, 2026
…nd implemented moe-backend selection (vllm-project#46184)

Signed-off-by: Hongxia Yang <hongxia.yang@amd.com>
Signed-off-by: tjtanaa <tunjian.tan@embeddedllm.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: TJian <tunjian.tan@embeddedllm.com>
Co-authored-by: Andreas Karatzas <akaratza@amd.com>
Co-authored-by: Tan Pin Siang <tanpinsiang@gmail.com>
philippesic pushed a commit to philippesic/vllm-semantic-cache that referenced this pull request Jul 19, 2026
…nd implemented moe-backend selection (vllm-project#46184)

Signed-off-by: Hongxia Yang <hongxia.yang@amd.com>
Signed-off-by: tjtanaa <tunjian.tan@embeddedllm.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: TJian <tunjian.tan@embeddedllm.com>
Co-authored-by: Andreas Karatzas <akaratza@amd.com>
Co-authored-by: Tan Pin Siang <tanpinsiang@gmail.com>
plasticchris pushed a commit to plasticchris/vllm that referenced this pull request Jul 20, 2026
…nd implemented moe-backend selection (vllm-project#46184)

Signed-off-by: Hongxia Yang <hongxia.yang@amd.com>
Signed-off-by: tjtanaa <tunjian.tan@embeddedllm.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: TJian <tunjian.tan@embeddedllm.com>
Co-authored-by: Andreas Karatzas <akaratza@amd.com>
Co-authored-by: Tan Pin Siang <tanpinsiang@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready ONLY add when PR is ready to merge/full CI is needed rocm Related to AMD ROCm

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants