Repository navigation
[ROCm][CI][AiterExperts] Add test coverage for hidden/intermediate padding correctness - #59333
Conversation
Covers step 4b of the "Test padding" ask in vllm-project#54966: adds optional Config.hidden_dim_unpadded / intermediate_size_per_partition_unpadded fields (default None, preserving today's behavior everywhere else) threaded through to FusedMoEConfig in make_modular_kernel(), and a parametrized test_aiter_moe_padding_matrix covering the {no padding, hidden-only, intermediate-only, both} x {unquantized, fp8_channel_token, fp8_tensor_tensor, fp8_tensor_token, fp8_block_token} matrix for AiterExperts, using deliberately unaligned K/N so hidden_pad/ intermediate_pad actually diverge from zero. Compares against reference_moe_impl run at the true unpadded size and asserts the modular kernel's output is already unpadded-width (AiterExperts.apply() never slices its own output). Adds a skipped MXFP4 stub pending MI350/gfx950 hardware. Gated via require_aiter_moe / has_aiter(); inert when AITER isn't available or off ROCm. Signed-off-by: Divakar Verma <divakar.verma@amd.com>
Check torch.isfinite() only on AiterExperts.apply()'s real hidden_dim_unpadded-wide output slice, not the full padded-width buffer: the tail beyond hidden_dim_unpadded is unspecified/reused memory, not something AiterExperts promises to leave finite, so asserting on it risked a spurious failure unrelated to any real bug. Drop the redundant @pytest.mark.parametrize and inner pytest.skip() on test_aiter_moe_padding_matrix_mxfp4: the outer @pytest.mark.skip already prevents the body from ever running, so both were dead weight collecting 4 identical skipped test IDs instead of 1. Signed-off-by: Divakar Verma <divakar.verma@amd.com>
Signed-off-by: Divakar Verma <divakar.verma@amd.com>
|
/ci run |
|
✅ Triggered Buildkite CI #92709 for commit |
| # K/N intentionally unaligned to AITER's 64/128 granularity (unlike the | ||
| # shared mk_objects.py defaults) so hidden_pad/intermediate_pad are forced. | ||
| _PADDING_E = 8 | ||
| _PADDING_M = 16 | ||
| _PADDING_TOPK = 2 | ||
| _PADDING_K_UNPADDED = 896 # 7 * 128 | ||
| _PADDING_K_PADDED = 1024 # +128 | ||
| _PADDING_N_UNPADDED = 384 # 3 * 128 | ||
| _PADDING_N_PADDED = 512 # +128 | ||
| # hidden_pad = (K_padded - hidden_dim_unpadded) // 128 * 128 (rocm_aiter_moe.py) | ||
| _PADDING_HIDDEN_PAD_EXPECTED = 128 | ||
| # intermediate_pad = (N_padded - intermediate_size_per_partition_unpadded) | ||
| # // 64 * 64 * (2 if tp_size == 1 else 1) (rocm_aiter_moe.py); tp_size==1 here. | ||
| _PADDING_INTERMEDIATE_PAD_EXPECTED = 256 |
There was a problem hiding this comment.
Could you provide brief explanation of these hyper params and why these over a grid set ?
There was a problem hiding this comment.
These are the usual model params like number of Experts, num tokens, hidden_dim etc. This is for a single fixed small example model size rather than a grid set.
The only grid in this PR is the 4 (padding mode) × 5 (quant scheme) = 20 case-matrix
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Numerical comparisons can miss padding errors, and the tensor-token FP8 cases use incompatible weight scales.
Review effort: Balanced
Findings: 3
Open (3)
What changed in this PR
Adds ROCm AiterExperts padding coverage to the modular MoE test harness, addressing part of #54966.
Changes:
- Adds optional unpadded dimensions to the shared test configuration.
- Tests padding argument forwarding, output width, and numerical correctness across unquantized and FP8 configurations.
- Adds an MXFP4 placeholder and skips two unsupported block-FP8 shapes.
| File | Description |
|---|---|
| tests/kernels/moe/test_modular_kernel_combinations.py | Adds padding scenarios, reference slicing helpers, and assertions. |
| tests/kernels/moe/modular_kernel_tools/common.py | Passes optional unpadded dimensions into FusedMoEConfig. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
CI selector (shadow): 1 test steps (5 jobs) instead of 6 (10 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.
Selector would run (1)
Would skip (today's rules run them) (5)
Would add (today's rules do not run them) (0)none AMD mirrors: would skip (6)
AMD mirrors: would add (0)none 2 changed files · base |
- Always use the lenient check_accuracy path for the padding-matrix comparison, instead of a strict/lenient branch whose condition was always true (dead code). - Add a magnitude-ratio guard before check_accuracy: elementwise atol/rtol alone wouldn't catch a degenerate/zeroed output here, since ref_out's magnitude is below atol at this problem size. - Add _make_padding_matrix_weights(), scoped to this test, so the fp8_tensor_token case gets per-tensor (not per-channel) weight scales, matching the quant scheme it declares. Signed-off-by: Divakar Verma <divakar.verma@amd.com>
|
/ci run |
|
✅ Triggered Buildkite CI #92725 for commit |
ref_out's typical magnitude here (~1e-3-1e-2) sits below the 3e-2 atol used by both check_accuracy and torch.testing.assert_close, so a fully zeroed-out mk_out -- e.g. a garbage row's inf/nan corrupting the real rows via some leak the isfinite check doesn't catch (zero isn't NaN/Inf) -- would still spuriously pass. Mirrors the same guard added to the stacked 4b padding-matrix test (vllm-project#59333) for the same reason. Signed-off-by: Divakar Verma <divakar.verma@amd.com>

Summary
Covers the logical
hidden_dim_unpadded/intermediate_size_per_partition_unpaddedportion of the "Test padding" (4b) ask in #54966. TheseFusedMoEConfigfields driveAiterExperts'shidden_pad/intermediate_padcomputation so AITER's CK/FlyDSL kernels can strip padded regions internally; no existing test forces them to diverge from the padded size for any quant family other than MXFP4's own coverage (tests/quantization/test_online_mxfp4.py).This PR:
Config.hidden_dim_unpadded/Config.intermediate_size_per_partition_unpaddedfields to the modular kernel test harness (tests/kernels/moe/modular_kernel_tools/common.py), defaulting toNone(today's behavior, unchanged everywhere else).test_aiter_moe_padding_matrix, parametrized across {no padding, hidden-only, intermediate-only, both} x {unquantized, fp8_channel_token, fp8_tensor_tensor, fp8_tensor_token, fp8_block_token}. AssertsAiterExperts.apply()forwards the expectedhidden_pad/intermediate_padtorocm_aiter_ops.fused_moe, that its output buffer is still the raw (padded) width, then slices that buffer down to the realhidden_dim_unpaddedregion and compares it againstreference_moe_implrun at the true unpadded size.2 of the 20
test_aiter_moe_padding_matrixcases (block-quantized FP8 x {no padding, intermediate-only}) are runtime-skipped: AITER's block CK GEMM kernel rejects the raw unpadded hidden_dim shape on this hardware, so only thehidden_pad-forcing modes are exercised for that quant scheme.
Test plan
Plus a full-file regression run of
test_modular_kernel_combinations.pyto confirm no regressions to existing AITER coverage.AI assistance disclosure
This PR was developed with assistance from Claude Code and reviewed by me.