首页 / 资讯中心 / 文章详情

Windows 上用 WSL2 搭建 CUDA 与 PyTorch 深度学习环境实战

Windows 上用 WSL2 搭建 CUDA 与 PyTorch 深度学习环境实战 ★ FEATURED ARTICLE
1. 为什么要在 Windows 上折腾 WSL2 跑 AI 开发环境如果你是一个长期在 Windows 上做深度学习的人大概率经历过这样的场景想跑一个 PyTorch 训练脚本结果发现某个依赖库在 Windows 上编译不过想用某个只在 Linux 上维护的工具链又不想重启切换到双系统好不容易配好了 CUDA结果发现 Windows 版的显存管理策略和 Linux 下差别不小多卡训练时总有些莫名其妙的问题。我自己就是从这套痛苦里走出来的前后在纯 Windows、双系统、远程 Linux 服务器之间反复横跳了好几年最后稳定下来的方案就是 WSL2。WSL2 全称是 Windows Subsystem for Linux 2它不是虚拟机也不是简单的兼容层而是微软在 Windows 内核里内置的一个轻量级虚拟化方案跑的是真正的 Linux 内核。这意味着你在里面装 CUDA、装 PyTorch、跑训练脚本和在原生 Ubuntu 上几乎没有区别。更关键的是它支持 GPU 直通也就是你 Windows 主机上的 NVIDIA 显卡可以直接被 WSL2 里的 Linux 环境调用不需要额外配置显卡虚拟化。这套方案解决的核心问题是让你在保留 Windows 日常使用习惯的同时获得一个几乎原生的 Linux AI 开发环境。适合谁呢适合那些主力机器是 Windows、显卡是 NVIDIA、需要频繁使用 PyTorch 或 CUDA 做训练和推理的开发者。如果你用的是 AMD 显卡情况会复杂一些后面我会专门说。如果你只是偶尔跑跑小模型那其实 Windows 原生环境也够用不一定非要上 WSL2。我写这篇东西的出发点很简单网上关于 WSL2 装 CUDA 的教程很多但大部分要么版本过时要么跳过了关键的坑要么只告诉你敲什么命令却不解释为什么。我把自己从零开始配环境、踩坑、重装、再踩坑的完整过程整理出来包括每一步背后的逻辑和那些文档里不会写的细节。2. 环境准备与方案选型为什么这么配2.1 硬件与系统的前置条件在动手之前先确认你的机器满足以下条件。这不是废话我见过太多人折腾半天最后发现硬件不支持。项目最低要求推荐配置说明Windows 版本Win10 2004Win11 22H2Win11 对 WSL2 的支持更完善GPU 直通更稳定显卡NVIDIA GTX 10 系RTX 30/40 系需要支持 CUDAAMD 和 Intel 核显情况不同显存6GB12GB训练大模型显存是硬瓶颈内存16GB32GBWSL2 默认会占用一半内存磁盘50GB 空闲NVMe SSD 100GBWSL2 的虚拟磁盘 IO 对性能影响很大Windows 版本这块我要多说一句。Win10 2004 是 WSL2 正式可用的起点但如果你还在用更早的版本GPU 直通基本没戏。Win11 在这方面做了大量优化尤其是 22H2 之后WSL2 的 GPU 调用效率明显提升。我实测下来同样的训练脚本Win11 下的 WSL2 比 Win10 下的 WSL2 快大概 5% 到 10%虽然不多但白给的性能没理由不要。显卡方面NVIDIA 是唯一省心的选择。WSL2 的 GPU 直通依赖 NVIDIA 提供的 Windows 驱动和 WSL 专用驱动AMD 和 Intel 虽然也有对应的方案但成熟度差不少。如果你手里是 AMD 显卡后面我会单独讲怎么处理。2.2 为什么选 WSL2 而不是虚拟机或双系统这个问题我被问过无数次这里一次性说清楚。虚拟机的方案比如 VMware 或 VirtualBox最大的问题是 GPU 直通极其麻烦而且性能损耗大。你需要在宿主机和虚拟机之间来回切换文件共享也不方便。更致命的是很多虚拟机的 GPU 直通方案对 CUDA 的支持并不完整跑推理还行训练基本没法用。双系统的方案性能最好但切换成本太高。你正在 Windows 上查资料突然想跑个脚本重启切换到 Linux跑完再切回来一天下来光重启就浪费不少时间。而且双系统下的文件共享也是个麻烦事NTFS 和 ext4 之间的读写权限问题能把你逼疯。WSL2 的优势在于它把两者的优点结合了。它跑的是真正的 Linux 内核性能接近原生同时它和 Windows 的文件系统可以互相访问你在 Windows 下用 VSCode 直接编辑 WSL2 里的代码无缝衔接。GPU 直通方面NVIDIA 官方提供了专门的驱动装好之后 CUDA 调用和原生 Linux 几乎没区别。我自己的使用场景是这样的日常在 Windows 下用浏览器查文档、用 VSCode 写代码需要跑训练的时候直接在 WSL2 的终端里执行训练日志和结果文件通过共享目录直接在 Windows 下查看。整个流程不需要切换系统也不需要额外的文件传输工具。2.3 WSL2 的安装与磁盘位置调整安装 WSL2 本身很简单但有一个细节很多人忽略了默认安装位置在 C 盘。如果你的 C 盘空间紧张或者你想把 WSL2 的虚拟磁盘放到更快的 SSD 上就需要在安装前或者安装后做迁移。安装命令如下以管理员身份打开 PowerShellwsl --install这条命令会默认安装 Ubuntu 发行版。如果你想指定发行版可以先查看可用列表wsl --list --online然后安装指定版本比如 Ubuntu 22.04wsl --install -d Ubuntu-22.04安装完成后需要重启一次。重启后系统会提示你设置 Linux 用户名和密码这个密码在后面执行 sudo 命令时会用到记牢。关于磁盘位置我强烈建议在安装完发行版之后立刻迁移。WSL2 的虚拟磁盘文件默认在C:\Users\你的用户名\AppData\Local\Packages\下面随着你装 CUDA、PyTorch、各种数据集这个文件会迅速膨胀到几十 GB。迁移方法如下# 先关闭 WSL wsl --shutdown # 导出当前发行版到指定位置 wsl --export Ubuntu-22.04 D:\wsl\ubuntu2204.tar # 注销原来的发行版 wsl --unregister Ubuntu-22.04 # 从备份文件导入到新位置 wsl --import Ubuntu-22.04 D:\wsl\ubuntu2204 D:\wsl\ubuntu2204.tar --version 2导入之后需要重新设置默认用户否则每次进去都是 root。编辑/etc/wsl.conf文件[user] default你的用户名这个迁移操作我做过三次每次都是因为 C 盘爆了。实测下来把 WSL2 放到 NVMe SSD 上数据加载速度比放在机械硬盘上快好几倍训练时的 IO 瓶颈明显缓解。3. GPU 直通与 CUDA 环境配置的核心细节3.1 NVIDIA 驱动的正确安装方式这是整个配置过程中最容易出错的地方我单独拎出来讲。很多人以为要在 WSL2 里装 NVIDIA 驱动其实不对。WSL2 的 GPU 直通依赖的是 Windows 主机上的驱动你只需要在 Windows 下安装支持 WSL 的 NVIDIA 驱动WSL2 里不需要再装一遍驱动。具体操作去 NVIDIA 官网下载最新的 Windows 驱动安装时选择“自定义安装”确保勾选“WSL 驱动组件”。如果你之前已经装过驱动建议用 DDU 工具彻底卸载后重装避免旧版本残留导致冲突。装好之后在 WSL2 的终端里执行nvidia-smi如果能看到显卡信息说明 GPU 直通已经生效。如果提示命令找不到说明驱动没装好或者 WSL2 没有正确识别。这里有个坑我要重点提醒不要在 WSL2 里用apt install nvidia-driver-xxx这种方式装驱动。我试过一次结果把 WSL2 的 GPU 直通搞崩了最后只能重装发行版。WSL2 里的 CUDA 工具包和 Windows 驱动是两回事驱动归 Windows 管CUDA 工具包归 Linux 管。3.2 CUDA Toolkit 的版本选择与安装CUDA 版本的选择取决于你要用的 PyTorch 版本。截至我写这篇东西的时候PyTorch 2.x 稳定支持的 CUDA 版本主要是 11.8 和 12.1。我建议选 12.1因为新卡对新版 CUDA 的支持更好而且 12.x 在 WSL2 下的兼容性经过几轮迭代已经相当稳定。安装 CUDA Toolkit 有两种方式用 NVIDIA 官方的 apt 源或者用 runfile。我推荐 apt 源因为管理方便卸载也干净。# 下载并安装 CUDA 密钥 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-get update # 安装 CUDA Toolkit 12.1 sudo apt-get install -y cuda-toolkit-12-1安装完成后配置环境变量编辑~/.bashrcexport 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 装好了。这里有个细节WSL2 的 CUDA 安装包和原生 Linux 的不一样必须用wsl-ubuntu这个源用普通的ubuntu源会装不上或者装完不能用。我第一次就是没注意这个折腾了半天才发现下错了包。3.3 cuDNN 的配置cuDNN 是 NVIDIA 的深度学习加速库PyTorch 底层会调用它。从 CUDA 11.x 开始cuDNN 可以通过 apt 直接安装sudo apt-get install -y cudnn装完之后验证一下cat /usr/include/cudnn_version.h | grep CUDNN_MAJOR -A 2能看到版本号就说明装好了。cuDNN 的版本要和 CUDA 版本匹配apt 源会自动处理依赖关系比手动下载 tar 包再拷贝文件省事得多。3.4 环境变量配置的常见误区环境变量这块我见过太多人配错。最常见的错误是把 Windows 的 CUDA 路径和 WSL2 的 CUDA 路径搞混。记住一个原则WSL2 里的环境变量只指向 WSL2 内部的路径不要引用/mnt/c/下面的任何东西。另一个误区是LD_LIBRARY_PATH的顺序。如果你同时装了多个 CUDA 版本LD_LIBRARY_PATH里排在前面的会优先生效。我建议只保留一个版本避免混乱。还有一个容易被忽略的点WSL2 默认不会继承 Windows 的环境变量但如果你在 Windows 下设置了CUDA_PATH之类的变量可能会通过某种方式影响到 WSL2。我的做法是在 WSL2 的~/.bashrc里显式设置所有 CUDA 相关的变量不依赖任何继承。4. PyTorch 环境搭建与 GPU 验证的完整实操4.1 Python 环境的选择conda 还是 venv这个问题没有标准答案但我可以给你我的选择逻辑。conda 的优势是管理非 Python 依赖方便比如某些需要编译的库conda 可以直接装预编译版本。缺点是体积大有时候会和你系统的库冲突。venv 的优势是轻量、干净和系统 Python 隔离得好缺点是装某些科学计算库时需要自己编译。我的做法是用 conda 创建基础环境但在环境内部用 pip 装 PyTorch。这样兼顾了两者的优点。具体命令# 安装 miniconda wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh # 创建环境 conda create -n pytorch python3.10 conda activate pytorchPython 版本选 3.10 是因为它在兼容性和新特性之间平衡得最好。3.11 和 3.12 虽然更新但某些库的支持还没跟上我遇到过几次装不上的情况。4.2 PyTorch 的安装与 CUDA 版本匹配PyTorch 官网提供了安装命令生成器你只需要选好版本和 CUDA 版本它会给你对应的 pip 命令。以 CUDA 12.1 为例pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121这里的关键是--index-url参数它指定了 PyTorch 的 CUDA 12.1 专用源。如果你不加这个参数pip 会从默认源装 CPU 版本装完发现 GPU 用不了又得重来。安装完成后验证import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))如果torch.cuda.is_available()返回True并且能打印出显卡型号说明整个链路通了。我实测下来PyTorch 2.1 CUDA 12.1 在 WSL2 下的稳定性最好。PyTorch 2.2 刚出的时候我试过有几个算子在小显存卡上会报错后来回退了。所以如果你不是非要追新建议选一个经过社区验证的稳定组合。4.3 GPU 直通验证与性能测试装好之后别急着跑训练先做个简单的性能测试确认 GPU 直通的效率。import torch import time # 创建一个较大的矩阵 a torch.randn(10000, 10000).cuda() b torch.randn(10000, 10000).cuda() # 预热 for _ in range(5): c torch.matmul(a, b) # 计时 torch.cuda.synchronize() start time.time() for _ in range(20): c torch.matmul(a, b) torch.cuda.synchronize() end time.time() print(f平均耗时: {(end - start) / 20 * 1000:.2f} ms)这个测试能跑通说明 GPU 直通没问题。如果报错说找不到 CUDA 设备回去检查驱动和 CUDA 安装。性能方面我在 RTX 4090 上实测WSL2 下的矩阵乘法性能大约是原生 Linux 的 95% 到 98%差距主要来自虚拟化层的开销。对于大多数训练任务来说这个损耗完全可以接受。4.4 数据盘挂载与文件系统性能优化WSL2 访问 Windows 文件系统是通过/mnt/c/这样的路径但这种方式有个性能问题跨文件系统的 IO 比 WSL2 内部的文件系统慢很多。我实测过从/mnt/d/读取数据集比从 WSL2 内部路径读取慢 3 到 5 倍。解决方案是把数据集放在 WSL2 内部或者用 WSL2 的虚拟磁盘挂载一个专门的数据分区。我的做法是在 WSL2 里创建一个数据目录然后用 rsync 从 Windows 同步数据过去mkdir -p ~/data rsync -avh --progress /mnt/d/datasets/ ~/data/如果数据集太大同步一次要很久可以考虑用符号链接的方式但性能会打折扣。我的建议是常用的、需要频繁读取的数据集放在 WSL2 内部归档的、偶尔用一次的数据放在 Windows 下通过/mnt/访问。5. 常见问题排查与避坑经验实录5.1 WSL2 启动失败与网络问题“WSL2 尚未准备就绪”这个报错我遇到过好几次原因各不相同。最常见的是 Windows 的虚拟机平台功能没开启。解决方法# 以管理员身份运行 dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart然后重启电脑。如果还是不行检查 BIOS 里的虚拟化选项是否开启Intel 平台叫 VT-xAMD 平台叫 SVM。网络问题方面WSL2 默认使用 NAT 模式有时候会出现 DNS 解析失败的情况。解决方法是在/etc/wsl.conf里配置[network] generateResolvConf false然后手动设置/etc/resolv.confnameserver 8.8.8.8 nameserver 114.114.114.114这个问题的典型表现是apt update卡住或者报错但pingIP 地址是通的。5.2 CUDA 版本冲突与 conda 环境隔离如果你在多个 conda 环境里装了不同版本的 PyTorch可能会遇到 CUDA 版本冲突。典型报错是undefined symbol或者CUDA error: no kernel image is available。根本原因是不同环境里的 PyTorch 链接了不同版本的 CUDA 库而LD_LIBRARY_PATH是全局的切换环境时不会自动切换。解决方案有两个一是每个环境装对应版本的 CUDA Toolkit用 conda 管理二是用conda activate时自动设置环境变量。我推荐第二种在~/.bashrc里加一段conda_env_cuda() { if [ -n $CONDA_PREFIX ] [ -d $CONDA_PREFIX/cuda ]; then export CUDA_HOME$CONDA_PREFIX/cuda export LD_LIBRARY_PATH$CONDA_PREFIX/cuda/lib64:$LD_LIBRARY_PATH fi }这样每个环境可以有自己的 CUDA 版本互不干扰。5.3 显存不足与 system 进程占用 GPU 的排查“system 进程占用 GPU 高”这个问题在 WSL2 下比较常见尤其是你同时开了 Windows 的图形界面和 WSL2 的训练任务时。Windows 的桌面窗口管理器会占用一部分显存导致 WSL2 里可用的显存比标称值少。排查方法在 Windows 下打开任务管理器切换到性能标签页看 GPU 的专用显存占用。如果 system 进程占了几百 MB 甚至上 GB那是正常的Windows 桌面本身就要用显存。应对策略训练时关掉不必要的图形应用尤其是浏览器。Chrome 开几十个标签页能吃掉 1 到 2GB 显存。如果还是不够考虑用torch.cuda.empty_cache()手动清理缓存或者减小 batch size。5.4 常见问题速查表问题现象可能原因解决方法nvidia-smi 找不到命令Windows 驱动未装 WSL 组件重装 NVIDIA 驱动勾选 WSL 组件torch.cuda.is_available() 返回 FalsePyTorch 装成了 CPU 版用 --index-url 重新安装 CUDA 版CUDA error: out of memory显存不足或被 Windows 占用减小 batch size关闭图形应用apt update 卡住DNS 解析问题手动配置 resolv.confWSL2 启动报错虚拟机平台未开启启用 VirtualMachinePlatform 功能训练速度异常慢数据在 /mnt/ 下读取把数据移到 WSL2 内部conda 命令找不到未初始化 shell执行 conda init bash 并重开终端5.5 几个我踩过的坑和对应的经验第一个坑在 WSL2 里用sudo apt upgrade升级了内核相关的包结果 GPU 直通失效。原因是 WSL2 的内核是微软定制的不能随便升级。后来我学乖了只升级用户态的包内核相关的包一律不动。第二个坑把数据集放在/mnt/d/下直接训练结果 IO 成了瓶颈GPU 利用率只有 30% 左右。把数据移到 WSL2 内部后GPU 利用率直接拉到 90% 以上。这个教训让我明白WSL2 的跨文件系统 IO 开销比我想象的大得多。第三个坑同时开了多个 conda 环境每个环境装了不同版本的 CUDA结果环境变量互相污染。后来我养成了习惯每个项目单独一个环境环境内显式设置 CUDA 路径不依赖全局配置。第四个坑用wsl --shutdown关闭 WSL2 后发现虚拟磁盘文件没有自动收缩占用的空间越来越大。解决方法是用diskpart工具手动压缩虚拟磁盘或者定期导出再导入。6. 进阶配置与性能调优6.1 WSL2 内存与 CPU 资源限制WSL2 默认会占用宿主机的很大一部分资源尤其是内存。如果你在 Windows 下还要跑其他应用可能会觉得卡顿。解决方法是在用户目录下创建.wslconfig文件[wsl2] memory16GB processors8 swap8GB localhostForwardingtrue这个配置的意思是WSL2 最多用 16GB 内存、8 个 CPU 核心、8GB 交换空间。根据你的机器配置调整一般建议内存不超过宿主机的一半CPU 核心数不超过总核心数的 70%。改完之后执行wsl --shutdown重启生效。我实测下来限制资源后 Windows 主机的响应速度明显改善而 WSL2 里的训练速度几乎没有下降因为大多数训练任务的瓶颈在 GPU 而不是 CPU 和内存。6.2 多卡训练与分布式配置如果你有多张显卡WSL2 也支持多卡训练。验证方法import torch print(torch.cuda.device_count())如果输出大于 1说明多卡识别正常。然后用torchrun或者DistributedDataParallel启动分布式训练torchrun --nproc_per_node2 train.py这里要注意的是WSL2 下的多卡通信走的是 PCIe 总线和原生 Linux 一样。但如果你用的是 NVLink 桥接的卡WSL2 目前还不支持 NVLink只能走 PCIe。对于大多数消费级显卡来说PCIe 的带宽足够影响不大。6.3 与 Windows 端工具链的协同WSL2 的一个巨大优势是和 Windows 工具链的无缝协同。我常用的几个场景用 VSCode 的 Remote-WSL 插件直接在 WSL2 里开发代码存在 WSL2 的文件系统里但编辑体验和 Windows 下完全一样。调试的时候可以直接在 VSCode 里打断点变量查看、调用栈都和本地开发一样。用 Windows 下的 TensorBoard 查看训练日志。WSL2 里启动 TensorBoard 后在 Windows 的浏览器里访问localhost:6006就能看到。这是因为 WSL2 和 Windows 共享 localhost不需要额外配置端口转发。用 Windows 下的 Git 客户端管理 WSL2 里的代码仓库。虽然 Git 在 WSL2 里也能用但 Windows 下的图形化 Git 工具比如 Fork 或 SourceTree体验更好。通过/mnt/路径可以直接操作 WSL2 里的文件不过要注意换行符的问题建议在 Git 配置里设置core.autocrlfinput。6.4 备份与迁移策略WSL2 环境配好之后建议做一次完整备份。方法就是前面提到的导出命令wsl --export Ubuntu-22.04 D:\backup\ubuntu2204_backup.tar这个 tar 文件包含了整个 Linux 环境包括你装的所有软件和配置。下次换机器或者环境搞崩了直接导入就能恢复。我自己的做法是环境配好之后导出一次作为基线备份之后每次装完重要的库或者改完关键配置再导出一次。备份文件放在移动硬盘上这样换机器的时候直接导入省去重新配置的时间。导入到新机器的命令wsl --import Ubuntu-22.04 D:\wsl\ubuntu2204 D:\backup\ubuntu2204_backup.tar --version 2导入后记得重新设置默认用户方法和前面迁移磁盘位置时一样。6.5 AMD 显卡用户的替代方案如果你用的是 AMD 显卡WSL2 的 GPU 直通支持要差一些。AMD 官方提供了 ROCm 的 WSL 驱动但支持的显卡型号有限主要是 RX 6000 系和部分 7000 系。安装方法和 NVIDIA 类似先在 Windows 下装 AMD 的 WSL 驱动然后在 WSL2 里装 ROCm。不过我要说实话AMD 在 WSL2 下的深度学习生态远不如 NVIDIA 成熟。PyTorch 对 ROCm 的支持虽然在进步但很多库和算子还是有问题。如果你主要做深度学习NVIDIA 显卡是更省心的选择。如果只是跑一些推理任务AMD 的方案也能用但要做好折腾的心理准备。7. 我个人的一些使用体会这套 WSL2 环境我用了快两年中间重装过三次每次都是因为自己手贱升级了不该升级的东西。现在稳定下来的配置是 Win11 WSL2 Ubuntu 22.04 CUDA 12.1 PyTorch 2.1日常训练和推理都没出过问题。最大的体会是WSL2 的 GPU 直通已经足够成熟对于大多数个人开发者和小团队来说它完全能替代原生 Linux 工作站。你不需要为了跑深度学习专门装一台 Linux 机器也不需要忍受双系统切换的麻烦。一台 Windows 机器装好 WSL2就能同时满足日常使用和 AI 开发的需求。另一个体会是环境配置这件事稳定比新更重要。我见过太多人追新版本结果踩了一堆坑浪费大量时间在排查问题上。选一个社区验证过的稳定组合把精力放在真正的开发工作上这才是正道。最后分享一个小技巧如果你在 WSL2 里跑训练时发现 GPU 利用率上不去先检查数据加载是不是瓶颈。用nvidia-smi -l 1实时监控 GPU 利用率如果一直在 0% 和 100% 之间跳动说明数据供给跟不上。这时候要么把数据移到 WSL2 内部要么增加 DataLoader 的num_workers要么用更快的存储。这个问题的排查思路和原生 Linux 下是一样的但 WSL2 的跨文件系统 IO 更容易成为瓶颈所以更要注意。
阅读完成 · 觉得有帮助?
咨询建站