How to Install Flash-Attention
PyPI serves only a source distribution for flash-attn, so pip install flash-attn has no wheel to fall back on and compiles CUDA kernels for hours (see Why Installing GPU Python Packages Is So Complicated).
Prebuilt wheels exist in two places. The Astral GPU indexes publish one wheel per CUDA and PyTorch pair for the resolver to match. GitHub Releases hosts wheels that setup.py downloads by guessing a filename.
Pick an install path
- Install from the Astral GPU index for any project on a supported CUDA version. Start here.
- Install from GitHub Releases when the Astral index carries no wheel for your CUDA and PyTorch pair.
- Pin a wheel by URL when a requirements file needs one fixed artifact.
- Compile from source when no wheel covers your combination. This needs
nvccand takes minutes to hours. - Skip the wheels with conda-forge or pixi to hand CUDA toolkit and ABI matching to a solver.
Check your platform and driver
- Supported GPUs: NVIDIA Ampere (A100, A10, RTX 3090), Ada Lovelace (RTX 4090), Hopper (H100), or Blackwell (B200, RTX 5090). The kernels require compute capability 8.0 or higher.
- Unsupported GPUs: Turing (T4, RTX 20-series) and older. The install succeeds and the first kernel call raises
RuntimeError: FlashAttention only supports Ampere GPUs or newer.The separate flash-attention-turing project covers a subset of features on those cards. - Blackwell: use
cu128or newer.setup.pyemits thesm_100andsm_120gencode flags only from CUDA 12.8, socu126wheels carry no Blackwell kernels. - Operating systems: Linux. Windows support is experimental, and macOS has none.
- Driver: 525.60.13 or newer for any CUDA 12.x index, 580 or newer for a CUDA 13 index. Under CUDA minor version compatibility, a driver whose
nvidia-smiheader reports 12.4 still runscu128wheels, so a header number below the index does not rule it out. - Toolkit: needed only for the GitHub Releases and source build paths. The Astral index installs a prebuilt wheel and touches no compiler.
Install from the Astral GPU index
Each index covers one CUDA version, and each wheel targets one PyTorch version. Both appear in the version segment rather than in a platform tag, so flash-attn resolves like any other dependency:
flash_attn-2.8.3.post1+cu.12.8.torch.2.8-cp312-cp312-manylinux_2_24_x86_64.whlRoute torch and flash-attn to indexes on the same CUDA line. Pick the CUDA version your driver supports (cu126, cu128, cu130, and others listed at wheels.astral.sh), then add both:
uv add torch --index pytorch-cu128=https://download.pytorch.org/whl/cu128
uv add flash-attn --index astral-cu128=https://wheels.astral.sh/simple/cu128/$ uv add flash-attn --index astral-cu128=https://wheels.astral.sh/simple/cu128/
Resolved 28 packages in 222ms
Downloading flash-attn (241.7MiB)
Installed 3 packages in 5ms
+ einops==0.8.2
+ flash-attn==2.8.3.post1+cu.12.8.torch.2.11
~ myproject==0.1.0 (from file:///home/you/myproject)
Warning
Routing torch is not optional. The Astral indexes serve no torch, so an unrouted torch comes from PyPI, whose CUDA build changes between releases: PyPI ships PyTorch 2.11 as a CUDA 13 build. Pairing it with a cu128 wheel installs cleanly and then fails at import flash_attn with ImportError: libcudart.so.12: cannot open shared object file.
Each wheel declares its PyTorch as a dependency (torch==2.11.*), so the resolver picks the build matching the project’s torch. Routing torch to a CUDA-specific index pins the other half of the pair.
Installing flash-attn as a dependency of something else (vLLM, transformers) skips this routing, because [tool.uv.sources] applies only to declared dependencies. Declare flash-attn directly too.
Configure the index in pyproject.toml
uv add --index writes both indexes and the source mappings:
[tool.uv.sources]
torch = { index = "pytorch-cu128" }
flash-attn = { index = "astral-cu128" }
[[tool.uv.index]]
name = "pytorch-cu128"
url = "https://download.pytorch.org/whl/cu128"
explicit = true # add by hand; uv add omits it
[[tool.uv.index]]
name = "astral-cu128"
url = "https://wheels.astral.sh/simple/cu128/"
explicit = trueA named index outranks PyPI for every package it carries, so flash-attn comes from Astral. The cu128 index also carries vllm, deepspeed, mmcv, and 18 others; explicit = true keeps it from silently supplying those. uv’s PyTorch guide recommends the flag.
Important
explicit = true without a matching [tool.uv.sources] entry removes the index from the pool and resolves flash-attn from PyPI instead. uv lock reports no error, and uv sync then starts the source build this page exists to avoid. Add both or neither.
Commit pyproject.toml and uv.lock, and uv sync rebuilds the environment on another machine. The lock records the index URL and the CUDA-specific version, so it reproduces across machines sharing that CUDA generation, not across all machines.
Install outside a project
A bare package name resolves to the highest version on the index, which is the build for the newest PyTorch it carries. Name the full version to choose a different pairing:
uv pip install 'flash-attn==2.8.3.post1+cu.12.8.torch.2.8' \
--index astral-cu128=https://wheels.astral.sh/simple/cu128/The local segment is valid only with ==, so >=2.8.3.post1+cu.12.8.torch.2.8 is rejected. Install a matching torch first, since neither command routes it, and skip --no-build-isolation, because neither builds anything.
pip has no equivalent of explicit = true: --extra-index-url merges every index into one pool and takes the highest version, across all 22 packages the index carries.
Check the Astral index coverage
Coverage for flash-attn on the CUDA 12.8 index, across both the 2.8.3 and 2.8.3.post1 builds:
| PyTorch | Python | Platforms |
|---|---|---|
| 2.7 | 3.9-3.13 | x86_64, aarch64 |
| 2.8 | 3.9-3.13 | x86_64 |
| 2.9 | 3.10-3.14 | x86_64, aarch64 |
| 2.10 | 3.10-3.14 | x86_64, aarch64 |
| 2.11 | 3.10-3.14 | x86_64, aarch64 |
Coverage is uneven. PyTorch 2.8 ships no aarch64 wheel on this index, and Python 3.14 appears only on the 2.8.3 build for PyTorch 2.9. On aarch64, take torch from the PyTorch CUDA index rather than PyPI, whose aarch64 torch wheels are CPU-only. Other indexes carry different ranges; wheels.astral.sh is the current manifest.
Install from GitHub Releases
flash-attn’s setup.py runs a CachedWheelsCommand that downloads a matching wheel from GitHub Releases before falling back to compilation. Both pip and uv need --no-build-isolation here, because setup.py imports torch and packaging at the top level.
This path needs the full CUDA toolkit even when it finds a wheel. setup.py constructs a torch CUDAExtension at module level before it looks for one, so without CUDA_HOME the install stops at OSError: CUDA_HOME environment variable is not set and never reaches the download.
uv pip install torch==2.7.1 packaging # a PyTorch the release covers
uv pip install flash-attn --no-build-isolationWhen a wheel matches, the install finishes in seconds; otherwise the command falls back to compiling without warning, so an install running past a minute means nothing matched.
Check the GitHub release assets
PyPI serves flash-attn 2.8.3.post1. Its release carries these wheels:
| PyTorch | CUDA | Python | Platform |
|---|---|---|---|
| 2.4 | 12 | 3.9-3.12 | linux_x86_64 |
| 2.5-2.8 | 12 | 3.9-3.13 | linux_x86_64 |
| 2.9 | 13 | 3.12 | linux_x86_64, linux_aarch64 |
The CUDA 12 wheels ship in both CXX11 ABI TRUE and FALSE variants; the CUDA 13 wheels are TRUE only. The v2.8.3 release covers more: CUDA 12 wheels for PyTorch 2.9 and CUDA 13 wheels for PyTorch 2.10, all cp312.
A listed asset can still fail to download. The PyTorch 2.9 assets in the v2.8.3.post1 release carry the version 2.8.3, while automatic download builds the filename from the installed 2.8.3.post1 and hits a 404. Use Pin a wheel by URL there.
Coverage changes with every release; check the flash-attention releases page before picking a wheel.
Pin a wheel by URL
For a requirements file that needs one fixed artifact, install the wheel URL directly. The URL pattern is:
https://github.com/Dao-AILab/flash-attention/releases/download/v{release}/flash_attn-{version}+cu{cuda}torch{torch}cxx11abi{abi}-cp{py}-cp{py}-linux_x86_64.whlTo fill in the blanks, check your environment:
python -c "import torch; print('torch:', '.'.join(torch.__version__.split('.')[:2]))"
python -c "import torch; print('cxx11abi:', torch._C._GLIBCXX_USE_CXX11_ABI)"
python -c "import sys; print('python: cp' + ''.join(map(str, sys.version_info[:2])))"Install the matching PyTorch before the wheel. These wheels declare an unpinned torch dependency, so installing one into an empty environment pulls whatever PyTorch is current, and import flash_attn then fails with the undefined symbol error from Verify the install. For Python 3.12, PyTorch 2.7, and CXX11 ABI True:
uv pip install torch==2.7.1
uv pip install https://github.com/Dao-AILab/flash-attention/releases/download/v2.8.3.post1/flash_attn-2.8.3.post1+cu12torch2.7cxx11abiTRUE-cp312-cp312-linux_x86_64.whlFilenames do not always carry the release tag. The torch 2.9 wheels inside the v2.8.3.post1 release are named flash_attn-2.8.3+cu13torch2.9..., so copy the exact filename off the release page rather than assembling it from the pattern.
Compile from source
Source builds need the CUDA toolkit 12.0 or newer with nvcc on PATH, and PyTorch 2.2 or newer already installed. When no prebuilt wheel matches, install the build dependencies into the same environment as PyTorch and compile with a constrained job count:
uv pip install ninja packaging psutil
MAX_JOBS=4 uv pip install flash-attn --no-build-isolationpsutil matters only when MAX_JOBS is unset. setup.py imports it then to size the job count from free memory and cores, and aborts with ModuleNotFoundError: No module named 'psutil' if it is missing.
The toolkit’s CUDA major version must match PyTorch’s. Compare nvcc --version against python -c "import torch; print(torch.version.cuda)". A minor mismatch only warns; a major mismatch aborts the build with The detected CUDA version ... mismatches the version that was used to compile PyTorch.
The project’s README puts a compile without ninja at roughly two hours, against 3-5 minutes with ninja on a 64-core machine. It recommends capping MAX_JOBS on machines with less than 96GB of RAM, where ninja launches enough parallel jobs to exhaust memory.
In a uv project, route the build dependencies through extra-build-dependencies instead of a command-line flag:
[project]
dependencies = ["flash-attn", "torch==2.7.1"]
[tool.uv.extra-build-dependencies]
flash-attn = ["packaging", "psutil", { requirement = "torch", match-runtime = true }]
[tool.uv.extra-build-variables]
flash-attn = { MAX_JOBS = "4" }match-runtime = true makes the build use the same torch version the project resolves at runtime.
Skip the wheels with conda-forge or pixi
conda and pixi skip wheel selection and compilation. The conda-forge build resolves the CUDA toolkit through the solver, so nothing here needs nvcc, ABI variants, or --no-build-isolation.
pixi add flash-attnconda-forge builds linux-64 and linux-aarch64 packages. uv vs pixi vs conda for Scientific Python compares these tools for GPU workloads.
Verify the install
Run one attention call to confirm that the package imports and that its CUDA kernels load against your GPU. The first line reports torch’s CUDA build, which must sit on the same major version as the index:
import torch
from flash_attn import flash_attn_func
print(torch.__version__, torch.version.cuda, torch.cuda.is_available())
q = torch.randn(2, 256, 8, 64, dtype=torch.float16, device="cuda")
k, v = torch.randn_like(q), torch.randn_like(q)
out = flash_attn_func(q, k, v, causal=True)
print(tuple(out.shape), out.dtype)$ uv run python check_flash_attn.py
2.11.0+cu128 12.8 True
(2, 256, 8, 64) torch.float16
A ModuleNotFoundError means the installation did not complete; check the install output for errors. An ImportError naming an undefined symbol in flash_attn_2_cuda means the wheel was built against a different PyTorch than the one installed:
ImportError: .../flash_attn_2_cuda.cpython-312-x86_64-linux-gnu.so: undefined symbol:
_ZN3c104cuda29c10_cuda_check_implementationEiPKcS2_ibReinstall the wheel matching both torch.__version__ and, on the GitHub Releases path, the CXX11 ABI variant. A CUDA error naming the device or its compute capability points at a GPU architecture mismatch.
Fix a failed install
-
ImportError: libcudart.so.12: cannot open shared object file. The installed torch is a CUDA 13 build and the wheel is a CUDA 12 build. Routetorchto an index on the same CUDA line as the flash-attn index, as in Install from the Astral GPU index. -
No solution found when resolving dependencies. No wheel covers your combination of platform, Python version, and pinned PyTorch. uv names the missing tag and the platforms that do have wheels, and the last three lines carry the answer:flash-attn==2.8.3+cu.12.8.torch.2.8 has no wheels with a matching platform tag (e.g., `manylinux_2_28_aarch64`) hint: Wheels are available for `flash-attn` (v2.8.3+cu.12.8.torch.2.8) on the following platform: `manylinux_2_24_x86_64`Try another CUDA index, since torch coverage differs between them, or fall back to conda-forge when the project’s torch pin cannot move.
-
ModuleNotFoundError: No module named 'torch'while building. The installer is building the PyPI source distribution instead of downloading a wheel, and the isolated build has no torch. Point it at an index, or pass--no-build-isolationwith torch already installed. -
OSError: CUDA_HOME environment variable is not set. The GitHub Releases path needs the CUDA toolkit. Install it from NVIDIA’s CUDA toolkit archive, use a CUDAdevelimage such asnvidia/cuda:12.8.0-devel-ubuntu22.04, or switch to the Astral index, which needs no toolkit. -
ModuleNotFoundError: No module named 'packaging'. Thesetup.pyimportspackagingbefore it does anything else, including downloading prebuilt wheels. Runuv pip install packagingfirst, then retry. -
The build compiles instead of downloading a wheel. On the GitHub Releases path,
setup.pyprintsGuessing wheel URL:before it tries, so compare that line against the release page. PyTorch 2.9 is the known case: the guessed filename carries a.post1that the asset lacks. -
The build is killed by the OOM killer. Set
MAX_JOBS=2orMAX_JOBS=1. Each compilation job can consume several gigabytes of memory. -
The build runs for hours. Install
ninja(uv pip install ninja) and retry. Withoutninja, the CUDA extensions compile one file at a time.
Note
FlashAttention-3 is a Hopper-targeted beta, published on the Astral GPU indexes as flash-attn-3. FlashAttention-4 is a separate package (uv pip install --pre flash-attn-4) written in CuTeDSL for Hopper and Blackwell GPUs, shipping as a pure Python wheel that compiles kernels at runtime and needs no CUDA compiler.
Learn More
Handbook articles:
- Why Installing GPU Python Packages Is So Complicated explains the wheel format limits behind
flash-attnpackaging - How to Install PyTorch with uv covers installing PyTorch before
flash-attn - How to Install RAPIDS with uv covers another GPU package that requires custom index configuration
- uv vs pixi vs conda for Scientific Python compares tooling choices for GPU workloads
External resources:
- Astral GPU indexes for the current wheel manifest across CUDA versions
- uv’s PyTorch integration guide for the index configuration uv recommends
- flash-attention GitHub repository for release notes and issue tracker
- flash-attn on PyPI (source distributions only)
- flash-attention releases for the GitHub-hosted wheel assets