Skip to content

[Kernel] Add VLLM_FLASHINFER_MOE_FUSED_FINALIZE to disable the nondeterministic MoE finalize - #54948

Open
jschmied wants to merge 2 commits into
vllm-project:mainfrom
jschmied:fix/flashinfer-moe-fused-finalize
Open

jschmied wants to merge 2 commits into
vllm-project:mainfrom
jschmied:fix/flashinfer-moe-fused-finalize

Conversation

@jschmied

@jschmied jschmied commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Purpose

Fixes #54945. flashinfer.fused_moe.cutlass_fused_moe has a use_fused_finalize argument whose default (fused epilogue, atomics) is documented as nondeterministic. vLLM's flashinfer_cutlass_moe.py never passed it, so identical requests at temperature 0 could return different logits on this backend with no switch to turn it off. This adds VLLM_FLASHINFER_MOE_FUSED_FINALIZE (default 1, behaviour unchanged) and passes it through.

Test Plan

Test Result

shape default VLLM_FLASHINFER_MOE_FUSED_FINALIZE=0
cache off, eager token 2 differs, 3 distinct of 3 1 distinct of 3
cache on token 1 differs, 3 distinct of 3 1 distinct of 3
cache on + MTP n=5 not probed 1 distinct of 3

Decode cost of the unfused finalize: +3.6 % in one 8-turn agent-loop measurement (43.92 → 45.50 ms/tok; run-to-run band for this config 42.8–47.7), i.e. indicative. ruff check / ruff format --check clean.

Note for FlashInfer ≤ 0.6.17: with a populated VLLM_FLASHINFER_AUTOTUNE_CACHE_DIR, switching the finalize fails at init with Invalid gemm2 profile id because the autotune cache key did not distinguish the two runners; fixed in FlashInfer from v0.6.18rc2 (MoERunner.get_cache_key_extras). Use a fresh cache dir on older versions.

Includes AI-assisted code (Claude Code); the change and the repro were reviewed and run by me.

Generated with [Claude Code]

…erministic MoE finalize

FlashInfer's cutlass_fused_moe reduces the top-k expert outputs in a fused
epilogue that uses atomics and is documented as nondeterministic; vLLM never
passed `use_fused_finalize`, so there was no way to get reproducible logits
from the FlashInfer CUTLASS MoE path. On Qwen3.8-Flash-Next (NVFP4) on a
GB10, identical requests at temperature 0 returned different logits, traced
by per-module hashing to `mlp.experts`; passing `use_fused_finalize=False`
makes all tokens bit-identical across requests (verified in three serving
shapes). Default unchanged (fused).

Fixes vllm-project#54945

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011SuBgdp87NbfLbiigmzn1z
Signed-off-by: Jürgen Schmied <juergenschmied70@gmail.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.

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

👋 Hi! Thank you for contributing to the vLLM project.

💬 Join our developer Slack at https://slack.vllm.ai to discuss your PR in #pr-reviews, coordinate on features in #feat- channels, or join special interest groups in #sig- channels.

PRs do not trigger a full CI run by default. Reviewers with write access and configured trusted contributors can comment /ci run for upstream CI or /amd-ci run for AMD CI only whenever CI signals are needed.

Once the PR is approved or has the ready label, the PR author can also use the corresponding /ci run, /ci retry, and /ci cancel commands, or their /amd-ci variants. New commits do not start upstream CI automatically.

If you have any questions, please reach out to us on Slack at https://slack.vllm.ai.

Agent Guidelines

IMPORTANT: 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.

🚀

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

Labels

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

[Bug] FlashInfer CUTLASS NVFP4 MoE gives different logits for identical requests (fused finalize); use_fused_finalize=False is bit-stable

1 participant