很多同学第一次接触深度学习,不是在 Linux 服务器上,而是在自己那台装了 Windows 的电脑上。这个开头非常常见:装完 Python,装完深度学习框架,一跑torch.cuda.is_available()就冒出来 False,于是整个人麻了。我自己前前后后重装过十几次环境,各种花式报错都遇到过,最后总结出一条能安稳跑起来的流程,今天就完整写出来。
这篇内容适合完全没搭过环境的新手,也适合已经在 Linux 上跑过训练、但回到 Windows 后被各种 DLL 和路径问题搞到怀疑人生的老手。我会把整个流程切成三块:Python 基础环境、GPU 加速环境、日常工具箱和报错排查。按照这个顺序走,基本不会出现“环境跑通了但显卡用不上”的尴尬结局。
1. 动手前先定路线图:原生 Windows、WSL2 还是容器
1.1 核心需求解析:你到底想做什么
配置环境之前先别急着下载东西。深度学习开发在 Windows 上通常分三类场景,选型差别很大:
第一类:在本机写代码、做小规模实验。比如跑一个图像分类 Demo、调一个网络结构、处理几万条样本。这类场景直接用原生 Windows 环境最省事,GPU 驱动直通,文件读写都在本地磁盘,不需要搞虚拟化。
第二类:要复现别人的开源项目,尤其项目里全是 Linux 脚本。有些依赖只在 Linux 上有预编译包,Windows 上要么自己编译,要么干脆装不了。这种场景直接上 WSL2 会舒服很多。
第三类:想给团队做一个可复制的开发环境。需要保证每个人装出来的版本完全一致,那就要考虑容器化,把环境打包成镜像。
不过从大多数人的实际经历来看,第一类场景占大头,也是这篇内容的主线。如果你后面要迁移到服务器训练,在 Windows 原生环境里调通的代码,只要代码写得规范,换到 Linux 上通常也就是改个路径的事。
1.2 三种搭建思路的取舍
我实际用过三种方式,简单列个对比:
| 方案 | 优点 | 痛点 | 适合人群 |
|---|---|---|---|
| 原生 Windows | 驱动兼容最好,安装最快 | 部分 Linux 专属库装不了,路径分隔符、环境变量容易埋坑 | 初学者、小规模实验 |
| WSL2 | 接近真实 Linux,迁移性高 | 文件跑在 Linux 文件系统里,跨盘访问 Windows 文件时 IO 慢;GPU 配置比原先生态复杂 | 复现 Linux 项目、后续服务器迁移 |
| Docker Desktop | 环境隔离彻底,可打包分发 | 对新手太不友好,GPU 透传配置得多层处理 | 团队协作、多环境并行 |
我个人建议是:如果电脑是日常主力机,先不要折腾虚拟化。Windows 原生环境完全能支撑深度学习学习阶段的大部分需求。等遇到“非 Linux 不可”的依赖时,再补一个 WSL2 也不迟。
1.3 环境隔离是省时间的关键
在 Windows 上最容易犯的一个错误,就是所有包都装到系统 Python 里。今天给 A 项目装了一个旧版numpy,明天 B 项目需要新版,直接冲突,然后就开始无限重装 Python。所以第一件事不是选框架,而是先建立一个干净、可隔离的 Python 环境。后面第二节会详细说。
2. Python 与包管理:把地基打牢
2.1 为什么我建议用发行版而不是直接用系统 Python
Windows 上没有系统自带的 Python,你得去官网下载安装包,于是很多人就下载完一直点下一步。这种全局安装方式短期内能用,但有几个明显的坑:权限问题、多个版本并存困难、卸载不干净、装包时容易写进错误目录。
所以我更推荐用发行版来管理 Python 环境。常见的发行版自带环境隔离功能,安装时可以顺便装好常用的数据科学库。除此之外,它还能管理一些不只是 Python 的依赖,比如后面要提到的 CUDA 相关库,这是普通venv做不到的。
2.2 发行版的安装与初始化
安装过程不需要什么特殊技巧,但有两点值得注意。
下载时建议选最小化版本,因为完整版会带一大堆你可能永远用不到的库,体积大还容易让环境变量变得混乱。安装时按照默认路径装即可,但尽量保持路径简单,不要出现中文目录名,也不要放在带空格的路径下。
安装完成后,打开一个终端。Windows 上我喜欢直接使用 PowerShell 或者自带的 Prompt。先确认版本:
conda --version python --version然后创建一个独立的深度学习环境:
conda create --name dl python=3.10这里的dl是我给环境起的名字。Python 版本我建议选 3.10 或 3.11。3.12 之后的版本部分旧框架可能出现兼容问题,3.8 以下又太老,很多新特性用不了。3.10 是目前兼容性最稳的选择。
创建完成后激活环境:
conda activate dl你会在终端里看到当前环境名从base变成了(dl)。这一步非常重要,很多新手报错说找不到torch,其实就是环境没激活,装到了别的环境里。
2.3 环境的导出与复制
如果你是先在本机搭好环境,后面要部署到另一台 Windows 机器上,环境文件能帮你省下巨大的工作量。在dl环境激活的状态下导出:
conda env export > environment.yml另一台机器上执行:
conda env create -f environment.yml这样 Python 版本、核心库、甚至部分依赖的精确版本都会一起复现。不过我遇到过一个问题:原环境里面有某个包的版本只在特定平台有,直接迁移容易报错。保险起见,我通常在environment.yml之外再维护一个requirements.txt:
pip freeze > requirements.txt两个文件都留着,哪个能用用哪个。
3. GPU 这块水最深:CUDA、cuDNN 和 PyTorch
3.1 先搞清楚驱动、CUDA、cuDNN 三个概念
很多同学在 GPU 环境配置上栽跟头,不是因为操作复杂,而是分不清三个东西。
显卡驱动是操作系统和显卡沟通的底层程序,它决定了你的显卡能不能被系统识别。CUDA是显卡厂商提供的并行计算平台,深度学习框架靠它来调动 GPU 做矩阵运算。cuDNN是在 CUDA 之上专门为深度学习优化的加速库,卷积、池化这类操作在 cuDNN 的加持下会快不少。
用一个生活化的类比:显卡驱动是操作系统之外的“主板 BIOS”,CUDA 是给程序员用的编程接口,cuDNN 则是提前准备好的“高性能算法库”。深度学习框架调用 CUDA,CUDA 再调用 GPU,中间如果有一层版本不匹配,整个链路就断掉。
3.2 查看显卡信息和驱动支持情况
打开终端,输入:
nvidia-smi如果这个命令不存在,说明显卡驱动没装好,或者电脑根本没有独立显卡。如果命令正常输出,你会看到表格里有Driver Version和CUDA Version。很多人以为这里的 CUDA 版本就是环境里要安装的版本,这是个常见误区。
nvidia-smi显示的 CUDA 版本,是当前驱动最高支持的版本,并不代表你已经安装了某个 CUDA 工具包。它更像一块牌匾,写着“本驱动最高能撑到 CUDA 12.1”,至于你有没有用上 12.1,还得看后续安装的框架。
我自己的判断标准很简单:只要驱动支持的 CUDA 版本高于框架需要的版本,就大概率没问题。比如 PyTorch 需要 CUDA 11.8,而驱动显示支持 12.1,那直接用即可。但如果驱动版本比较老,显示的 CUDA 版本低于框架需求,则要先更新显卡驱动。
3.3 最稳的安装方式:用框架的预编译包
以前很多人装 CUDA 环境,会先手动下载整个 CUDA Toolkit,再配环境变量,最后还要装 cuDNN。这个流程在 Windows 上非常容易出问题,因为版本组合多,一个没对上就白装。
而现代深度学习框架早就把 CUDA 运行库和 cuDNN 打包进了自己的发行包里。比如 PyTorch 的官方 wheel 包,里面就带了所需的 CUDA 运行库和 cuDNN 动态库,你根本不需要提前装完整版 CUDA Toolkit。
所以我的建议是:不手动装 CUDA 工具箱,直接安装 PyTorch 的 GPU 版本。安装命令以官方页面为准,大致长这样:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121这条命令里的cu121表示这个包对应 CUDA 12.1。系统驱动只要支持 12.1,就能正常使用。
如果用的是发行版自带的包管理器,也可以从官方渠道装:
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia这条命令会自动把 CUDA 相关的运行库作为依赖装进来。不过它的包体积大,安装时间会长一些,偶尔会有频道冲突,所以我自己更常直接用 pip 路线。
3.4 验证 GPU 是否真的可用
安装结束后,别急着跑什么大模型,先做最小的验证。在dl环境里执行:
python -c "import torch; print(torch.__version__); print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'CPU')"如果输出类似:
2.4.0+cu121 True GeForce RTX 4060 Laptop GPU说明你的 GPU 链路已经打通。如果is_available()返回False,别慌,先看第五节的排查清单。
3.5 什么时候才需要手动装完整版 CUDA
有一个例外:如果你要编译自定义的 CUDA 扩展,比如某些开源项目里包含.cu源文件,那光有 PyTorch 预编译包是不够的,必须安装与项目匹配的完整 CUDA Toolkit 和编译器。
但就日常训练而言,我强烈建议不要折腾这一步,等真遇到编译报错再补装也不迟。过早手动装完整工具箱,很容易把系统里已有的 CUDA 运行库搞乱,到时候错误信息更加复杂。
4. 把开发环境配顺手:解释器、编辑器和日常命令
4.1 编辑器怎么关联到 conda 环境
环境配好了,如果编辑器不知道用哪个 Python 解释器,等于白配。以常用的 VS Code 为例,你需要在项目文件夹下打开一个 Python 文件,然后按快捷键打开命令面板,选择 “Python: Select Interpreter”,再找到以dl结尾的解释器路径。
路径一般长这样:
C:\Users\你的用户名\.conda\envs\dl\python.exe一旦选中,编辑器里的终端也会默认使用这个环境。后续运行脚本、调试代码就都能识别到 PyTorch。
如果你用 JupyterLab,还需要让内核识别到这个环境。在dl环境里执行:
python -m ipykernel install --user --name dl --display-name "Python (dl)"之后打开 Jupyter 时,新建笔记本就能选Python (dl)这个内核。
4.2 训练过程里的几个日常命令
配置完成后,我会习惯在训练程序里加一段设备判断代码:
import torch device = torch.device("cuda" if torch.cuda.is_available() else "cpu") print("Using device:", device)这样在 Windows 和 Linux 服务器之间切换时,代码不需要改动。
训练期间最常用的巡检命令还是nvidia-smi。它能看到显存占用、功耗、温度、当前跑在 GPU 上的进程。比如训练时报错说 OutOfMemory,先跑一下nvidia-smi,看是不是之前有残留的 Python 进程占着显存没释放。
4.3 项目级依赖管理
很多人只创建了环境,但没有管理项目依赖,结果时间一长自己也忘了一开始装了哪些包。建议每个深度学习项目都放一个requirements.txt,至少包含以下内容:
torch torchvision torchaudio numpy pandas matplotlib jupyter注意这里的torch不带--index-url,如果在环境激活状态下执行:
pip install -r requirements.txtPyPI 上的默认版本是 CPU 版,这个坑很容易踩。为了避免误装,可以在requirements.txt里写上带有+cu121后缀的精确版本号,但这种写法的可移植性较差。更稳妥的做法是,首次安装 GPU 版本时就手动用带--index-url的完整命令安装,之后通过pip freeze把结果固化到requirements.txt。
5. 高频报错排查:从“装完”到“能跑”的最后一步
5.1torch.cuda.is_available()为 False 的原因
这是我见过最多的报错场景,没有之一。核心原因往往只有两个:
第一个是装了 CPU 版 PyTorch。下载 PyTorch 时如果不指定 CUDA 版本,默认安装的就是 CPU 版本。判断方法很简单:
python -c "import torch; print(torch.version.cuda; )"如果输出是None,那就是 CPU 版,需要重新安装 GPU 版,覆盖即可。
第二个是显卡驱动太老。比如 PyTorch 的 wheel 需要 CUDA 12.1,但驱动只支持 CUDA 11.8。这种情况跑nvidia-smi就能发现,去显卡驱动管理页更新到支持 12.1 的版本后再试。
5.2 导入 torch 时 DLL 报错
在 Windows 上,经典的报错信息长这样:
OSError: [WinError 126] The specified module could not be found很多人看到这个就懵了,但大概率不是你的项目代码出问题,而是缺少系统级运行库。PyTorch 依赖 Microsoft Visual C++ Redistributable,缺了它就会出现这种奇奇怪怪的错误。解决办法是搜索并安装对应的 VC++ 运行库合集,安装后重启终端,再导入 torch 试试。
5.3 路径长度和中文路径导致的诡异问题
Windows 默认路径长度限制在某些项目依赖树比较深时非常致命。Node 风格的依赖通常还好,但 Python 的site-packages路径一旦过长,可能出现一些“明明文件在那里却导入失败”的情况。
解决办法有两个层面。一是开始安装 Python 或发行版时,尽量把根目录放在盘符下层级浅的位置,比如D:\eric,避免C:\Users\用户名\AppData\...这种超长路径。二是可以开启系统的长路径支持:运行gpedit.msc,打开“本地组策略编辑器”,找到“计算机配置 -> 管理模板 -> 系统 -> 文件系统 -> 启用 Win32 长路径”,改为“已启用”,重启电脑。
5.4 常见问题速查表
| 现象 | 最可能原因 | 解决方案 |
|---|---|---|
ModuleNotFoundError: No module named 'torch' | 没激活环境或装错环境 | 先执行conda activate dl,再pip list确认 |
torch.version.cuda输出为 None | 装的是 CPU 版 | 用--index-url指定 cu 版本重新安装 |
torch.cuda.is_available()为 False | 驱动过老或 CPU 版 | 更新驱动,检查框架 CUDA 需求 |
| 导入 torch 报 WinError 126 | 缺少 VC++ 运行库 | 安装最新版 VC++ Redistributable |
| 训练时 OutOfMemory | 显存溢出 | 降低batch_size,或调用torch.cuda.empty_cache() |
| 训练完再次训练显存不足 | 残留 Python 进程占用显存 | 关闭旧终端,或用nvidia-smi查看并结束残留进程 |
5.5 用日志而不是截图来定位问题
Windows 的终端乱码、弹窗等会让报错信息很难看清,尤其是在 PowerShell 里跑训练脚本。我习惯在脚本开头加上:
import logging logging.basicConfig(level=logging.INFO)同时配合print(torch.__version__)、print(torch.version.cuda),把自己需要的信息打印出来。这样就算报错,至少能知道当前环境到底是哪个版本。
6. 用一个小 Demo 跑通整条链路
6.1 不依赖数据集的合成数据实验
很多新手装完环境,想直接跑一个公开数据集项目,结果卡在数据集下载和依赖缺失上。我建议先用一个合成数据的小实验验证整条链路,成本低,不用下载任何东西。
下面这个 Demo 用 1000 个随机样本训练一个极小的多层感知机,用来拟合一个简单的线性关系。代码里自动选择 GPU 或 CPU:
import torch import torch.nn as nn device = torch.device("cuda" if torch.cuda.is_available() else "cpu") torch.manual_seed(0) X = torch.randn(1000, 2) y = 2 * X[:, [0]] - 1.5 * X[:, [1]] + 0.01 * torch.randn(1000, 1) model = nn.Sequential( nn.Linear(2, 8), nn.ReLU(), nn.Linear(8, 1) ).to(device) opt = torch.optim.Adam(model.parameters(), lr=0.01) loss_fn = nn.MSELoss() X, y = X.to(device), y.to(device) for step in range(200): pred = model(X) loss = loss_fn(pred, y) opt.zero_grad() loss.backward() opt.step() if step % 50 == 0: print(f"step {step}, loss {loss.item():.6f}")如果你跑完看到 loss 从 0.5 一路降到 0.1 以下,说明 PyTorch、GPU、管理器、解释器全部正常。如果打印出step 0, loss ...,而脚本运行时候的风扇转速明显提高,那就说明 GPU 真的在工作。
6.2 怎样确认程序真的跑在 GPU 上
有时候你以为跑在 GPU 上,其实还是 CPU 在扛。除了看torch.cuda.is_available()之外,可以在训练循环里临时加一行:
print(next(model.parameters()).device)输出是cuda:0才是真正在使用显卡。如果输出是cpu,检查一下是不是代码里没有调用.to(device),或者模型本身没有被放到 GPU 上。
6.3 从 Demo 到真实项目之间的少数步骤
这个 Demo 跑通后,你就有了一套完全可以复用的环境。接下来要做的事就是把它复制到真实项目里:
- 在项目根目录创建
requirements.txt。 - 根据项目需要,把模型、数据加载、训练循环拆成独立模块。
- 写训练脚本时,统一在代码开头判断设备。
- 每次安装新包后,用
pip freeze > requirements.txt更新依赖清单。
这套流程我用了很长时间,从 Windows 原生环境迁移到 Linux 服务器时,几乎不用改环境配置,只需要确保服务器上的 CUDA 版本不低于本地需求即可。
最后分享一个我踩过很多次坑后的小习惯
配置环境这件事,最怕的不是过程麻烦,而是装完没记录,下次重装又要从零开始。我现在每搭一个环境,都会在同一目录下放一个env_notes.txt,里面记录三样东西:conda 环境的名称、Python 版本、PyTorch 对应 CUDA 版本,再加上我实际执行过的命令。这样即使半年后系统重装,也能照着原命令一小时内恢复开发环境。
另一个建议是:不要在一台电脑上反复创建太多深度学习环境。环境多了之后,终端的激活信息容易混淆,装包位置也可能互相覆盖。我一般保留一个日常开发环境dl,再加一个实验环境experiment,有冲突就重建,简单直接。
整个 Windows 下 Python 深度学习环境配置,说到底就是三件事:隔离好 Python 环境、选对 CUDA 版本、验证链路是否通畅。只要这三步都确认过,后面写模型、跑训练、复现代码都会顺畅很多。