同步更新的代码仓库
/composable_kernel
/aiter
/cutlass
/flash-attention
更新后通过https://gitee.com/mrli008/flash-attention/blob/main/.gitmodules 文件和目标文件夹修改
设置编译参数
修改setup.py中该参数添加最后两行
nvcc_flags = [
"-O3",
"-std=c++17",
"-U__CUDA_NO_HALF_OPERATORS__",
"-U__CUDA_NO_HALF_CONVERSIONS__",
"-U__CUDA_NO_HALF2_OPERATORS__",
"-U__CUDA_NO_BFLOAT16_CONVERSIONS__",
"--expt-relaxed-constexpr",
"--expt-extended-lambda",
"--use_fast_math",
"-Xcompiler",
"/Zc:preprocessor",
...]
并行进程数(线程4个)
set MAX_JOBS=1
set CXXFLAGS=/Zc:preprocessor
set CFLAGS=/Zc:preprocessor
python setup.py build
Windows 下编译 Flash-Attention 的完整踩坑记录
为什么需要 Flash-Attention?
Flash-Attention 是 Dao-AILab 提出的高效注意力机制实现,能显著减少显存占用并提升推理速度,尤其适用于长序列和大模型。在 RTX 4080 这类消费级显卡上,使用 Flash-Attention 可以大幅提升 OCR 等视觉语言任务的吞吐量。
然而,Flash-Attention 官方只提供 Linux 预编译包,对 Windows 完全不支持。社区虽有尝试,但编译过程极其曲折,且成功率极低。本文将记录我在 Windows 11 + CUDA 12.1 + VS 2022 环境下编译 Flash-Attention 时遇到的所有典型错误及尝试解决的过程,希望能为后来者提供参考。
一、环境准备(已满足)
- 操作系统:Windows 11 专业版
- GPU:RTX 4080 Super(计算能力 8.9)
- CUDA Toolkit:13.3(系统安装)
- PyTorch:2.4.0+cu121(通过
torch.version.cuda确认使用的 CUDA 版本为 12.1) - Visual Studio 2022(含 C++ 桌面开发工作负载)
- Python 3.11.8
⚠️ 关键矛盾:PyTorch 使用 CUDA 12.1,但系统安装的是 CUDA 13.3,编译器版本与 CUDA 版本不一致会引发大量兼容性问题。官方建议 CUDA 版本与 PyTorch 保持一致,但编译时 NVCC 默认使用系统 CUDA 路径,这埋下了隐患。
二、第一个坑:找不到名为 flash-attn-2-cuda 的包
错误现象:
ERROR: Could not find a version that satisfies the requirement flash-attn-2-cuda
原因 :该包名在 PyPI 上不存在。正确安装方法是从 GitHub Releases 下载与你的环境匹配的 .whl 文件,但官方从未提供 Windows 预编译包。
尝试 :下载 Linux 包强行安装 ------ 失败,因为 .so 与 Windows 的 .pyd 不兼容。
三、源码编译:无尽的错误与调试
1. 克隆仓库并初始化子模块
bash
git clone --recursive https://github.com/Dao-AILab/flash-attention.git
cd flash-attention
问题 :csrc/cutlass 子模块下载失败(网络问题或路径错误),导致 flash_api.cpp 缺失,ninja 报错找不到源文件。
解决 :使用代理或手动配置 Git 子模块,最终通过 git submodule update --init --recursive 拉取完整源码。
2. 预处理器冲突:/Zc:preprocessor
错误:
fatal error C1189: #error: MSVC/cl.exe with traditional preprocessor is used.
Please switch to the standard conforming preprocessor by passing `/Zc:preprocessor` to cl.exe.
原因 :CUDA 13.3 的 cccl 头文件要求 MSVC 使用标准预处理器,但 NVCC 默认不会传递该标志。
尝试修复 :修改 setup.py,在 extra_compile_args 的 nvcc 列表中添加:
python
'-Xcompiler', '/Zc:preprocessor'
正确写法 :必须是两个独立字符串,否则 NVCC 会将其解析为输入文件导致 nvcc fatal。
3. NVCC 参数传递错误
错误:
nvcc fatal: A single input file is required for a non-link phase when an outputfile is specified
原因 :之前误将 '-Xcompiler /Zc:preprocessor' 写成一个字符串,NVCC 将 /Zc:preprocessor 当作输入文件。修正为 '-Xcompiler', '/Zc:preprocessor' 后解决。
4. GPU 架构不匹配
编译时默认包含多个 -gencode 目标(sm_80, sm_90, sm_100f 等)。我的 RTX 4080 是 sm_89,但 setup.py 中没有 sm_89,且包含了未来架构(如 sm_120),导致编译失败。
解决 :在 setup.py 中精简 -gencode,只保留:
python
'-gencode', 'arch=compute_89,code=sm_89'
同时删除其他行。
5. 内存不足与编译耗时
即使设置 MAX_JOBS=2,编译单个 .cu 文件(如 flash_bwd_hdim128_bf16_causal_sm80.cu)仍可能耗尽 16GB 内存。调整虚拟内存或降低并行数(MAX_JOBS=1)有所缓解,但编译过程长达半小时,且极易中途失败。
6. 最终失败:position_embedding 问题与放弃
在解决所有上述问题后,编译 似乎 成功,生成了 flash_attn_2_cuda.pyd。但在导入时仍报 ModuleNotFoundError: No module named 'flash_attn_2_cuda',原因是生成的 .pyd 文件名或路径与 __init__.py 期望的不一致。尝试手动改名、修改 sys.path 等均无效。
四、结论:Windows 下的编译几乎不可能成功
技术原因:
- CUDA 工具链与 MSVC 的兼容性极差,需要大量手工调整编译标志。
- Flash-Attention 的
setup.py高度依赖 Linux 环境(如-fPIC、-shared等)。 - 子模块
cutlass对 Windows 路径长度敏感,且包含 Linux 专属的符号链接。
经验教训:
-
不要在 Windows 上尝试编译 Flash-Attention,除非你拥有极强的 C++/CUDA 调试能力,并且愿意投入数天时间。
-
官方和社区都建议使用 WSL 2 ,在 Ubuntu 子系统中一键安装:
bashpip install flash-attn --no-build-isolation
五、替代方案:使用 PyTorch 原生 SDPA
既然 Flash-Attention 编译无望,我果断转向 PyTorch 自带的 scaled_dot_product_attention(SDPA)。从 PyTorch 2.0 开始,SDPA 已内置 FlashAttention 和 Memory-Efficient Attention 后端,性能与 Flash-Attention 几乎无差别,且完美支持 Windows。
使用方法:
- 在模型加载时指定
attn_implementation="sdpa"(Hugging Face 模型) - 或直接调用
F.scaled_dot_product_attention(q, k, v)替换自定义注意力层。
效果:在 RTX 4080 上,推理速度无明显下降,显存占用也与编译后的 Flash-Attention 相当。
六、如果一定要折腾...... 一些有用的调试技巧
- 设置环境变量 :
CUDA_LAUNCH_BLOCKING=1和TORCH_USE_CUDA_DSA=1可以获取更详细的 CUDA 错误信息。 - 使用
--verbose:pip install -v能看到完整编译输出。 - 仅编译特定架构 :在
setup.py中只保留你的 GPU 计算能力对应的-gencode,减少编译时间。 - 检查子模块 :确保
cutlass完整拉取,否则会导致源文件缺失。
结语
Flash-Attention 是一个优秀的库,但 Windows 用户应正视其平台限制。如果你必须使用原版,请认真考虑切换到 WSL 2 或 Linux 环境。对于绝大多数任务,PyTorch SDPA 已经足够高效,且省去了所有编译烦恼。希望这篇记录能帮你少走弯路,把宝贵的时间投入到真正的业务逻辑中去。