Repository navigation
[Kernel] Batch invariance: pin FlashInfer FP8 bmm and W4A16 NVFP4 kernels - #62192
Merged
Merged
Conversation
Under VLLM_BATCH_INVARIANT: the router serves BF16 x BF16 -> FP32 logits on one persistent matmul (mm_batch_invariant gains out_dtype; on top of vllm-project#59985), FP8 bmm is pinned to the cutlass backend, W4A16 NVFP4 linears use Humming, and the Blackwell BI-matmul table gets the tuned M buckets. Split out of vllm-project#62017; the code is unchanged from that PR. Signed-off-by: aoshen02 <[email protected]> Signed-off-by: 0z5a <[email protected]> Co-Authored-By: Claude Opus 5.5 <[email protected]>
0z5a
requested review from
Harry-Chen,
bnellnm,
khluu,
mgoin,
pavanimajety,
wzhao18,
yewentao256 and
zyongye
as code owners
October 17, 2026 15:19
Contributor
|
This pull request has merge conflicts that must be resolved before it can be |
Move the router FP32-logits branch, the mm_batch_invariant out_dtype parameter and the sm100 Nemotron-H tuned M buckets back to vllm-project#62017. Add regression tests for the two remaining pins. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: aoshen02 <[email protected]>
aoshen02
requested review from
AndreasKaratzas,
WoosukKwon and
tlrmchlsmth
as code owners
October 30, 2026 03:50
aoshen02
approved these changes
Oct 30, 2026
aoshen02
enabled auto-merge (squash)
October 30, 2026 04:26
aoshen02
approved these changes
Oct 31, 2026
Contributor
|
/ci run |
|
✅ Triggered Buildkite CI #98922 for commit ℹ️ This PR is 21 commits behind upstream |
Drop the helper and the CI dependency line it needed. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: aoshen02 <[email protected]>
Contributor
|
/ci run |
|
✅ Triggered Buildkite CI #98938 for commit |
yewentao256
reviewed
Oct 31, 2026
Comment on lines
+1211
to
+1219
| if envs.VLLM_BATCH_INVARIANT and use_a16: | ||
| if linear_backend not in ("auto", "humming"): | ||
| logger.warning_once( | ||
| "VLLM_BATCH_INVARIANT overrides --linear-backend=%s; using the " | ||
| "Humming backend for deterministic W4A16 execution.", | ||
| linear_backend, | ||
| ) | ||
| force_kernel = HummingNvFp4LinearKernel | ||
| elif envs.VLLM_BATCH_INVARIANT: |
Comment on lines
+36
to
+48
|
|
||
|
|
||
| def test_batch_invariant_w4a16_selects_humming(monkeypatch): | ||
| # The batch-invariant CUTLASS kernel is W4A4-only. | ||
| monkeypatch.setattr(envs, "VLLM_BATCH_INVARIANT", True) | ||
| for kernel in (CutlassNvFp4LinearKernel, HummingNvFp4LinearKernel): | ||
| monkeypatch.setattr( | ||
| kernel, | ||
| "is_supported", | ||
| classmethod(lambda cls, compute_capability=None: (True, None)), | ||
| ) | ||
| kernel = init_nvfp4_linear_kernel(use_a16=True) | ||
| assert isinstance(kernel, HummingNvFp4LinearKernel) |
Member
There was a problem hiding this comment.
Suggested change
| def test_batch_invariant_w4a16_selects_humming(monkeypatch): | |
| # The batch-invariant CUTLASS kernel is W4A4-only. | |
| monkeypatch.setattr(envs, "VLLM_BATCH_INVARIANT", True) | |
| for kernel in (CutlassNvFp4LinearKernel, HummingNvFp4LinearKernel): | |
| monkeypatch.setattr( | |
| kernel, | |
| "is_supported", | |
| classmethod(lambda cls, compute_capability=None: (True, None)), | |
| ) | |
| kernel = init_nvfp4_linear_kernel(use_a16=True) | |
| assert isinstance(kernel, HummingNvFp4LinearKernel) |
This test not needed for this small update
Contributor
There was a problem hiding this comment.
Sorry for that and will not do enable auto merge next time. Will add a follow up pr right now.
aoshen02
added a commit
that referenced
this pull request
Nov 2, 2026
…(follow-up to #62192) (#65000) Signed-off-by: aoshen02 <[email protected]> Co-authored-by: Claude Opus 5.5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Under
VLLM_BATCH_INVARIANT=1, pins two GEMM paths so that a row's result does not depend on the batch:bmm(flashinfer_scaled_fp8_mm) is pinned to thecutlassbackend.This was split from #62017 by @aoshen02. Without BI, behavior is unchanged.
Changes
vllm/utils/flashinfer.py:flashinfer_scaled_fp8_mmpassesbackend="cutlass"tobmm_fp8under BI and"auto"otherwise. With FlashInfer autotune (on by default at-O1and above),"auto"tunes over cutlass, cuBLAS and cuDNN per M bucket, so different batch sizes can run different backends.vllm/model_executor/kernels/linear/__init__.py: under BI, a W4A16 NVFP4 linear selectsHummingNvFp4LinearKernel, which already readsuse_batch_invariantfromVLLM_BATCH_INVARIANT. Before this change, the BI branch forced the W4A4-onlyCutlassNvFp4LinearKernel, and kernel init raisedValueError: CutlassNvFp4LinearKernel does not support W4A16. With--linear-backendset to something other than Humming, a warning is logged and the setting is overridden.test_flashinfer_fp8_mm_batch_invariant_after_autotuneintests/v1/determinism/test_cutlass_batch_invariance.py(SM100+);test_batch_invariant_w4a16_selects_hummingintests/kernels/quantization/test_nvfp4_kernel_selection.py(CPU).The router FP32-logits branch (with the
out_dtypeargument ofmm_batch_invariant) and the two sm100 tuned M buckets for Nemotron-H shapes were moved out of this PR. They stay in #62017 for the Nemotron-H wiring.Validation
Hardware: GB200 (SM100), vLLM nightly image
0.32.0rc1.dev281+g49cb2bbf7, FlashInfer 0.7.2. The touched files are identical between that image and this PR's basefa75d3456d, so "base" is the image as shipped and "PR" is the image with this PR's two files overlaid.FP8
bmm. Static per-tensor FP8 inputs. Each M slicex[:M]was compared bitwise against the first M rows of the M=2048 output, for M in {1, 2, 7, 16, 64, 128, 512, 2048}, on four (N, K) shapes. The table counts rows that differ.auto(base)auto(base)cutlass(PR)cutlass(PR)Max abs diff of the differing rows is 3e-5 to 6e-5. Without autotune,
"auto"falls back to its first runner (cutlass), so it is invariant; the variance only appears after tuning. As a diagnostic, cuBLAS alone and cuDNN alone were each invariant after autotune on these shapes: the variance comes from switching backends between buckets. The new test failed in 1 of 2 runs at base (the tuner's pick is timing dependent) and passed in 2 of 2 runs with the PR.W4A16 NVFP4. A synthetic
CompressedTensorsW4A4Fp4(use_a16=True)layer, with the same M sweep, on shapes 4096x4096, 2688x4096 and 4608x2688.ValueError: CutlassNvFp4LinearKernel does not support W4A16at initHummingNvFp4LinearKernelFlashInferCuteDslNvFp4W4A16LinearKernel(unchanged)So the W4A16 change fixes a crash at init under BI rather than a numerical difference.
Tests.
pre-commit(ruff, mypy) passes on the changed files.Not tested: end-to-end serving of an FP8 or W4A16 NVFP4 model under BI, and throughput. Humming and pinned
cutlassare chosen for invariance, not speed.Pull Request Checklist
I used vLLM's
/pr-checklistskill. (Mandatory for agents, optional for humans).AI assistance was used during the creation of this PR.
Design Fit: Minimizes impact on core components, reuses existing functionality, and justifies added complexity.
Testing and Validation: Validates the change and ensures any added tests are meaningful and reliable, with CI coverage or documented CI resource constraints and validation performed outside CI.
Code Quality and Style: Keeps code and comments clear and concise, and updates relevant documentation and examples.
Pull Request Contents: Includes a brief summary and relevant links, supports claims with evidence, explains root causes and implementation trade-offs, and follows the contributing guide.