编译flash-attn

同步更新的代码仓库

/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_argsnvcc 列表中添加:

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 子系统中一键安装:

    bash 复制代码
    pip 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=1TORCH_USE_CUDA_DSA=1 可以获取更详细的 CUDA 错误信息。
  • 使用 --verbosepip install -v 能看到完整编译输出。
  • 仅编译特定架构 :在 setup.py 中只保留你的 GPU 计算能力对应的 -gencode,减少编译时间。
  • 检查子模块 :确保 cutlass 完整拉取,否则会导致源文件缺失。

结语

Flash-Attention 是一个优秀的库,但 Windows 用户应正视其平台限制。如果你必须使用原版,请认真考虑切换到 WSL 2 或 Linux 环境。对于绝大多数任务,PyTorch SDPA 已经足够高效,且省去了所有编译烦恼。希望这篇记录能帮你少走弯路,把宝贵的时间投入到真正的业务逻辑中去。