如果你正在 Windows 上做 AI 开发,又不想为了训练模型去装双系统,那这套“WSL2 部署 AI 开发环境:内核级 Linux + GPU 直通”的做法应该能帮上忙。我前后在几台不同配置的机器上折腾过这套环境,也帮同事排查过各种奇怪问题,总的体验是:方案成熟度比大部分人想象的高,但坑也不少。这篇文章不打算写成官方文档的复述,而是把我实际用到的步骤、踩过的坑、以及为什么这么做的底层逻辑都摊开讲一遍。不管你是刚接触 AI 开发环境部署的新手,还是已经在用虚拟机和双系统想换个更顺手的方案,这篇文章应该都能给你一些可以直接抄作业的内容。
1. 先拆解法子:WSL2 到底解决了什么
1.1 为什么不是双系统,也不是传统虚拟机
很多人在 Windows 上做 AI 开发,第一反应是装双系统。这种方式确实是最“纯粹”的 Linux 体验,但代价也很现实:每次切换系统都要重启,开着训练实验想临时看一眼 Windows 文件,要么用 U 盘拷,要么再花几分钟重启回去。时间一长,人就会开始偷懒,实验管理也会变得稀碎。
传统虚拟机则是另一个方向。VMware 或 VirtualBox 这类方案在 CPU 和内存上能提供不错的隔离,但显卡计算一直是个老大难。特别是近几年的深度学习框架,对 GPU 直通的要求非常高,传统虚拟机要么不支持,要么配置过程极其痛苦。而且虚拟机的图形界面、磁盘占用、快照体积都比 WSL2 重不少。说到底,它们是给“需要完整虚拟机管理功能”的场景准备的,不是给个人开发机“顺便跑一下 Linux 环境”设计的。
WSL2 的定位就很明确:它在 Windows 内置的虚拟化平台上跑一个极轻量的虚拟机,里面是一个完整的 Linux 内核。所以你在 WSL2 里运行的是真正的 Linux 二进制,不是 Cygwin 那种模拟层,也不是 WSL1 那种翻译层。启动速度接近秒级,内存动态占用,还能通过文件路径直接访问 Windows 目录——这对日常做 AI 实验的人来说,几乎是最低摩擦的折中方案。
| 方案 | 切换成本 | GPU 利用率 | Windows 文件互访 | 适合场景 |
|---|---|---|---|---|
| 双系统 | 高,需要重启 | 裸机级 | 需单独挂载分区 | 长期纯 Linux 用户 |
| 传统虚拟机 | 中 | 配置复杂且依赖虚拟化支持 | 共享目录较绕 | 需要完整隔离环境 |
| WSL2 | 低,秒级启动 | 可直通 GPU | 原生路径互访 | Windows 为主力系统的 AI 开发 |
1.2 这套组合的核心逻辑
标题里的三个关键词其实是三层东西:
第一层是 WSL2,它提供了 Linux 内核运行环境。第二层是“内核级 Linux”,意味着你面对的是真实的系统调用、真实的内核模块,而不是模拟出来的 Linux API。第三层是 GPU 直通,也就是让 Linux 侧的程序能调用 Windows 上的物理显卡资源。
这三层拼在一起,效果是:你可以在 Windows 桌面上开着浏览器查文档,同时 WSL2 里跑着 Python 数据管线,训练任务把显卡占满。两边不互相卡顿,数据也可以通过文件系统互通。开发体验上接近“一台电脑同时跑两个系统”,但切换成本和磁盘占用远低于双系统。
需要强调一点:WSL2 的 GPU 直通并不是把整张显卡 PCI 设备塞给 Linux,而是通过一种半虚拟化机制共享显卡调度能力。Windows 那边的显卡驱动仍然负责真正的硬件交互,Linux 这边的用户态库把计算请求转发给 Windows 驱动,再由驱动调度到物理 GPU。对开发者来说,你只需要关心 Linux 侧能不能跑显卡计算工具,不需要关心底层 DMA 映射这些细节。
1.3 谁适合这套方案,谁不适合
适合的人很明确:主力电脑是 Windows 系统,同时又要做 AI 模型训练、数据处理、Linux 容器相关开发。尤其是公司电脑不能随便重装系统的人,WSL2 是在现有机器上获取 Linux 开发环境最合规也最轻量的路子。
不适合的人也有两类。一类是需要直接操作物理硬件的人,比如你要烧写固件、访问特殊 USB 设备、做内核调试配合串口透传,那 WSL2 的设备访问能力会限制你,老老实实用原生 Linux 更省心。另一类是对 Linux 图形桌面有刚需的人,虽然现代 WSL2 已经能跑图形应用,但体验和原生桌面还是有差距,日常办公、视频剪辑这类场景就别指望它替代原生 Linux 桌面了。
2. 部署前准备:把地基打稳再盖楼
2.1 先确认硬件和固件支持
在开始敲命令之前,先做两分钟检查。第一是确认 CPU 支持虚拟化。Intel 平台看 VT-x,AMD 平台看 SVM,这类功能近几年几乎都有,但有些品牌机的 BIOS 默认是关闭的。如果后面 WSL2 启动时报错,优先怀疑这里。
检查方式很简单:打开任务管理器,切到“性能”标签,看“虚拟化”那一行是“已启用”还是“已禁用”。如果是禁用,进 BIOS 找到对应的虚拟化开关,开启后重启。这一步别跳过,WSL2 依赖 Windows 虚拟化平台,没有硬件虚拟化支持,后面所有步骤都白搭。
2.2 开启 WSL2 需要的两个 Windows 功能
打开 PowerShell,以管理员身份运行下面两条命令:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform第一条是装 WSL 主体功能,第二条是装虚拟化后端。运行完按提示重启系统。
如果你的 Windows 版本够新,系统版本满足要求,其实可以直接用一条命令搞定:
wsl --install它会自动启用需要的功能,并安装默认的 Linux 发行版。不过我还是习惯手动分开执行,因为能清楚地看到每一步在哪里失败。遇到过不止一次,某台机器上“虚拟机平台”功能单独装不上去,报错原因还会指向 BIOS 里的虚拟化设置。
2.3 安装 Linux 发行版并切换到 WSL2 模式
Windows 应用商店里有多个发行版可用,我一般选常见的 Debian/Ubuntu 系,因为软件源好配、资料多。安装命令可以写成:
wsl --install -d <发行版名称>如果发行版已经装好,但你不确定它在用 WSL1 还是 WSL2,用下面的命令查:
wsl -l -v输出列表里的“版本”列如果是 1,就手动升级:
wsl --set-version <发行版名称> 2这一步很关键。WSL1 和 WSL2 的内核机制完全不同,GPU 直通必须依赖 WSL2。很多人装了发行版就急着用,结果跑显卡测试时说找不到设备,一查才发现系统还在 WSL1 模式。
内核更新也要顺手做一次:
wsl --updateWSL2 的内核是由 Windows 侧管理的独立内核镜像,更新机制和普通 Linux 发行版的内核升级不是一回事。后面自定义内核时你会更理解这个设计。
2.4 首次进入系统的三件收尾事
第一次启动发行版会让你创建用户名和密码。这里有一个容易被忽略的点:这个用户默认在 sudo 组里,但有些精简版镜像不带 sudo,需要先切到 root 用户安装:
apt update && apt install -y sudo创建普通用户后,第一件事是把系统软件更新到最新:
sudo apt update && sudo apt upgrade -y第二件事是安装一组基础工具,后面编译内核、拉代码、跑数据流程都用得上:
sudo apt install -y build-essential git curl cmake第三件事是确认 WSL2 的资源配置文件存在。Windows 用户目录下新建一个.wslconfig文件,内容大概这样:
[wsl2] memory=8GB processors=4 swap=2GB localhostForwarding=true这里的memory是 WSL2 能使用的最大内存,processors是最大 CPU 核数,swap是交换空间。如果你跑大模型训练,建议给 16GB 以上内存;如果只是做数据处理和入门学习,8GB 足够。配置完执行wsl --shutdown再重新进系统才会生效。
3. 内核级 Linux:从“能用”到“可调”
3.1 WSL2 的“真内核”到底真在哪
很多第一次用 WSL2 的人会有一个疑问:它到底是不是虚拟机?答案是“是,但不是传统意义上的虚拟机”。WSL2 跑在 Windows 内置的虚拟化平台上,但虚拟机的规格被裁剪得很轻,启动时只加载一个极简的 Linux 内核和用户态进程集合。你没有独立启动加载器,不涉及 GRUB,也不需要关心内核启动参数,Windows 侧或者/etc/wsl.conf帮你处理了大部分启动逻辑。
但它确实是真正的 Linux 内核。你在 WSL2 里执行uname -a,能看到内核版本号,能加载内核模块,能调用绝大多数 Linux 系统调用。这正是“内核级 Linux”的含义:它不是一个翻译层,不是兼容层,而是一颗实实在在的 Linux 内核在跑。
这个特性带来的直接好处是,很多原本只能跑在 Linux 服务器上的 AI 基础设施,比如容器运行时、GPU 调度工具、分布式训练库,在 WSL2 里都能照常工作。以前要在 Windows 上搞这些要么靠双系统要么靠远程服务器,现在本地就能处理。
3.2 自定义内核的完整流程
WSL2 默认内核对于绝大多数 AI 开发场景已经够用,但如果你想启用某些特殊内核功能、调试驱动、或者参与内核相关的开发,那自定义内核是绕不开的。这里给出一个实测可行的流程。
第一步,安装编译工具和依赖:
sudo apt install -y build-essential libncurses-dev flex bison bc libssl-dev第二步,下载与当前 WSL2 内核版本接近的内核源码。选择源码版本时不要盲选最新版,最好先执行uname -a看当前版本,然后找同系列的源码。
第三步,进入源码目录,配置编译选项:
make menuconfig这个命令会打开一个交互式配置界面,逻辑和普通 Linux 内核编译一样。只在需要的时候做修改,比如启用某个文件系统支持或者加入调试信息,不需要的模块全都保持默认。配置完保存退出。
第四步,编译:
make bzImage -j$(nproc)编译时间取决于机器核数,从几分钟到半小时不等。结束后在arch/x86/boot/目录下会生成bzImage文件。把这个文件复制到 Windows 能访问的路径,比如C:\wsl-kernel\bzImage。然后修改.wslconfig:
[wsl2] kernel=C:/wsl-kernel/bzImage保存后执行:
wsl --shutdown再启动进入系统,执行uname -a,看到的内核版本应该已经变了。这个流程最大的坑是路径写错,.wslconfig里的内核路径一旦不对,WSL2 会启动失败。所以第一次测试时,保持默认内核能正常启动,再去换自定义内核,出问题也能回退。
3.3 内核模块和设备观察
自定义内核之后,日常排查最常用的几个命令要心里有数:
uname -a:看内核版本。dmesg:看启动日志和内核级报错。lsmod:列出已加载的内核模块。cat /proc/cpuinfo、cat /proc/meminfo:看 CPU 和内存信息。
有一次同事说 WSL2 里的 GPU 工具突然消失,我让他先执行dmesg | tail -50,结果看到一段与显卡直通设备初始化相关的报错日志,顺藤摸瓜发现是 Windows 侧的系统更新把显卡驱动刷回旧版本,导致新旧接口不匹配。这种问题如果只看应用层会绕很久,内核日志能帮你直接定位到底层原因。
3.4 我的建议:别为了炫技乱动内核
自定义内核并不是 WSL2 部署 AI 开发环境的必经之路。默认内核已经包含了对 GPU 直通、容器运行时、常见文件系统的支持,绝大多数人根本不需要碰内核。我自己折腾过几次自定义内核,最后实际生产用的还是默认内核。
如果你真的要做内核实验,我强烈建议准备一个可以随时丢弃的 WSL2 环境,比如把发行版导出成备份,或者复制一份干净镜像。别在存有重要训练数据和环境的机器上反复编译内核,一旦配置出错,启动失败是小事,浪费在找配置上的时间才让人头疼。
4. GPU 直通:让训练任务真正跑起来
4.1 Windows 驱动与 Linux 库的正确分工
GPU 直通是这套环境里最容易误解的环节。请记住一个总原则:显卡驱动装在 Windows 上,Linux 侧不装完整驱动,只装显卡的用户态计算库。
为什么这样设计?因为 WSL2 的 GPU 直通是把 GPU 调度权保持在 Windows 驱动手里,Linux 侧的进程通过虚拟化接口把计算请求交过去。如果 Linux 侧再装一套内核驱动,反而会发生冲突。所以你在 Windows 里把显卡驱动更新到支持 WSL2 GPU 直通的版本,然后进 WSL2,直接安装显卡计算工具包和深度学习框架就行。
实际安装时,先到显卡官网下载对应型号的最新驱动。安装驱动的时候不要开着一堆 WSL2 进程,装完重启电脑,再进 WSL2 测试。
4.2 第一步:确认 GPU 被正确看到
进 WSL2 终端,执行:
nvidia-smi如果你看到了显卡型号、驱动版本和显存信息,说明 GPU 直通已经打通。没有信息也不要慌,可能是下面几种情况:
- 显卡驱动过旧,升级到支持 WSL2 的最新版。
- 执行过
wsl --shutdown没?重新启动一次。 - 发行版还在 WSL1 模式,确认执行了
wsl --set-version。 - Windows 系统更新没完成,先让系统更新完再测试。
除了nvidia-smi,还可以看看 GPU 虚拟化设备是否存在:
ls -l /dev/dxg这个设备文件是 WSL2 GPU 直通的核心通道,没有它说明底层虚拟化链路没建立起来。出现这种情况,优先排查 Windows 侧驱动和虚拟化设置。
4.3 第二步:搭建 AI 运行底座
确认 GPU 能被看到之后,就可以搭 AI 开发环境了。我习惯的做法是:先建一个 Python 虚拟环境,再把显卡计算库和深度学习框架装进去,避免把系统全局环境搞乱。
python -m venv ai-venv source ai-venv/bin/activate pip install --upgrade pip pip install 你的深度学习框架这里我不提具体框架名,因为你用的框架不同,安装命令会有差异。关键是装完之后,在框架里跑一个 GPU 可用性检测。不同框架的函数名不一样,但思路都是一样的:看看它能不能拿到 CUDA 设备,能拿到就是直通成功。
我通常会额外装一个支持矩阵计算的基础库,然后写一个十行左右的矩阵乘法脚本,让它跑在显卡上。这一步的意义在于,nvidia-smi只能证明显卡被系统看到,应用层能不能真正调用还要实际算一次才知道。
4.4 第三步:跑一次真实的训练流程
环境搭好之后,不要直接上大模型。先用一个小规模数据跑通全流程。比如找个轻量的图像分类测试数据集,写一个训练脚本,让它跑几十步就退出。重点关注几个指标:显存占用有没有变化、训练速度是否符合预期、系统会不会 OOM。
在实际操作中,我遇到过nvidia-smi显示显存为 0,但训练脚本一运行就报“显存不足”的情况。原因是 Windows 侧有别的进程占用了显存,WSL2 里的程序申请不到足够空间。这种问题不是环境没搭好,而是资源竞争。解决办法是把 Windows 侧无关进程关掉,或减小训练批次大小。
还有一点要注意:大体积数据集千万别放在/mnt/c/下面反复读。WSL2 访问 Windows 盘符下的文件要走一层文件系统转换,速度比访问 Linux 原生文件系统慢得多。正确做法是把数据集拷贝到 WSL2 自己的用户目录里,也就是/home/你的用户名/下面。这一步看着不起眼,但直接影响训练时的数据加载速度。
4.5 容器化使用 GPU 的场景
如果你的项目本来就是用容器交付的,那 WSL2 里也能顺滑使用。现在主流容器引擎一般都支持 WSL2 后端,也就是容器引擎还是装在 Windows 上,但实际容器进程运行在 WSL2 的轻量虚拟机里,性能损耗很小。
启动容器时,记得加上 GPU 参数。通用形式的命令是:
容器运行命令 --gpus all 你的镜像加了--gpus all之后,容器内的 AI 程序才能看到 GPU。我见过不少人把 WSL2 环境搭好了,直接跑容器镜像,忘了加 GPU 参数,结果容器内训练全部走 CPU,速度慢到怀疑人生。这个问题不是环境问题,纯粹是命令漏了参数。
容器化方案适合项目依赖复杂、需要多人协作复现的环境。它的好处是,你把整个 AI 开发环境封装成一个镜像,别人拉过去就能直接跑,不需要重复踩环境配置的坑。但如果你只是自己做实验,直接在该用 WSL2 里建虚拟环境也完全够用,没必要多套一层容器。
4.6 性能表现的合理预期
WSL2 的 GPU 性能虽然比不了双系统裸机,但差距没有想象中那么大。我实测下来,常规训练任务的吞吐量能达到裸机 Linux 的九成以上,数据加载如果放在 Linux 文件系统内,差距更小。
但要注意,小批量、频繁启动 GPU 任务的场景下,WSL2 会有额外延迟。因为每次任务都要经过 Linux 用户态库到 Windows 驱动的转发链路。如果你在跑那种几千步、每步很小的强化学习任务,可能会明显感觉比裸机慢。反过来,大规模矩阵运算、长时间训练,直通链路的开销会被摊薄,性能损失感知不强。
5. 常见问题与排查实录
5.1 发行版停留在 WSL1 模式
这个问题出现频率极高。症状是 WSL2 功能都开了,但nvidia-smi永远提示找不到设备。解决方法是先看版本:
wsl -l -v如果是 1,执行:
wsl --set-version <发行版名称> 2切换过程可能要等一两分钟,耐心等它跑完。切换完成后重新进入系统,再执行显卡检测。这一步是 GPU 直通的前置条件,没有 WSL2 内核,后面什么都白搭。
5.2 GPU 工具报错找不到设备
nvidia-smi报错的原因,按优先级检查下面几项:
- 显卡驱动是不是在 Windows 侧成功安装并配置了 WSL 支持。
- Windows 系统最近有没有自动更新,驱动版本是否被回退。
.wslconfig里有没有配置奇怪的内核路径导致启动异常。- 执行
wsl --shutdown后再启动。
我遇到过最诡异的一次:显卡工具在 WSL2 里时好时坏,后来发现是电脑接了两个显卡,Windows 桌面用的是集成显卡,WSL2 默认分配了集成显卡的虚拟化通道,独显却一直空闲。这种多显卡场景,需要在 Windows 显卡设置里把 AI 任务优先分配到独立显卡,然后再进 WSL2 测试。
5.3 内存和交换空间不够用
训练任务一跑起来,内存占用瞬间飙升。如果 WSL2 直接卡死或者进程被杀,优先检查.wslconfig里的内存限制。默认配置下 WSL2 最多能占到宿主机内存的一大半,但如果你在配置里手动限制得太小,大模型训练就会频繁触发 OOM。
这时候调整思路是:内存给训练留足,交换空间给一个兜底。但别指望交换空间能救大模型,数据量上去之后,交换空间只会让系统慢到没法看。在有限内存的机器上,最实际的方案是缩小批次大小或者换更小规模的模型。
5.4 跨盘符读写数据特别慢
在 WSL2 里操作/mnt/c/下的文件,特别是在上面跑数据读取,速度会比原生 Linux 文件系统慢不少。这不是偶然现象,而是跨文件系统边界的天然开销。解决办法很简单:所有频繁读写的数据都放到 WSL2 自己的文件系统,比如/home/用户名/data/。只有少数需要传递的资料才放在/mnt/c/下,拷进来之后就不要反复在两边倒腾。
5.5 localhost 访问异常
WSL2 默认会把 Linux 侧的监听端口转发到 Windows 的 localhost,所以你在 Windows 浏览器里访问http://localhost:8888,能直接打开 WSL2 里的开发服务页面。这个机制大多数时候是开箱即用的。
但如果你改动了.wslconfig里的localhostForwarding配置,或者服务监听的地址不是0.0.0.0而是127.0.0.1,就可能出现 Windows 侧访问不到的现象。排查时先在 WSL2 里确认服务进程确实在跑,再用curl localhost:端口自测一遍,最后检查 Windows 防火墙有没有拦截。防火墙是第一嫌疑,因为 WSL2 的端口转发机制在一些杀毒软件和防火墙策略下会被误伤。
5.6 启动即报错或卡死
如果wsl命令执行后直接报错,或者一直停在启动界面,优先级最高的排查方向是虚拟化支持。打开任务管理器看“虚拟化”是不是“已启用”。如果不是,重启进 BIOS 打开虚拟化开关。
另一种常见情况是.wslconfig里的配置写错,比如内核路径不存在、内存值超出物理内存范围。这类错误有时候不会给出特别明确的提示,而是表现为启动卡死。处理办法是把.wslconfig临时重命名,让 WSL2 用默认配置启动,如果能正常起来,再逐行排查配置。
6. 最后的实际体会
用 WSL2 做 AI 开发环境,我最大的感受是它把“Windows 主力 + Linux 开发”这两个需求调和得相当好。日常办公、开视频会议、看文档都在 Windows 侧,训练实验和数据管线在这些 WSL2 里跑,两边的切换成本几乎为零。这套方案不能说是万能的,但它解决了我大部分实际工作中的痛点。
如果你刚开始折腾,我的建议是:先把默认内核跑顺,把 GPU 直通验证通过,再考虑自定义内核和容器化的进阶玩法。不要一上来就追求最复杂的配置,AI 开发的核心目标是让你能快速迭代实验,而不是把时间耗在环境搭建上。最后提醒一句,所有环境相关的命令和配置,建议记在一个笔记文件里,踩过的坑也要随手写下来——这种积累比任何教程都值钱。