Skip to content

[ROCm][MoE] Split AiterExperts by weight-quantization key - #60322

Merged
AndreasKaratzas merged 8 commits into
vllm-project:mainfrom
divakar-amd:aiter-moe-experts-split-by-quant-scheme
Oct 13, 2026
Merged

AndreasKaratzas merged 8 commits into
vllm-project:mainfrom
divakar-amd:aiter-moe-experts-split-by-quant-scheme

Conversation

@divakar-amd

@divakar-amd divakar-amd commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Split AITER experts by weight quantization key. Splits the single catch-all AiterExperts modular-kernel class into five narrower leaf classes, one per weight-quantization scheme:

  • AiterUnquantizedExperts — (None, None)
  • AiterFp8BlockExperts — (kFp8Static128BlockSym, kFp8Dynamic128Sym)
  • AiterFp8TensorExperts — (kFp8StaticTensorSym, {Static,Dynamic}TensorSym)
  • AiterFp8ChannelExperts — (kFp8StaticChannelSym, kFp8DynamicTokenSym)
  • AiterMxfp4Experts — (kMxfp4Static, {None, kMxfp4Dynamic}), gfx950-only

AiterExperts becomes a shared, non-instantiable base class. All other methods (apply(), workspace_shapes(), device/activation/parallel-config gating, weight-conversion dispatch) stay on the base since they're already scheme-agnostic at runtime — only _supports_quant_scheme() meaningfully diverges per scheme, so that's the only thing that moved into the leaves. This is intentionally scoped narrowly: apply()'s internal quant_method derivation, the asm_moe_tkw1 dispatch, and MXFP4's gate_mode/bias selection all remain in the shared base, still keyed off runtime quant_config flags rather than owned per-leaf. Moving quant_method down is a reasonable follow-up; gate_mode is more tangled (it checks activation == SITU before weight-quant key) and likely stays shared. Issue #54966's "own apply()/scale contract per leaf" isn't done by this step — only the scheme-gating (_supports_quant_scheme) is.

This mirrors the pattern already used by the Cutlass family (CutlassExpertsFp8Base, CutlassExpertsNvfp4, CutlassExpertsMxfp4), where AiterExperts was the remaining monolithic outlier. Part of #54966

Test plan

MI300 (gfx942), dv_DistriDPBasic container, HIP_VISIBLE_DEVICES=0,1,2,3:

pytest -x -v tests/kernels/moe/test_modular_kernel_combinations.py -k "aiter"
pytest -x -v tests/kernels/moe/test_rocm_aiter_moe.py
pytest -x -v tests/kernels/moe/test_mori_moe.py
pytest -x -v tests/kernels/moe/test_moe_layer.py -k "mori or aiter"
pytest -x -v tests/kernels/moe/test_topk_softplus_sqrt.py

All green. Also ran the full tests/kernels/moe/ suite as a broader regression sanity check (ROCm/AITER-only change; no CUDA or other-backend code paths touched); all observed failures traced to a pre-existing, unrelated triton-version environment issue (is_hip_gfx1250 import error) or full-suite resource contention, not this change — confirmed by rerunning the affected tests standalone.

MI350 (gfx950), same test files — all green, including the three gfx950-only numeric MXFP4 tests:

  • test_aiter_mxfp4_quant_scheme_support_matches_gfx950 — PASSED
  • test_aiter_fused_moe_mi350_mxfp4_w4a16_accuracy — PASSED, 100% match (16384/16384) against the dequantized MXFP4 reference
  • test_aiter_fused_moe_mi350_mxfp4_w4a16_determinism — PASSED

Merged with main (resolving the conflict in test_modular_kernel_combinations.py) and re-ran the full test plan on MI355 (gfx950), twice, on two disjoint GPU sets (HIP_VISIBLE_DEVICES=0,1,2,3 and 4,5,6,7), identical results both times:

Known limitations / follow-up

  • AiterMxfp4Experts's harness registration (mk_objects.py) doesn't currently produce any modular-kernel test case — MK_QUANT_CONFIGS has no quant_dtype="mxfp4" entry, so it's registered but unreachable. Real MXFP4 modular-kernel coverage is tracked separately in [ROCm][MoE] Add AITER MXFP4 W4A16/W4A4 modular-kernel test coverage #60886.
  • This PR only moves _supports_quant_scheme() to the leaves (see Summary); other scheme-specific runtime dispatch stays in the shared base for now.

Bugs found and fixed along the way

Why this isn't a duplicate

No PR performs this exact split. #59333/#59334 (merged into main after this PR was opened) do instantiate AiterExperts directly in two new tests — as noted above, merging main surfaced this as a real incompatibility, now fixed by picking the correct leaf class in both tests.

AI assistance disclosure

This change was developed with AI assistance (Claude Code),

Break up the single catch-all AiterExperts modular-kernel class into
five narrower leaf classes, one per weight-quantization scheme:

  - AiterUnquantizedExperts  (None, None)
  - AiterFp8BlockExperts     (kFp8Static128BlockSym, kFp8Dynamic128Sym)
  - AiterFp8TensorExperts    (kFp8StaticTensorSym, {Static,Dynamic}TensorSym)
  - AiterFp8ChannelExperts   (kFp8StaticChannelSym, kFp8DynamicTokenSym)
  - AiterMxfp4Experts        (kMxfp4Static, {None,kMxfp4Dynamic}), gfx950-only

AiterExperts becomes a shared, non-instantiable base class (all other
methods -- apply(), workspace_shapes(), device/activation/parallel-config
gating, weight-conversion dispatch -- stay on the base since they are
already scheme-agnostic at runtime). This mirrors the existing pattern
used by the Cutlass family (CutlassExpertsFp8Base, CutlassExpertsNvfp4,
CutlassExpertsMxfp4), where AiterExperts was the remaining catch-all
outlier.

Update the oracle backend_to_kernel_cls() mappings (fp8.py, mxfp4.py,
unquantized.py) to return the appropriate leaf class(es) instead of the
old monolithic class; existing multi-class-list consumers already
iterate correctly so no further changes were needed there.

Update the modular-kernel test harness (mk_objects.py) to register each
leaf class with its own supported dtypes instead of one class registered
fp8_types-only -- this was silently excluding the unquantized and MXFP4
cases from ever being exercised by the harness. Convert `is AiterExperts`
identity checks in test_modular_kernel_combinations.py to
`issubclass(_, AiterExperts)` (safe: Config.fused_experts_type is a
required, non-Optional field, never None), and update direct-construction
call sites / parametrize tables in test_mori_moe.py, test_rocm_aiter_moe.py,
and test_topk_softplus_sqrt.py to reference the correct leaf class.

ROCm/AITER-only change; no CUDA or other-backend code paths touched.

Test plan:
  pytest -x -v tests/kernels/moe/test_modular_kernel_combinations.py -k "aiter"
  pytest -x -v tests/kernels/moe/test_rocm_aiter_moe.py
  pytest -x -v tests/kernels/moe/test_mori_moe.py
  pytest -x -v tests/kernels/moe/test_moe_layer.py -k "mori or aiter"
  pytest -x -v tests/kernels/moe/test_topk_softplus_sqrt.py
All green on MI300 (gfx942) in the dv_DistriDPBasic container
(HIP_VISIBLE_DEVICES=0,1,2,3). Full tests/kernels/moe/ suite also run
as a regression sanity check; all failures traced to a pre-existing,
unrelated triton-version environment issue or full-suite resource
contention, not this change.

MXFP4 leaf (AiterMxfp4Experts) is a mechanical, behavior-preserving
relocation of the existing gfx950/gfx1250 gate, verified via code
review and the gfx950-independent gate-logic unit test
(test_aiter_mxfp4_quant_scheme_support_matches_gfx950); full numeric
MXFP4 verification remains blocked on MI350/gfx950 hardware access,
consistent with the existing status of steps 1b/2b in the issue's
test-coverage plan.

Signed-off-by: Divakar Verma <divakar.verma@amd.com>
@mergify mergify Bot added quantization rocm Related to AMD ROCm labels Oct 7, 2026
…eme split

Package-level re-export and the design doc's kernel table still
referenced the now-abstract AiterExperts base class instead of the new
concrete leaf classes:

- vllm/model_executor/layers/fused_moe/__init__.py re-exported
  AiterExperts directly. Since it's no longer instantiable, this is a
  behavior change for anything constructing it via this import path.
  Following the existing convention for CutlassExpertsFp8Base (whose
  abstract base is never re-exported, only its concrete leaves), export
  the 5 concrete leaf classes instead.
- docs/design/moe_kernel_features.md's "Fused Experts Kernels" table
  listed `AiterExperts` as the rocm aiter moe row's representative
  modular class; update to list the 5 leaf classes with proper mkdocstrings
  cross-reference links, matching every other row in the table.

Found via a full-repo grep for all AiterExperts references (not just the
files already known to reference it) plus a check for any reflection-based
class registries (__subclasses__, etc.) that might also need updating --
none found.

No functional/test behavior change: nothing in-repo constructs AiterExperts
via the top-level package import or relies on class-based reflection.

Signed-off-by: Divakar Verma <divakar.verma@amd.com>
@mergify

mergify Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Documentation preview: https://vllm--60322.org.readthedocs.build/en/60322/

@mergify mergify Bot added the documentation Improvements or additions to documentation label Oct 7, 2026
@divakar-amd
divakar-amd marked this pull request as ready for review October 7, 2026 02:16
Copilot AI balanced review requested due to automatic review settings October 7, 2026 02:16

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

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.

Copilot review overview

🟡 Changes recommended

The claimed MXFP4 modular-harness coverage remains unreachable, and the updated feature matrix contains incorrect capability information.

Review effort: Balanced
Findings: 1 Medium severity · 1 Low severity

Open (2)
What changed in this PR

Splits the ROCm AITER MoE implementation into quantization-specific expert classes and updates selection, exports, tests, and documentation accordingly.

Changes:

  • Adds five quantization-specific AiterExperts subclasses.
  • Updates backend oracles and tests to select the appropriate subclass.
  • Registers the subclasses in the modular-kernel test harness.
File Description
vllm/​model_executor/​layers/​fused_moe/​oracle/​unquantized.py Selects the unquantized AITER class.
vllm/​model_executor/​layers/​fused_moe/​oracle/​mxfp4.py Selects the MXFP4 AITER class.
vllm/​model_executor/​layers/​fused_moe/​oracle/​fp8.py Selects among FP8 AITER classes.
vllm/​model_executor/​layers/​fused_moe/​experts/​rocm_aiter_moe.py Introduces quantization-specific subclasses.
vllm/​model_executor/​layers/​fused_moe/​__init__.py Re-exports the new classes.
tests/​kernels/​moe/​test_topk_softplus_sqrt.py Updates expected MXFP4 class selection.
tests/​kernels/​moe/​test_rocm_aiter_moe.py Updates MXFP4 support checks.
tests/​kernels/​moe/​test_mori_moe.py Chooses the appropriate MoRI expert class.
tests/​kernels/​moe/​test_modular_kernel_combinations.py Recognizes AITER subclasses in test logic.
tests/​kernels/​moe/​modular_kernel_tools/​mk_objects.py Registers per-scheme AITER classes.
docs/​design/​moe_kernel_features.md Links the new expert classes.

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

(AiterFp8BlockExperts, fp8_types),
(AiterFp8TensorExperts, fp8_types),
(AiterFp8ChannelExperts, fp8_types),
(AiterMxfp4Experts, mxfp4_types),
Comment thread docs/design/moe_kernel_features.md Outdated
The AiterExperts leaf classes are FusedMoEExpertsModular subclasses
(Modular: N -> Y), AiterUnquantizedExperts supports the unquantized
(None, None) scheme, and the shared base's _supports_activation()
accepts MoEActivation.SITU. Update the table row to reflect this.

Signed-off-by: Divakar Verma <divakar.verma@amd.com>
@fxmarty-amd

Copy link
Copy Markdown
Contributor

🔥🔥🔥

@divakar-amd

Copy link
Copy Markdown
Contributor Author

/ci run

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown

✅ Triggered Buildkite CI #93301 for commit 04f4d2cdeb36.

output.copy_(result)


class AiterUnquantizedExperts(AiterExperts):

@fxmarty-amd fxmarty-amd Oct 7, 2026 •

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 there any other logic that is weight quant key-specific from the parent class that could be ported in the children? Let me know if it makes sense or not / this could also be left as is or done later.

things like:

quant_method = QuantMethod.NO.value
# mxfp4 i.e. w4a4, w4a16 uses BLOCK_1X32
# mxfp6 and mxfp8 are unsupported in AITER currently and use emulation instead
if quant_config.use_mxfp4_w4a4 or quant_config.use_mxfp4_w4a16:
quant_method = QuantMethod.BLOCK_1X32.value
# w8a8 block-scaled
if quant_config.block_shape is not None and quant_config.use_fp8_w8a8:
assert not apply_router_weight_on_input, (
"apply_router_weight_on_input is not supported for block scaled moe"
)
assert quant_config.w1_scale is not None
assert quant_config.w2_scale is not None
quant_method = QuantMethod.BLOCK_128x128.value
elif quant_config.use_fp8_w8a8 and quant_config.per_out_ch_quant:
quant_method = QuantMethod.PER_TOKEN.value
elif quant_config.use_fp8_w8a8:
# Currently only per tensor quantization method is enabled.
quant_method = QuantMethod.PER_TENSOR.value

elif quant_config.use_mxfp4_w4a16:
if moe_config.use_mxfp4_w4a4_dsv4:
# Opt-in a4w4 for DeepSeek V4.1 (VLLM_ROCM_USE_AITER_MOE_A4W4_DSV4=1).
# Must match the SEPARATED weight shuffle from load time.
from aiter import dtypes
gate_mode = GateMode.SEPARATED.value
q_dtype_a = dtypes.fp4x2
else:
gate_mode = GateMode.INTERLEAVE.value
elif activation_interleave is not None:
gate_mode = (
GateMode.INTERLEAVE.value
if activation_interleave
else GateMode.SEPARATED.value
)

this is simply with the goal of making AiterExperts less obscure and more easily debuggable.

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.

Also if there is, any restriction on weight quant key / activation quant key / activation / gate_mode combination.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Regarding, porting it down to the children: Yeah, that can be moved down, mainly the quant_method derivation. It is basically the same split we just did for _supports_quant_scheme(). We can keep the scope narrow in this PR since apply() didn't strictly need to change for the split to be correct, but I'm happy to push this as a follow-up.

The gate_mode logic is a bit more tangled since it checks activation == SITU before weight quant key, so it doesn't split as cleanly per class. I'd lean toward leaving that one in the shared function.

@vllm-agent

vllm-agent commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

CI selector (shadow): 75 test steps (126 jobs) instead of 69 (92 jobs)

Shadow mode: this changes nothing about what CI runs. It shows what the evidence-based selector would pick for this PR, next to today's rules. How it works.

Feedback welcome: reply here if it would skip a step this change needs, or runs something unrelated.

steps (jobs) Today's rules Selector Would skip Would add
NVIDIA, CPU and others 69 (92) 75 (126) 36 (45) 42 (79)
AMD mirrors 81 (121) 155 (215) 2 (2) 76 (96)
Selector would run (75)
  • amd-fp8-moe-kernels-mi355
  • amd-kernels-mi355
  • amd-lm-eval-small-models-harness
  • amd-native-quantization-kernels-mi355
  • amd-qwen3-next-mtp-async-eplb-accuracy
  • arm-cpu-test ×3
  • basic-models-test-other-cpu
  • basic-models-tests-extra-initialization ×14
  • basic-models-tests-initialization
  • basic-models-tests-other
  • batch-invariance-b200
  • batch-invariance-h100
  • cpu-kernel-tests ×2
  • cpu-quantization-model-tests
  • crosslayer-kv-layout-distributed-nixlconnector-pd-accuracy-tests-4-gpus
  • deepseek-v4-kernel-test-b200
  • distributed-dp-tests-2-gpus
  • distributed-dp-tests-4-gpus
  • distributed-flashinfer-nixlconnector-pd-accuracy-4-gpus
  • distributed-model-tests-2-gpus ×3
  • distributed-nixlconnector-pd-accuracy-4-gpus
  • distributed-torchrun-examples-4-gpus
  • dp-ep-distributed-nixlconnector-pd-accuracy-tests-4-gpus
  • dsv41-mono-decode-numerics-amd
  • e2e-core-1-gpu
  • e2e-core-large-memory
  • elastic-ep-scaling-test
  • entrypoints-integration-api-server ×4
  • entrypoints-integration-api-server-generate
  • entrypoints-integration-api-server-openai-chat_completion
  • entrypoints-integration-api-server-openai-completion
  • entrypoints-integration-responses-api
  • fault-tolerance-e2e-2xh100
  • fusion-e2e-quick-h100
  • fusion-e2e-tp2-ar-rms-dynamo-partition-amd
  • fusion-e2e-tp2-ar-rms-inductor-partition-amd
  • fusion-e2e-tp2-b200
  • fusion-e2e-tp2-quick-h100
  • hybrid-ssm-nixlconnector-pd-accuracy-tests-4-gpus
  • hybrid-ssm-nixlconnector-pd-prefix-cache-2-gpus
  • kernels-b200 ×3
  • kernels-core-operation-test ×3
  • kernels-deepgemm-test-h100
  • kernels-fusedmoe-layer-test-2-b200s
  • kernels-fusedmoe-layer-test-2-h100s
  • kernels-moe-test ×5
  • kernels-quantization-test ×6
  • kernels-root-misc-test-b200
  • kimi-k3-prefix-cache-4xb200 ×2
  • kimi-k3-unit-tests-b200
  • kv-offload-large
  • kv-offload-medium
  • language-models-tests-granite-l4-compatibility
  • language-models-tests-hybrid ×2
  • language-models-tests-standard
  • lm-eval-small-models
  • lora ×4
  • lora-tp-distributed ×4
  • model-executor
  • multi-modal-models-standard-4-other-whisper
  • multi-modal-processor ×4
  • pipeline-context-parallelism-4-gpus
  • push-nixlconnector-pp-prefill-pd-accuracy-4-gpus
  • pytorch-compilation-unit-tests-h100
  • pytorch-fullgraph-test
  • quantization ×4
  • quantized-models-test
  • quantized-moe-test-b200
  • replayssm-e2e
  • rust-frontend-distributed
  • sharded-rdt-weight-transfer
  • spec-decode-draft-model ×4
  • spec-decode-eagle-1-deepseek-qwen
  • spec-decode-mtp-deepseek-mimo
  • v1-executor-worker
Would skip (today's rules run them) (36)
  • ascend-npu-test
  • async-engine-inputs-utils-worker
  • basic-correctness ×2
  • basic-correctness-cpu-offload
  • basic-correctness-cumem
  • basic-correctness-prefetch-offload
  • basic-correctness-sleep-mode
  • benchmarks-cli-test
  • cpu-language-generation-and-pooling-model-tests ×3
  • distributed-compile-unit-tests-2xh100
  • entrypoints-integration-llm
  • entrypoints-integration-multimodal
  • entrypoints-integration-pooling
  • entrypoints-integration-speech_to_text
  • kernels-fla-ops-test-b200
  • kernels-mhc-test-b200
  • metrics-tracing-2-gpus
  • multi-modal-models-standard-1-qwen2
  • multi-modal-models-standard-2-qwen3-gemma
  • multi-modal-models-standard-3-llava-qwen2-vl
  • multi-modal-processor-cpu ×4
  • pytorch-compilation-dynamic-shapes
  • pytorch-compilation-passes-unit-tests
  • pytorch-compilation-unit-tests
  • pytorch-fullgraph-cudagraph-l4-compatibility
  • regression
  • rl-entrypoints-tests
  • samplers-multimodal-beam-search
  • samplers-test
  • v1-core
  • v1-kv-connectors ×4
  • v1-kv-offload
  • v1-logits-oracle
  • v1-metrics-lmeval
  • v1-sample
  • v1-spec-decode
Would add (today's rules do not run them) (42)
  • amd-kernels-mi355 (code map)
  • amd-lm-eval-small-models-harness (code map)
  • amd-native-quantization-kernels-mi355 (code map)
  • arm-cpu-test ×3 (code map)
  • basic-models-tests-extra-initialization ×14 (Python record)
  • cpu-kernel-tests ×2 (code map)
  • cpu-quantization-model-tests (code map)
  • crosslayer-kv-layout-distributed-nixlconnector-pd-accuracy-tests-4-gpus (Python record)
  • deepseek-v4-kernel-test-b200 (code map)
  • distributed-dp-tests-2-gpus (Python record)
  • distributed-dp-tests-4-gpus (Python record)
  • distributed-flashinfer-nixlconnector-pd-accuracy-4-gpus (Python record)
  • distributed-model-tests-2-gpus ×3 (Python record)
  • distributed-nixlconnector-pd-accuracy-4-gpus (Python record)
  • distributed-torchrun-examples-4-gpus (Python record)
  • dp-ep-distributed-nixlconnector-pd-accuracy-tests-4-gpus (Python record)
  • dsv41-mono-decode-numerics-amd (code map)
  • e2e-core-1-gpu (Python record)
  • e2e-core-large-memory (Python record)
  • elastic-ep-scaling-test (Python record)
  • fault-tolerance-e2e-2xh100 (Python record)
  • hybrid-ssm-nixlconnector-pd-accuracy-tests-4-gpus (Python record)
  • hybrid-ssm-nixlconnector-pd-prefix-cache-2-gpus (Python record)
  • kernels-b200 ×3 (code map)
  • kernels-core-operation-test ×3 (code map)
  • kernels-quantization-test ×6 (code map)
  • kimi-k3-prefix-cache-4xb200 ×2 (Python record)
  • kimi-k3-unit-tests-b200 (code map)
  • kv-offload-large (Python record)
  • kv-offload-medium (Python record)
  • lm-eval-small-models (Python record)
  • lora ×4 (code map)
  • pipeline-context-parallelism-4-gpus (Python record)
  • push-nixlconnector-pp-prefill-pd-accuracy-4-gpus (Python record)
  • quantization ×4 (code map)
  • quantized-models-test (code map)
  • replayssm-e2e (Python record)
  • rust-frontend-distributed (Python record)
  • sharded-rdt-weight-transfer (Python record)
  • spec-decode-draft-model ×4 (Python record)
  • spec-decode-eagle-1-deepseek-qwen (Python record)
  • spec-decode-mtp-deepseek-mimo (Python record)
AMD mirrors: would skip (2)
  • kernels-fla-ops-test-b200
  • platform-tests
AMD mirrors: would add (76)
  • crosslayer-kv-layout-distributed-nixlconnector-pd-accuracy-tests-4-gpus (code map)
  • cudagraph (code map)
  • deepseek-v4-kernel-test-h100 (code map)
  • distributed-comm-ops (code map)
  • distributed-compile-comm-4-gpus (code map)
  • distributed-compile-rpc-tests-2-gpus (code map)
  • distributed-dp-tests-2-gpus (code map)
  • distributed-dp-tests-4-gpus (code map)
  • distributed-flashinfer-nixlconnector-pd-accuracy-4-gpus (code map)
  • distributed-mooncakeconnector-pd-accuracy-4-gpus (code map)
  • distributed-nixlconnector-pd-accuracy-4-gpus (code map)
  • distributed-tests-8xh100 (code map)
  • distributed-torchrun-examples-4-gpus (code map)
  • distributed-torchrun-shutdown-tests-2-gpus (code map)
  • dp-ep-distributed-nixlconnector-pd-accuracy-tests-4-gpus (code map)
  • e2e-core-1-gpu (code map)
  • e2e-core-large-memory (code map)
  • e2e-scheduling-1-gpu (code map)
  • e2e-scheduling-accuracy-1-gpu (code map)
  • engine (code map)
  • engine-1-gpu (code map)
  • entrypoints-unit-tests (code map)
  • examples (code map)
  • extract-hidden-states-integration (code map)
  • extract-hidden-states-integration-2-gpus (code map)
  • fusion-e2e-config-sweep-h100 (code map)
  • gemm-rs-ar-2xb200 (code map)
  • glm5next-unit-tests (code map)
  • hybrid-ssm-nixlconnector-pd-accuracy-tests-4-gpus (code map)
  • hybrid-ssm-nixlconnector-pd-prefix-cache-2-gpus (code map)
  • inkling-unit-tests-b200 (code map)
  • jit-monitor-no-runtime-jit (code map)
  • kernels-attention-test ×7 (code map)
  • kernels-b200 ×3 (code map)
  • kernels-core-operation-test ×3 (code map)
  • kernels-flashmla-test-h100 (code map)
  • kernels-mamba-test (code map)
  • kernels-minimax-reduce-rms-test-2-gpus (code map)
  • kernels-quantization-test ×6 (code map)
  • kimi-k3-unit-tests-b200 (code map)
  • kv-offload-large (code map)
  • kv-offload-medium (code map)
  • kv-offload-small (code map)
  • lm-eval-dspark-watermark-2xh100 (code map)
  • lm-eval-small-models (code map)
  • lm-eval-turboquant-k3v4nc (code map)
  • lm-eval-turboquant-k8v4 (code map)
  • lm-eval-turboquant-t3nc (code map)
  • lm-eval-turboquant-t4nc (code map)
  • lm-eval-watermarking (code map)
  • lora ×4 (code map)
  • mooncake-ec-tcp-e2e-2-gpus (code map)
  • mrcr-eval-small-models (code map)
  • multi-modal-accuracy-eval-small-models (code map)
  • multiconnector-nixl-offloading-pd-accuracy-2-gpus (code map)
  • multiconnector-nixl-offloading-pd-edge-cases-2-gpus (code map)
  • nixlconnector-pd-edge-cases-2-gpus (code map)
  • nixlconnector-pd-spec-decode-acceptance-2-gpus (code map)
  • plugin-tests-2-gpus (code map)
  • push-nixlconnector-pp-prefill-pd-accuracy-4-gpus (code map)
  • pytorch-nightly-dependency-override-check (code map)
  • quantized-fusions (code map)
  • quantized-models-test (code map)
  • qwen4-exp-unit-tests (code map)
  • ray-dependency-compatibility-check (code map)
  • rayexecutorv2-4-gpus (code map)
  • rust-frontend-core-correctness (code map)
  • rust-frontend-distributed (code map)
  • rust-frontend-openai-coverage (code map)
  • rust-frontend-serve-admin-coverage (code map)
  • rust-frontend-tool-use (code map)
  • scale-out-ec-e2e-2-gpus (code map)
  • sharded-rdt-weight-transfer (code map)
  • torch-stable-abi-audit (code map)
  • v1-attention-b200 ×2 (code map)
  • v1-attention-h100-mi300 ×2 (code map)

13 changed files · base fe341a53dd · head 1b6ae65b56 · Python record: build 93039 at 1e5d0ea888 · kernel record: table 74f4404 (build 94125), map 74f4404 · not counted: 11 build steps, 5 A100 steps the generator no longer emits, 110 optional steps the selector would also run

@fxmarty-amd fxmarty-amd 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.

LGTM with comment above. I think we could split much further but this can be done later on

note: did not run agent review

@mergify

mergify Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

This pull request has merge conflicts that must be resolved before it can be
merged. Please rebase the PR, @divakar-amd.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase label Oct 8, 2026

@AndreasKaratzas AndreasKaratzas 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.

Tested on MI355 (gfx950), PR head 04f4d2cdeb, VLLM_ROCM_USE_AITER=1 VLLM_ROCM_USE_AITER_MOE=1, GPUs 0-3.

Test (author's plan + tests/rocm/test_moe_padding.py) PR head main
test_modular_kernel_combinations.py -k aiter 13 passed, 18 failed (all test_aiter_moe_padding_matrix) padding matrix: 12 passed, 6 failed (pre-existing gfx950 CK device_gemm ... does not support this GEMM problem)
test_rocm_aiter_moe.py (incl. 3 gfx950 MXFP4 tests) 70 passed
test_mori_moe.py 14 passed
test_moe_layer.py -k "mori or aiter" 3 passed, 20 skipped (generic config skips)
test_topk_softplus_sqrt.py 1672 passed, 4 skipped
tests/rocm/test_moe_padding.py 7 passed

The AITER cases in the modular-kernel sweep are the same 10 on both sides (same configs, now spread across the right leaves).

  1. tests/kernels/moe/test_modular_kernel_combinations.py:952** fused_experts_type=AiterExperts,
    test_aiter_moe_padding_matrix (#59333, brought in by your merge of main) still builds a Config with the base class. The base is no longer in EXPERT_INFO, so config.is_valid() → expert_info(AiterExperts) fails with AssertionError (mk_objects.py:162). All 18 params fail at PR head in about 2 s. Pick the leaf from the quant config, e.g. a small {None: AiterUnquantizedExperts, ...} lookup or a helper that returns the first leaf whose _supports_quant_scheme(*config.fp8_quant_key_pair()) is true. This also contradicts the "no overlap with #59332/#59333/#59334" line in the description.

  2. Merge with current main (conflict + two new AiterExperts dependencies)**
    git merge-tree against origin/main (2ddde19e8e) has a conflict in the test_modular_kernel_combinations.py imports. Since your last merge, main also added:

  • #59334 test_aiter_moe_token_padding*: fused_experts_type=AiterExperts (main L1116). This will hit the same expert_info assertion as point 1, so it needs the same leaf lookup.
  • #60633 modular_kernel_tools/common.py:737: if fe_name == "AiterExperts" and (...). This compares the class __name__, so after the split it never matches. Nothing fails, but the AITER weight pre-shuffle stops and every AITER harness case falls back to JIT-compiling the preshuffle_off module (the exact slowdown #60633 fixed). Switch to issubclass(fe_type, AiterExperts).

(Points 1 and the #59334 case come from a test run and a traced code path. )

  1. PR description, "Bugs found and fixed along the way": The claim isn't true. Both the merge base (d9503dc503) and current main already register AiterExperts with common_float_types, with a comment saying it covers (None, None). Collect-only shows the same 10 AITER sweep cases before and after this PR. The split doesn't change harness coverage, so please drop or reword this section. The commit message makes the same claim and also says MXFP4 is "now exercised", which it isn't (point 4).

Comment thread tests/kernels/moe/modular_kernel_tools/mk_objects.py
Comment thread vllm/model_executor/layers/fused_moe/experts/rocm_aiter_moe.py
Comment thread vllm/model_executor/layers/fused_moe/__init__.py
Comment thread tests/kernels/moe/modular_kernel_tools/mk_objects.py
Comment thread docs/design/moe_kernel_features.md
@mergify mergify Bot removed the needs-rebase label Oct 9, 2026
divakar-amd and others added 2 commits October 9, 2026 18:06
Resolves a conflict in tests/kernels/moe/test_modular_kernel_combinations.py
between this branch's AiterExperts split and main's new HIP-graph token
padding tests. Since AiterExperts is now a non-instantiable base class,
updates main's two new tests (test_aiter_moe_padding_matrix and
test_aiter_moe_token_padding_garbage_rows) to select the concrete per-scheme
leaf class instead of instantiating AiterExperts directly.

Also fixes a latent bug this branch's split exposed in
modular_kernel_tools/common.py: _maybe_convert_weights_for_experts matched
on the literal class name "AiterExperts" to decide whether to apply the
gfx950 weight-preshuffle workaround, which no longer matches any
instantiated class post-split. Switched to an issubclass(fe_type,
AiterExperts) check so the workaround still applies to
AiterUnquantizedExperts/AiterFp8BlockExperts as before.

Signed-off-by: Divakar Verma <divakar.verma@amd.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…mem_cudagraph_pool

Main's use_cumem_cudagraph_pool (vllm/config/vllm.py) unconditionally reads
model_config.enable_sleep_mode/sleep_mode_backend/sleep_mode_offload_cudagraph.
The modular-kernel test harness's Config.make_env_data() fakes model_config
with a bare SimpleNamespace that predates these fields, so any multi-GPU
modular-kernel test that initializes a process group now raises
AttributeError. Add the three fields with their real ModelConfig defaults.

Signed-off-by: Divakar Verma <divakar.verma@amd.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…binations

test_modular_kernel_combinations_multigpu always needs world_size=2 and
self-skips via its own GPU-count check otherwise. The only AMD CI job
covering this file runs on the single-GPU mi300_1 pool, so these cases
have never actually executed in CI - they show green while silently
skipping every run.

Add a dedicated mi300_2 job (num_gpus: 2) that runs just the -k
"multigpu" cases, and deselect them from the mi300_1 job so the two
jobs don't both claim the same test IDs.

This surfaced while debugging a real failure caught running these
tests locally on MI300 (2 GPUs): a stale model_config test stub
(fixed in the AiterExperts-split commit on this branch) broke every
multi-GPU modular-kernel test with an AttributeError on
sleep_mode_offload_cudagraph. That bug had been silently unreachable
in CI for the same reason - no job ever ran these cases with enough
GPUs to hit it.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Divakar Verma <divakar.verma@amd.com>
@divakar-amd

Copy link
Copy Markdown
Contributor Author

/ci run

@github-actions

Copy link
Copy Markdown

✅ Triggered Buildkite CI #94317 for commit 1b6ae65b5653.

@AndreasKaratzas

Copy link
Copy Markdown
Member

/amd-ci run nightly --allow-stale

@github-actions

Copy link
Copy Markdown

✅ Triggered Buildkite AMD CI #14512 for commit 1b6ae65b5653.

⚠️ This PR is 2 commits behind upstream main. Running CI at your own risk because --allow-stale was requested; outdated CI configuration may cause failures. Before merging, merge or rebase onto the latest main, then rerun /amd-ci run nightly on the latest PR commit.

@AndreasKaratzas
AndreasKaratzas merged commit f7ba007 into vllm-project:main Oct 13, 2026
205 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in AMD Oct 13, 2026
aarushjain29 added a commit to ROCm/vllm that referenced this pull request Oct 14, 2026
…est_areas

Some AMD test groups run the same command in test-amd.yaml and in the
test_areas mirror, but with a different version or flags. Use the more
recently changed side in both places:

- (MI300) Quantization: torchao 0.17.0 -> 0.18.0 in test_areas, matching
  test-amd.yaml (vllm-project#53009).
- (MI355 DPX) Language Models (Extended Generation): use the
  fix-rocm-7.0-warp-size-constexpr mamba branch in test-amd.yaml,
  matching test_areas (vllm-project#57877).
- (MI300) MoE Kernels: run test_modular_kernel_combinations with AITER
  enabled and without the multi-GPU cases in test_areas, matching
  test-amd.yaml (vllm-project#57074, vllm-project#60322).
- (MI355 DPX) Basic Correctness Models: run with
  VLLM_TARGET_TEST_SUITE=MI355 in test_areas, as test-amd.yaml does.

Signed-off-by: aarushjain29 <aarushi.jain2@amd.com>
aarushjain29 added a commit to ROCm/vllm that referenced this pull request Oct 14, 2026
…est_areas

Some AMD test groups run the same command in test-amd.yaml and in the
test_areas mirror, but with a different version or flags. Use the more
recently changed side in both places:

- (MI300) Quantization: torchao 0.17.0 -> 0.18.0 in test_areas, matching
  test-amd.yaml (vllm-project#53009).
- (MI355 DPX) Language Models (Extended Generation): use the
  fix-rocm-7.0-warp-size-constexpr mamba branch in test-amd.yaml,
  matching test_areas (vllm-project#57877).
- (MI300) MoE Kernels: run test_modular_kernel_combinations with AITER
  enabled and without the multi-GPU cases in test_areas, matching
  test-amd.yaml (vllm-project#57074, vllm-project#60322).

Signed-off-by: aarushjain29 <aarushi.jain2@amd.com>
aarushjain29 added a commit to ROCm/vllm that referenced this pull request Oct 14, 2026
…est_areas

Some AMD test groups run the same command in test-amd.yaml and in the
test_areas mirror, but with a different version or flags. Use the more
recently changed side in both places:

- (MI300) Quantization: torchao 0.17.0 -> 0.18.0 in test_areas, matching
  test-amd.yaml (vllm-project#53009) and the NVIDIA step.
- (MI355 DPX) Language Models (Extended Generation): use the
  fix-rocm-7.0-warp-size-constexpr mamba branch in test-amd.yaml,
  matching test_areas (vllm-project#57877).
- (MI300) MoE Kernels: run test_modular_kernel_combinations with AITER
  enabled and without the multi-GPU cases in test_areas, matching
  test-amd.yaml (vllm-project#57074, vllm-project#60322).
- (MI355 DPX) Basic Correctness Models: drop VLLM_TARGET_TEST_SUITE=MI355
  from test-amd.yaml, matching test_areas. It is only read by
  test_models_distributed, which needs 2 GPUs and detects MI355 itself.

Signed-off-by: aarushjain29 <aarushi.jain2@amd.com>
AndreasKaratzas pushed a commit to AndreasKaratzas/vllm that referenced this pull request Oct 16, 2026
…ct#60322)

Signed-off-by: Divakar Verma <divakar.verma@amd.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>

Signed-off-by: Andreas Karatzas <AndreasKaratzas@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/build documentation Improvements or additions to documentation quantization rocm Related to AMD ROCm

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants