如果你和我一样,主力机用 Windows,却要天天和 PyTorch、CUDA、命令行、模型训练打交道,那你大概率经历过这种撕裂感:Windows 上能装环境、能跑小 demo,可一旦要跑训练脚本、编译自定义算子、搞分布式,或者直接照着一份带 bash 的项目 README 操作,Windows 就开始各种不配合。过去两年多,我的主力 AI 开发环境一直住在 WSL2 里——日常办公留在 Windows,训练和推理全部在 WSL2 中完成,两边共享文件,GPU 照常调用。这篇文章就把我这套环境的完整搭建过程、GPU 直通的底层原理、CUDA 配置细节,以及我踩过的坑全部梳理出来。
文章面向两类人:一类是刚接触 WSL2、想在 Windows 上正经跑 AI 项目的开发者;另一类是已经在用 WSL2,但 GPU 直通或性能始终没调明白的人。内容按实际搭建顺序展开,从零开始,每步都会说清楚为什么这么做,以及不做会有什么后果。
1. 为什么是 WSL2:从“翻译层兼容”到“内核级 Linux”
1.1 WSL1 与 WSL2 的本质差异,不只是换个版本号
很多人以为 WSL2 只是 WSL1 的“性能加强版”,这个理解会直接影响你后面排查问题的思路。WSL1 本质上是一个系统调用翻译层:它把 Linux 程序发出来的系统调用“实时翻译”成 Windows NT 内核能理解的操作。好处是启动快、文件访问原生,坏处是翻译总有不完整的地方——比如某些 Linux 内核特有的功能、需要内核模块配合的场景,WSL1 根本无法兼容。
WSL2 直接把这个问题连根拔起:它不再翻译,而是用一个轻量级虚拟机,在 Hyper-V 虚拟化平台上跑一个微软自己维护的 Linux 内核。对 AI 开发来说,这个改变是决定性的:真正的 Linux 内核,意味着 Docker 能跑、CUDA 能跑、内核级特性能用,Linux 生态里的东西基本都能搬进来。标题里说的“内核级 Linux”,指的是这一层,而不是某个发行版名称。
用生活化类比:WSL1 像一个同声传译,你说德语他翻译成英语,但遇到文化梗可能翻不动;WSL2 则是直接把一个德国人请到了你家里,他说德语,你也听得懂,交流中的损耗降到最低。AI 工具链几乎全是 Linux 优先,在 WSL2 里跑就是“原住民”待遇。
1.2 “GPU 直通”三个字,其实没那么简单
标题里的“GPU 直通”需要先说清楚边界。严格的 PCIe 直通,是把物理显卡整个分配给虚拟机独占,那种方案配置复杂,而且本质上只在一台机器上跑一个 VM 时才划算。WSL2 的 GPU 机制不是这种,它更像“GPU 半虚拟化转发”,具体链路是:
- Windows 侧安装 NVIDIA 官方驱动,驱动通过 WDDM 2.9+ 接口暴露 GPU 能力;
- WSL2 内核中启用了
/dev/dxg设备节点,负责把 Linux 侧发来的 GPU 请求转发到 Windows 驱动栈; - NVIDIA 为 WSL 专门提供了 CUDA 用户态适配层,让 Linux 程序以为自己在原生 Linux 下跑,实际上底层是 Windows 驱动在工作。
对开发者来说,最终体验就是:在 WSL2 里nvidia-smi能看到显卡和显存,PyTorch 里torch.cuda.is_available()返回 True,训练照常跑。虽然称不上物理级直通,但实际使用中不是瓶颈。我一开始也怀疑这套转发层性能损耗大,后面的实测告诉我:GPU 密集型任务,损耗小到基本可以忽略。
1.3 先划清边界:WSL2 适合做什么,不适合做什么
任何工具都有适用边界,WSL2 也一样。我基于实际使用体验做了一个梳理:
| 场景 | 是否适合 | 原因 |
|---|---|---|
| 模型训练 | 适合 | CUDA、显存管理、多进程训练都能正常工作 |
| 推理服务开发 | 适合 | FastAPI 等服务端程序在真实 Linux 内核上跑,行为与生产一致 |
| 分布式多机训练 | 较适合 | 单机多卡没问题,多机需要网络协商,NAT 模式稍有额外配置 |
| 需要加载自定义内核模块 | 不适合 | WSL2 内核由微软维护,自定义模块不一定能装 |
| 长时间满载生产环境 | 不建议 | 毕竟底子是虚拟化,稳定性依赖 Windows 宿主 |
| 直接操作物理 GPU 硬编码 | 不适合 | 无法做完整 PCIe 设备透传 |
说白了,WSL2 最适合的定位是“开发环境”——你在上面写代码、调模型、做实验,跑通了再部署到真正的 Linux 服务器或云端。搞清楚这层定位,后面很多纠结自然就放下了:不需要神化它,也用不着因为一次虚拟化报错就全盘否定。
2. 安装前的硬件确认:BIOS 虚拟化、系统版本和内存余量
2.1 先确认硬件和系统版本,别等装一半才报错
我第一次装 WSL2 时,吭哧吭哧运行wsl --install,结果重启后直接告诉我“WSL2 无法启动,因为此计算机上未启用虚拟化”。当时一头雾水,后来才明白是主板 BIOS 里虚拟化开关没开。这类错误其实完全可以提前规避。
安装前先确认三件事:
- Windows 版本。Windows 10 21H2 以上或 Windows 11 都行,Windows 11 对 WSL2 的维护更积极,很多新特性都先给 Win11。打开“设置 -> 系统 -> 系统信息”即可查看版本号。
- CPU 虚拟化。Intel CPU 需要 VT-x,AMD CPU 需要 SVM。可以在任务管理器“性能”标签里查看“虚拟化”选项是否为“已启用”。
- 内存与磁盘。基础门槛 8GB 内存能跑起来,但 AI 开发建议 16GB 起步;磁盘至少留 20GB 给 Linux 发行版,还要考虑模型和数据集动不动几个 GB 的情况。
另外,如果机器上装了老版本的 VMware Workstation、VirtualBox 等虚拟机软件,它们和 Windows 的虚拟化平台可能冲突。不是不能用,但排查问题时要把这些变量考虑进去。
2.2 一条命令装完 Ubuntu:wsl --install与wsl --update
最省事的方式是用管理员身份打开 PowerShell,执行:
wsl --install -d Ubuntu-24.04这条命令会自动完成三件事:安装 WSL2 的核心组件、启用虚拟化平台功能、从在线商店拉取 Ubuntu 24.04 镜像。首次执行后通常提示重启,重启后再打开终端,会进入 Ubuntu 初始化流程,设置一个 Linux 用户名和密码。
我在实际环境里遇到过wsl --install只装了 WSL 而没有发行版的情况,这是因为早期版本命令行为不同。补救很简单:直接运行wsl --install -d Ubuntu-24.04指定发行版即可。
装完后第一步,建议先在 PowerShell 里执行:
wsl --update这一步把 WSL 内核和用户态组件更新到最新版本。很多莫名其妙的 Bug,比如镜像网络模式不可用、systemd 无法启动,都是因为 WSL 本身版本太旧。更新之后再看问题,往往就消失了。
2.3 两个高频报错:虚拟化未启用 与 “WSL2 尚未准备就绪”
这两个报错我身边同事几乎都遇到过,分开说。
第一个是开篇提到的“WSL2 无法启动,因为此计算机上未启用虚拟化”。处理方式:进入 BIOS(开机时按 Del 或 F2 键),找到SVM Mode(AMD)或Intel Virtualization Technology,设为 Enabled,保存重启。重启后如果还报错,去“启用或关闭 Windows 功能”里确认“虚拟机平台”和“适用于 Linux 的 Windows 子系统”两项都已勾选,必要时再重启一次。
第二个是“WSL2 尚未准备就绪”。这个报错通常是 WSL2 内核组件缺失导致的。Windows 功能里勾上了,但内核更新包没装,或 WSL 版本太旧。解决方式就是上面说的wsl --update,它会自动补上内核。如果更新命令失败,可以手动下载微软官方的 WSL 内核更新安装包,安装后再启动。整个链路排查思路是:BIOS 开关 -> Windows 可选功能 -> WSL 内核包 -> WSL 版本,按这个顺序来就不会乱。
2.4 下载慢和 C 盘空间焦虑:离线安装包与迁移 D 盘
“wsl2 下载慢”是个热门问题,其实原因是发行版镜像默认从微软商店或微软 CDN 拉取,网络高峰时期速度确实感人。我的处理方式分两种情况:
- 如果只是速度慢,可以稍等重试,或直接在 Microsoft Store 搜索 Ubuntu 24.04 手动安装。Store 会走自己的下载链路,有时候反而更快。
- 如果连 Store 都打不开,可以从 Ubuntu 官网下载 WSL 用的 rootfs 或 appx 格式离线包,然后在 PowerShell 里用
Add-AppxPackage安装。这个方式可控性最高,适合网络环境受限的机器。
更头疼的是 C 盘空间。WSL2 默认把虚拟磁盘放在 C 盘用户目录下,时间一长,加上模型文件,几百 GB 说满就满。想迁移到 D 盘,最稳妥的是wsl --export和wsl --import组合:
wsl --export Ubuntu-24.04 D:\backup\ubuntu-wsl.tar wsl --unregister Ubuntu-24.04 wsl --import Ubuntu-24.04 D:\WSL\Ubuntu-24.04 D:\backup\ubuntu-wsl.tar这里有个容易忽略的细节:--import导入后,默认登陆用户会变成 root,而不是你之前设置的普通用户。解决方式是在 WSL 内编辑/etc/wsl.conf:
[user] default=你的用户名改完执行wsl --shutdown重启 WSL,再进就是正常用户了。导入后的系统、软件包、Python 环境全部原样保留,不需要重装。
3. 初始配置:软件源、终端、文件互通与 systemd
3.1 换软件源,否则apt install速度会让你崩溃
Ubuntu 默认软件源指向国外服务器,在本地环境下apt update慢得让人以为网络坏了。装完系统第一件事,就是把 apt 源换成国内镜像源。
我习惯用清华镜像源,只改 Ubuntu 24.04 的主源,示例写法:
sudo sed -i 's/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list.d/ubuntu.sources sudo apt update不同版本的 Ubuntu 源文件位置略有差异,22.04 及更早版本通常是/etc/apt/sources.list,24.04 改成了/etc/apt/sources.list.d/ubuntu.sources。改完源再装任何软件都顺畅很多。这一步不涉及任何特殊网络手段,就是走国家法定可用的镜像服务。
3.2 Windows Terminal + SSH:让 WSL 用起来像个正经开发机
WSL2 默认用 Windows Terminal 承载,强烈建议直接装 Windows Terminal(如果 Windows 11 自带就更好了),然后把它默认配置文件设置为 WSL 发行版。这样做的好处是命令行体验完整,支持多标签页、主题、真彩色,还能直接阅读 Linux 路径下的文件。
我还会顺手配一个 SSH 服务,原因很简单:有时候 Windows 本机不方便操作,要远程连进来看训练进度。配置方式:
sudo apt install openssh-server sudo systemctl enable ssh sudo systemctl start ssh虽然 WSL2 的默认网络模式是 NAT,但本机回环访问 localhost 通常没问题,局域网远程访问需要进一步处理网络模式(后面专门说)。在 Windows 上直接用ssh 用户名@localhost就能连进 WSL,这个在日常调试里非常方便,不用来回开终端。
3.3/mnt/c的性能陷阱,与正确的路径规划
WSL2 里可以通过/mnt/c访问 Windows 的 C 盘,但这是通过 9P 协议实现的,性能比 WSL 内部的 Linux 文件系统差很多。尤其是大量小文件读写时,速度差距能达到数倍。很多人把 Python 环境、数据集放在C:\workspace,然后在 WSL 里通过/mnt/c/workspace跑训练,结果发现慢得离谱,还以为是 WSL2 的锅。
正确的路径规划是:
- 项目代码、虚拟环境、模型缓存全部放进 WSL 内部的 Linux 文件系统,比如
~/projects、~/.cache; - Windows 侧的 VS Code 通过
\\wsl$\Ubuntu-24.04\home\用户名\projects这个 UNC 路径直接访问,编辑体验和本地无所差别; - 数据文件、大模型权重,放在 Windows 侧做长期存储,但训练时先复制进 WSL 的文件系统再读,速度反而更快。
这个习惯我在无数次被/mnt/c拖慢后彻底养成了。记住一句话:能在 WSL 文件系统里放的东西,就不要放/mnt/c。
3.4 systemd 与.wslconfig:让 WSL 成为一台“完整”的实验机
WSL2 早期不支持 systemd,导致很多依赖 systemctl 的服务跑不起来。现在较新版本已经默认启用 systemd,如果你用的镜像比较保守,可以在/etc/wsl.conf里手动开启:
[boot] systemd=true开启后,Docker、SSH、vllm 这类服务都可以用systemctl管理,这算是 WSL2 向“完整 Linux 开发机”看齐的关键一步。如果你只是跑 Python 脚本,这一步可以跳过,但做 AI 服务开发和容器化部署时,systemd 几乎必备。
Windows 侧还有一个配置文件.wslconfig,放在用户主目录,例如C:\Users\你的用户名\.wslconfig,用于限制 WSL2 的资源占用。我最常用的配置:
[wsl2] memory=16GB processors=8 swap=8GB networkingMode=mirroredmemory控制 WSL 最多能用多少内存,processors限制核数,networkingMode=mirrored则是后面要重点讲的镜像网络模式,它能让局域网设备直接访问 WSL 里的服务。配置完执行wsl --shutdown重启 WSL 生效。
4. GPU 直通的落地实操:驱动分工、CUDA 与验证
4.1 先弄懂分工:Windows 装驱动,WSL 内部不装驱动
这是最容易搞反的一步。很多人在 WSL 里执行sudo apt install nvidia-driver-470之类命令,最后系统直接黑屏或启动失败,原因就是 WSL2 不需要、也不应该安装 Linux 侧的显卡驱动。因为 GPU 转发走的 Windows 驱动栈,Linux 内核只是把请求转发出去,真正的渲染和计算发生在 Windows 驱动层。
所以正确分工是:
- Windows 侧安装 NVIDIA Studio 驱动或 Game Ready 驱动,版本不要太老,最好保持最新;
- WSL2 内部只安装 CUDA Toolkit,不需要安装任何 NVIDIA 驱动包;
- WSL2 内核自带
/dev/dxg和 NVIDIA 相关内核模块,不需要手动加载。
这个概念想通之后,整个 GPU 配置就会非常顺畅。安装 CUDA 时不要再搜“Linux 驱动安装方式”,要去 NVIDIA 官方文档里找 WSL 专用的安装入口。
4.2 安装 CUDA Toolkit on WSL:官方仓库的完整命令
进入 WSL,执行以下命令安装 CUDA Toolkit 12.4,这是目前兼容性最稳的版本之一:
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 sudo apt-get -y install cuda-toolkit-12-4注意:这里的源是wsl-ubuntu,不是普通 Ubuntu 的linux源。如果你装成普通 Ubuntu 的 deb 源,会在 apt 里引入真正的 Linux 驱动项,容易造成混乱。为了稳妥,我需要说明:以上路径是 NVIDIA 官方提供的 WSL 专用源,适合在 WSL2 内部使用,大家从项目正文里也能看到,这是基于官方实践的标准做法。
安装完成后,把 CUDA 工具目录加入环境变量:
echo 'export PATH=/usr/local/cuda/bin:$PATH' >> ~/.bashrc echo 'export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc source ~/.bashrc我习惯同时加好PATH和LD_LIBRARY_PATH,否则后续编译torch扩展或调用nvcc时会找不到命令。这里的版本号可以按需调整,CUDA 11.8、12.1、12.6 都支持 WSL,但建议跟随 PyTorch 官方稳定组合来选择。
4.3 验证 GPU 真的在用:nvidia-smi与 PyTorch 探测
装完第一件事,执行:
nvidia-smi正常情况下会输出显卡型号、Windows 侧驱动版本、显存容量。此时你看到的驱动版本是 Windows 驱动映射出来的,并不是 WSL 里安装的,这再次印证了上面的机制。
接下来进入 Python 验证完整链路:
import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))如果输出True和显卡名称,说明 CUDA 栈彻底打通。再跑一个简单的矩阵乘法:
import torch a = torch.randn(4096, 4096, device="cuda") b = torch.randn(4096, 4096, device="cuda") c = a @ b print(c.shape)这个测试的意义不在于性能,而在于确认显存分配和计算调度都能正常工作。第一次跑通这个,基本可以宣告 GPU 直通环境就绪了。
4.4 双显卡、多 GPU 与显存释放细节
笔记本双显卡场景下,WSL2 会自动识别 NVIDIA 独显,不需要额外设置,但要注意 Windows 侧把 NVIDIA 设为 3D 首选 GPU,否则部分负载会落在集显上。
如果你有多个 NVIDIA GPU,同样可以使用CUDA_VISIBLE_DEVICES=0,1环境变量控制可见设备,这个在 WSL2 内和原生 Linux 完全一致。我常在大显存推理时只暴露一块卡:
CUDA_VISIBLE_DEVICES=0 python train.py显存不释放是另一个高频问题。WSL2 里跑崩了训练脚本,nvidia-smi看到的显存仍然被占用,很可能是残留的 Python 进程没死透。排查方式:
ps aux | grep python sudo kill -9 <pid>如果怎么都找不到进程,又确认显存占用异常,直接wsl --shutdown重启 WSL 环境最有效。这个操作会同时清理所有残留进程和显存状态,代价是要重新启动环境,所以适合在非训练时间做。
5. AI 开发环境:Python、PyTorch、工具链与路径约定
5.1 用 Miniconda 管理 Python 环境,省心省事
WSL2 里管理 Python 环境,我首推 Miniconda。系统自带 Python 是 3.12,但 AI 生态里很多老项目只兼容 3.8-3.10,靠 conda 建独立环境最不折腾。安装命令:
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh source ~/.bashrcConda 的默认源同样可以换成清华镜像,这一步能大幅提升创建环境的速度:
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --set show_channel_urls yes创建环境示例:
conda create -n py311 python=3.11 -y conda activate py311在py311环境内再做 PyTorch 安装,互不污染。我试过直接拿系统 Python 裸装 PyTorch,也能用,但一旦项目冲突出现环境依赖问题,处理成本远高于一开始就用 conda。
5.2 装 PyTorch 时最容易搞错的 CUDA 版本匹配
PyTorch 安装命令里cu121、cu124这类标签必须和上面安装的 CUDA Toolkit 版本对齐,否则会出现“驱动能识别但 PyTorch 不认”的诡异现象。以 CUDA 12.1 为例:
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121或者用 conda 方式:
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia我自己的经验是:先定 PyTorch 需要的 CUDA 版本,再回过去装对应 CUDA Toolkit。因为 PyTorch 每年发布频率固定,版本依赖关系更明确。如果你安装的 CUDA Toolkit 是 12.4,但 PyTorch 选了 cu121,多数情况下也能跑,因为 CUDA 库对旧版本保持兼容;但反过来如果 Toolkit 特别新、PyTorch 版本老,就可能出现运行时找不到符号的报错。
验证 PyTorch CUDA 状态的方法就是上面那一段torch.cuda.is_available()。补充一个小细节:如果 import torch 时提示libcuda.so找不到,检查LD_LIBRARY_PATH是否包含/usr/local/cuda/lib64。这个环境变量在 WSL2 的镜像网络模式下尤其重要,因为某些服务进程继承的环境可能不完整。
5.3 开发工具链:VS Code、PyCharm、Jupyter 的对接
日常编码我主要用 VS Code。装一个 Remote - WSL 扩展,然后通过code .在 WSL 目录中打开,体验上完全像是在 Linux 里开发:终端自动进入 WSL,调试器直接连到 Linux 进程,文件路径也是 Linux 路径。这比在 Windows 侧直接编辑/mnt/c文件要舒服得多,更重要的是调试时能直接看见 WSL 里 Python 解释器的包环境。
PyCharm 专业版和社区版同样支持远程解释器。在 PyCharm 中设置解释器时,选择 WSL 路径下的 Python,例如/home/ubuntu/miniconda3/envs/py311/bin/python,选择完就能像本地开发一样运行和调试。
Jupyter 用起来也很顺手:WSL 里执行jupyter notebook --port=8888,然后在 Windows 浏览器访问http://localhost:8888。WSL2 默认会把 localhost 端口转发到 Windows,这条链路基本是通着的。如果端口被占用或转发失效,重启一下 WSL 网络即可。
5.4 数据集、模型缓存和日志的路径约定
养成路径统一的好习惯,能帮你节省大量排错时间。我现在的约定是:
- 项目代码放
~/projects/<项目名>; - 数据集放
~/datasets/; - Hugging Face 模型缓存自动落在
~/.cache/huggingface/; - 训练日志放
~/logs/; - 虚拟环境全部由 conda 管理,不手动 pip install 到系统环境。
这样做的底层原因是:文件 IO 性能差异。上面说过/mnt/c慢,而 WSL 内部文件系统很快。把数据集放在~/datasets里,训练时的数据读取瓶颈就只在 CPU 和磁盘本身,而不是协议转发。对大规模数据加载,这么做甚至能肉眼可见地缩短每个 epoch 的时间。
另外,如果要把这些数据备份到 Windows 侧,直接通过资源管理器访问\\wsl$\Ubuntu-24.04\home\你的用户名\复制出来就行,不需要在 WSL 里把文件再挪到/mnt/c再做备份,少走一层中转。
6. 性能实测与避坑记录:和原生 Linux 到底差多少?
6.1 我实测过的性能:GPU 调用几乎无损,瓶颈在 IO 和网络
先说结论:GPU 密集型训练和推理任务,WSL2 和原生 Ubuntu 的性能差距非常小。我在同一台机器上分别用原生 Ubuntu 和 WSL2 跑了 ResNet50 的训练脚本,损失曲线基本重合,单轮 epoch 时间差距在 3%-8% 之间,主要来自数据加载和随机抖动,不是 GPU 算力本身。
原因也不难理解:模型的正向传播、反向传播、CUDA 内核启动,都在 Windows 驱动栈上执行,GPU 层面没有二次虚拟化。WSL2 的转发层只负责把 Linux 侧的请求桥接到驱动上,它不是把 CUDA 计算变成两条额外路径,所以计算密集型任务损耗有限。
真正需要留意的是 IO。小文件大量读写时,WSL 内部 ext4 和/mnt/c9P 协议的差距可以拉到 3-5 倍。所以,正确放置项目和数据,比调任何 WSL 参数都有效。
网络方面,默认 NAT 模式下 WSL2 访问外网没问题,但外部设备访问 WSL 里的服务就需要端口转发。Windows 11 22H2 以后可以在.wslconfig里开启networkingMode=mirrored,让 WSL 直接共享宿主机网络接口,局域网里的其他设备就能直接用 Windows 的 IP 访问训练服务了,局域网调试模型服务会方便很多。
6.2 WSL2 日常使用里最折磨人的五个坑
坑一:显存不释放。训练脚本崩溃或手动中断后,nvidia-smi看到显存依然被占。先找残留的 Python 进程,找不到就wsl --shutdown,别死磕。
坑二:内存回收慢。Windows 任务管理器里vmmem占用几十 GB,这是 WSL 文件页缓存的正常表现,不是内存泄漏。如果影响日常使用,调小.wslconfig里的memory值,或者定期重启 WSL。
坑三:Docker 无法启动。WSL2 里的 Docker 需要 systemd 或手动启动 Docker daemon。开启 systemd 之后执行sudo systemctl enable docker --now就能稳定运行。用 Docker Desktop 也可以,但资源占用明显更大。
坑四:休眠后 GPU 异常。笔记本合盖休眠再唤醒后,WSL 里nvidia-smi可能报错或卡住。这不是环境坏了,是 Windows 驱动重新初始化导致的。执行wsl --shutdown再启动基本都能恢复。
坑五:时钟漂移。虚拟机长时间运行后,WSL 内时间可能和实际时间漂移,影响训练日志的时间戳和 HTTPS 请求。可以临时用sudo ntpdate ntp.ubuntu.com校正,长期使用建议在 crontab 里定时同步。
6.3 VHD 磁盘只增不减:压缩、备份与迁移
WSL2 的虚拟磁盘文件(ext4.vhdx)会随使用不断增大,删除 WSL 内的大文件后,磁盘镜像不会自动缩小。这在长期做 AI 开发、频繁装大模型包后非常明显:WSL 内df -h显示一切正常,但 Windows C 盘空间却在悄悄减少。
压缩方式:先wsl --shutdown,然后在管理员 PowerShell 中对 vhdx 文件做 compact 操作:
diskpart select vdisk file="C:\Users\你的用户名\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu24.04LTS_...\LocalState\ext4.vhdx" attach vdisk readonly compact vdisk detach vdisk注意 vhdx 路径会因为发行版和安装方式不同而不同,在文件资源管理器里搜索 ext4.vhdx 即可定位。
备份方式更简单:wsl --export出一条 tar 把整个系统封装起来,这个 tar 可以放到移动硬盘或 D 盘归档。恢复时用wsl --import,并在/etc/wsl.conf里重设默认用户即可。这个组合方案同时解决了备份、迁移、重置三个问题,是我最推荐的做法。
结尾:我的体悟和建议
把这套环境从零搭到顺手,我花了大概一个周末,后面所有的训练和推理都转移了过来。如果只让我分享一条最重要的经验,那就是:WSL2 里跑 AI 开发,把项目和数据集都放进 Linux 文件系统,性能比你想象中快得多;遇见任何 GPU 相关怪问题,先wsl --shutdown再启动,能解决一半的烦恼。
另外,别纠结“GPU 直通到底是不是真直通”。只要nvidia-smi能显示显卡、PyTorch 能调用 CUDA、训练曲线和原生 Linux 一致,这套环境就是可用的。后面我打算在 WSL2 里继续折腾 AI Agent 开发,把 LangChain 和 vLLM 的部署流程也一并沉淀成环境配置,让这套开发机继续承担更多工作。