1. 为什么我最终把 AI 开发环境整体搬进了 WSL2
1.1 从双系统到 WSL2 的折腾史
最早做深度学习那会儿,我的方案是 Windows 加 Ubuntu 双系统。每次要跑训练就得重启,切到 Linux 下面调代码,调完想查个资料又得切回 Windows,一天下来光重启就浪费不少时间。后来试过纯 Linux 主机,显卡驱动、桌面环境、输入法各种小毛病不断,日常办公体验确实不如 Windows 顺手。再后来虚拟机也试过,VMware 和 VirtualBox 都跑过,但 GPU 直通要么不支持,要么配置极其折腾,性能损耗也大,跑个小模型都费劲。
直到 WSL2 成熟之后,我才真正找到了一个平衡点。WSL2 本质上是跑在轻量级虚拟化层上的完整 Linux 内核,不是以前 WSL1 那种系统调用翻译层。这意味着它兼容原生 Linux 的 ELF 二进制文件,Docker 能跑,CUDA 也能跑。微软和 NVIDIA 合作把 GPU 直通做进了 WSL2 的内核里,Windows 主机上的 NVIDIA 显卡驱动可以直接被 WSL2 里的 Linux 发行版调用,不需要在 Linux 里再单独装一遍驱动。这一点是质变。
我现在的主力方案就是:Windows 11 负责日常办公、浏览器、微信、Office,WSL2 里的 Ubuntu 22.04 负责所有 AI 开发工作,包括 PyTorch 训练、CUDA 编译、数据处理脚本。两边文件系统互通,剪贴板共享,VS Code 直接远程连进 WSL2 写代码,体验几乎和原生 Linux 一样,但省去了双系统切换的所有麻烦。
1.2 这套方案到底适合谁
如果你符合下面任意一条,这套方案大概率能帮你省下大量时间:
- 主力机器是 Windows,但需要 Linux 环境跑 PyTorch、TensorFlow 等框架
- 有 NVIDIA 显卡,想让 WSL2 里的代码直接调用 GPU 做训练或推理
- 不想折腾双系统,也不想忍受传统虚拟机的性能损耗和 GPU 配置难题
- 需要同时用 Windows 办公软件和 Linux 开发工具链
- 想用 VS Code 或 Cursor 这类编辑器直接连进 Linux 环境写代码
反过来说,如果你用的是 AMD 显卡想做 ROCm 开发,或者需要特定的 Linux 桌面环境做图形界面开发,WSL2 目前的支持还不算完美,这种情况可能还是原生 Linux 更合适。但对于绝大多数做深度学习、CUDA 编程、Python 开发的人来说,WSL2 已经是相当成熟的方案了。
1.3 整体架构一句话说清
Windows 主机装好 NVIDIA 驱动,WSL2 里装 Ubuntu 22.04,Ubuntu 里装 CUDA Toolkit 和 PyTorch,代码通过 VS Code Remote 连接编写,训练时 GPU 直接由 Windows 驱动接管。整个链路里,WSL2 负责提供 Linux 用户空间和内核,Windows 负责硬件驱动和 GPU 调度,两者通过微软的 GPU 虚拟化层通信。理解这个架构,后面所有配置步骤的逻辑就都通了。
2. 环境准备:从零开始的完整配置流程
2.1 Windows 侧的前置检查与 WSL2 启用
在动手之前,先确认几件事。第一,Windows 版本必须是 Windows 10 版本 2004 及以上,或者 Windows 11。第二,确认 CPU 支持虚拟化,在任务管理器性能标签页里看“虚拟化”是否显示“已启用”。如果没启用,需要进 BIOS 打开 Intel VT-x 或 AMD-V。
确认无误后,以管理员身份打开 PowerShell,执行下面这条命令:
wsl --install这条命令会自动完成几件事:启用“适用于 Linux 的 Windows 子系统”可选功能、启用“虚拟机平台”功能、下载并安装 WSL2 内核更新包、把 WSL2 设为默认版本、安装 Ubuntu 发行版。执行完重启电脑即可。
如果你之前已经装过 WSL,想确认版本,可以运行:
wsl --list --verbose输出里 VERSION 列显示 2 就对了。如果显示 1,用wsl --set-version <发行版名> 2转换。
注意:有些机器上
wsl --install会因为组策略或系统精简原因失败,这时候需要手动在“启用或关闭 Windows 功能”里勾选“适用于 Linux 的 Windows 子系统”和“虚拟机平台”,重启后再执行安装命令。
2.2 Ubuntu 22.04 的安装与初始化
我选 Ubuntu 22.04 LTS 而不是 24.04,原因是 22.04 的 CUDA 和 PyTorch 生态兼容性经过大量验证,踩坑最少。安装命令:
wsl --install -d Ubuntu-22.04安装完成后会提示创建用户名和密码,这个用户名和密码是 Linux 系统内的,和 Windows 账户无关。创建完成后就进入了 Ubuntu 的终端。
第一件事是更新软件源:
sudo apt update && sudo apt upgrade -y然后装一些基础工具,后面编译和调试都会用到:
sudo apt install -y build-essential git curl wget vim python3-pip python3-venv这里有个经验:WSL2 默认的 apt 源在国内访问速度一般,可以换成国内镜像源。编辑/etc/apt/sources.list,把archive.ubuntu.com和security.ubuntu.com替换成清华或阿里的镜像地址,更新速度能从几十 KB 提升到几 MB。
2.3 Windows 显卡驱动的确认
这一步是 GPU 直通的关键。WSL2 里的 CUDA 不依赖 Linux 侧的 NVIDIA 驱动,而是直接调用 Windows 主机上的驱动。所以你要做的是:在 Windows 上安装最新版的 NVIDIA 显卡驱动,而不是在 WSL2 里装驱动。
去 NVIDIA 官网下载对应你显卡型号的 Game Ready 或 Studio 驱动,安装完成后在 Windows 命令行运行:
nvidia-smi能看到显卡信息和驱动版本就说明 Windows 侧没问题。记住这个驱动版本号,后面装 CUDA Toolkit 时要参考它支持的 CUDA 版本上限。
注意:千万不要在 WSL2 里执行
apt install nvidia-driver-xxx,这会把 Linux 侧的驱动装进去,和 Windows 驱动冲突,导致 GPU 无法调用。WSL2 里只需要装 CUDA Toolkit,不需要装驱动。
2.4 验证 GPU 是否已经直通进 WSL2
在 WSL2 终端里运行:
nvidia-smi如果输出和 Windows 侧一致,说明 GPU 直通已经生效。如果提示 command not found,说明 CUDA Toolkit 还没装,但驱动层面其实已经通了,装完 Toolkit 就能用。如果提示找不到设备,检查 Windows 驱动版本是否太旧,或者 WSL2 内核是否需要更新(运行wsl --update)。
这一步是整个方案的地基,地基没打好后面全是坑。我见过太多人卡在这里,反复在 WSL2 里装驱动,结果越装越乱。
3. CUDA 与 PyTorch 的安装:版本匹配是核心
3.1 CUDA Toolkit 的版本选择逻辑
CUDA 版本选择不是越新越好,而是要看三个东西的交叉点:Windows 驱动支持的最高 CUDA 版本、PyTorch 官方支持的 CUDA 版本、你的显卡算力是否被支持。
先看 Windows 驱动支持的最高版本,运行nvidia-smi,右上角会显示CUDA Version: 12.x,这是驱动能支持的上限。然后去 PyTorch 官网看当前稳定版支持的 CUDA 版本,通常有 11.8、12.1、12.4 几个选项。取两者的交集,再选一个较新的稳定版本。
以我目前的配置为例:驱动支持到 CUDA 12.4,PyTorch 2.4 支持 CUDA 12.1 和 12.4,我选 12.1,因为生态兼容性更好,很多第三方库对 12.1 的支持更成熟。
安装 CUDA Toolkit 推荐用 NVIDIA 官方仓库的方式,比 runfile 更干净:
wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-keyring_1.1-1_all.deb sudo dpkg -i cuda-keyring_1.1-1_all.deb sudo apt update sudo apt install -y cuda-toolkit-12-1注意这里用的是wsl-ubuntu仓库,不是普通的ubuntu2204仓库,这是专门为 WSL2 准备的,包依赖关系不一样。
3.2 环境变量的配置细节
装完之后需要配置环境变量,编辑~/.bashrc,在末尾加上:
export PATH=/usr/local/cuda-12.1/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda-12.1/lib64:$LD_LIBRARY_PATH然后source ~/.bashrc生效。验证:
nvcc --version能输出版本信息就说明 CUDA Toolkit 装好了。
注意:
LD_LIBRARY_PATH这一行很多人会漏掉,导致编译时找不到 CUDA 动态库。另外如果你装了多个 CUDA 版本,通过修改 PATH 里的路径来切换,不要用update-alternatives,在 WSL2 里那个方式容易出问题。
3.3 PyTorch 安装的三种方式对比
PyTorch 安装方式主要有三种:pip 直接装、conda 装、源码编译。我的建议是优先用 pip 配合虚拟环境,原因如下表:
| 安装方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| pip + venv | 轻量、版本可控、官方 wheel 直接下载 | 需要手动管理虚拟环境 | 绝大多数场景 |
| conda | 依赖管理强、科学计算包全 | 体积大、有时和系统 CUDA 冲突 | 需要大量科学计算库 |
| 源码编译 | 可定制、支持最新特性 | 耗时长、容易失败 | 需要特定优化或最新功能 |
我一般用 venv:
python3 -m venv ~/venvs/torch source ~/venvs/torch/bin/activate pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121这里的cu121对应 CUDA 12.1,必须和前面装的 CUDA Toolkit 版本一致,否则会出现版本不匹配的警告甚至运行错误。
3.4 验证 PyTorch 能否调用 GPU
装完后写个最简单的验证脚本:
import torch print("PyTorch version:", torch.__version__) print("CUDA available:", torch.cuda.is_available()) print("CUDA version:", torch.version.cuda) print("GPU count:", torch.cuda.device_count()) print("GPU name:", torch.cuda.get_device_name(0))如果CUDA available输出 True,说明整条链路打通了。如果输出 False,按下面顺序排查:先确认nvidia-smi在 WSL2 里能跑,再确认 PyTorch 版本和 CUDA 版本是否匹配,最后检查是不是装成了 CPU 版本的 PyTorch(用pip list | grep torch看版本号后面有没有+cu121后缀)。
4. 开发工作流的搭建与优化
4.1 VS Code Remote 连接 WSL2
这是我认为 WSL2 方案里体验最好的部分。在 Windows 上装好 VS Code,然后装一个叫 WSL 的官方扩展。装完后按 F1,输入WSL: Connect to WSL,VS Code 就会在 WSL2 里启动一个服务端,界面还是 Windows 的,但终端、文件系统、Python 解释器全部是 WSL2 里的。
这意味着你可以在 Windows 的 VS Code 里写代码,代码实际存在 Linux 文件系统里,运行时用的是 Linux 的 Python 和 CUDA。调试、断点、变量查看全部正常。而且因为文件在 Linux 侧,IO 性能比放在/mnt/c/下好很多。
注意:项目文件一定要放在 WSL2 的 Linux 文件系统里,比如
~/projects/,不要放在/mnt/c/Users/xxx/下。跨文件系统访问的 IO 性能差距在大量小文件读写时非常明显,训练时加载数据集能差出好几倍。
4.2 数据集与模型文件的存放策略
WSL2 的磁盘空间默认是动态扩展的,但上限受 Windows 磁盘剩余空间限制。数据集大的话,建议单独挂载一块 Windows 磁盘到 WSL2 里,或者用wsl --mount挂载物理磁盘。
我自己的做法是:代码和虚拟环境放在 WSL2 默认的 ext4 文件系统里,数据集放在 Windows 的 D 盘,通过/mnt/d/datasets/访问。虽然跨文件系统有性能损耗,但数据集通常是大文件顺序读取,损耗可以接受,而且方便在 Windows 侧用工具管理和备份。
如果数据集特别大且读取频繁,可以考虑在 WSL2 里单独挂一块虚拟磁盘(VHD),格式化成 ext4,性能接近原生。
4.3 终端与 Shell 的个性化配置
WSL2 默认的终端是 Windows Terminal,体验已经不错。我一般会做几件事:装 zsh 和 oh-my-zsh,配置一些常用别名,装 tmux 做会话管理。
常用别名示例:
alias gs='git status' alias ll='ls -alF' alias nv='nvidia-smi' alias act='source ~/venvs/torch/bin/activate'tmux 在跑长时间训练时特别有用,SSH 断开或者终端关闭后训练进程不会中断。配合nohup或者直接tmux new -s train开一个会话,训练跑起来后 detach,随时可以 reattach 查看进度。
4.4 性能调优的几个关键点
WSL2 默认会占用较多内存,可以在 Windows 用户目录下创建.wslconfig文件限制资源:
[wsl2] memory=32GB processors=16 swap=8GB这个配置根据你机器的实际内存调整,一般给 WSL2 分配总内存的一半到三分之二比较合适。内存给太少训练时容易 OOM,给太多 Windows 侧会卡。
GPU 方面,WSL2 的 CUDA 性能损耗在 5% 到 10% 左右,主要来自虚拟化层的通信开销。对于大多数训练任务来说可以接受。如果追求极致性能,可以考虑用--gpu-support相关的优化参数,但实际提升有限。
磁盘 IO 是 WSL2 相对薄弱的环节,尤其是跨文件系统访问。如果训练时数据加载是瓶颈,可以考虑把数据集预处理成单个大文件(比如 LMDB 或 HDF5 格式),减少小文件随机读取。
5. 常见问题与排查实录
5.1 GPU 相关问题的排查思路
问题一:nvidia-smi在 WSL2 里提示找不到命令
这通常是因为 CUDA Toolkit 没装或者 PATH 没配好。先确认 Windows 侧nvidia-smi能跑,然后在 WSL2 里检查/usr/local/cuda-12.1/bin是否在 PATH 里。如果 CUDA 装了但命令找不到,多半是.bashrc没 source 或者路径写错了。
问题二:PyTorch 显示 CUDA available 为 False
按这个顺序排查:第一,nvidia-smi在 WSL2 里能不能跑;第二,PyTorch 版本是不是 CPU 版;第三,CUDA Toolkit 版本和 PyTorch 编译版本是否匹配;第四,Windows 驱动版本是否太旧。我遇到过最常见的原因是装成了 CPU 版 PyTorch,用pip list一看版本号没有+cu后缀就知道了。
问题三:训练时报 CUDA out of memory
WSL2 里 GPU 显存是直接透传的,和 Windows 侧共享。如果 Windows 侧有程序占着显存(比如浏览器硬件加速、游戏),WSL2 里能用的显存就会减少。训练前关掉不必要的 GPU 占用程序。另外.wslconfig里可以设置gpuMemoryLimit但一般不需要。
5.2 网络与下载速度问题
WSL2 的网络是 NAT 模式,默认走 Windows 主机的网络。pip 和 apt 下载慢的话,换国内源是最直接的方案。pip 换源:
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simpleapt 换源前面提过,编辑 sources.list 替换域名即可。
如果遇到 WSL2 里 DNS 解析异常,可以检查/etc/resolv.conf,有时候需要手动指定 DNS 服务器。不过较新版本的 WSL2 已经自动处理了这个问题,一般不用管。
5.3 文件系统与权限问题
WSL2 里访问 Windows 文件时,权限显示为 777,这是正常的,因为 NTFS 和 ext4 的权限模型不同。如果某些程序对权限敏感,可以把文件复制到 Linux 文件系统里再操作。
另一个常见问题是 Git 在跨文件系统时的换行符处理。建议在 WSL2 里配置:
git config --global core.autocrlf input这样提交时统一转成 LF,避免 Windows 和 Linux 协作时的换行符混乱。
5.4 常见问题速查表
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| nvidia-smi 找不到 | CUDA Toolkit 未装或 PATH 未配 | 装 CUDA Toolkit,检查 .bashrc |
| CUDA available False | PyTorch 是 CPU 版 | 重装 GPU 版 PyTorch |
| 训练 OOM | Windows 侧占用显存 | 关闭占用 GPU 的程序 |
| pip 下载慢 | 默认源在国外 | 换清华或阿里源 |
| 文件读写慢 | 跨文件系统访问 | 项目文件放 Linux 侧 |
| WSL2 启动失败 | 虚拟化未启用或内核旧 | 检查 BIOS,运行 wsl --update |
| 内存占用过高 | 默认无限制 | 配置 .wslconfig 限制 |
6. 我踩过的几个坑和最终建议
6.1 驱动和 Toolkit 的版本陷阱
我最早犯的错是在 WSL2 里装 NVIDIA 驱动,结果和 Windows 驱动冲突,GPU 完全用不了。后来才明白 WSL2 的 GPU 直通是 Windows 驱动负责硬件层,Linux 侧只需要 CUDA Toolkit 提供编译和运行时库。这个分工一定要搞清楚。
另一个坑是 CUDA 版本和 PyTorch 版本不匹配。有次我装了 CUDA 12.4,但 PyTorch 当时只支持到 12.1,结果torch.cuda.is_available()一直是 False。后来降级 CUDA 到 12.1 就正常了。所以版本匹配这件事,宁可花十分钟查清楚,也不要凭感觉装。
6.2 磁盘空间和性能的平衡
WSL2 的虚拟磁盘文件(ext4.vhdx)会随着使用不断增长,但不会自动收缩。删了大文件后,vhdx 文件在 Windows 侧看还是那么大。可以用wsl --manage <发行版> --set-sparse true开启稀疏模式,或者手动用 diskpart 压缩。不过压缩有风险,操作前备份重要数据。
性能方面,我的经验是:代码和虚拟环境放 Linux 侧,数据集放 Windows 侧用/mnt/访问,模型 checkpoint 存 Linux 侧。这样兼顾了 IO 性能和磁盘空间管理。
6.3 日常使用的几个小技巧
第一,用 Windows Terminal 的标签页功能,一个标签跑训练,一个标签写代码,一个标签看日志,切换很方便。
第二,VS Code 的 Remote WSL 模式下,Python 解释器要选 WSL2 里的 venv 路径,不要选 Windows 的 Python。
第三,训练脚本用tmux或者nohup跑,避免终端关闭导致训练中断。
第四,定期用wsl --shutdown完全关闭 WSL2 再重启,可以释放一些缓存和僵尸进程,尤其是长时间运行后。
第五,如果要用 Docker,WSL2 里装 Docker Engine 比用 Docker Desktop 更轻量,性能也更好。装完后配置 GPU 支持,容器里也能直接用 CUDA。
这套环境我从去年用到现在,跑了十几个训练项目,稳定性很好。唯一需要注意的是 Windows 更新后偶尔会重置 WSL2 的网络配置,遇到网络问题时先wsl --shutdown重启一下,大部分情况都能解决。