前阵子帮团队把AI开发环境从双系统迁移到 WSL2,折腾了差不多一整天,踩了不少坑,也把 GPU 直通的原理彻底摸了一遍。说实话,当nvidia-smi在 Linux 终端里顺利跑出显卡信息的那一刻,确实有种“Windows 和 Linux 终于和解了”的感觉。这篇文章我不打算写成官方文档的复读机,而是把从零搭建 WSL2 AI 开发环境的完整思路、实操命令和排障记录一起整理出来。无论你是刚接触深度学习的入门玩家,还是被双系统切换折磨已久的开发者,只要想在 Windows 上跑 AI 训练、推理或容器化环境,这篇文章都值得你花十分钟读完。
1. 为什么选 WSL2 做 AI 开发环境
1.1 WSL2 的虚拟化架构与“内核级 Linux”含义
很多人一听到 WSL2 就以为它只是“Windows 里开个 Linux 窗口”,这种理解在 WSL1 时代勉强成立,到 WSL2 就完全不够用了。WSL2 的本质是一台轻量级虚拟机,它运行在 Windows 的 Hyper-V 虚拟化平台上,里面跑的是一颗真正的 Linux 内核,而不是像 WSL1 那样靠 API 翻译层模拟 Linux 系统调用。这就是标题里“内核级 Linux”的来源:你获得的是一个完整的、原生的 Linux 内核环境。
这个架构带来的直接好处是系统调用完全兼容,绝大多数 Linux 软件包、深度学习框架、甚至内核模块都能直接跑,不用再担心“这个工具在 WSL1 下会炸”。代价是虚拟机和宿主机之间隔了一层虚拟化边界,所以 WSL2 的 IO 性能、启动速度、跨文件系统访问效率都有自己的一套逻辑。如果你以前用过 Docker Desktop 的 WSL2 后端,就能明显感觉到:文件放在 Linux 文件系统里读写飞快,而放在/mnt/c/下的 Windows 磁盘里则慢得让人怀疑人生。所以在 WSL2 里做 AI 项目,我强烈建议把所有代码、数据集、虚拟环境全部放在 Linux 侧目录,Windows 盘只做中转。
我见过不少新手在 WSL2 里直接conda create -p /mnt/d/env,结果模型训练时数据读取卡成幻灯片。这个习惯一定要改,路径规划做不好,后面所有优化都是白搭。
1.2 GPU 直通到底直通了什么
所谓 GPU 直通,在云服务器领域通常指把物理显卡直接分配给虚拟机使用,绕过半虚拟化或软件模拟的开销。WSL2 的GPU 直通不是把整个显卡设备完整暴露给 Linux 内核,而是通过微软和 NVIDIA 合作实现的 GPU 分区与共享机制。简单说,Windows 侧安装的显卡驱动会作为宿主驱动,WSL2 里的 Linux 通过/dev/dxg设备访问 GPU 的计算能力,再配合 NVIDIA 提供的 WSL 版 CUDA 驱动库,把 CUDA 运行时封装成可以在 Linux 侧直接调用的形态。这个方案既保留了 Windows 图形界面的日常使用,又让 Linux 侧拥有了接近原生的 CUDA 计算能力,训练深度学习模型完全够用。
我实测下来的体感是:同样一个 PyTorch 训练脚本,WSL2 里的 FPS 和原生 Linux 双系统相比,差距通常在 5% 以内。对绝大多数 AI 开发场景来说,这点差异换来的便利性完全值得。如果你是做多卡训练的,WSL2 也支持多 GPU,只要 Windows 驱动能识别到,Linux 侧就能通过CUDA_VISIBLE_DEVICES正常分配。
2. 环境准备与安装流程
2.1 Windows 侧前置条件与功能启用
动手之前先把 Windows 版本确认好。WSL2 和 GPU 直通都需要较新的系统支持,我建议至少 Windows 11 22H2 以上,Windows 10 在 21H2 及以上也能凑合,但有些 WSLg 功能体验会差一点。开启 WSL2 需要 Intel/AMD 的 CPU 支持虚拟化,也就是 BIOS 里的 SVM 或 VT-x 选项,现在绝大多数主板默认开启,但如果后面启动 WSL 时报“虚拟化支持未启用”,记得进 BIOS 确认。
接下来以管理员身份打开 PowerShell,执行这组命令:
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart Restart-Computer这两条命令分别启用了“适用于 Linux 的 Windows 子系统”和“虚拟机平台”。重启之后还需要把 WSL 默认版本设置为 2,避免创建出老旧的 WSL1 实例:
wsl --set-default-version 2如果你之前装过 WSL1 的发行版,可以单独用wsl --set-version <发行版名> 2做版本转换。这一步只改配置不删数据,转换过程可能持续几分钟,中途别关机就好。
2.2 安装 WSL2 与 Ubuntu 22.04
现在 Windows 11 上安装 WSL 比以前简单太多了,一条命令搞定:
wsl --install -d Ubuntu-22.04这条命令会帮你把 WSL 核心组件、虚拟机平台、内核更新包、Ubuntu 镜像全部装好,省掉了以前手动下载安装包的繁琐流程。如果执行之后提示找不到发行版,可以先用wsl --list --online查看支持列表,然后把Ubuntu-22.04替换成列表中的对应名字。
第一次安装完 Ubuntu 会弹出终端让你创建 Linux 用户和密码,这个用户默认拥有 sudo 权限。创建时密码不会显示在屏幕上,盲打即可,输入完回车就行。有个小细节:这个 Linux 用户和 Windows 用户是两套独立的账号体系,后续在 Windows 侧打开的 VS Code、终端工具也要记得以这个 Linux 用户身份操作,否则文件权限会出现各种怪异问题。
安装完成后建议立刻升级一次系统软件包:
sudo apt update && sudo apt upgrade -y这一步能避免很多因为内核头文件和 CUDA 包版本不匹配导致的编译错误,尤其是后续要装 GPU 相关工具链时,系统源越新越省事。
2.3 把发行版装到非系统盘
C 盘空间紧张是很多人的痛,尤其 AI 环境里一个pip install torch就能吃掉好几个 G,再加上 CUDA 工具包、数据集、模型权重,C 盘分分钟告急。好在 WSL2 支持把整个发行版迁移到其他磁盘,操作不算复杂,唯一的坑是要先把发行版导出再导入。
假设你已经装好了名为Ubuntu-22.04的发行版,现把它迁移到 D 盘WSL目录,步骤是:先关闭正在运行的 WSL 实例,导出为 tar 文件,注销原发行版,再用--import导入到新位置。
wsl --shutdown wsl --export Ubuntu-22.04 D:\wsl\ubuntu2204.tar wsl --unregister Ubuntu-22.04 wsl --import Ubuntu-22.04 D:\WSL\Ubuntu-22.04 D:\wsl\ubuntu2204.tar --version 2注意--unregister会删除原有发行版的所有数据,所以千万别在没导出前执行。导入后的发行版默认使用 root 用户,你需要在导入完成后用wsl -d Ubuntu-22.04进入,然后手动把默认用户改回之前创建的用户:编辑/etc/wsl.conf,加上[user]和default=你的用户名两行配置,保存后用wsl --terminate Ubuntu-22.04重启实例即可生效。迁移完记得把 D 盘那个 tar 文件留着,后续出现环境损坏时还能快速恢复。
3. GPU 直通与 CUDA/AI 框架配置
3.1 安装 Windows GPU 驱动与 WSL 版 CUDA
现在进入整个部署的重头戏:让 WSL2 里的 Linux 真正用上显卡。首先要明确一个关键概念:WSL2 里不需要在 Linux 侧单独安装 NVIDIA 官方显卡驱动,驱动是安装在 Windows 侧的,Linux 侧只需要安装 CUDA 工具包和配套库。微软把这种模式叫“GPU 分区”,驱动由宿主机统一管理,Linux 通过/dev/dxg调用计算单元。
所以第一步,去 NVIDIA 官网下载对应你显卡型号的 Windows 驱动。有一个特别注意的地方:如果装了新版驱动后发现 WSL2 里看不到显卡,别急着重装系统,先确认驱动是否支持 WSL2。NVIDIA 从 470.x 版本开始全面支持 WSL2,现在官网新驱动基本都默认包含 vGPU 功能,安装时选“Game Ready”或“Studio”驱动都没问题,关键是版本别太老,建议在 525 以上。
驱动装好后,在 WSL2 终端里安装 CUDA。这里推荐用 NVIDIA 官方的 WSL-Ubuntu 软件源方式安装,比去官网手动下载 runfile 省心很多,而且后续apt upgrade能自动维护 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 update sudo apt install cuda-toolkit装完之后记得把 CUDA 的 bin 目录加到 PATH:
echo 'export PATH=/usr/local/cuda/bin:$PATH' >> ~/.bashrc echo 'export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc source ~/.bashrc这里有一点容易迷惑:cuda-toolkit是元包,会拉取当前 CUDA 大版本对应的所有组件,比如 12.x 系列。你不需要关心具体小版本号,因为 AI 框架的预编译轮子通常自带 CUDA 运行时,Linux 侧只需要有 nvcc 和驱动兼容层就够了。
提示:NVIDIA 在 WSL 上专门维护了
cuda-wsl-ubuntu软件源,这个源里的包和 Ubuntu 桌面版的 CUDA 源略有不同。如果你在apt search时看到一堆带-wsl后缀的包,不用怀疑,直接用就行。
3.2 验证 GPU 可用性:nvidia-smi
安装完成后,最激动人心的时刻就是输入nvidia-smi。如果一切正常,你会看到和原生 Linux 几乎一样的输出,显卡型号、驱动版本、CUDA 版本、显存占用全部正常显示。
我第一次配置时卡在最诡异的地方:nvidia-smi提示command not found,但明明装了 CUDA 工具包。后来发现是/usr/local/cuda/bin没进 PATH。如果你也遇到这个情况,先执行ls /usr/local/cuda确认目录存在,再检查.bashrc里的 export 是否生效。
还有一种更隐蔽的情况:nvidia-smi能跑,但显示No devices were found。这通常意味着 Windows 驱动自带的 WSL vGPU 组件没有正确加载。解决办法是去 Windows 的“设置 -> 应用 -> 已安装的应用”里找到 NVIDIA 驱动程序,点“修改”做一次修复安装;或者直接下载最新驱动执行自定义安装,勾选“执行清洁安装”。修复之后wsl --shutdown再重进 WSL2,基本就能识别了。
3.3 配置 Python 与 AI 框架
GPU 驱动层打通后,剩下的就是普通 Python 环境的活了。我个人推荐在 Linux 侧用 Miniconda,因为 AI 框架的依赖矩阵实在太复杂,conda 可以帮你隔离出干净的环境,避免和系统 Python 互相污染。
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh安装完 conda 之后创建一个新环境:
conda create -n ai python=3.10 -y conda activate ai pip install torch torchvision torchaudio这里有个值得展开的细节:PyTorch 默认的 pip 包带的是 CUDA 12.x 运行时,如果你在 WSL2 里只想快速跑起来,直接pip install torch就够了。要是你安装完成之后在 Python 里import torch报CUDA unavailable,用下面这段代码验证一下:
import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))如果torch.cuda.is_available()返回 False,先别急着卸载重装,检查 Linux 侧有没有装好 CUDA 基础库:
ls /usr/lib/wsl/lib/正常情况下你会看到libcuda.so、libcuda.so.1等文件。这些文件是 WSL2 里由 Windows 驱动映射进来的,如果缺失,说明 Windows 侧驱动太老或者 WSL 内核版本不支持,升级 Windows 驱动后重启即可。
TensorFlow 的安装也类似,区别在于 TensorFlow 2.x 需要额外关注 CUDA 版本兼容性。我的建议是无论 PyTorch 还是 TensorFlow,都直接用 pip 最新版,让 pip 自动拉取匹配的 CUDA 依赖,避免自己手动管理 CUDA 和 cuDNN 的版本对应关系,这样最省心。
3.4 WSLg:图形界面与本地可视化
AI 开发不只跑训练脚本,很多时候还需要看训练曲线、绘制图表、显示图片。WSL2 从 Windows 11 开始支持 WSLg,也就是在 Linux 侧运行图形界面程序时,窗口会直接显示到 Windows 桌面上,不需要额外安装 X Server。
我第一次在 WSL2 里跑 matplotlib 时,发现plt.show()能正常弹窗,确实惊喜了一下。这意味着你可以在 WSL2 里直接跑 TensorBoard:
tensorboard --logdir ./logs然后在 Windows 浏览器里访问http://localhost:6006,数据实时刷新,体验和原生 Linux 几乎没有区别。因为 WSL2 的网络层会自动把 Linux 侧的端口映射到宿主机,所以你不需要做任何端口转发配置。
如果你用的是 VS Code,强烈建议安装“WSL”扩展。装完之后在 VS Code 左下角打开远程列表,选择“Connect to WSL”,就能直接在 Windows 的 VS Code 界面里编辑 Linux 侧的文件、运行终端、调试 Python 代码。底层走的是真实的 Linux 进程,编辑器的语言服务、调试器、终端都和原生 Linux 一样,比 Windows 侧的 Python 环境干净得多。
4. 常见问题与排查技巧
4.1 WSL2 尚未准备就绪
“WSL2 尚未准备就绪”大概是全网出现频率最高的 WSL 报错了。这个问题通常出现在刚升级完 WSL 内核或系统更新之后,本质是 WSL 的核心服务没有正常初始化。我的排查顺序是:先打开 PowerShell 执行wsl --status看版本信息,如果显示“默认版本:2”并且内核版本正常,再执行wsl --shutdown然后重新进入。如果还不行,就去“启用或关闭 Windows 功能”里确认“虚拟机平台”和“适用于 Linux 的 Windows 子系统”两个选项是否都勾选,它们缺一不可。
还有种情况是 Windows 更新把 WSL 的内核文件弄坏了。解决办法是把 WSL 组件更新到最新版,在已安装的应用里搜索“Windows Subsystem for Linux”或“Windows Terminal”,如果你用的是新版 Store 版本 WSL,直接去 Microsoft Store 搜“Windows Subsystem for Linux”点更新;如果是旧版系统自带组件,就用 PowerShell 执行wsl --update强制拉取最新内核。更新完之后一定记得重启终端工具,因为 WSL 的环境变量在旧的容器里可能还是旧路径。
4.2 vGPU 驱动缺失或 nvidia-smi 报错
这类问题的症状前面提过:Linux 侧执行nvidia-smi显示驱动错误,或者torch.cuda.is_available()返回 False。除了清洁安装 Windows 驱动之外,我还会检查 WSL 版本是不是全新的。有些老版本 WSL 内核里没有包含 WSLg 和 GPU 分区模块,简单方法就是执行一次wsl --update把内核升级到最新。
另一个常被忽略的点是 Windows 和 Linux 侧的图形驱动冲突。如果你的电脑同时装有 NVIDIA Studio 驱动和某个优化工具注入的驱动,两者可能互相干扰。打开设备管理器,展开“显示适配器”,确认显卡设备没有黄色感叹号。如果有,右键卸载设备并勾选“删除此设备的驱动程序软件”,然后重装官方驱动。
最后,如果你是在公司电脑上操作,还要留意 IT 策略是否禁用了 Hyper-V 或虚拟化。这个不展开聊,但如果你其他步骤都对还是不行,可以跑一下systeminfo看“Hyper-V 要求”里最后一项“已启用虚拟机监控程序”是否为“是”。
4.3 apt 下载慢与源更换
WSL2 的 Ubuntu 默认源指向国外服务器,在大陆网络环境下apt update慢到让人想砸键盘。解决办法是换用国内镜像源,比如清华 TUNA 或阿里云开源镜像站。操作方式很简单:编辑/etc/apt/sources.list,把archive.ubuntu.com和security.ubuntu.com替换成镜像地址。
以 Ubuntu 22.04 为例,改源之后长这样:
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse配置文件里的地址其实是可以带http或https的,只要镜像站支持就行。改完执行sudo apt update,速度提升十几倍很正常。如果你的发行版已经用上了/etc/apt/sources.list.d/ubuntu.sources这种新格式,操作逻辑一样,把对应文件里的 URL 替换掉即可。
这里说个我自己的习惯:源文件改之前先用sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak备份一下,万一手滑改错还能快速还原。镜像源地址第一时间不要贪多,只留一个官方镜像和update用的源就够了,有些 DIY 源会引入奇怪的包依赖问题。
4.4 OOM 内存溢出与内存回收
WSL2 的默认内存上限是宿主机内存的 50%,这个配置在 AI 任务加载大模型时经常爆掉,尤其你一边跑训练一边开着 Chrome、微信、IDE 的情况下。解决办法是手动给 WSL2 设置内存上限,在 Windows 用户目录下创建.wslconfig文件,写入如下内容:
[wsl2] memory=12GB swap=8GB processors=6memory是 WSL 能使用的最大内存,swap是虚拟内存文件大小,processors是分配给 WSL 的 CPU 核数。我一般建议预留 Windows 本身 4 到 8GB 内存,比如电脑物理内存 32GB,给 WSL 设置memory=24GB。配置保存后执行wsl --shutdown,下次启动时生效。
还有一个容易忽略的点:WSL2 的内存回收机制和原生 Linux 不太一样,即使 Linux 侧任务结束,内存也未必马上归还给 Windows。如果你发现 Windows 越来越卡,偷偷跑一下wsl --shutdown是最粗暴有效的办法。只要你没有运行中的任务,这个操作完全安全,下次打开 WSL 终端会自动启动。
5. 实操中的性能优化与个人体会
5.1 文件系统布局与数据目录规划
我在前面反复强调过:WSL2 里访问 Windows 文件系统性能很差,根本原因是 9P 文件协议和跨虚拟化边界的开销。所以在 WSL 里做 AI 项目时,一定要把 Linux 侧的文件系统当成主战场。我的目录布局是这样设计的:~/projects放代码,~/data放数据集,~/model_zoo放预训练权重,所有内容都放在 Linux 文件系统,Windows 侧只保留安装包等一次性文件。
如果你实在有跨系统访问的需求,比如经常需要将 Windows 侧的数据集拷进 Linux,建议先把数据复制到 Linux 目录再操作,不要直接在脚本里读取/mnt/d/...。复制时的速度也会快很多,用cp -r或rsync都行。实测下来,从 Windows 盘复制 10GB 数据集到 WSL2 内部目录,大概需要两分钟,而训练时直接读 Windows 盘,同样数据量光数据加载就能多花近一倍时间。这个差距对大规模训练来说是致命的,无论如何都得避免。
5.2 内存与 Swap 调优的数值推荐
关于内存调优,我给出一个比较实用的参考表,方便你按自己的机器配:
| 物理内存 | 建议 WSL 内存上限 | 建议 Swap 上限 | 建议 CPU 核数 |
|---|---|---|---|
| 16GB | 8GB | 4GB | 4 |
| 32GB | 20GB | 8GB | 8 |
| 64GB | 48GB | 16GB | 16 |
如果你的训练任务经常在 CPU 上做数据预处理,processors可以适当调大;如果你主要靠 GPU 计算,processors留给 Windows 系统多点也无妨。Swap 放在 Windows 的虚拟内存文件里,实际上是磁盘 IO,千万别指望它加速训练,它只是防止 OOM killer 杀掉进程的保险。
还有个更激进但很实用的选项:在 Linux 侧用zram或者压缩 swap 来缓解内存压力。WSL2 的内核默认支持 zram,你可以在/etc/systemd或者启动脚本里加一行modprobe zram然后进行配置,但对大多数人来说,把.wslconfig里的 swap 调大已经足够解决 99% 的问题。
5.3 容器化环境:Docker Desktop 与 WSL2 的协同
AI 开发中 Docker 使用频率很高,而 Docker Desktop 本身就能跑在 WSL2 后端上。这意味着你可以直接在 WSL2 里安装 Docker 引擎,或者直接启用 Windows 侧的 Docker Desktop 并让它使用 WSL2 后端。我推荐后者,理由很简单:Docker Desktop 会帮你自动管理 WSL 实例,而且 Windows 侧的 Docker 命令行和 Linux 侧可以共享同一个 daemon,你不必在两边各维护一套 Docker 环境。
在 WSL2 Linux 里想直接用 docker 命令,只需要在 Docker Desktop 的设置里打开“Use the WSL 2 based engine”,然后在 WSL 发行版里执行docker ps就能连通。如果你更习惯纯 Linux 环境,也可以选择在 WSL2 里安装原生 Docker Engine,但要注意服务管理的差异,WSL2 默认不是用 systemd 启动所有服务的,需要你手动把 dockerd 拉起来或用wsl --exec方式后台运行。这个坑我踩过,所以建议新手直接用 Docker Desktop 接管,它会处理好所有细节,GPU 也能通过--gpus all参数直接透传给容器。
5.4 备份与迁移完整环境
AI 开发环境一旦配好,切不可大意。建议把整个 WSL2 发行版定期导出备份,尤其是你装了特定版本的 CUDA、配置好了 conda 环境、写好了.wslconfig之后,这一套东西重装起来非常耗时。备份操作前面已经提到过,用wsl --export导出 tar 文件,恢复到新机器就用wsl --import。如果只是迁移部分文件,也可以直接把 Linux 侧目录压缩打包到 Windows 盘存档。
我个人的习惯是每个季度导出一份干净的基础环境,命名带上日期,比如wsl2-ai-2025-03.tar,放在专门的大容量磁盘里。这个备份的好处是,一旦你实验性的操作把环境搞坏,比如conda env remove删错了、内核头文件升级失败,直接导出备份回来,五分钟就能回到可用状态。
如果你用的是 Git 管理代码,那么代码本身不需要备份,但 conda 环境、CUDA 工具链、系统级配置这些“不可复制”的内容一定要进备份。还有一点很关键:备份前先执行wsl --shutdown,否则正在写入的文件可能处于不一致状态,导出的 tar 会损坏。
6. 一些想单独说给你的经验
到这里,WSL2 部署 AI 开发环境的主流程基本讲完了。回顾这几天的操作,我最大的感受是:WSL2 其实已经不是一个“玩具”了,它是 Windows 平台上相当成熟的原生 Linux 环境。对 AI 开发者来说,它的价值在于让你同时拥有 Windows 的各种生产力软件和 Linux 的完整工具链,而且 GPU 计算能力几乎无损,这种体验在几年前是不可想象的。
如果你只是偶尔跑个小模型,WSL2 可能感觉和普通 Linux 虚拟机差不多;但如果你每天要在 Linux 和 Windows 之间来回切换,还要跑 CUDA、Docker、TensorBoard,这套方案能帮你省下大量时间。我在迁移之后,Windows 侧照常开着 Office、浏览器、通讯工具,Linux 侧跑着训练任务和 Jupyter,互不干扰,体验非常顺畅。
还有一个我后来才意识到的小技巧:如果你敲wsl进入默认系统时希望直接落到项目目录,可以在 Windows Terminal 的设置里把命令行改成wsl -d Ubuntu-22.04 --cd ~/projects,或者直接在.bashrc末尾加一行cd ~/projects。这样每次打开终端直接进入工作区,省掉反复cd的时间,对日常开发体感提升很明显。
最后再多说一句,WSL2 的 GPU 直通能力会随着 Windows 和 NVIDIA 驱动版本持续增强,如果你发现某些 AI 框架的新特性在 WSL2 里支持得不好,优先检查 Windows 驱动是否太旧。保持驱动和 WSL 内核的更新节奏,这个环境会越来越稳。希望我的这些踩坑记录能帮你少走弯路。