1. Windows 11 下 vLLM 0.16 源码编译实战(CUDA 12.6 / PyTorch 2.7.1 完全匹配方案)
最近在 Windows 11 上折腾 vLLM 的源码编译,发现官方文档对 Windows 平台的支持并不完善。经过多次尝试,终于成功用 CUDA 12.6 编译出了与 PyTorch 2.7.1+cu126 完全匹配的 vLLM 0.16 版本。相比之前用 CUDA 12.8 编译的方案,这次确保了运行时环境的一致性,避免了潜在的兼容性问题。下面就把完整的踩坑过程和解决方案分享给大家。
1.1 为什么选择 CUDA 12.6 重新编译?
之前我用 CUDA 12.8 成功编译过 vLLM,但后来发现虚拟环境中安装的 PyTorch 是 2.7.1+cu126 版本。虽然 CUDA 12.8 编译的 wheel 在大多数情况下能向前兼容运行,但为了彻底避免潜在的版本不匹配问题,还是决定用与 PyTorch 完全一致的 CUDA 12.6 重新编译。
验证当前环境的 PyTorch CUDA 版本很简单:
bash复制python -c "import torch; print(torch.__version__, '| CUDA:', torch.version.cuda)"
# 输出:2.7.1+cu126 | CUDA: 12.6
如果你也遇到类似情况,建议检查 PyTorch 的 CUDA 版本,确保编译环境与之匹配。这样可以避免运行时出现莫名其妙的错误。
2. 环境准备与关键配置
2.1 硬件与软件环境
我的编译环境配置如下:
| 项目 | 版本 |
|---|---|
| 操作系统 | Windows 11 专业版 23H2 |
| GPU | NVIDIA GeForce RTX 3090 (sm_86) |
| 显卡驱动 | 595.02 |
| CUDA Toolkit | 12.6 |
| Python | 3.12.11 |
| PyTorch | 2.7.1+cu126 |
| Visual Studio | 2022 Professional v17.12.17 |
| vLLM 分支 | SystemPanic/vllm-windows (vllm-for-windows 分支) |
2.2 解决 CUDA 路径空格问题
Windows 下 CUDA 默认安装在 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.6,路径中包含空格。MSVC 的 cl.exe 在处理 -I 参数时不会自动加引号,这会导致编译时路径被截断。
解决方案是使用 subst 命令将 CUDA 目录映射到一个没有空格的盘符(如 Z:):
powershell复制subst Z: "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.6"
验证映射是否成功:
powershell复制subst | findstr Z
重要提示:这里映射的是 CUDA 目录,不是 vLLM 源码目录。源码应该放在其他路径(如 J:\PythonProjects4\vllm-windows),编译命令中也使用完整的源码路径。
2.3 清理 CMake 缓存
如果之前有过失败的编译尝试,必须先清理缓存,否则旧的 CMake 变量会干扰新的编译:
powershell复制Remove-Item -Recurse -Force "J:\PythonProjects4\vllm-windows\build" -ErrorAction SilentlyContinue
Remove-Item -Recurse -Force "J:\PythonProjects4\vllm-windows\.deps" -ErrorAction SilentlyContinue
.deps 目录包含 CMake 自动下载的外部依赖(如 CUTLASS、triton-windows、FlashMLA 等),清理后会重新下载,所以需要保持网络连接。
3. 编译环境详细设置
所有操作都在 VS 2022 Developer Command Prompt (x64) 中执行。以下是完整的设置步骤:
powershell复制# 1. 映射 CUDA 12.6 到 Z: 盘
subst Z: "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.6"
# 验证映射
dir Z:\bin\nvcc.exe
# 2. 设置 CUDA 相关环境变量
$env:CUDA_HOME = "Z:"
$env:CUDA_PATH = "Z:"
$env:CUDA_ROOT = "Z:"
$env:CudaToolkitDir = "Z:\"
$env:PATH = "Z:\bin;" + $env:PATH
# 3. 验证 nvcc 路径
where.exe nvcc # 第一行应该是 Z:\bin\nvcc.exe
# 4. 设置编译参数
$env:DISTUTILS_USE_SDK = "1"
$env:VLLM_TARGET_DEVICE = "cuda"
$env:MAX_JOBS = "10" # 根据 CPU 核心数调整
$env:TORCH_CUDA_ARCH_LIST = "8.6" # RTX 3090 对应 sm_86
$env:USE_LIBUV = "0"
关键点说明:
- MAX_JOBS 应根据你的 CPU 核心数设置,可以加快编译速度
- TORCH_CUDA_ARCH_LIST 需要匹配你的 GPU 架构(RTX 3090 是 sm_86)
- USE_LIBUV=0 是为了避免 PyTorch 2.7.1 的兼容性问题
4. 执行编译与问题排查
4.1 编译命令
powershell复制pip wheel J:\PythonProjects4\vllm-windows `
--no-build-isolation `
--no-deps `
-w J:\PythonProjects4\vllm-windows\wheels\ `
2>&1 | Tee-Object -FilePath "J:\PythonProjects4\vllm-windows\wheels\build-cu126.log"
编译过程分为两个阶段:
- CMake 配置阶段(约 5-10 分钟):下载并配置外部依赖
- ninja 编译阶段(约 60-90 分钟):实际编译 145 个目标
4.2 正常跳过的编译项
以下信息可以安全忽略,不是错误:
code复制-- FlashMLA will not compile: unsupported CUDA architecture 8.6
-- [QUTLASS] Skipping build: CUDA 12.8 or newer is required
-- Not building scaled_mm_c3x_sm90
-- Not building NVFP4
4.3 成功编译的标志
看到以下输出表示编译成功:
code复制[145/145] Linking CXX shared module vllm-flash-attn\_vllm_fa2_C.pyd
Successfully built vllm
5. 验证与使用
5.1 检查生成的 wheel 文件
powershell复制Get-ChildItem "J:\PythonProjects4\vllm-windows\wheels\"
正常应该看到类似这样的文件:
code复制vllm-0.16.0rc2.dev243+gc8e1f5abe.d20260309.cu126-cp312-cp312-win_amd64.whl
文件名各部分含义:
- cu126:匹配 PyTorch 2.7.1+cu126
- cp312:Python 3.12
- d20260309:编译日期
5.2 验证安装
在 vLLM 的虚拟环境中验证:
python复制import os
os.environ['USE_LIBUV'] = '0'
import vllm._C as _C
print('✅ _C 扩展加载成功')
from vllm import LLM, SamplingParams
import vllm
print('✅ vllm 导入成功,版本:', vllm.__version__)
5.3 安装到其他环境
powershell复制pip install vllm-0.16.0rc2.dev243+gc8e1f5abe.d20260309.cu126-cp312-cp312-win_amd64.whl --no-deps
pip install llguidance xgrammar
重要提示:USE_LIBUV=0 必须在 import vllm 之前设置,否则 PyTorch 2.7.1 会报错。
6. 一键恢复脚本
为了方便后续重新编译,可以创建一个一键恢复脚本:
powershell复制cd J:\PythonProjects4\vllm-windows
.\.venv\Scripts\Activate.ps1
# 清理旧缓存(可选)
# Remove-Item -Recurse -Force build, .deps
# 映射 CUDA 路径
subst Z: "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.6"
# 设置环境变量
$env:CUDA_HOME = "Z:"
$env:CUDA_PATH = "Z:"
$env:CUDA_ROOT = "Z:"
$env:CudaToolkitDir = "Z:\"
$env:PATH = "Z:\bin;" + $env:PATH
$env:DISTUTILS_USE_SDK = "1"
$env:VLLM_TARGET_DEVICE = "cuda"
$env:MAX_JOBS = "10"
$env:TORCH_CUDA_ARCH_LIST = "8.6"
$env:USE_LIBUV = "0"
# 确认 nvcc 路径
where.exe nvcc
# 执行编译
pip wheel J:\PythonProjects4\vllm-windows `
--no-build-isolation --no-deps `
-w J:\PythonProjects4\vllm-windows\wheels\
7. CUDA 12.6 vs 12.8 版本对比
| 项目 | CUDA 12.8 版本 | CUDA 12.6 版本 |
|---|---|---|
| 匹配 PyTorch | 部分匹配 | 完全匹配 ✅ |
| subst 映射 | CUDA 12.8 目录 | CUDA 12.6 目录 |
| wheel 大小 | 269 MB | 269 MB |
| 兼容性 | 可能有问题 | 最佳 |
建议根据目标环境的 PyTorch CUDA 版本选择合适的 wheel 安装。两个版本可以同时保留,按需使用。
8. 常见问题与解决方案
-
编译失败:找不到 nvcc
- 确保 subst 映射正确
- 检查 where.exe nvcc 的第一行是 Z:\bin\nvcc.exe
- 确认 PATH 环境变量以 Z:\bin 开头
-
导入 vLLM 时报错
- 确保在 import vllm 前设置 os.environ['USE_LIBUV'] = '0'
- 检查 PyTorch 和 vLLM 的 CUDA 版本是否匹配
-
CMake 配置阶段卡住
- 检查网络连接,CMake 需要下载外部依赖
- 可以手动提前下载依赖项
-
ninja 编译内存不足
- 减少 MAX_JOBS 数量
- 关闭其他占用内存的程序
经过这次完整的编译过程,我深刻体会到环境一致性在深度学习项目中的重要性。特别是当使用自定义编译的组件时,版本匹配更是关键。希望这篇指南能帮助你在 Windows 上顺利编译 vLLM,避免我踩过的那些坑。