Conversation
a4838b1 to
c6004fc
Compare
CutlassFP8ScaledMMLinearKernel.is_supported() only checked that the platform is CUDA, so it won a pre-Ada auto-selection it cannot serve: cutlass_scaled_mm_supports_fp8() rejects anything below SM89, and also rejects SM89 without CUDA 12.4 and SM90+ without CUDA 12.0. On SM75/80/86 this makes the affected FP8 linear layers unservable. With VLLM_COMPILE the FP8 activation-quant op keeps a float8_e4m3fn tensor in the Inductor graph; Triton has no fp8e4nv on those archs, so fallback_node_due_to_unsupported_type() skips the auto_functionalized node and decompose_auto_functionalized() raises "auto_functionalized was not removed". With --enforce-eager the CUTLASS GEMM itself has no kernel for the arch. Reuse the existing capability probe so selection falls through to MarlinFP8ScaledMMLinearKernel, which exists precisely for GPUs that lack FP8 hardware support. The failure reason names the architecture and toolkit requirement the probe actually enforces rather than a capability threshold alone. Tests cover the probe thresholds, the device-query fallback when a caller omits the capability, and the selector itself: an SM80 configuration must land on Marlin, while a control that restores the CUDA-only check lands on CUTLASS and reproduces the regression. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: lesj0610 <lesj0610@godoiksan.org>
c6004fc to
ae490e7
Compare
|
@coderabbitai full review |
✅ Action performedFull review finished. |
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review. 📝 WalkthroughWalkthroughThe change gates CUTLASS FP8 kernel support by CUDA capability and adds selection tests. It also updates pinned CUDA 13.0 ARM64 builder image digests across image, release, and GH200 test pipelines. ChangesCUTLASS FP8 capability gating
ARM64 CUDA builder image updates
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to The change prevents unsupported GPUs and CUDA combinations from selecting the CUTLASS FP8 kernel and allows them to fall back to Marlin; the supplied checks pass, and no actionable merge-blocking risk remains beyond normal review. Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
Purpose
CutlassFP8ScaledMMLinearKernel.is_supported()only checks that the platform is CUDA. It never consults a capability probe, even thoughcutlass_scaled_mm_supports_fp8()rejects everything below SM89 (and also rejects SM89 without CUDA 12.4, or SM90+ without CUDA 12.0). Since_POSSIBLE_FP8_KERNELS[PlatformEnum.CUDA]places it ahead ofMarlinFP8ScaledMMLinearKernel, it wins auto-selection on pre-Ada GPUs and nothing downstream can recover.This became reachable at
bca7bea2405127bd5291bb6fffa679bdcd8f6dd9("Remove VLLM_TEST_FORCE_FP8_MARLIN to replace with linear_backend/moe_backend"), which movedMarlinFP8ScaledMMLinearKernelfrom first to sixth in the CUDA FP8 priority list and dropped itscompute_capability >= 89self-exclusion. Before that commit the ordering plus the self-exclusion made Marlin the only candidate on SM75/80/86; after it, the ungated CUTLASS entry is chosen there instead.Coverage does not catch it. The GSM8K eval configs that used to reach the Marlin path now pass
--linear-backend marlinexplicitly, so they no longer exercise auto-selection at all.tests/quantization/test_fp8.pystill parametrizesforce_marlin=False, which does go through auto-selection, but nothing guarantees that parametrization runs on pre-Ada hardware.Symptoms on SM80 with a mixed-precision ModelOpt checkpoint whose attention projections are FP8:
CompilationMode.VLLM_COMPILE: the FP8 activation-quant op keeps afloat8_e4m3fntensor in the Inductor graph. Triton has nofp8e4nvon SM80, sounsupported_input_tensor()makesfallback_node_due_to_unsupported_type()returnTrue,PatternMatcherPass.apply()skips theauto_functionalizednode, anddecompose_auto_functionalized()ends withAssertionError: auto_functionalized was not removed.--enforce-eager: the CUTLASS FP8 GEMM has no kernel compiled for the arch.Either way the affected ModelOpt FP8 linear layers are unservable unless the user knows to pass
--linear-backend marlinby hand.MarlinFP8ScaledMMLinearKernelis documented as the "FP8 Marlin kernel for GPUs that lack FP8 hardware support", so making it unreachable on exactly those GPUs is the defect.This PR reuses the probe that already backs
cutlass_fp8_supported()so the CUTLASS entry declines the architecture/toolkit combinations it cannot serve and selection falls through to Marlin. On the tested CUDA 13.0 build, SM89+ behaviour is unchanged.AI assistance: Claude Opus 5 was used to bisect the regression, implement the gate, and draft this description; the submitter reviewed the changes.
Changes
CutlassFP8ScaledMMLinearKernel.is_supported()resolves the compute capability (argument first, device query as fallback) and returns unsupported whenops.cutlass_scaled_mm_supports_fp8()rejects it. The failure reason names the architecture and toolkit requirement the probe enforces, since a rejection on SM89/SM90 can come from the CUDA version rather than the capability.tests/model_executor/kernels/test_cutlass_fp8_linear.py: probe thresholds, the device-query fallback when a caller omits the capability, selector-level fall-through to Marlin on SM80 with a control that reproduces the regression, a check that SM90 still selects CUTLASS, and agreement with the unmocked runtime probe.Test Plan
Run on an SM80 host.
Test Result
ruff check: passed.ruff format --check: 2 files already formatted.pytest tests/model_executor/kernels/test_cutlass_fp8_linear.py -q: 11 passed, 0 skipped.pytest tests/model_executor/kernels/ -q: all 39 tests in that directory passed.MarlinFP8ScaledMMLinearKernel; the control that restores the CUDA-only check on the same config selectsCutlassFP8ScaledMMLinearKernel, i.e. the regression is reproduced and the gate is what changes the outcome. An SM90 config still selectsCutlassFP8ScaledMMLinearKernel.80,is_supported()returnsFalsewith the architecture/toolkit reason,is_supported(89)returns(True, None).[(80, False), (86, False), (89, True), (90, True), (100, True), (120, True)]— the same threshold the pre-regression Marlin self-exclusion used.mypyfor Python 3.10.The mocked tests pin the platform enum, the device-capability queries and the CUTLASS probe, so their outcome does not depend on the host or on the CUDA version the wheel was built against.
test_cutlass_fp8_is_supported_matches_runtime_probeis the one unmocked case; it isskipif-guarded oncurrent_platform.is_cuda(), which is a platform-enum check, and both sides of its assertion route through the same capability resolution, so it is consistent even where no device is visible.Serving-level confirmation still needs a server restart with this head. The failing run was captured before the change and logs
Selected CutlassFP8ScaledMMLinearKernel for ModelOptFp8LinearMethodimmediately before the Inductor assertion; the expected post-fix log line isSelected MarlinFP8ScaledMMLinearKernel for ModelOptFp8LinearMethod.Essential Elements of an Effective PR Description Checklist
Summary by CodeRabbit
Bug Fixes
Testing
Chores