Skip to content

feat: trtllm FP4 routed-MoE: accept fp32 topk_weights (copy-free) - #3763

Merged
aleozlx merged 1 commit into
flashinfer-ai:mainfrom
jdebache:feat/fp32_trtllm_fused_moe_unpacked_router_weights
Jul 21, 2026
Merged

aleozlx merged 1 commit into
flashinfer-ai:mainfrom
jdebache:feat/fp32_trtllm_fused_moe_unpacked_router_weights

Conversation

@jdebache

@jdebache jdebache commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

📌 Description

trtllm_fp4_block_scale_routed_moe's unpacked routing path
(topk_ids=(ids, weights)) silently assumed bf16 topk_weights. vLLM
routers emit fp32 by design, so the finalize kernel reinterpreted the fp32
bytes as bf16 → ~1e36/NaN per-expert scales → garbage output).

Fix

  • FP4BlockScaleLauncher::prepare_routing() — set args->mDtypeExpW from the
    actual topk_weights dtype in UnpackedPrecomputed mode. The finalize kernel
    already has a compiled fp32 path; this just selects it. No new kernel, no copy.
  • FP4BlockScaleLauncher::check_routing() — assert topk_ids is int32 and
    topk_weights ∈ {bf16, fp32}, so a wrong dtype fails loudly instead of being
    misread.
  • flashinfer/fused_moe/core.py — matching Python-side dtype guard + docstring
    now documents bf16-or-fp32 (consumed natively, no cast).
  • Test — new unpacked_fp32 variant in test_trtllm_gen_routed_fused_moe
    (fails with garbage before the fix, matches reference after).

🔍 Related Issues

Enables merging vllm-project/vllm#46872, saving 1.5 to 2 us per layer, which matters in decode.

🚀 Pull Request Checklist

✅ Pre-commit Checks

  • I have installed pre-commit by running pip install pre-commit (or used your preferred method).
  • I have installed the hooks with pre-commit install.
  • I have run the hooks manually with pre-commit run --all-files and fixed any reported issues.

🧪 Tests

  • Tests have been added or updated as needed.
  • All tests are passing (unittest, etc.).

Reviewer Notes

Summary by CodeRabbit

Summary by CodeRabbit

  • Bug Fixes

    • Added stricter runtime validation for unpacked precomputed routing to ensure topk IDs use int32 and topk weights use bfloat16 or float32.
    • Improved handling of unpacked float32 weights so they’re consumed in their native precision without unintended reinterpretation.
  • Documentation

    • Clarified routed MoE operator behavior: unpacked topk_weights are consumed at native dtype (commonly copy-free for float32 routers).
  • Tests

    • Expanded routed fused MoE test coverage with a new unpacked_fp32 routing format case.

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds float32 topk_weights support for RoutingInputMode::UnpackedPrecomputed in the FP4 block-scale MoE path. The C++ launcher, Python wrapper, and tests now validate and route unpacked weights by dtype.

Changes

FP4 MoE UnpackedPrecomputed float32 weights

Layer / File(s) Summary
C++ dtype check and mDtypeExpW selection
csrc/trtllm_fused_moe_kernel_launcher.cu
check_routing enforces int32 topk_ids and bfloat16/float32 topk_weights for UnpackedPrecomputed; prepare_routing sets mDtypeExpW to Fp32 or Bfloat16 from topk_weights dtype.
Python assertion and docstring update
flashinfer/fused_moe/core.py
Asserts topk_weights is bfloat16 or float32 in the FP4 kernel path; updates the routed MoE docstring to note native-dtype consumption.
Test coverage for unpacked_fp32 routing format
tests/moe/test_trtllm_gen_routed_fused_moe.py
Adds "unpacked_fp32" to parametrization and type annotation, and splits routing-input construction into packed, unpacked_fp32, and unpacked cases.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested labels: run-ci

Suggested reviewers: saltyminty, yzh119, jiahanc

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: accepting fp32 topk_weights copy-free in trtllm FP4 routed-MoE.
Description check ✅ Passed The description follows the template and includes Description, Related Issues, Checklist, Tests, and Reviewer Notes, with only minor checklist items left unchecked.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request adds support for float32 routing weights in the TRT-LLM FP4 block scale MoE kernel when using the unpacked precomputed routing mode. This includes adding validation checks, updating the Python API documentation and assertions, and expanding test coverage to include unpacked_fp32 routing format. The reviewer points out that setting args->mDtypeExpW conditionally only for UnpackedPrecomputed mode could cause correctness issues in other routing modes, and suggests setting it unconditionally based on topk_weights.dtype().

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread csrc/trtllm_fused_moe_kernel_launcher.cu

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@csrc/trtllm_fused_moe_kernel_launcher.cu`:
- Around line 1820-1823: The `mDtypeExpW` update in
`trtllm_fused_moe_kernel_launcher.cu` only covers
`RoutingInputMode::UnpackedPrecomputed`, but `trtllm_fp4_block_scale_moe_op()`
also builds `topk_weights` from `routing_logits` in the `FromLogits` path.
Update the launcher logic around `args->mDtypeExpW` to also set the
exponent-weight dtype based on `topk_weights.dtype()` when routing comes from
logits, so fp32 logits correctly propagate `btg::Dtype::Fp32` instead of falling
back to the bf16 default.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: be72cfa3-fae3-4174-8b90-a542417d984e

📥 Commits

Reviewing files that changed from the base of the PR and between eb79c53 and 814a3a8ea4b39dc88d3fdd02d048b16565462c9f.

📒 Files selected for processing (3)
  • csrc/trtllm_fused_moe_kernel_launcher.cu
  • flashinfer/fused_moe/core.py
  • tests/moe/test_trtllm_gen_routed_fused_moe.py

Comment thread csrc/trtllm_fused_moe_kernel_launcher.cu
@jdebache
jdebache force-pushed the feat/fp32_trtllm_fused_moe_unpacked_router_weights branch 4 times, most recently from bf6f828 to cf51af3 Compare July 3, 2026 06:37
@jiahanc

jiahanc commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

/bot run tests/moe

@flashinfer-bot

Copy link
Copy Markdown
Collaborator

GitLab MR !879 has been created, and the CI pipeline #56703724 is currently running. I'll report back once the pipeline job completes.

@flashinfer-bot

Copy link
Copy Markdown
Collaborator

[FAILED] Pipeline #56703724: 11/20 passed

@yongwww yongwww added the run-ci label Jul 3, 2026
@jdebache
jdebache force-pushed the feat/fp32_trtllm_fused_moe_unpacked_router_weights branch from cf51af3 to 84c9623 Compare July 9, 2026 07:22
@jdebache
jdebache requested a review from qiching as a code owner July 9, 2026 07:22
@jdebache
jdebache force-pushed the feat/fp32_trtllm_fused_moe_unpacked_router_weights branch from 84c9623 to a025362 Compare July 15, 2026 07:01
@jdebache

Copy link
Copy Markdown
Contributor Author

/bot run tests/moe

@flashinfer-bot

Copy link
Copy Markdown
Collaborator

GitLab MR !879 has been updated with latest changes, and the CI pipeline #58082989 is currently running. I'll report back once the pipeline job completes.

@flashinfer-bot

Copy link
Copy Markdown
Collaborator

[FAILED] Pipeline #58082989: 11/20 passed

@jdebache
jdebache force-pushed the feat/fp32_trtllm_fused_moe_unpacked_router_weights branch from a025362 to e8f80b3 Compare July 16, 2026 07:50
@jdebache

Copy link
Copy Markdown
Contributor Author

/bot run tests/moe

@flashinfer-bot

Copy link
Copy Markdown
Collaborator

GitLab MR !879 has been updated with latest changes, and the CI pipeline #58251976 is currently running. I'll report back once the pipeline job completes.

@flashinfer-bot

Copy link
Copy Markdown
Collaborator

[FAILED] Pipeline #58251976: 1/20 passed

@jdebache
jdebache force-pushed the feat/fp32_trtllm_fused_moe_unpacked_router_weights branch from e8f80b3 to 79eba7c Compare July 17, 2026 07:45
@jdebache

Copy link
Copy Markdown
Contributor Author

/bot run tests/moe

@flashinfer-bot

Copy link
Copy Markdown
Collaborator

GitLab MR !879 has been updated with latest changes, and the CI pipeline #58416904 is currently running. I'll report back once the pipeline job completes.

@flashinfer-bot

Copy link
Copy Markdown
Collaborator

[FAILED] Pipeline #58416904: 13/20 passed

…expert ids

Signed-off-by: jdebache <jdebache@nvidia.com>
@jdebache
jdebache force-pushed the feat/fp32_trtllm_fused_moe_unpacked_router_weights branch from 79eba7c to f6f81cf Compare July 20, 2026 06:45
@jdebache

Copy link
Copy Markdown
Contributor Author

/bot run tests/moe

@flashinfer-bot

Copy link
Copy Markdown
Collaborator

GitLab MR !879 has been updated with latest changes, and the CI pipeline #58742486 is currently running. I'll report back once the pipeline job completes.

@flashinfer-bot

Copy link
Copy Markdown
Collaborator

[FAILED] Pipeline #58742486: 11/20 passed

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

change looks to me

adds one test, which sounds fine

@aleozlx
aleozlx merged commit ba6bc50 into flashinfer-ai:main Jul 21, 2026
28 of 34 checks passed
@jdebache
jdebache deleted the feat/fp32_trtllm_fused_moe_unpacked_router_weights branch July 21, 2026 06:48
b8zhong pushed a commit to bzhng-development/flashinfer that referenced this pull request Aug 5, 2026
The packed `(expert_id << 16) | bf16(weight)` topk_ids format truncates the
fp32 routing weights callers already hold. Take a `(topk_ids, topk_weights)`
pair instead, as the FP4 runner has since flashinfer-ai#3763, and pick `mDtypeExpW` from
the caller's weights dtype so fp32 reaches the combine.

`routing_input_mode` now moves to `FusedMoeLauncher`, which both entry points
pass through explicitly; FP4 drops its own copy of the field.
Aneureka pushed a commit that referenced this pull request Aug 6, 2026
`trtllm_fp8_block_scale_routed_moe` and `trtllm_bf16_routed_moe` only
take the packed `(expert_id << 16) | bf16(weight)` form, which truncates
the fp32 routing weights callers already have. However FP4 already
handles this.

#3763 gave the FP4 path`(topk_ids, topk_weights)` form; this does the
same for the FP8 block-scale and BF16 runners.

And unified support in
#4104

Now fp32 weights reach the combine as fp32.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added logits-based, packed precomputed, and unpacked precomputed
routing for BF16, FP8, and FP4 Mixture-of-Experts operations.
- Routed APIs now accept packed expert IDs or separate expert IDs and
weights.
- Precomputed routing supports FP32 and BF16 expert weights where
applicable.

- **Bug Fixes**
  - Improved validation and handling of unpacked routing inputs.

- **Tests**
  - Added FP8 routing coverage for multiple expert-weight formats.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Brayden Zhong <brayden@radixark.ai>
bkryu pushed a commit that referenced this pull request Aug 11, 2026
…4448)

## 📌 Description

Add unpacked FP32 routing coverage for BF16, FP8, FP4, and MXFP8 routed
MoE paths.

## 🔍 Related Issues

Testing to address this comment:
vllm-project/vllm#46872 (review).

## 🚀 Pull Request Checklist

Thank you for contributing to FlashInfer! Before we review your pull
request, please make sure the following items are complete.

### ✅ Pre-commit Checks

- [X] I have installed `pre-commit` by running `pip install pre-commit`
(or used your preferred method).
- [X] I have installed the hooks with `pre-commit install`.
- [X] I have run the hooks manually with `pre-commit run --all-files`
and fixed any reported issues.

## 🧪 Tests

- [x] Tests have been added or updated as needed.
- [x] All tests are passing (`unittest`, etc.).

## Reviewer Notes

None.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Tests**
* Expanded routed mixture-of-experts coverage to support both packed and
unpacked FP32 routing inputs.
* Added coverage for BF16, FP8 block-scale, and FP4 block-scale
implementations.
* Improved activation-parity checks to report the routing format when
mismatches occur.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: jdebache <jdebache@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants