Skip to content

[Bugfix][ROCm] Handle MoE padding sentinel in AITER fused experts - #57036

Open
xiao-llm wants to merge 1 commit into
vllm-project:mainfrom
xiao-llm:xiaoyu/fix-aiter-moe-padding-sentinel
Open

xiao-llm wants to merge 1 commit into
vllm-project:mainfrom
xiao-llm:xiaoyu/fix-aiter-moe-padding-sentinel

Conversation

@xiao-llm

@xiao-llm xiao-llm commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

VLLM_MOE_SKIP_PADDING (enabled by default) lets the topk kernels mark cudagraph padding rows by writing -1 into topk_ids, so downstream MoE kernels can skip work for them. The AITER fused-expert path never handled that sentinel and passed topk_ids straight into aiter.fused_moe, where moe_sorting indexes the expert weights with the raw id. A value of -1 reads outside the weight buffer and trips a GPU memory access fault:

Memory access fault by GPU node-9 on address 0x7f255b5b2000.
Reason: Unknown.

This reproduces on DeepSeek-V4.1-Flash (MXFP4 experts, TP=4, MI355X): the profiling run builds a fully synthetic batch whose rows are all marked as padding, so every routing index is -1 and all ranks fault before the server can start. It is not limited to startup -- trailing cudagraph padding rows are marked the same way on real batches.

Neutralize the sentinel where the other AITER dtype fixups happen: route padding rows to expert 0 with zero weight, contributing nothing to the output. The rewrite is branchless so it remains cudagraph-capturable.

Purpose

Test Plan

Test Result


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.

VLLM_MOE_SKIP_PADDING (enabled by default) lets the topk kernels mark
cudagraph padding rows by writing -1 into topk_ids, so downstream MoE
kernels can skip work for them. The AITER fused-expert path never handled
that sentinel and passed topk_ids straight into aiter.fused_moe, where
moe_sorting indexes the expert weights with the raw id. A value of -1
reads outside the weight buffer and trips a GPU memory access fault:

  Memory access fault by GPU node-9 on address 0x7f255b5b2000.
  Reason: Unknown.

This reproduces on DeepSeek-V4.1-Flash (MXFP4 experts, TP=4, MI355X): the
profiling run builds a fully synthetic batch whose rows are all marked as
padding, so every routing index is -1 and all ranks fault before the
server can start. It is not limited to startup -- trailing cudagraph
padding rows are marked the same way on real batches.

Neutralize the sentinel where the other AITER dtype fixups happen: route
padding rows to expert 0 with zero weight, contributing nothing to the
output. The rewrite is branchless so it remains cudagraph-capturable.

Signed-off-by: Xiao Yu <xiao.yu.dc@outlook.com>

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

@mergify mergify Bot added rocm Related to AMD ROCm bug Something isn't working labels Sep 15, 2026
@github-project-automation github-project-automation Bot moved this to Todo in AMD Sep 15, 2026
@Fangzhou-Ai

Copy link
Copy Markdown
Collaborator

Hi @xiao-llm thanks for your fix. Have we measured the perf-wise impact? Those extra elementwise operations can be expensive cc @shen-shanshan

@Fangzhou-Ai

Copy link
Copy Markdown
Collaborator

@xiao-llm please also take a look at this ROCm/aiter#5295 , do you think this fix can address your problem here?

# nothing to the output. Done branchlessly to stay cudagraph-capturable.
is_padding = topk_ids < 0
topk_ids = torch.where(is_padding, torch.zeros_like(topk_ids), topk_ids)
topk_weights = torch.where(is_padding, torch.zeros_like(topk_weights), topk_weights)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

These ops can be quite expensive, can you test the kernel level and e2e cost first?

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.

sure, will verify it

@xiao-llm

Copy link
Copy Markdown
Contributor Author

@xiao-llm please also take a look at this ROCm/aiter#5295 , do you think this fix can address your problem here?

It looks like solve the same issue, will verify if it works for DeepSeek-V4.1-Flash mxfp4.

@shen-shanshan shen-shanshan self-assigned this Sep 16, 2026
@Fangzhou-Ai

Copy link
Copy Markdown
Collaborator

@micah-wil is bumping the aiter version and it should help us to solve the problem

@tjtanaa

tjtanaa commented Oct 14, 2026

Copy link
Copy Markdown
Member

@xiao-llm is this PR still needed?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working rocm Related to AMD ROCm

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

4 participants