Repository navigation
Build vllm-flash-attn FA2 kernels with SM12x SASS - #91
Conversation
Upstream vllm-flash-attn hardcodes the FA2 kernels (flash_fwd_*.cu) to
"8.0+PTX", so a TORCH_CUDA_ARCH_LIST=12.0 build picks 8.0+PTX and
_vllm_fa2_C.abi3.so carries only sm_80 SASS plus compute_80 PTX. On SM120
the driver must JIT that PTX; with the CUDA 13.3 toolkit and the R595
(CUDA 13.2) driver it refuses with cudaErrorUnsupportedPtxVersion ("the
provided PTX was compiled with an unsupported toolchain"). That breaks the
FLASH_ATTN ViT path (Qwen3.5/3.6 vision encoders) and every FA2 varlen call
unless the cuda-13.3 compat libraries are put on LD_LIBRARY_PATH.
Mirror MARLIN_OTHER_ARCHS / HADACORE_ARCHS: resolve 12.0f (CUDA >= 13) or
12.0a;12.1a (CUDA 12.8+) against CUDA_ARCHS with SlimServe's
cuda_archs_loose_intersection before FetchContent_MakeAvailable (the copy
vllm-flash-attn installs over it does not understand the a/f suffixes),
then append the matching -gencode to the FA2 sources in vllm-flash-attn's
directory scope. The pinned upstream source is untouched and FA3 (9.0a)
is unchanged. A FATAL_ERROR guards against the upstream source layout
moving out from under the glob.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
Problem
vllm/vllm_flash_attn/_vllm_fa2_C.abi3.socarries only sm_80 code. On an RTX 5090 (sm_120) the driver has to JIT the compute_80 PTX, and the R595 driver (CUDA 13.2) rejects PTX produced by nvcc 13.3:This breaks every FA2 varlen call on SM12x, including the
FLASH_ATTNViT path used by the Qwen3.5/3.6 vision encoders. It is whyqwen36-nvfp4-1andqwen36-fp8-1(rtx5090) setLD_LIBRARY_PATH=/usr/local/cuda-13.3/compat.Root cause
The pinned upstream vllm-flash-attn (
ed4b7342) hardcodes the FA2 kernels (csrc/flash_attn/src/flash_fwd_*.cu) to"8.0+PTX". For aTORCH_CUDA_ARCH_LIST=12.0build, its loose intersection picks8.0+PTX, so the extension holds sm_80 SASS plus compute_80 PTX and nothing for SM12x. This is the same class of bug #88 fixed forMARLIN_OTHER_ARCHS/HADACORE_ARCHS. FA3 is Hopper-only (9.0a) and is not affected.Fix
cmake/external_projects/vllm_flash_attn.cmakenow does whatMARLIN_OTHER_ARCHSdoes:FetchContent_MakeAvailable, it resolves12.0f(CUDA >= 13) or12.0a;12.1a(CUDA 12.8+) againstCUDA_ARCHSwith SlimServe'scuda_archs_loose_intersection. This has to happen first because vllm-flash-attn installs its own older copy of that function over ours, and that copy doesn't understand thea/fsuffixes.FetchContent_MakeAvailable, it appends the matching-gencodeto the FA2 sources in vllm-flash-attn's directory scope (set_property(SOURCE ... DIRECTORY <fa src>)). The flag shape is the same oneset_gencode_flag_for_srcsproduces.There is no patch to the fetched source and the pin is unchanged. The override also applies when
VLLM_FLASH_ATTN_SRC_DIRis used. If the upstream FA2 source glob ever comes back empty, the configure stops with aFATAL_ERRORinstead of skipping the override without warning. Builds without an SM12x target are unchanged, and the FA3 gencodes are untouched (verifiedarch=compute_90a,code=sm_90aonly).Why this mechanism: the arch list lives inside the fetched upstream CMakeLists, and SlimServe passes no variable that controls it. A
PATCH_COMMANDwould need idempotent re-apply logic on top of FetchContent's git update step. Setting the property after the fetch keeps the arch policy in SlimServe next to the Marlin/hadacore lists.Evidence
Configure, CUDA 13.3,
TORCH_CUDA_ARCH_LIST=12.0(this box):Configure only,
TORCH_CUDA_ARCH_LIST="8.0 8.6 8.9 9.0 10.0 12.0": FA2 gets the same three gencodes,FA3_ARCHS: 9.0a, and the FA3 sources still use onlycompute_90a,code=sm_90a.cuobjdumpof_vllm_fa2_C.abi3.so:--list-elf--list-ptxAll tests below ran on an RTX 5090 with the R595 driver, with
LD_LIBRARY_PATHunset. Only the FA2.sochanged; every other extension was the installed build.tests/kernels/attention/test_flash_attn.py::test_varlen_with_paged_kv, recovered from history):.so:160 failed, 480 skipped. Every failure iscudaErrorUnsupportedPtxVersion..so:160 passed, 480 skipped. The skips are FA3 (unsupported on sm_120) and FP8-Q with FA2.vllm.LLMwith an image request, seed 1234, temperature 1.0 / top_p 0.95 / top_k 20, thinking on,gpu_memory_utilization=0.3:.so: engine init fails in the encoder profiling run (vit_flash_attn_wrapper -> flash_attn_varlen_func) with "the provided PTX was compiled with an unsupported toolchain"..so: the engine comes up withFLASH_ATTN for vit attention. The image request answers "There is a red circle and a blue square." (synthetic red circle + blue rectangle), and the text request completes.What remains
LD_LIBRARY_PATH=/usr/local/cuda-13.3/compatenv onqwen36-nvfp4-1andqwen36-fp8-1(rtx5090) should become removable once installs are rebuilt with this change. That needs a live profile serving check (text and image) without the compat path first, so this PR leaves the env in place. The operator-localaffine-king-nvfp4-1record carries the same env and needs the same check.12.0a;12.1a) mirrors Fix test failures on main #88 but was not built here, because only CUDA 13.x toolkits are installed.Summary by CodeRabbit