Conversation
… to the Volta one Turing GPUs got no FlashAttention backend: the CMake FA2 block fetches vllm-project/flash-attention for 8.0+ and the Volta fork for 7.0, so an sm75 or mixed 7.0;7.5 build shipped no sm75 kernels and the platform fell back to FlashInfer (paged prefill fails on SM75) or TRITON_ATTN. - cmake/external_projects/vllm_flash_attn_sm75.cmake: ExternalProject that builds Peuqui/flash-attention @ 43b9d29c (tag sm75-1cat-2026-09-13) with CUDA_ARCHS=7.5 and VLLM_FA2_OUTPUT_NAME=_vllm_fa2_C_sm75, installed next to the regular library; included only when 7.5 is in CUDA_ARCHS. - setup.py: the extension and the precompiled-wheel extraction entry. - flash_attn_interface: load the FA2 library on first use, chosen per the worker's own device (one library per process); ensure_fa2_library_loaded() for the SM70 backend's operator lookups, which relied on import-time loading (flash_attn_v100, sm70_e4m3_long, sm70_e4m3_scalar). - platforms/cuda.py: FLASH_ATTN, TRITON_ATTN, FLEX_ATTENTION on 7.5, capability read from the worker's own device. - flash_attn backend: capability floor 7.5, fp16 only below 8.0. - docs: FA2 row 7.5+. - tests: library per device, Turing gates, backend priority, sm75 forward against torch SDPA on a 7.5 device. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Peuqui <peuqui@github.com>
…icy test test_flash_v100_priority_is_sm70_only asserted FLASHINFER second on 7.5; the sm75 list is FLASH_ATTN, TRITON_ATTN, FLEX_ATTENTION and FlashInfer is not offered there (its paged prefill fails with "invalid argument" on SM75). Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Peuqui <peuqui@github.com>
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.
Purpose
Turing GPUs (RTX 8000, RTX 6000, T4, RTX 20xx) get no FlashAttention backend today:
CMakeLists.txtfetches vllm-project/flash-attention for 8.0+ and zhinianqin/flash-attention-v100 for 7.0, so an sm75-only or a mixed 7.0;7.5 build ships no sm75 kernels. At runtime the platform offers FLASHINFER first, whose paged prefill fails with "invalid argument" on sm75, and TRITON_ATTN as the working fallback. Issue #612 asked which form you prefer for closing that gap; this PR is form 1 of the three, the one that mirrors how the sm70 build already pins a fork.What changes
cmake/external_projects/vllm_flash_attn_sm75.cmake(new): anExternalProject_Addthat builds https://github.com/Peuqui/flash-attention at 43b9d29c (tag sm75-1cat-2026-09-13; vllm-project pin 28e862d plus the sm75 forward path, split-KV for paged multi-token queries, and a CMake option that names the output file) with-DCUDA_ARCHS=7.5 -DFA2_ENABLED=ON -DFA3_ENABLED=OFF -DVLLM_FA2_OUTPUT_NAME=_vllm_fa2_C_sm75, and installs_vllm_fa2_C_sm75.abi3.sointovllm/vllm_flash_attn/as component_vllm_fa2_C_sm75. It is included only when 7.5 is inCUDA_ARCHSand is independent of which FA2 tree the existing block fetches. A second FetchContent of the same project is not possible: both trees define the target_vllm_fa2_Cand override global CMake functions (see the note invllm_flash_attn.cmake). The fork names the interpreterPython_EXECUTABLE, so the file translatesVLLM_PYTHON_EXECUTABLE.CMakeLists.txt: the include, gated on 7.5.setup.py: the extensionvllm.vllm_flash_attn._vllm_fa2_C_sm75whenTORCH_CUDA_ARCH_LISTcontains 7.5, and the file in the precompiled-wheel extraction list.vllm/vllm_flash_attn/flash_attn_interface.py: the FA2 library is no longer imported at module import time.load_fa2_library(device)loads, on first use, the library built for the capability of the device the ops run on:_vllm_fa2_C_sm75.abi3.sofor (7, 5), the regular_vllm_fa2_Cotherwise. One library per process._is_fa2_supportedasks the worker's own device (torch.accelerator.current_device_index()), not index 0 of the visibility list, and accepts 7.5 when the matching library is installed.vllm/platforms/cuda.py: on (7, 5) the priority list is FLASH_ATTN, TRITON_ATTN, FLEX_ATTENTION (FlashInfer is not offered there); the capability for the backend choice is read from the worker's own device.flash_attn_interface.ensure_fa2_library_loaded()(new) and one call each invllm/v1/attention/backends/flash_attn_v100.py,vllm/v1/attention/ops/sm70_e4m3_long.pyandvllm/v1/attention/ops/sm70_e4m3_scalar.py: the SM70 backend resolves its D256 prefill, grouped long-context and scalar tail operators fromtorch.ops._vllm_fa2_Cbefore the first attention call, and relied on the module import to have loaded the library. With loading moved to first use, those lookups now load the library for the worker's device first. Without this, Volta booted but logged "SM70 D256 exact-prefill operators are unavailable" and took its slower long-prefill fallback (found in the end-to-end run below).vllm/v1/attention/backends/flash_attn.py: capability floor 7.5; below 8.0 only fp16 is accepted (the sm75 build is fp16-only, bf16 is rejected by its entry points).docs/design/attention_backends.md: FA2 row 7.5+.tests/v1/attention/test_sm70_flash_v100_policy.py::test_flash_v100_priority_is_sm70_only: the expectation for 7.5 follows the new priority list (FLASH_ATTN, TRITON_ATTN, FLEX_ATTENTION; FlashInfer not offered).Measurements
2x Quadro RTX 8000 (TP2), Qwen3.8-27B-NVFP4, MTP k=3, greedy, fp16 KV cache. Because a ModelOpt NVFP4 checkpoint does not load on Turing on main without #604 (minimum capability 89 for modelopt_mixed), the runs were made on main plus #604 and #611 plus this change; the attention backend is the only variable between the two arms, and the sm75 library was the one produced by the fork build, not a hand-built file.
Output text identical in both arms (same SHA-256 for the 400-token probe and for the 13k answers). The 27B production entries of our rig have run on this library since 2026-09-06.
Volta is untouched: 2x V100 TP2 with the same checkpoint and DFlash2 gives 76.42 tok/s before and after (V100 loads
_vllm_fa2_C.abi3.soas before; the loader log line names the file per worker).Build proof
Wheel built from this branch (dfef334 plus these changes) with the sm75 tree fetched by the new ExternalProject, nothing prebuilt on the path:
Result:
1cat_vllm-1.5.1.dev986+gdfef33421.d20260913.cu128-cp312-cp312-linux_x86_64.whl, 167,220,823 bytes, containingvllm/_C.abi3.sovllm/_moe_C.abi3.sovllm/vllm_flash_attn/_vllm_fa2_C_sm75.abi3.soNo
_vllm_fa2_C.abi3.sois in this wheel, as expected for an arch list without 7.0 or 8.0+;nm -Dshows no undefinedflash::symbol in the sm75 library. Installed into a clean venv (torch 2.10.0+cu128), the library loads on a Quadro RTX 8000 and the GPU test below runs against it.Second wheel, same tree,
TORCH_CUDA_ARCH_LIST="7.0;7.5", to show that the new ExternalProject sits next to the existing Volta fetch without touching it: 211,317,095 bytes, containing both FA2 libraries and the Volta-only components:cuobjdump -lelfvllm/_C.abi3.sovllm/_moe_C.abi3.sovllm/_sm70_sampler_C.abi3.sovllm/vllm_flash_attn/_vllm_fa2_C.abi3.so(zhinianqin fork, unchanged)vllm/vllm_flash_attn/_vllm_fa2_C_sm75.abi3.soWith this wheel,
load_fa2_libraryon a Tesla V100 loads_vllm_fa2_C.abi3.so(capability 7.0) and on a Quadro RTX 8000 loads_vllm_fa2_C_sm75.abi3.so(7.5); the log line names the file. Volta keeps its own backend (FLASH_ATTN_V100, chosen by the platform on 7.0), so_is_fa2_supportedstill answers False there exactly as on main (main gates at 8.0, this change at 7.5), andget_flash_attn_versionstill falls back to None on SM70.Test Plan
pre-commit run --files <the 12 changed and new files>andpre-commit run mypy-3.10 --hook-stage manual --files <the 8 python files>.FlashAttentionBackend, whose class body callsget_flash_attn_version(), so one CUDA device has to be visible once an FA2 library is installed):tests/vllm_flash_attn/test_fa2_library_per_device.py(library path per capability, one load per process, the current-device helper loads once, refusal without a library),tests/v1/attention/test_flash_attn_turing_gates.py(capability floor, fp16 gate),tests/v1/attention/test_cuda_backend_priority_turing.py(priority list on 7.5 and 8.0).tests/kernels/attention/test_fa2_sm75_forward.py(loader picks the sm75 library, varlen forward against a torch SDPA reference for head sizes 64/128/256 and query lengths 1/8/333).tests/v1/attention/test_sm70_flash_v100_policy.py(81 tests, one expectation updated as listed above) andtests/kernels/attention/test_sm70_e4m3_scalar_fp32.py.fa2_chain.sh,fa2_probe2.shin our v100-skinny repository).Test Result
Turing rig: 2x Quadro RTX 8000 (compute capability 7.5), driver 580, CUDA 12.8, torch 2.10.0+cu128, Python 3.12.
pre-commit run --files <all 12 changed and new files>: every hook passed (includingcheck-torch-cuda-call, SPDX, attention-backend docs check).pre-commit run mypy-3.10 --hook-stage manual --files <8 python files>: passed.Tests without a Turing device, run with one V100 visible:
tests/vllm_flash_attn/test_fa2_library_per_device.py: 5 passedtests/v1/attention/test_flash_attn_turing_gates.pyandtests/v1/attention/test_cuda_backend_priority_turing.py: 8 passedGPU test on one RTX 8000 (
CUDA_DEVICE_ORDER=PCI_BUS_ID CUDA_VISIBLE_DEVICES=<the RTX>):tests/kernels/attention/test_fa2_sm75_forward.py: 9 passed (head sizes 64/128/256 x query lengths 1/8/333, loader picked_vllm_fa2_C_sm75.abi3.so, output matches torch SDPA).Existing test files, in full, one V100 visible:
tests/v1/attention/test_sm70_flash_v100_policy.pyandtests/kernels/attention/test_sm70_e4m3_scalar_fp32.py: 144 passed (both in this branch and in our fork).tests/kernels/attention/test_flash_attn.pyon the RTX 8000, as shipped: every case fails withFlashAttention on Turing (sm75) only supports fp16 data type, because the file parametrizesDTYPES = [torch.bfloat16]only and the sm75 build rejects bf16 by design. The same file withDTYPES = [torch.float16]andQDTYPES = [None](no fp8 KV on this build): 160 passed, 160 skipped (the FA3 half, "Flash attention version 3 not supported").tests/v1/attention/test_attention_backends.pycould not run here: it needs the gatedmeta-llama/Meta-Llama-3-8Bandgoogle/embeddinggemma-300mconfigs from Hugging Face (403).Measurement matrix: see the tables above.
End to end with the mixed 7.0;7.5 wheel (this branch plus [Feature][SM75] Run ModelOpt NVFP4 and FP8 linears on Turing through the SM70 QPN kernels #604 so that the NVFP4 checkpoint loads on Turing; the wheel's libraries, the branch's Python):
--kv-cache-dtype float16(the checkpoint declares FP8 KV; [Bugfix][SM70/SM75] Honor a checkpoint's KV-cache quantization directive only on Ampere and newer #613 is not in this stack): both TP workers logLoaded FA2 library _vllm_fa2_C_sm75.abi3.so for compute capability 7.5, backend FLASH_ATTN, ready after 451 s on an empty compile cache; a 400-token answer and a 13k-token-prefix answer, both coherent.--max-model-len 32768 --gpu-memory-utilization 0.90(32 GB cards) and without the drafter's explicitattention_backend: FLASH_ATTN(main selects FLASH_ATTN_V100 on 7.0 itself; the explicit value is a convention of our fork): both workers logLoaded FA2 library _vllm_fa2_C.abi3.so for compute capability 7.0, backend FLASH_ATTN_V100, no "D256 exact-prefill operators are unavailable" line, ready after 145 s.a3dffc7c5e9b417afor the 400-token answer and22da50b5c73529f5for the 13k-prefix answer on both.--tensor-parallel-size 1 --pipeline-parallel-size 2, no speculative config): stage 0 logsLoaded FA2 library _vllm_fa2_C_sm75.abi3.so for compute capability 7.5and FLASH_ATTN, stage 1 logs the FLASH_ATTN_V100 decode and prefill paths active and runs its SM70 TurboMind warmup inside its own TP group; ready after 451 s (cold cache root), the same two answers with the same SHA-256 as above. Two things stay out of reach on main and are not claimed: the MTP drafter class of this model family declares noSupportsPP(speculative.pyrejects the draft config under PP; the target model inheritsSupportsPPthrough its VL wrapper), so the PP2 run is without speculation; and TP2 across the two card types hangs in_warmup_fp8_dense_layers_coordinated(vllm/model_executor/warmup/awq_sm70_warmup.py:170broadcasts LUT records from rank 0 inside the TP group, and a Turing rank never enters that warmup), which is a warmup assumption, not attention. Our rig runs Flash-Next TP2 PP2 with the RTX pair as stage 0 and the V100 pair as stage 1 on our fork with this loader since 2026-09-06; there every stage's TP group is homogeneous.Not a duplicate
Issue #612 (ours) asked for the form; #39 and #237 are usage questions about V100.
gh pr list --state open --search "sm75 OR turing OR flash attention"shows only our own #572 (merged), #604 and #611, none touching the FA2 loader or the CMake FA2 block.AI assistance (Claude) was used to prepare the change and run the matrix; I reviewed every line, built the wheel and measured on the hardware named above.