资讯动态

Windows 上跑 PyTorch:WSL2 + GPU 直通实战

发布时间:2026/10/27 6:44:50 来源:尧图企业网站定制
1. 为什么要在 Windows 上折腾 WSL2 而不是装双系统很多人第一次接触深度学习开发时都会面临一个经典的选择题到底是在 Windows 上直接跑 PyTorch还是装个 Ubuntu 双系统或者干脆买台 Linux 服务器。我前后试过这三种方案最后稳定下来的工作流是 WSL2 GPU 直通。这个选择不是拍脑袋决定的而是踩了不少坑之后才收敛到的方案。先说 Windows 原生跑 PyTorch 的问题。早期版本确实能跑CUDA 也支持但一旦涉及到一些依赖 Linux 特有系统调用的库比如某些数据加载的num_workers多进程实现、fork语义、文件锁机制就会莫名其妙地卡死或者报错。更别提很多开源项目在 README 里默认你用的是 Linux安装脚本全是apt-get和bash在 Windows 上要么改脚本要么用 conda 硬凑体验非常割裂。双系统的问题在于切换成本太高。你正在 Windows 上查文档、写笔记想跑个训练还得重启进 Ubuntu跑完再重启回来一天下来光重启就浪费半小时。而且双系统下两个环境的文件互访很麻烦NTFS 分区在 Linux 下挂载虽然能读写但权限和换行符问题一堆。WSL2 恰好卡在中间它是一个真正的 Linux 内核微软自己编译的跑在轻量级虚拟机里但和 Windows 的集成度极高。你可以在 Windows Terminal 里开一个 Ubuntu 标签页同时另一个标签页跑 PowerShell文件系统互相挂载剪贴板互通甚至可以用 VS Code 的 Remote-WSL 插件直接在 Windows 界面里编辑 Linux 里的代码。最关键的是从 WSL2 开始微软支持了 GPU 直通GPU Paravirtualization也就是把宿主机的 NVIDIA 显卡直接透传给 WSL2 里的 Linux 用CUDA 和 cuDNN 都能正常工作。这里要澄清一个常见误解WSL2 的 GPU 直通不是模拟也不是软件渲染而是基于 GPU-PVGPU Paravirtualization技术把物理 GPU 的计算能力直接暴露给虚拟机。所以你跑nvidia-smi看到的显存、温度、功耗都是真实的训练速度和原生 Linux 几乎没差别。我实测过 ResNet-50 在 CIFAR-100 上的训练WSL2 和原生 Ubuntu 22.04 的每 epoch 耗时差距在 3% 以内完全在可接受范围。那这个方案适合谁呢如果你主力工作机是 Windows又需要 Linux 环境做 AI 开发且显卡是 NVIDIA 的AMD 显卡在 WSL2 下的 ROCm 支持目前还很有限那 WSL2 就是最优解。如果你用的是 macOS那这套方案不适用因为 WSL2 是 Windows 独有的。另外如果你的项目需要特定的 Linux 内核模块或者硬件直通比如某些 FPGA 加速卡WSL2 可能满足不了那种情况还是老老实实装原生 Linux。2. 装之前必须搞清楚的几个硬性前提在动手之前有几个前提条件必须先确认否则装到一半发现不满足返工成本很高。我把这些前提整理成了一张表你可以逐项核对。检查项要求不满足的后果Windows 版本Win10 21H2 及以上或 Win11 全版本不支持 WSL2 GPU 直通显卡NVIDIA GTX 10 系及以上无法使用 CUDA显卡驱动Windows 端驱动版本 ≥ 470.76WSL2 内识别不到 GPU虚拟化BIOS 中开启 VT-x / AMD-VWSL2 无法启动磁盘空间至少 40GB 可用镜像和依赖装不下内存建议 16GB 以上训练时容易 OOM先说 Windows 版本。WSL2 的 GPU 直通是 2021 年才正式落地的功能需要 Windows 10 版本 21H2内部版本 19044及以上或者 Windows 11。如果你还在用 Win10 20H2 甚至更早要么升级系统要么放弃 GPU 直通。检查方法很简单按Win R输入winver看弹出的版本号。显卡这块必须是 NVIDIA 的。AMD 显卡在 WSL2 下虽然微软和 AMD 都在推进但 ROCm 的支持远不如 CUDA 成熟很多 PyTorch 的预编译包也不覆盖。Intel 核显就更不用想了只能做显示输出不能做计算。所以如果你手里是 AMD 卡这篇文章的方案只能参考前半部分GPU 部分需要另找方案。驱动是最容易出问题的一环。很多人以为要在 WSL2 里装 NVIDIA 驱动其实恰恰相反——WSL2 里的驱动是 Windows 驱动透传进来的你只需要在 Windows 端装好最新的 Game Ready 或 Studio 驱动WSL2 里不要再装一遍 Linux 驱动否则会冲突。这一点后面还会详细说。虚拟化这块现在大部分主板默认是开的但有些品牌机出厂会关掉。开机进 BIOS找Intel Virtualization Technology或SVM Mode设为 Enabled。如果不开WSL2 启动时会报WSL2 尚未准备就绪之类的错误。磁盘空间和内存是软性要求但很影响体验。WSL2 的 ext4 虚拟磁盘默认放在 C 盘随着你装 conda 环境、下载数据集、存模型权重很容易膨胀到几十 GB。建议至少留 40GB如果要做大模型微调100GB 起步。内存方面WSL2 默认最多用宿主机一半的内存16GB 机器分 8GB 给 WSL2跑小模型够用跑大点的就紧张了。后面会讲怎么通过.wslconfig调整。提示如果你用的是笔记本且是双显卡核显 独显WSL2 会优先使用独显做计算核显负责显示输出这个分工是自动的不用手动配。3. 从零开始WSL2 安装与 Ubuntu 22.04 落地确认前提都满足后就可以开始装了。整个过程分两大步先在 Windows 端装好 WSL2 和 Ubuntu 发行版再进 Ubuntu 里配 CUDA 和 PyTorch。3.1 一条命令搞定 WSL2 启用以前装 WSL 要手动开好几个 Windows 功能现在 Win10 21H2 和 Win11 简化成了一条命令。以管理员身份打开 PowerShell执行wsl --install这条命令会自动做几件事启用Virtual Machine Platform和Windows Subsystem for Linux两个功能下载并安装 WSL2 内核更新包把默认版本设为 WSL2然后安装 Ubuntu 发行版。执行完重启电脑。如果你已经装过 WSL 但版本是 1可以用wsl --set-default-version 2切换默认版本。想确认当前版本跑wsl -l -v输出里 VERSION 列是 2 就对了。有时候wsl --install会因为网络原因卡在下载环节尤其是国内网络。这时候可以手动下载 Ubuntu 22.04 的 appx 包或者用wsl --install -d Ubuntu-22.04指定发行版。如果还是慢可以考虑先跳过自动安装用wsl --install --no-distribution只装 WSL2 内核然后自己去 Microsoft Store 装 Ubuntu。3.2 把镜像挪到 D 盘别让 C 盘爆掉默认情况下WSL2 的虚拟磁盘文件ext4.vhdx放在C:\Users\你的用户名\AppData\Local\Packages\下面。这个路径又深又占 C 盘空间强烈建议装完就迁走。迁移步骤分三步。先关闭 WSLwsl --shutdown然后导出当前发行版到一个 tar 文件wsl --export Ubuntu-22.04 D:\wsl\ubuntu22.tar导出完成后注销原来的发行版wsl --unregister Ubuntu-22.04最后从 tar 文件导入到新位置wsl --import Ubuntu-22.04 D:\wsl\ubuntu22 D:\wsl\ubuntu22.tar --version 2导入完成后用wsl -d Ubuntu-22.04进去你会发现原来的用户变成了 root。这是因为 import 之后默认用户重置了。解决办法是修改/etc/wsl.conf加上[user] default你的用户名如果忘了原来的用户名可以在/home目录下看看有哪些文件夹。改完wsl.conf后在 PowerShell 里wsl --shutdown再重进用户就恢复了。注意迁移过程中如果 tar 文件很大几十 GB导出和导入都会花不少时间建议在空闲时操作。另外迁移后原来的 C 盘空间不会自动释放需要手动删掉旧的 Packages 目录下的文件夹。3.3 首次进入 Ubuntu 的初始化配置第一次进 Ubuntu 会让你设用户名和密码这个密码是 sudo 密码记牢。进去之后先更新软件源sudo apt update sudo apt upgrade -y然后装一些基础工具这些后面配环境都会用到sudo apt install -y build-essential git curl wget vim htop tmuxbuild-essential提供 gcc、g、make很多 Python 包的源码编译依赖它。git不用多说curl和wget用来下载东西htop看系统资源tmux让你在 SSH 断开后训练任务还能继续跑。如果你觉得 Ubuntu 默认的软件源慢可以换成国内镜像。编辑/etc/apt/sources.list把archive.ubuntu.com和security.ubuntu.com替换成mirrors.tuna.tsinghua.edu.cn或mirrors.aliyun.com。换完再sudo apt update一次速度会快很多。4. GPU 直通的核心驱动到底装在哪一端这一节是整个方案里最容易搞错的地方我见过太多人在这里翻车。核心原则只有一句话Windows 端装驱动WSL2 端不装驱动。4.1 Windows 端驱动的正确装法在 Windows 上去 NVIDIA 官网下载最新的驱动。这里有个选择Game Ready Driver 还是 Studio Driver两者底层是同一个驱动区别在于 Game Ready 更新更频繁针对新游戏优化Studio 更新慢一些但经过更多创意软件的兼容性测试。对于 AI 开发两者都能用我一般选 Studio因为稳定性更好。下载后正常安装装完重启。然后在 Windows 的 PowerShell 或 CMD 里跑nvidia-smi能看到显卡信息就说明 Windows 端驱动没问题。4.2 WSL2 端为什么不能装驱动这是关键。WSL2 的 GPU 是通过/dev/dxg这个设备节点暴露给 Linux 的NVIDIA 在 WSL2 内核里内置了一个特殊的驱动模块叫dxgkrnl。这个模块负责把 Linux 的 CUDA 调用翻译成 Windows 驱动能理解的指令。如果你在 WSL2 里再装一遍标准的 Linux NVIDIA 驱动它会试图去接管 GPU和dxgkrnl冲突结果就是nvidia-smi报错或者 CUDA 初始化失败。所以正确的做法是WSL2 里什么都不装直接跑nvidia-smi。如果 Windows 驱动装好了WSL2 里应该能直接看到显卡。我实测在 Ubuntu 22.04 里刚装完系统、没装任何 NVIDIA 相关包的情况下nvidia-smi就能输出正常的显卡信息包括驱动版本、CUDA 版本、显存占用等。如果nvidia-smi提示 command not found说明 Windows 驱动版本太旧或者 WSL2 内核没更新。先wsl --update更新内核再确认 Windows 驱动版本 ≥ 470.76。4.3 CUDA Toolkit 的安装策略虽然 WSL2 里不装驱动但 CUDA Toolkit 是要装的。不过这里也有讲究你不需要装完整的 CUDA Toolkit因为 PyTorch 的 pip 包和 conda 包都自带了运行时的 CUDA 库。你只需要装cuda-toolkit里的一小部分主要是nvcc编译器和一些头文件用于编译自定义算子。最省事的办法是用 conda 装cudatoolkit它会自动处理版本匹配。比如conda install cudatoolkit11.8 -c nvidia这样装出来的 CUDA 运行时和 PyTorch 的版本是对齐的不会出现版本冲突。如果你需要nvcc来编译扩展再单独装cuda-nvccconda install cuda-nvcc11.8 -c nvidia验证 CUDA 是否可用跑nvcc --version能看到版本号就说明编译器就绪了。注意nvcc的版本和nvidia-smi显示的 CUDA 版本不一定要一致前者是编译器版本后者是驱动支持的最高 CUDA 版本只要编译器版本不高于驱动支持版本就行。5. PyTorch 环境搭建conda 还是 pip版本怎么选环境管理这块我强烈建议用 conda或者更轻量的 mamba。原因很简单conda 能同时管理 Python 包和非 Python 依赖比如 CUDA 库、MKL 数学库而 pip 只管 Python 包。在 AI 开发里CUDA 版本和 PyTorch 版本的匹配是个高频痛点conda 能帮你自动解决。5.1 Miniconda 安装与初始化不要装完整的 Anaconda几个 GB 太臃肿。装 Miniconda 就够wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh安装过程中会问你是否conda init选 yes。装完关掉终端重开或者source ~/.bashrc让 conda 生效。这里有个常见坑很多人装完 conda 后在 PowerShell 里跑conda activate报错无法将conda项识别。这是因为 conda 装在 WSL2 里PowerShell 是 Windows 的环境两者不互通。你要么在 WSL2 的终端里操作要么在 PowerShell 里用wsl conda activate xxx的方式调用。我建议直接在 Windows Terminal 里开一个 Ubuntu 标签页所有操作都在里面做省得混淆。5.2 创建专用环境并安装 PyTorch给 AI 开发建一个独立环境别用 baseconda create -n pytorch python3.10 -y conda activate pytorchPython 版本选 3.10 是因为它在兼容性和新特性之间平衡得最好3.11 有些库还没跟上3.9 又偏旧。装 PyTorch 时去官网的安装命令生成器选好版本。以 CUDA 11.8 为例pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118注意这里用的是 pip 而不是 conda因为 PyTorch 官方现在主推 pip 安装conda 渠道的更新会慢一些。--index-url指定 CUDA 11.8 的专用源这样装出来的包自带对应的 CUDA 运行时不需要你系统里预装 CUDA。如果你需要 conda 渠道可以用conda install pytorch torchvision torchaudio pytorch-cuda11.8 -c pytorch -c nvidia两种方式都行pip 更轻量conda 更省心。我一般用 pip因为下载速度快而且和requirements.txt的兼容性更好。5.3 验证 GPU 是否真的通了装完后必须验证别假设它一定工作。跑这段代码import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.device_count()) print(torch.cuda.get_device_name(0))期望输出是版本号、True、1、你的显卡型号。如果is_available()返回False按这个顺序排查先确认nvidia-smi在 WSL2 里能跑再确认 PyTorch 装的是 CUDA 版本而不是 CPU 版本torch.__version__里应该带cu118之类的后缀最后检查是不是装了两个 PyTorchpip 和 conda 各一个导致冲突。再跑一个实际的张量运算确认计算真的在 GPU 上import torch x torch.randn(1000, 1000).cuda() y torch.randn(1000, 1000).cuda() z x y print(z.device) print(torch.cuda.max_memory_allocated() / 1024**2, MB)如果z.device显示cuda:0且显存有占用说明 GPU 直通完全正常。6. 让 WSL2 更好用的几个调优配置装完能跑只是第一步要让日常开发舒服还得调一些配置。这些配置网上散落各处我把自己用的整理出来。6.1 .wslconfig控制内存和 CPU 分配在 Windows 用户目录下创建.wslconfig文件路径是C:\Users\你的用户名\.wslconfig内容如下[wsl2] memory12GB processors8 swap8GB localhostForwardingtruememory控制 WSL2 最多用多少内存默认是宿主机的一半。如果你有 32GB 内存可以给到 16GB 甚至 20GB。processors控制用几个核默认是全部但有时候留一两个核给 Windows 会更流畅。swap是交换空间建议设成内存的一半。改完在 PowerShell 里wsl --shutdown重启生效。6.2 文件系统性能跨系统访问的坑WSL2 访问 Windows 文件/mnt/c/...和 Windows 访问 WSL2 文件\\wsl$\Ubuntu-22.04\...都很方便但性能差异巨大。WSL2 访问/mnt/c下的文件IO 性能只有访问 Linux 原生文件系统的几分之一。如果你把数据集放在 Windows 的 D 盘然后在 WSL2 里训练数据加载会成为瓶颈。我的做法是代码和数据都放在 WSL2 的 Linux 文件系统里比如~/projects只在需要和 Windows 交换文件时才用/mnt/c。VS Code 用 Remote-WSL 插件连接后直接编辑 Linux 里的文件体验和本地一样。6.3 终端与开发工具链Windows Terminal 是必装的比默认的控制台好用太多。装完后把 Ubuntu 设为默认 profile启动就是 Linux 环境。字体建议用等宽字体如 Cascadia Code 或 JetBrains Mono看代码舒服。VS Code 装 Remote - WSL 插件然后在 WSL2 终端里cd到项目目录跑code .VS Code 会自动以远程模式打开这个目录。这时候你用的 Python 解释器、终端、调试器全都是 WSL2 里的但界面是 Windows 的兼顾了两边的优势。Git 配置别忘了尤其是换行符。在 WSL2 里跑git config --global core.autocrlf input这样 Windows 的 CRLF 换行符在提交时会被转成 LF避免污染仓库。7. 踩过的坑与排查实录这部分是我实际遇到过的几个典型问题以及完整的排查过程。如果你遇到类似症状可以照着这个思路走。7.1 nvidia-smi 报错 No devices were found这个错误通常出现在刚装完 WSL2、还没更新内核的时候。排查链路是这样的先在 Windows 端确认nvidia-smi正常排除驱动问题然后在 PowerShell 里跑wsl --update把 WSL2 内核更新到最新更新完wsl --shutdown重启再进 WSL2 跑nvidia-smi。如果还不行检查 Windows 驱动版本低于 470.76 的话升级驱动。还有一种情况是装了 WSL2 版的 NVIDIA 驱动。有些人看到网上教程说要在 WSL2 里装驱动就apt install nvidia-driver-xxx结果把dxgkrnl覆盖了。解决办法是卸载 WSL2 里的驱动包sudo apt remove --purge nvidia-*然后重启 WSL2。7.2 PyTorch 能 import 但 cuda.is_available() 返回 False这个症状说明 PyTorch 装的是 CPU 版本。检查torch.__version__如果是2.x.x不带cu后缀就是 CPU 版。卸载重装pip uninstall torch torchvision torchaudio -y pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118如果版本带cu118但还是 False可能是 CUDA 运行时版本和驱动不匹配。比如驱动只支持到 CUDA 11.6你装了 cu118 的包就会失败。这时候要么升级驱动要么降级 PyTorch 到 cu116 版本。7.3 训练时显存溢出但 nvidia-smi 显示显存充足这个坑很隐蔽。WSL2 的显存管理有个特点它不会主动释放缓存nvidia-smi显示的显存占用可能包含之前进程的残留。如果你反复跑训练脚本显存会越占越多最后 OOM。解决办法是在训练脚本里加torch.cuda.empty_cache()或者在每次训练前重启 WSL2wsl --shutdown。更优雅的做法是用torch.cuda.memory_summary()看显存分配详情定位是哪个张量没释放。另外把batch_size调小、用梯度累积、开混合精度训练都能有效降低显存压力。7.4 WSL2 下载慢、apt 卡住国内网络访问 Ubuntu 官方源和 PyPI 都可能很慢。apt 换国内镜像前面说过了。pip 的话临时用-i指定源pip install xxx -i https://pypi.tuna.tsinghua.edu.cn/simple永久配置可以写~/.pip/pip.conf[global] index-url https://pypi.tuna.tsinghua.edu.cn/simpleconda 也可以换源编辑~/.condarc加上清华的 channel。不过要注意PyTorch 的 CUDA 包在清华源里可能不全装 PyTorch 时还是用官方源比较稳。8. 把这套环境用起来的几个实战建议环境搭好之后怎么用才是关键。分享几个我日常开发中的习惯能帮你少走弯路。第一项目目录结构要规范。我一般是这样组织的~/projects/项目名/下放code、data、checkpoints、logs四个子目录。data用软链接指向实际的数据存储位置这样代码里路径统一换机器时只改软链接。checkpoints定期清理旧权重只保留最好的几个不然磁盘很快满。第二训练任务用 tmux 或 nohup 挂后台。WSL2 的终端关掉后前台进程会被杀掉。用tmux new -s train开一个会话在里面跑训练然后CtrlB D脱离任务继续跑。下次tmux attach -t train回来看进度。或者用nohup python train.py train.log 21 日志重定向到文件用tail -f train.log实时看。第三善用 VS Code 的调试功能。Remote-WSL 模式下VS Code 的调试器和本地一样好用。在.vscode/launch.json里配好 Python 调试配置可以打断点、看变量、单步执行。对于调试数据加载、模型前向传播这种逻辑比 print 大法高效得多。第四定期备份 conda 环境。conda env export environment.yml导出依赖列表换机器或者环境搞坏了可以快速重建。但要注意environment.yml里的 pip 包和 conda 包要分开写不然重建时容易冲突。第五关注 WSL2 的内存回收。WSL2 有个已知问题Linux 里释放的内存不会立刻还给 Windows导致 Windows 端看起来内存被占满。可以在.wslconfig里加autoMemoryReclaimgradual需要较新版本的 WSL2或者定期wsl --shutdown重启。我一般每天下班前 shutdown 一次第二天开机重新进内存就干净了。这套 WSL2 GPU 直通的方案我从 2022 年用到现在跑过 BERT 微调、Stable Diffusion 推理、YOLO 训练稳定性没问题。唯一要注意的是WSL2 毕竟隔了一层虚拟化某些极端场景下比如需要精确控制 GPU 时钟、需要特定内核模块还是得用原生 Linux。但对 90% 的 AI 开发场景来说它已经足够好了而且让你不用离开 Windows 生态这个便利性值得那一点点性能损耗。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑