【没有轮子就自己造】BasicSR Windows 编译安装教程 Python3.14 CUDA13.0
BasicSR Windows 编译安装教程 Python3.14 CUDA13.0
系列:Windows AI 开发环境 “没有轮子(.whl) 就自己造”从零到一
难度:⭐⭐⭐⭐
环境:Windows 11 · Python 3.14 · PyTorch 2.12.0.dev+cu130 · CUDA 13.0 · RTX 3090 · VS 2022
前言

BasicSR 是做超分/图像修复绕不开的库,但它的官方文档只写了 Linux 的安装步骤,Windows 用户在 Python 3.13 + CUDA 13.0 环境下直接 pip install basicsr 大概率翻车——要么找不到 CUDA,要么扩展编译失败,要么在 Python 3.13+ 上直接报 KeyError。
本文以实际踩坑过程为主线,记录在 Python 3.14 + CUDA 13.0 + PyTorch nightly 这个"前沿"组合下,完整编译出包含三个 CUDA 扩展的 BasicSR wheel 的完整步骤,以及每一步背后的原理。
BasicSR 的三个 CUDA 扩展:
| 扩展 | 用途 |
|---|---|
deform_conv_ext |
DCN 可变形卷积,EDVR/BasicVSR 必需 |
fused_act_ext |
Fused Leaky ReLU,StyleGAN2 系列必需 |
upfirdn2d_ext |
上采样滤波,StyleGAN2 系列必需 |
一、环境准备
1.1 本文实际使用的环境
OS : Windows 11
GPU : RTX 3090 (sm_86)
Driver : 595.02
Python : 3.14.0
PyTorch : 2.12.0.dev20260323+cu130
CUDA : 13.0 (Switch-CUDA 多版本管理)
cuDNN : v9.14 (for CUDA 13.0)
VS : Visual Studio 2022 Professional v17.12
1.2 CUDA 版本匹配原则
Switch-CUDA 工具来源:
核心原则:nvcc 版本必须与 PyTorch 内部 CUDA 版本一致。
# 查看 PyTorch 内部 CUDA 版本
python -c "import torch; print(torch.version.cuda)"
# 输出: 13.0

确认是 13.0 后,切换到 CUDA 13.0:
# 加载 Switch-CUDA 工具(若未在 profile 中自动加载)
. D:\Program\switch-cuda.ps1
Switch-CUDA 13.0
# 验证
nvcc --version
# Cuda compilation tools, release 13.0, V13.0.88 ✅

💡 Switch-CUDA 工具:本系列前几期介绍的多版本 CUDA 共存切换脚本,通过读取系统环境变量
cuDNN_PATH_V12_6~cuDNN_PATH_V13_1动态切换 PATH,支持 CUDA 12.6 ~ 13.1 五个版本一键切换。没有这个工具的读者,手动把对应 CUDA 版本的bin和bin\x64加到 PATH 最前面即可。
二、克隆源码并安装依赖
在 VS 2022 Developer Shell x64 中执行以下所有命令。
# 克隆 BasicSR
git clone https://github.com/XPixelGroup/BasicSR.git
cd BasicSR
# 安装 Python 依赖(不含 CUDA 扩展)
pip install -r requirements.txt

三、设置编译环境变量
3.1 subst 消除路径空格
CUDA 安装在 C:\Program Files\...,路径含空格,MSVC 编译时偶发解析错误。用 subst 映射到无空格的盘符:
subst Z: "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.0"
3.2 设置所有必要变量
$env:CUDA_HOME = "Z:"
$env:CUDA_PATH = "Z:"
$env:CUDA_ROOT = "Z:"
$env:CudaToolkitDir = "Z:"
$env:TORCH_CUDA_ARCH_LIST = "8.6" # RTX 3090 的 compute capability
$env:MAX_JOBS = "8"
$env:DISTUTILS_USE_SDK = "1"
$env:BASICSR_EXT = "True" # 告诉 setup.py 编译 CUDA 扩展
$env:PATH = "Z:\bin;Z:\bin\x64;" + $env:PATH
⚠️ CUDA 13.x 特别注意:CUDA 13.0 开始 nvcc 同时存在于
bin\和bin\x64\,Switch-CUDA 工具已同时将两个路径加入 PATH。手动设置时不要漏掉bin\x64。
3.3 验证 nvcc 优先级
where.exe nvcc
# Z:\bin\nvcc.exe ← 第一行必须是 subst 后的路径 ✅
# C:\Program Files\...

四、编译 wheel
4.1 第一次尝试:直接 pip wheel
pip wheel . --no-deps -w dist\
报错:
ModuleNotFoundError: No module named 'torch'
ImportError: Unable to import torch - torch is needed to build cuda extensions
原因:pip wheel 默认使用 isolated build 环境,该环境是临时创建的,看不到当前 venv 里已安装的 torch。
4.2 改用 --no-build-isolation
正确姿势是用 python -m build 并关闭 isolation:
pip install build # 先装 build 工具
python -m build --wheel --no-isolation 2>&1 | Tee-Object -FilePath "build.log"
又报错:
KeyError: '__version__'
ERROR Backend subprocess exited when trying to invoke get_requires_for_build_wheel
这才是本文最核心的坑,下一节详细说。
五、核心坑:Python 3.14 的 exec 作用域变化
5.1 问题定位
报错栈指向 setup.py 第 79 行的 get_version() 函数:
def get_version():
with open(version_file, 'r') as f:
exec(compile(f.read(), version_file, 'exec'))
return locals()['__version__'] # ← 问题在这里
5.2 根本原因
Python 3.13+ 对 exec() 的作用域语义做了调整:在函数内部调用不带命名空间参数的 exec(),exec 内部定义的变量不再自动"泄漏"到外层的 locals() 中。
这个变化从 Python 3.13 开始,3.14 完全生效。所有用这个模式读版本号的老项目(setup.py 中 exec + locals()['__version__'])都会中招,不只是 BasicSR。
5.3 解决方案:patch get_version()
修复方法是给 exec() 传入一个显式的命名空间字典:
# 修复前(Python 3.14 失效)
def get_version():
with open(version_file, 'r') as f:
exec(compile(f.read(), version_file, 'exec'))
return locals()['__version__']
# 修复后(兼容所有 Python 版本)
def get_version():
ns = {}
with open(version_file, 'r') as f:
exec(compile(f.read(), version_file, 'exec'), ns)
return ns['__version__']
用 Python 一行命令完成 patch(无需手动编辑文件):
python -c "
with open('setup.py', 'r', encoding='utf-8') as f:
content = f.read()
old = '''def get_version():
with open(version_file, 'r') as f:
exec(compile(f.read(), version_file, 'exec'))
return locals()['__version__']'''
new = '''def get_version():
ns = {}
with open(version_file, 'r') as f:
exec(compile(f.read(), version_file, 'exec'), ns)
return ns['__version__']'''
content = content.replace(old, new)
with open('setup.py', 'w', encoding='utf-8') as f:
f.write(content)
print('patch OK')
"


5.4 重新编译
Remove-Item -Recurse -Force build -ErrorAction SilentlyContinue
python -m build --wheel --no-isolation 2>&1 | Tee-Object -FilePath "build.log"
编译成功后可以在输出末尾看到:
adding 'basicsr/ops/dcn/deform_conv_ext.cp314-win_amd64.pyd' ✅
adding 'basicsr/ops/fused_act/fused_act_ext.cp314-win_amd64.pyd' ✅
adding 'basicsr/ops/upfirdn2d/upfirdn2d_ext.cp314-win_amd64.pyd' ✅
Successfully built basicsr-1.4.2-cp314-cp314-win_amd64.whl
三个 .pyd 文件全部编译进 wheel,大功告成。





六、安装与验证
pip install dist\basicsr-1.4.2-cp314-cp314-win_amd64.whl --no-deps
验证所有扩展可正常加载:
from basicsr.ops.dcn import ModulatedDeformConvPack
from basicsr.ops.fused_act import FusedLeakyReLU
from basicsr.ops.upfirdn2d import upfirdn2d
import basicsr
print(f'basicsr {basicsr.__version__} 所有扩展加载成功 ✅')
# basicsr 1.4.2 所有扩展加载成功 ✅

七、踩坑汇总
| # | 错误信息 | 原因 | 解决方案 |
|---|---|---|---|
| 1 | No module named 'torch' |
pip isolated build 环境隔离了 venv | 改用 python -m build --wheel --no-isolation |
| 2 | KeyError: '__version__' |
Python 3.14 改变了 exec() + locals() 的作用域语义 |
patch get_version(),传入显式命名空间 ns = {} |
| 3 | nvcc 版本不匹配 | 系统默认 CUDA 版本与 PyTorch 内部版本不一致 | Switch-CUDA 切换到对应版本 |
| 4 | 路径含空格导致编译错误 | MSVC 处理带空格路径不稳定 | subst Z: 映射到无空格盘符 |
八、附:JIT 模式(不想编译 wheel 的替代方案)
如果你不需要打 wheel 分发,只是自用,BasicSR 支持 JIT(Just-In-Time)模式——首次运行时自动编译 CUDA 扩展并缓存,之后直接加载:
# 安装纯 Python 版(不触发 CUDA 扩展编译)
pip install -e . --no-deps
# 运行时开启 JIT
$env:BASICSR_JIT = "True"
# 或写入 venv 的 Activate.ps1,永久生效
Add-Content .venv\Scripts\Activate.ps1 "`n`$env:BASICSR_JIT = 'True'"
JIT 模式的优缺点:
- 优点:安装简单,无需 VS 编译环境
- 缺点:首次运行慢(需要编译),需要机器上有 CUDA 开发环境,不适合分发给他人
小结
本文核心结论只有两句话:
-
用
python -m build --wheel --no-isolation,不要用pip wheel,这样才能让 setup.py 看到当前 venv 里的 torch。 -
Python 3.13+ 的
exec()不再把变量泄漏到locals(),凡是用这个老模式读版本号的setup.py都要 patch。
这两个坑不只是 BasicSR 独有,整个老一代 PyTorch 扩展生态(BasicSR、mmcv、spconv……)的 setup.py 大量使用相同模式,随着 Python 3.14 普及,会有越来越多的项目踩到第二个坑。希望本文能帮到同样在 Windows 前沿环境折腾的你。
本文为「Windows AI 开发环境从零到一」系列文章,更多 CUDA 编译、多版本管理、ComfyUI 生态相关内容见 CSDN 主页。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)