日常搞 AI 的同学应该都有这种感觉:Windows 上跑 Linux 工具链一直是老大难。我在公司用 Windows 笔记本,回到家台式机也是 Windows,之前想碰 CUDA 相关的开发,来来回回就那几条路——双系统开机切换、虚拟机里装 Ubuntu、或者干脆在 Windows 上硬装深度学习环境。结果要么折腾启动项,要么 GPU 性能打折,要么被一堆 DLL 缺失折磨到怀疑人生。直到 WSL2 把真正的 Linux 内核以轻量虚拟机的方式跑在 Windows 上,再加上 GPU 直通能让 CUDA 直接调用物理显卡,我才终于找到了一套既能日常办公、又能写代码跑模型的正解。这篇文章就把我从零开始部署 WSL2 AI 开发环境的完整过程写下来,包括原理、步骤、性能实测和踩坑记录,给所有想在 Windows 上做深度学习但被环境配置劝退过的朋友一个可以直接抄的作业。
1. 为什么我最终选了 WSL2 而不是双系统或虚拟机
1.1 双系统的无限重启之痛
双系统听起来很美好:开机选系统,进 Linux 就是纯正环境,性能没有任何折损。但用一段时间你就知道痛点在哪。每次想切系统都得重启,重启一次少说两分钟,频繁切换的时候整个人都很崩溃。更要命的是,Windows 和 Linux 之间的文件交换特别别扭,虽然可以挂载 NTFS 分区,但权限问题、中文文件名问题、软链接问题层出不穷。
我在双系统阶段遇到过最糟的一次经历:Linux 侧训练任务跑到一半,Windows 侧需要紧急处理一个文档,我只能把训练任务停了重启进 Windows。那次之后我就意识到,双系统只适合"一个机器只干一件事"的场景,不适合我这种需要在 Windows 办公和 Linux 开发之间高频切换的人。
双系统还有一个隐蔽风险,就是引导项被更新覆盖。Windows 大版本更新偶尔会把 GRUB 弄丢,每次都要拿启动盘去修复引导,操作倒是不难,但真的很耗精力。
1.2 传统虚拟机的性能天花板
虚拟机方案我也认真试过。VirtualBox 和 VMware 在 Windows 上跑 Linux 已经很成熟了,装个 Ubuntu 虚拟机做开发没问题,但一旦涉及到 GPU 就不太行了。VirtualBox 的 3D 加速基本停留在能看桌面不卡的程度,VMware 虽然有 vGPU 虚拟化,但对 CUDA 的支持非常有限,跑个小模型还行,稍微上点规模就报错或者慢得无法接受。
还有一个问题是虚拟机的资源开销。开一个 Ubuntu 虚拟机,内存占用轻松上 4GB,CPU 也要吃掉好几个核心,Windows 本体再跑着浏览器、IDE、通讯软件,16GB 内存的机器很快就捉襟见肘。而且传统虚拟机的磁盘 IO 性能折损比较大,尤其是大量小文件读写的场景,跑 git 操作、pip 安装的时候明显能感觉到卡顿。
WSL2 出来之后我把虚拟机和双系统都弃了,原因就是它把前两者的优势结合了:不需要重启、启动快、资源动态分配、GPU 能直通。而且它不是靠翻译系统调用模拟出来的 Linux,是货真价实的内核级 Linux,这一点对 AI 开发来说太重要了。
1.3 内核级 Linux 到底意味着什么
要理解 WSL2 为什么对 AI 开发友好,得先搞清楚它和 WSL1 的本质区别。WSL1 是一个系统调用翻译层,把 Linux 程序发出的系统调用翻译成 Windows 的系统调用,这个方案兼容性有限,很多依赖内核特性的软件跑不了。WSL2 则完全不同,它把真正的 Linux 内核编译成一个轻量虚拟机,直接在 Hyper-V 虚拟机框架里跑。所以你在 WSL2 里执行uname -r看到的是一串真实 Linux 内核版本号,而不是什么模拟出来的东西。
"内核级"这三个字对 AI 开发的意义体现在几个方面。第一,CUDA 工具链和 NVIDIA 驱动模块可以真正加载到 Linux 内核里,这是 GPU 直通的基础。第二,Docker 容器可以直接跑,因为 WSL2 本身就支持完整的容器运行环境,不需要额外的虚拟机层。第三,像 eBPF、内核模块、性能剖析这些底层工具都能正常用,调试和性能分析的手段和物理 Linux 机几乎没有差别。
我个人的体感是,在 WSL2 里写代码、跑训练、调优,和在原生 Ubuntu 上几乎没有区别。唯一要注意的是 Windows 和 Linux 文件系统之间的 IO 开销问题,这个我在后面会专门讲。
1.4 什么人适合用 WSL2 做 AI 开发
先说结论:如果你的主力机是 Windows,且需要同时兼顾日常办公和深度学习开发,WSL2 是目前最舒服的解法。下面这个表是我根据自己的使用场景整理出来的,可以参考一下。
| 场景 | 双系统 | 传统虚拟机 | WSL2 |
|---|---|---|---|
| Windows 办公与 Linux 开发切换 | 要重启,费时 | 不用重启,但两套系统并行 | 不用重启,原生切换 |
| GPU 支持 | 原生支持,性能无损 | 支持有限,性能折损大 | GPU 直通,性能接近原生 |
| 启动速度 | 分钟级 | 分钟级 | 秒级 |
| 系统资源占用 | 同时只能用一套 | 静态分配,开销大 | 动态分配,按需使用 |
| 与 Windows 文件互传 | 要挂载分区,麻烦 | 共享文件夹,较方便 | 直接访问 /mnt/c,无缝 |
| 适合人群 | 需要独占 GPU 跑长时间任务 | 想快速体验 Linux 的用户 | Windows 主力 + AI 开发的绝大多数人 |
还要说说什么人不适合。如果你跑的是动辄几天的超大模型训练,需要把 GPU 吃满还不关机,那纯 Linux 物理机或者双系统仍然更合适。另外如果是多卡环境的 NCCL 分布式训练,WSL2 里的网络栈和物理机有一些微妙差异,可能需要额外调参,这部分我也遇到过,后面会展开。
2. WSL2 的 GPU 直通到底是什么原理
2.1 不是 PCIe 直通,而是 GPU 半虚拟化
很多人听到"WSL2 GPU 直通",第一反应是把物理显卡直接塞给虚拟机。实际上 WSL2 的做法不是这种传统意义上的 PCIe Pass-Through,而是一套叫 GPU-PV(GPU 半虚拟化)的机制。
传统虚拟机如果要直通 GPU,通常需要把整个 PCIe 设备从宿主机解绑,然后分配给虚拟机,这种方式的缺点是宿主机自己就不能再用这块显卡了。而 WSL2 的 GPU 直通走的是另一条路:Windows 宿主机的显卡驱动仍然是主驱动,Linux 侧通过一个虚拟设备接口把 CUDA/OpenGL 的调用请求转发给 Windows 驱动,再由 Windows 驱动真正下发到物理 GPU 执行。
所以你在 WSL2 里输入nvidia-smi看到的 GPU 信息,其实是 Windows 侧驱动上报过来的。这样做的好处很明显:Windows 桌面还在用这块显卡显示、渲染,WSL2 里的训练任务也在用同一块显卡计算,两者互不干扰。我实测下来,Windows 桌面看视频、写文档的同时,WSL2 里跑小规模训练任务,Windows 侧几乎感觉不到卡顿。
2.2 一条 CUDA 调用的完整旅程
理解了半虚拟化的大框架,我们再往下钻一层,看看一次 PyTorch 里的 tensor 运算是怎么走到物理 GPU 上的。简化来说,调用链是这样的:
Linux 用户态的程序(比如 PyTorch)调用 CUDA 运行库 → CUDA 运行库通过 ioctl 访问 /dev/dxg 设备 → 这个设备由 Linux 侧的内核驱动模块 vGPU 驱动处理 → 请求通过虚拟化通道发送到 Windows 宿主机 → Windows 的 WDDM 驱动调度到物理 GPU → GPU 计算完成后结果原路返回。
这里面最关键的一点是,Linux 侧其实并不需要完整的 NVIDIA 显卡驱动,只需要一个能够对接 /dev/dxg 的设备驱动即可。所以你会发现,在 WSL2 里安装 CUDA 和物理 Linux 上安装 CUDA 的步骤不一样,物理机上要装显卡驱动,WSL2 里则不需要,因为驱动工作在 Windows 侧。
这也解释了为什么 Windows 侧显卡驱动的版本必须足够新,因为旧驱动根本没有实现针对 WSL2 半虚拟化的支持接口。NVIDIA 从 460 版本驱动开始才为 WSL2 提供了完善的 GPU 支持,所以如果你的驱动版本太老,WSL2 里是认不到 GPU 的。
2.3 GPU 直通与内核级 Linux 的强绑定关系
为什么要反复强调"内核级 Linux"?因为 GPU 直通的实现极度依赖 Linux 内核的能力。WSL1 那种系统调用翻译架构下,Linux 程序根本无法感知到 /dev/dxg 设备的存在,也就谈不上任何 GPU 加速。
WSL2 的轻量虚拟机里跑的是完整 Linux 内核,NVIDIA 的 vGPU 驱动模块可以以内核模块的方式加载,系统才能创建设备节点,用户态程序才能通过设备节点发起 GPU 调用。所以"内核级 Linux + GPU 直通"这两个关键词是强绑定的关系,缺一不可。
我后来还用 WSL2 跑过需要加载内核模块的 XDP/eBPF 程序,这在 WSL1 时代是想都不敢想的。对做 AI Infra 或者深度学习系统方向的同学来说,这点尤其关键,因为性能分析工具如perf、bpftrace都需要内核特性配合,能在 WSL2 里用上这些工具,意味着调试手段和物理 Linux 基本对齐了。
2.4 硬件与驱动版本的硬性门槛
不是所有显卡都能在 WSL2 里跑 CUDA,硬件和驱动都有明确要求。我自己整理了一个清单:
- NVIDIA 显卡:要求计算能力 6.0 以上,也就是 GTX 10 系及以上,包括 RTX 20/30/40 系、Tesla/Quadro 系列。如果用的是 GTX 9 系或更老的卡,基本不用指望了。
- NVIDIA 驱动:Windows 侧驱动版本必须大于等于 460,推荐用最新 Game Ready 或 Studio 驱动。不要用 Windows 设备管理器自动安装的基础驱动版本,那个往往太旧。
- AMD 显卡:想用 ROCm 跑 AI 的话,WSL2 里的支持目前比较有限,我自己没有深入测试,建议追求稳定体验还是选 NVIDIA。
- Intel 核显:目前没有官方 CUDA 支持,如果只有核显,WSL2 里的 AI 加速基本只能靠 CPU 硬扛。
另外要注意一点,就是显存方面。WSL2 看到的是物理显卡的完整显存,比如 8GB 显存的 RTX 4060,在 WSL2 里nvidia-smi就能看到完整的 8GB,所以不存在"虚拟机里显存被砍半"的问题。这也是 GPU 直通相比传统 GPU 虚拟化的一大优势,模型显存需求基本可以照着物理机规格去估。
3. 从零实操:装好一套能跑大模型的 WSL2 环境
3.1 动手之前的环境检查清单
正式开始之前,先花五分钟检查一下自己的机器条件,避免装到一半才发现不支持。需要确认这几点:
- Windows 版本:Windows 10 2004 及以上,或者 Windows 11。老版本 Windows 虽然也能单独装 WSL2 组件,但步骤复杂得多,建议至少保证 2004 以上。
- CPU 虚拟化:BIOS/UEFI 里必须开启 Intel VT-x 或 AMD-V。这一步常被忽视,如果 WSL2 安装后启动报错,第一个就去查这里。
- Windows 更新:建议把系统更新到最新,因为 WSL2 的很多组件和修复是通过 Windows 更新推送的。
- 显卡驱动:确认自己的 NVIDIA 驱动版本。在 Windows 的 NVIDIA 控制面板或者任务管理器里能看到,如果低于 460,先更新驱动再做后面的事。
检查命令可以这样用。在 Windows 的 PowerShell 里跑:
wsl --status如果显示没有安装,它会给出提示;如果已经装了,可以看到默认版本等信息。另外可以在 PowerShell 里查看 Windows 版本:
winver虚拟化是否开启,可以直接打开任务管理器,在"性能"标签页里看 CPU 一栏是否显示"虚拟化:已启用"。如果显示"已禁用",就需要进 BIOS 开启,这一步每家主板界面不一样,关键词搜 VT-x 或 SVM 即可。
3.2 安装 WSL2 和 Ubuntu 22.04
环境检查没问题之后,安装其实很快。最简单的做法是以管理员身份打开 PowerShell,执行:
wsl --install这个命令会默认安装 WSL2 和 Ubuntu 发行版。但如果想指定发行版,可以先看看在线列表:
wsl --list --online我推荐用 Ubuntu 22.04 LTS,因为它是目前 AI 生态适配最成熟的发行版,PyTorch、CUDA、Docker 等工具链对它的支持都最完整。指定安装命令:
wsl --install -d Ubuntu-22.04安装过程中会要求设置 Linux 用户名和密码,需要注意用户名不一定要和 Windows 一样,随便取一个就行,但密码要能记住,因为后面sudo命令都靠它。
装完之后建议立即执行更新和升级:
sudo apt update && sudo apt upgrade -y这个步骤很重要,尤其要保证内核最新,因为老内核可能有与 WSL2 交互相关的 bug。更新完用uname -r确认一下内核版本,正常会看到形如6.6.x-microsoft-standard-WSL2的版本号。
如果之前装过 WSL1 的旧发行版,可以手动指定默认版本:
wsl --set-version Ubuntu-22.04 2 wsl --set-default-version 23.3 驱动分工:Windows 装驱动,Linux 装工具链
WSL2 里装 CUDA 环境时有一个常见的认知误区:很多人会习惯性地在 Linux 侧装 NVIDIA 显卡驱动,结果发现怎么也装不上,或者装上之后各种冲突。这里一定要记住一个原则:WSL2 里不需要也不能装 Linux 侧显卡驱动,驱动完全由 Windows 侧负责。
Linux 侧要装的是 CUDA Toolkit 和 cuDNN,也就是运行 CUDA 程序所必需的库文件和工具链。我一般用 runfile 方式安装 CUDA,因为比 apt 源更可控,也不容易受到系统自带包的影响。
以 CUDA 12.4 为例,安装步骤是这样的:
wget https://developer.download.nvidia.com/compute/cuda/12.4.0/local_installers/cuda_12.4.0_550.54.14_linux.run sudo sh cuda_12.4.0_550.54.14_linux.run --toolkit --silent注意后面的--toolkit参数,它表示只安装 CUDA Toolkit,不安装驱动。因为 WSL2 里不需要驱动,如果默认安装会把驱动也带进去,然后大概率会报错。
装完 CUDA 之后再装 cuDNN,下载需要到 NVIDIA 官网注册账号,选择对应 CUDA 版本的 cuDNN 包。下载后解压,把库文件复制到 CUDA 安装目录:
tar -xvf cudnn-linux-x86_64-8.9.7.29_cuda12-archive.tar.xz sudo cp cudnn-*-archive/include/cudnn*.h /usr/local/cuda/include/ sudo cp cudnn-*-archive/lib/libcudnn* /usr/local/cuda/lib64/ sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*最后配置环境变量。编辑~/.bashrc,在末尾追加:
export PATH=/usr/local/cuda/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH然后source ~/.bashrc,执行nvcc --version验证 CUDA 编译器是否可用。
3.4 安装 PyTorch 并用一张图验证 GPU
深度学习框架我建议直接在虚拟环境里装,避免污染系统 Python。用 miniconda 比 conda 全量版更轻量,装完 Python 再配 PyTorch。
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh创建独立环境:
conda create -n pytorch python=3.10 conda activate pytorch安装 PyTorch,注意要下载带 CUDA 支持的版本。如果你前面装的是 CUDA 12.4,可以这样装:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124装完做最终的 GPU 验证,执行这一段 Python:
import torch print("PyTorch version:", torch.__version__) print("CUDA available:", torch.cuda.is_available()) print("Device name:", torch.cuda.get_device_name(0))如果输出CUDA available: True,说明整个 WSL2 + GPU 直通链路已经打通。我在第一次看到这个输出的时候还挺激动的,因为这意味着 Windows 机器真正具备了无缝跑深度学习的能力。
再顺手跑一个简单的张量运算验证一下实际计算确实走的是 GPU:
import torch x = torch.randn(1024, 1024, device="cuda") y = torch.randn(1024, 1024, device="cuda") z = x @ y print(z.device)输出cuda:0就稳了。
3.5 用 Docker 容器化你的 AI 工作流
如果你和我一样喜欢用容器管理环境,WSL2 里跑 Docker 也很丝滑。有两种方式,一种是用 Docker Desktop 并开启 WSL2 backend,另一种是直接在 WSL2 里装 Docker Engine。
我推荐第二种,因为更纯粹,不依赖 Windows 侧进程,资源占用也更低。安装命令:
curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh然后配置 GPU 容器支持。先安装 nvidia-container-toolkit:
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/libnvidia-container/gpgkey | sudo apt-key add - curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list sudo apt-get update sudo apt-get install -y nvidia-container-toolkit配置 Docker 运行时:
sudo nvidia-ctk runtime configure --runtime=docker sudo systemctl restart docker验证容器内 GPU 可见性:
sudo docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi能正常输出 GPU 信息,说明容器里的 GPU 直通也打通了。我平时跑模型基本都在容器里进行,宿主环境保持干净,出问题直接换镜像,效率高很多。
4. 性能实测与几个关键的调优点
4.1 GPU 直通后的实际性能表现
先说大家最关心的性能问题。我自己在 WSL2 里跑过 ResNet-50 训练、BERT fine-tune、LLaMA 推理等不同类型的任务,实测下来计算密集型的训练任务与原生 Ubuntu 的差距非常小,基本在 5% 以内,甚至有时候完全无感知。
原因也很简单:GPU 计算本身的耗时占大头,CPU 到 GPU 之间的调用开销在整个训练流程里占的比例很小。所以只要你的模型是那种在 GPU 上一跑几十秒甚至几分钟的任务,WSL2 的额外开销可以忽略不计。
但在小模型频繁推理的场景下,差异会明显一些。比如一个很小的 ONNX 模型,单次推理毫秒级,WSL2 里因为多了一层虚拟化转发,每次调用的固定开销占比就被放大了。实测可能慢 10% 到 20%,具体取决于调用频率和模型大小。所以如果你的核心场景是超高频小模型推理,还是建议以物理 Linux 为准。
多卡训练的情况要复杂一些。NCCL 在 WSL2 里通过虚拟网络栈通信,跨卡通信的时延和带宽相比物理机有一定的折损,尤其是在单机多卡场景。单卡训练完全没问题,多卡需要做分布式训练的同学,建议先在 WSL2 里测试,如果发现通信瓶颈明显,还是切到物理 Linux 或双系统更省心。
4.2 用 .wslconfig 控制资源配额
WSL2 默认会动态分配资源,但有时候默认策略不是最优的。比如默认情况下 WSL2 最多可以占满系统 50% 内存,如果你的机器内存不大,Windows 本体反而容易被拖垮。建议在用户目录C:\Users\你的用户名\.wslconfig下写一个配置文件,手动控制资源上限。
我的配置大致是这样:
[wsl2] memory=16GB processors=8 swap=8GB networkingMode=mirroredmemory控制 WSL2 最大可用内存,processors控制最多使用的 CPU 核心数,swap是虚拟内存的大小。networkingMode=mirrored是 Windows 11 22H2 之后新增的镜像网络模式,可以让 WSL2 和 Windows 共享网络接口,解决了很多端口转发和 localhost 访问的问题。
修改.wslconfig之后需要重启 WSL2 才能生效:
wsl --shutdown再重新进 WSL2,用free -h看内存、nproc看 CPU 数量,确认配置是否生效。这里有个细节,memory设成 16GB 并不代表 WSL2 启动就会占 16GB,它只是一个天花板,实际用了多少才算多少,动态伸缩是 WSL2 的一大优点。
4.3 文件系统性能陷阱:项目文件千万别放 /mnt/c
这是 WSL2 日常使用中最大的一个坑,我刚开始就踩了。WSL2 里的 Linux 文件系统和 Windows 的 NTFS 文件系统之间,存在一层很明显的性能损耗。如果你把项目放在C:\Users\你的用户名\projects,然后在 WSL2 里通过/mnt/c/Users/...去访问,pip 安装、git 操作、编译构建都会慢得离谱,尤其是大量小文件的场景,可能比原生 Linux 慢 10 倍以上。
我后来做了个实验,同样的 PyTorch 项目,放在/mnt/c下和放在 Linux 原生文件系统/home/用户名/projects下,跑一遍完整的pip install -r requirements.txt,耗时差距接近一倍。原因在于跨文件系统的每次文件操作都涉及协议转换和上下文切换,小文件成百上千个的时候,这部分开销就被无限放大。
所以正确的做法是:项目文件一律放在 WSL2 的 Linux 文件系统里,比如/home/用户名/projects,Windows 侧如果需要编辑,直接在 VS Code 里通过 WSL Remote 扩展打开。VS Code 的 WSL 支持做得很好,代码补全、调试、终端都能无缝工作,文件路径显示为 Linux 风格,但实际上读写的性能是原生 Linux 级别的。
Windows 侧偶尔需要访问 Linux 文件,可以直接在资源管理器地址栏输入\\wsl$\Ubuntu-22.04\home\用户名进入,这个入口只用来小量传文件没问题,但不适合作为项目的日常挂载点。
4.4 把 WSL2 安装到非 C 盘,给系统盘减负
WSL2 的虚拟磁盘文件默认放在 C 盘,默认大小就有几十 GB,装完 CUDA、Docker 镜像、conda 环境之后随便破百 GB。如果你的 C 盘空间紧张,这一步可以在刚装好系统后就做,省得以后倒腾。
原理是先导出再导入,把整个 WSL2 发行版迁移到其他盘。在 Windows 的 PowerShell 里操作:
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 2unregister会删除原来的发行版(注意先备份数据),import会把打包好的系统恢复到指定目录。恢复之后,进入系统检查原来的文件和环境是否完好。
我在一次迁移之后就顺手把 Alpine Linux 也装在 D 盘了,专门用来当轻量终端环境用。日常生活动开发都放在 D 盘的虚拟磁盘里,C 盘只留 Windows 系统本体,空间压力小很多。
5. 踩坑记录:我遇到的 5 个典型问题和排查方法
5.1 nvidia-smi 不存在或者看不到 GPU
这是刚装完最容易遇到的问题。先区分两种情况:如果nvidia-smi命令都不存在,说明没有安装 NVIDIA 相关的工具,不能直接在 Linux 侧装驱动,而是先确认 Windows 侧驱动是否满足要求,然后检查 Linux 侧的 /dev/dxg 设备是否存在:
ls -la /dev/dxg如果设备不存在,大概率是 Windows 驱动版本太旧,更新到最新 NVIDIA 驱动后重启 WSL2 再看看。如果设备存在但nvidia-smi还是不可用,可以尝试在 Ubuntu 里安装nvidia-utils-xxx包:
sudo apt install nvidia-utils-550版本号要和 Windows 侧驱动对应。这个包只提供用户态工具,不装驱动,所以不会有冲突问题。
还有一种情况是装完驱动之后不生效,重启一下 WSL2 就好:
wsl --shutdown重新进入后nvidia-smi就会出现了。
5.2 WSL2 无法启动,报虚拟化相关错误
如果你执行wsl --install -d ubuntu-24.04或者启动发行版时,报类似"WSL2 无法启动,因为此计算机上未启用虚拟化"的错误,第一优先级检查 BIOS 里的虚拟化开关。
进入 BIOS 或 UEFI 设置,找到 CPU Configuration 或 Intel Virtualization Technology / SVM Mode,改成 Enabled,保存重启。这一步做完基本能解决。
还有一种隐蔽情况是 Windows 的 Hyper-V 组件没有完全启用。在管理员 PowerShell 里执行:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All执行后重启系统。我遇到过一台机器 BIOS 虚拟化开了但 WSL2 还是起不来,就是用这个命令解决的。
另外,如果你在用 Windows 10 且没有更新到最新版,可能会出现"需要安装 WSL2 内核更新包"的提示,去微软官方下载对应的 MSI 安装包装一下即可。
5.3 内存占用过高,Windows 被拖垮
WSL2 默认的内存回收策略确实有些激进,跑过一次大模型训练之后,即使任务结束了,它的内存占用也不会立刻降下来,导致 Windows 本体卡顿。除了在 .wslconfig 里限制memory上限外,我养成了一个习惯:每次用完 WSL2 的深度学习环境,执行一次:
wsl --shutdown这个命令会关停所有 WSL2 发行版,立刻释放内存和 CPU 资源。代价是下次启动要重新初始化,但 WSL2 启动本来就很快,几秒钟就能进系统,所以这个操作非常划算。
如果你不想频繁关闭,也可以在 Linux 侧手动释放缓存:
echo 3 | sudo tee /proc/sys/vm/drop_caches这个命令能清掉 page cache,但在有活跃服务跑着的时候慎用,可能会短暂影响性能。
5.4 WSL2 里的网络问题:DNS 解析失败和下载慢
WSL2 的 DNS 是动态生成的,有时候会遇到/etc/resolv.conf被改坏或者失效,导致 apt 或 pip 显示网络不通。排查方式:
cat /etc/resolv.conf如果内容异常或者nameserver明显不对,可以临时写一个公共 DNS 试试:
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf但要注意,WSL2 重启后这个文件可能会被重新生成。更好的办法是在.wslconfig里配置镜像网络:
[wsl2] networkingMode=mirrored镜像网络模式下,WSL2 共享 Windows 的 DNS 配置,大部分网络问题都消失了。
关于下载慢的问题,最有效的办法是给 apt 和 pip 配置国内镜像源。apt 源在/etc/apt/sources.list或/etc/apt/sources.list.d/下,pip 源在~/.pip/pip.conf里。把默认源替换成镜像站之后,pip install和apt install的速度会有质的提升。
5.5 重启后环境变量失效或磁盘路径找不到
如果你发现每次启动 WSL2 都要重新source ~/.bashrc才能用 CUDA 工具链,大概率是因为环境变量写在.bashrc里但 shell 启动时没有加载。排查方式是确认你用的是不是 bash,以及.bashrc的归属:
echo $SHELL如果输出不是/bin/bash,而是其他 shell,就需要把环境变量写到对应的配置文件里。另外,如果你开了多个 WSL2 发行版,注意每个发行版的独立起点,路径/home/用户名/...不是全局共享的。
还有一个经验是,如果nvcc -V能用但nvidia-smi找不到,或者反过来,很可能是 PATH 里的 CUDA 和系统自带工具冲突了。我最终的解决方案是把 CUDA 环境变量单独写到一个文件里,然后在.bashrc里 source 它,这样管理更清晰,出问题也好定位。
结尾:这套环境我用了这么久的真实体感
从第一次打通 WSL2 GPU 直通到现在,我基本把日常的 AI 开发工作全部迁到了这套环境上。写代码用 VS Code + WSL Remote,跑训练直接在 WSL2 里敲命令,容器环境用 Docker 隔离,Windows 侧该办公办公、该玩游戏玩游戏,两边互不干扰。偶尔遇到必须用物理 Linux 的场景,找一台服务器或者开个双系统,也不会太纠结。
最后再分享一个小技巧,就是养成定期压缩虚拟磁盘的习惯。WSL2 的 ext4.vhdx 文件会随着你反复安装卸载包变得越来越大,即使删了文件也不会自动缩回去。在 PowerShell 里执行:
wsl --shutdown diskpart select vdisk file="D:\wsl\ubuntu2204\ext4.vhdx" compact vdisk detach vdisk exit执行之后虚拟磁盘文件能瘦身不少。我第一次操作的时候从 120GB 压回了 60GB,C 盘空间瞬间宽裕。这套 WSL2 + GPU 直通的环境配置虽然一开始花点时间,但一次性搞定之后,是真的能踏踏实实做很久的开发。