文章背景图

Windows 上从源码完整构建 vLLM wheel 的详细教程

2026-02-24
275
-
- 分钟

(附上vllm包和对应版本的flash_attn2包)


概览

本文档覆盖从环境准备、必须的源码修改、完整的 build_wheel.ps1 脚本、运行方法与常见故障排查。请在执行前把脚本中的路径替换为你本地实际安装路径(CUDA、cuDNN、conda 环境等)。


前置条件(必读)

  • 操作系统:Windows 10/11(建议 64-bit)

  • Visual Studio 2022:安装 Desktop development with C++ 工作负载(含 MSVC、CMake)

  • CUDA Toolkit:与要安装的 PyTorch CUDA 版本匹配(示例使用 CUDA v13.0)

  • cuDNN / cuSPARSELt / cuDSS:按需安装并记下 libinclude 路径

  • Conda / Miniconda:用于创建隔离 Python 环境

  • 网络:能访问 PyTorch nightly wheel 源(https://download.pytorch.org/whl/nightly/cu130


第 1 步:创建并准备 Python 环境

Developer PowerShell for VS 2022 中执行(可一键复制):

# 切换到你的工作目录(示例)
cd A:/AI    # 你的工作目录

# 创建并激活 conda 环境(Python 3.12.12,或者其他版本)
conda create -n vllm python==3.12.12 -y
conda init
conda activate vllm

# 克隆 vllm-windows 源码(vllm-for-windows 分支)
git clone --branch vllm-for-windows --depth 1 https://github.com/SystemPanic/vllm-windows.git
cd vllm-windows

# 安装 PyTorch nightly(已按你要求修改:只指定 torch 的具体 nightly 版本,其他包使用默认最新)
pip install --pre torch==2.12.0.dev20260223+cu130 torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cu130

说明与建议

  • 如果你使用的是不同 CUDA 版本,请改为对应的nightly版本( torch>=2.11.0.dev20260116,正式版gloo有问题)。

  • 安装完成后可用 python -c "import torch; print(torch.__version__, torch.version.cuda)" 验证。


第 2 步:必须的源码修改(避免编译错误)

重要:下面的修改需要在源码目录中手动编辑对应文件。可用 codenotepadvim 等工具打开并修改。

2.1 修改 generate_kernels.py

路径:A:\AI\vllm-windows\csrc\quantization\marlin\generate_kernels.py

替换原有 remove_old_kernels 实现(将 Linux rm 调用改为 Python 删除并加异常处理)

修改前:

def remove_old_kernels():
    for filename in glob.glob(os.path.dirname(__file__) + "/*kernel_*.cu"):
        subprocess.call(["rm", "-f", filename])

    filename = os.path.dirname(__file__) + "/kernel_selector.h"
    subprocess.call(["rm", "-f", filename])

修改后(请完整替换):

def remove_old_kernels():
    for filename in glob.glob(os.path.dirname(__file__) + "/*kernel_*.cu"):
        try:
            os.remove(filename)
        except FileNotFoundError:
            pass

    filename = os.path.dirname(__file__) + "/kernel_selector.h"
    try:
        os.remove(filename)
    except FileNotFoundError:
        pass

说明:Windows 上没有 rm 命令,且直接调用会导致错误;改为 os.remove 并捕获 FileNotFoundError 更稳健。

2.2 修改 PyTorch 头文件(PowerShell 执行)

注意:下面的 $file 路径必须替换为你 conda 环境中 torch 的实际 include 路径。

在 PowerShell 中运行(示例路径请替换):

# 将下面的路径替换为你 vllm 虚拟环境中 torch 的实际路径
$file = "L:\ProgramData\miniconda3\envs\vllm\Lib\site-packages\torch\include\c10\cuda\CUDACachingAllocator.h"

# 备份原文件
Copy-Item $file "$file.bak"

# 执行替换:修改函数参数名,避免编译时符号不匹配
(Get-Content $file -Raw) `
    -replace 'StreamSegmentSize\(cudaStream_t s, bool small, size_t sz\)', 'StreamSegmentSize(cudaStream_t s, bool is_small, size_t sz)' `
    -replace ': stream\(s\), is_small_pool\(small\)', ': stream(s), is_small_pool(is_small)' |
    Set-Content $file -NoNewline

# 验证替换结果
Write-Host "Patch 完成,验证结果:"
Select-String -Path $file -Pattern "StreamSegmentSize"

说明:该补丁将 small 重命名为 is_small,并修改初始化列表,避免与源码或编译器期望不一致导致的编译错误。

2.3 修改 CMakeLists.txt

路径:A:\AI\vllm-windows\CMakeLists.txt

将 TORCH 支持版本改为你安装的 torch 版本(示例改为 2.12.0)

修改前:

set(TORCH_SUPPORTED_VERSION_CUDA "2.10.0")
set(TORCH_SUPPORTED_VERSION_ROCM "2.10.0")

修改后:

set(TORCH_SUPPORTED_VERSION_CUDA "2.12.0")
set(TORCH_SUPPORTED_VERSION_ROCM "2.12.0")

说明:CMake 会检查 PyTorch 版本,若不一致会报错或拒绝构建。


第 3 步:完整构建脚本 build_wheel.ps1请完整保存为文件并运行

将下面完整脚本保存为项目根目录下的 build_wheel.ps1,脚本中已包含注释与提示,务必根据本机实际路径修改 $cudaPath$cudnnLibPath 等变量。

提示:脚本使用短路径获取函数 Get-ShortPath 来避免路径中空格导致的编译问题;脚本会设置一系列环境变量并直接调用 python -m build --wheel --no-isolation,这样在 PowerShell 中按 Ctrl+C 可以更可靠地中断构建。

# ---------------------------------------------------------
# build_wheel.ps1 - Windows 构建 vLLM wheel 的完整脚本
# 保存路径:vllm-windows 根目录下的 build_wheel.ps1
# 运行方式:在 Developer PowerShell for VS 2022 中执行 .\build_wheel.ps1
# ---------------------------------------------------------

# 函数:获取8.3短路径
function Get-ShortPath {
    param([string]$LongPath)
    
    if (-not (Test-Path $LongPath)) {
        Write-Host "警告:路径不存在: $LongPath" -ForegroundColor Yellow
        return $LongPath
    }
    
    try {
        $fso = New-Object -ComObject Scripting.FileSystemObject
        $shortPath = $fso.GetFolder($LongPath).ShortPath
        Write-Host "短路径: $shortPath" -ForegroundColor Gray
        return $shortPath
    } catch {
        Write-Host "无法获取短路径,使用原路径: $LongPath" -ForegroundColor Yellow
        # 修复点:直接返回路径,不加引号,防止环境变量路径错误
        return $LongPath
    }
}

# 清理构建目录
Write-Host "清理构建文件..." -ForegroundColor Yellow
$items = @("build", "dist", "vllm.egg-info", "_skbuild", "*.pyd", "__pycache__")
foreach ($item in $items) {
    if (Test-Path $item) {
        Remove-Item -Recurse -Force $item -ErrorAction SilentlyContinue
        Write-Host "已清理: $item" -ForegroundColor Gray
    }
}

# 获取短路径(请根据实际安装位置修改下面路径)
$cudaPath = "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.0"
$cudaShortPath = Get-ShortPath $cudaPath
$cudnnLibPath = "C:\Program Files\NVIDIA\CUDNN\v9.19\lib\13.1\x64"
$cudnnLibShortPath = Get-ShortPath $cudnnLibPath
$cudnnIncludePath = "C:\Program Files\NVIDIA\CUDNN\v9.19\include\13.1"
$cudnnIncludeShortPath = Get-ShortPath $cudnnIncludePath
$cudssLibPath = "C:\Program Files\NVIDIA cuDSS\v0.7\lib"
$cudssLibShortPath = Get-ShortPath $cudssLibPath
$cudssIncludePath = "C:\Program Files\NVIDIA cuDSS\v0.7\include"
$cudssIncludeShortPath = Get-ShortPath $cudssIncludePath
$cusparseltLibPath = "C:\Program Files\NVIDIA cuSPARSELt\v0.8\lib"
$cusparseltLibShortPath = Get-ShortPath $cusparseltLibPath
$cusparseltIncludePath = "C:\Program Files\NVIDIA cuSPARSELt\v0.8\include"
$cusparseltIncludeShortPath = Get-ShortPath $cusparseltIncludePath

# 设置环境变量
Write-Host "设置环境变量..." -ForegroundColor Yellow

$envVars = @{
    DISTUTILS_USE_SDK = "1"
    VLLM_TARGET_DEVICE = "cuda"
    MAX_JOBS = "24"  
    NVCC_THREADS = "8"
    CMAKE_BUILD_TYPE = "Release"
    VERBOSE = "1"
    FORCE_CUDA = "1"
    TORCH_CUDA_ARCH_LIST = "8.9"
    
    # 使用短路径
    CUDA_ROOT = $cudaShortPath
    CUDA_HOME = $cudaShortPath
    CUDA_PATH = $cudaShortPath
    
    # CUDA 相关库路径
    USE_CUDNN = "1"
    CUDNN_LIBRARY_PATH = $cudnnLibShortPath
    CUDNN_INCLUDE_PATH = $cudnnIncludeShortPath
    USE_CUDSS = "1"
    CUDSS_LIBRARY_PATH = $cudssLibShortPath
    CUDSS_INCLUDE_PATH = $cudssIncludeShortPath
    USE_CUSPARSELT = "1"
    CUSPARSELT_LIBRARY_PATH = $cusparseltLibShortPath
    CUSPARSELT_INCLUDE_PATH = $cusparseltIncludeShortPath
    
    # 解决 Windows 宏问题
    CFLAGS    = "/DNOMINMAX /DWIN32_LEAN_AND_MEAN /Usmall"
    CXXFLAGS  = "/DNOMINMAX /DWIN32_LEAN_AND_MEAN /Usmall"
    CMAKE_CXX_FLAGS = "/DNOMINMAX /DWIN32_LEAN_AND_MEAN /Usmall"
    NVCC_PREPEND_FLAGS = "-Xcompiler=/Usmall"
}
# 应用环境变量
foreach ($key in $envVars.Keys) {
    [Environment]::SetEnvironmentVariable($key, $envVars[$key], "Process")
    Write-Host "  $key = $($envVars[$key])" -ForegroundColor Gray
}

# 添加 CUDA 到 PATH
$env:PATH = "$cudaShortPath\bin;$env:PATH"

# 验证环境
Write-Host "`n验证环境..." -ForegroundColor Green

# 检查 CUDA
try {
    $cudaVersion = nvcc --version 2>&1 | Select-String -Pattern "release"
    Write-Host "  ✓ CUDA: $cudaVersion" -ForegroundColor Green
} catch {
    Write-Host "  ✗ CUDA 未找到或未在 PATH 中" -ForegroundColor Red
}

# 检查 PyTorch
try {
    # 修复点:使用单引号避免PowerShell转义导致的语法错误
    $torchInfo = python -c 'import torch; print(f"PyTorch {torch.__version__}, CUDA {torch.version.cuda if hasattr(torch.version, \"cuda\") else \"N/A\"}")' 2>&1
    Write-Host "  ✓ $torchInfo" -ForegroundColor Green
} catch {
    Write-Host "  ✗ PyTorch 导入失败" -ForegroundColor Red
}

# 检查构建文件是否存在
if (-not (Test-Path "setup.py") -and -not (Test-Path "pyproject.toml")) {
    Write-Host "`n✗ 错误:未找到 setup.py 或 pyproject.toml 文件。" -ForegroundColor Red
    Write-Host "  请确认当前目录是正确的 vllm-windows 源码根目录。" -ForegroundColor Yellow
    exit 1
}

# 运行构建准备脚本
if (Test-Path "use_existing_torch.py") {
    Write-Host "`n运行 use_existing_torch.py..." -ForegroundColor Green
    python use_existing_torch.py
}

# ---------------------------------------------------------
# 核心修改部分:直接执行构建命令,解决卡死和无法中断的问题
# ---------------------------------------------------------

Write-Host "`n开始构建..." -ForegroundColor Green
Write-Host "提示:编译过程可能需要 30 分钟以上,请耐心等待。如需中断请按 Ctrl+C。" -ForegroundColor Yellow

$startTime = Get-Date

# 直接调用 python -m pip,输出实时显示,Ctrl+C 可正常中断
python -m build --wheel --no-isolation

$exitCode = $LASTEXITCODE
$duration = (Get-Date) - $startTime
Write-Host "`n构建用时: $($duration.ToString('hh\:mm\:ss'))" -ForegroundColor Cyan

# 检查结果
if ($exitCode -eq 0) {
    Write-Host "`n✓ 构建成功!" -ForegroundColor Green
    
    # 显示生成的包
    $wheels = Get-ChildItem dist\*.whl -ErrorAction SilentlyContinue
    if ($wheels) {
        Write-Host "`n生成的 wheel 包:" -ForegroundColor Cyan
        $wheels | ForEach-Object {
            $size = "{0:N2} MB" -f ($_.Length / 1MB)
            Write-Host "  - $($_.Name) ($size)" -ForegroundColor White
        }
    } else {
        Write-Host "  未在 dist\\ 下找到 .whl 文件,请检查构建日志。" -ForegroundColor Yellow
    }
} else {
    Write-Host "`n✗ 构建失败 (退出代码: $exitCode)" -ForegroundColor Red
    Write-Host "  请查看上方输出的错误信息,常见问题:" -ForegroundColor Yellow
    Write-Host "    - CUDA / cuDNN 路径错误或版本不匹配" -ForegroundColor Gray
    Write-Host "    - PyTorch 版本与 CMakeLists.txt 中的 TORCH_SUPPORTED_VERSION 不一致" -ForegroundColor Gray
    Write-Host "    - Visual Studio C++ 工具链未安装或未在 PATH 中" -ForegroundColor Gray
}

# 结束脚本
Write-Host "`n脚本执行完毕。" -ForegroundColor Green

第 4 步:运行脚本与安装 wheel

  1. 在 Developer PowerShell for VS 2022 中进入源码根目录(含 setup.pypyproject.toml):

    cd A:\AI\vllm-windows
    
  2. 运行脚本(确保已激活 vllm conda 环境):

    .\build_wheel.ps1
    
  3. 构建成功后,wheel 文件会出现在 dist\ 目录下,例如:dist\vllm-*.whl。安装命令:

    pip install dist\your_vllm_wheel.whl
    

常见问题与排查建议

  • 构建看似“卡住”但无输出:编译大型 C++/CUDA 项目时可能长时间无输出,观察 CPU/GPU/磁盘活动或打开另一个终端查看 cl.exe / nvcc 进程。若需中断,按 Ctrl+C。脚本使用 --no-isolation 以便 Ctrl+C 更可靠中断。

  • 找不到 nvcc:确认 CUDA bin 已加入 PATH,或脚本中 $env:PATH 设置正确。可在 PowerShell 中运行 nvcc --version 验证。

  • PyTorch 导入失败:确认在当前 Python 环境中已安装 nightly torch(脚本中有验证步骤)。若失败,检查 pip install 输出并重装。

  • CMake 报 TORCH 版本不匹配:确保 CMakeLists.txtTORCH_SUPPORTED_VERSION_CUDA 与你安装的 torch 版本一致(示例使用 2.12.0)。

  • 找不到头文件或库:检查 CUDNN_LIBRARY_PATHCUDNN_INCLUDE_PATHCUSPARSELT_INCLUDE_PATH 等路径是否正确,且路径中不要包含 PowerShell 无法识别的特殊字符。

  • MSVC 编译器问题:确认 Visual Studio 2022 的 C++ 工作负载已安装,并在 Developer PowerShell 中运行(它会设置 MSVC 环境变量)。


评论交流

文章目录