
1. 为什么要在WSL2里折腾双显卡先说说我自己的情况。手头一台工作站主板上插了两块卡一块是日常显示输出用的消费级显卡另一块是计算专用的Tesla V100。平时在Windows下跑训练任务环境配置起来各种依赖冲突Python版本、CUDA版本、cuDNN版本互相打架重装系统的心都有了。后来想着干脆把开发环境整体挪到WSL2里Windows只负责驱动和显示Linux子系统负责跑代码这样既保留了Windows的日常使用体验又能享受Linux下相对干净的开发环境。想法很美好实际操作起来踩了一路的坑。最典型的就是nvidia-smi在WSL2里报各种莫名其妙的错误一会儿说找不到驱动一会儿说无法与驱动通信一会儿又提示缺少libnvidia-ml.so。折腾了大半天才搞明白问题的根源在于Tesla卡默认工作在TCC模式下而WSL2的GPU直通机制对TCC模式的支持非常有限。这篇文章就是把我整个配置过程完整记录下来包括双显卡环境下如何让WSL2正确识别到计算卡、TCC模式到底带来了什么问题、怎么绕过这些限制。如果你手头也有类似的双卡配置或者正在被nvidia-smi的各种报错折磨这篇内容应该能帮你省下不少时间。需要提前说明的是本文讨论的是在Windows 10/11上通过WSL2使用NVIDIA计算卡的场景涉及的操作都在合法合规的范围内纯粹是开发环境配置的技术分享。2. 环境准备与前置检查2.1 硬件与系统版本确认在动手之前先把基础信息确认清楚。我这边的工作站配置是这样的CPUIntel Xeon 系列支持虚拟化主板支持Above 4G Decoding和Resizable BAR显卡1消费级显卡负责显示输出显卡2Tesla V100负责计算内存64GB系统Windows 11 专业版版本号22H2以上WSL2对Windows版本有硬性要求。Windows 10需要2004版本内部版本19041及以上Windows 11则全版本支持。你可以按Win R输入winver查看当前版本。如果版本太低先通过Windows Update升级这一步没法跳过。另外确认CPU虚拟化已经在BIOS里打开。任务管理器→性能→CPU右下角能看到“虚拟化已启用”就说明没问题。如果显示已禁用重启进BIOS找到Intel VT-x或AMD-V选项开启。2.2 WSL2的安装与初始化安装WSL2现在比以前简单太多了。以管理员身份打开PowerShell一条命令搞定wsl --install这条命令会自动启用所需的Windows功能、下载WSL2内核、安装默认的Ubuntu发行版。执行完之后重启电脑。如果你需要指定发行版比如Ubuntu 22.04可以这样操作wsl --install -d Ubuntu-22.04安装完成后系统会提示你设置Linux用户名和密码。这里有个小细节用户名不要用大写字母避免后续路径出现大小写问题。密码输入时屏幕不显示是正常的输完回车即可。装完之后用wsl -l -v确认一下版本NAME STATE VERSION * Ubuntu-22.04 Running 2VERSION列显示2就对了。如果显示1用wsl --set-version Ubuntu-22.04 2转换。2.3 Windows端NVIDIA驱动的安装这一步是整个配置的地基也是最容易出问题的地方。WSL2的GPU直通依赖Windows端的驱动Linux子系统里不需要单独安装显卡驱动。这一点和传统的双系统完全不同很多人习惯性地在WSL2里装一遍驱动结果反而把环境搞乱了。正确的做法是去NVIDIA官网下载Windows版本的驱动注意要选支持WSL2的版本。对于Tesla系列计算卡需要下载对应的Data Center驱动消费级显卡则下载Game Ready或Studio驱动。我这边因为有两块卡装的是Data Center驱动它同时覆盖了消费级和Tesla系列。安装驱动时选择“自定义安装”勾选“执行清洁安装”避免旧驱动残留导致冲突。装完重启。验证Windows端驱动是否正常打开设备管理器两块显卡都应该正常识别没有黄色感叹号。然后在PowerShell里执行nvidia-smi如果能看到两块卡的信息说明Windows端没问题。注意这里显示的可能是TCC模式先记下这个状态后面会详细说。提示如果你的Tesla卡在Windows下显示为“Microsoft基本显示适配器”说明驱动没装对需要重新下载对应型号的驱动。3. 核心问题Tesla卡的TCC模式到底卡在哪3.1 TCC与WDDM两种模式的区别Tesla系列计算卡有一个消费级显卡没有的特性可以在TCCTesla Compute Cluster和WDDMWindows Display Driver Model两种模式之间切换。TCC模式是专门为计算任务设计的。在这个模式下显卡不参与任何图形显示工作驱动层更精简计算任务的延迟更低多卡并行时的通信效率也更高。数据中心里的计算集群基本都跑在TCC模式下。WDDM模式则是Windows标准的显示驱动模型显卡可以正常输出画面也能跑计算任务但计算性能会有一定损失尤其是在多卡场景下。问题就出在这里WSL2的GPU直通机制是基于WDDM模式设计的。微软在实现WSL2的GPU虚拟化时走的是Windows的图形驱动栈而TCC模式下的Tesla卡根本不走这条路。结果就是当你的Tesla卡处于TCC模式时WSL2里执行nvidia-smi会直接报错提示无法与驱动通信。3.2 报错信息背后的真实原因我遇到过的报错主要有这几种第一种是nvidia-smi has failed because it couldnt communicate with the nvidia driver。这个报错最直接意思就是WSL2里的nvidia-smi找不到可以通信的驱动接口。根本原因就是Tesla卡在TCC模式下WSL2的虚拟化层看不到它。第二种是nvidia-smi couldnt find libnvidia-ml.so library in your system。这个报错看起来像是缺库但实际上库是存在的只是WSL2的驱动挂载机制没有正确工作。如果你在WSL2里手动装了一遍Linux版驱动反而会加剧这个问题因为WSL2不需要也不应该装Linux驱动。第三种是failed to initialize n开头的报错通常出现在你同时有多块卡、驱动版本不匹配的情况下。WSL2在初始化GPU时会尝试枚举所有可用的计算设备如果其中某一块卡的状态不对整个初始化过程就会失败。理解这些报错的本质很重要它们几乎都不是Linux子系统内部的问题而是Windows端驱动模式和WSL2虚拟化机制之间的兼容性问题。3.3 双显卡环境下的特殊复杂性单卡环境相对简单要么把Tesla卡切成WDDM模式要么直接用消费级卡跑计算。但双显卡环境下情况会复杂一些。我的配置是消费级卡负责显示输出Tesla V100负责计算。理想状态下消费级卡保持WDDM模式供Windows使用Tesla卡切成WDDM模式供WSL2使用。但实际操作中切换Tesla卡的模式会影响整个驱动栈的加载顺序有时候会导致消费级卡的显示输出出现闪烁或黑屏。另一个坑是驱动版本的一致性。两块卡共用同一套Windows驱动如果驱动版本对其中一块卡支持不好另一块卡也会受影响。我试过好几个版本的驱动最后锁定在一个相对稳定的版本上具体版本号后面会说。4. 实操让WSL2正确识别Tesla计算卡4.1 切换Tesla卡的工作模式关键操作来了。你需要用NVIDIA提供的命令行工具把Tesla卡从TCC模式切换到WDDM模式。这个工具叫nvidia-smi在Windows下也能用路径通常在C:\Program Files\NVIDIA Corporation\NVSMI\。以管理员身份打开PowerShell先查看当前模式nvidia-smi -q | Select-String Driver Model输出会显示每块卡的当前模式。找到Tesla卡对应的那一行如果显示TCC就需要切换。切换命令nvidia-smi -g 1 -dm 0这里的-g 1指定GPU编号-dm 0表示切换到WDDM模式0WDDM1TCC。GPU编号可以通过nvidia-smi -L查看确认你要切换的是Tesla卡而不是显示卡。执行完命令后系统会提示需要重启才能生效。重启之后再次检查Tesla卡应该已经变成WDDM模式了。注意切换模式会导致该卡上正在运行的所有任务中断操作前确保没有正在跑的训练任务。另外某些型号的Tesla卡在WDDM模式下性能损失比较明显如果你的主要工作场景是长时间训练需要权衡一下。4.2 WSL2内部的驱动挂载验证Windows端切换完成后进入WSL2验证。打开Ubuntu终端执行nvidia-smi如果一切正常你应该能看到类似这样的输出----------------------------------------------------------------------------- | NVIDIA-SMI 535.xx Driver Version: 535.xx CUDA Version: 12.2 | |--------------------------------------------------------------------------- | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | || | 0 Tesla V100-SXM2... On | 00000000:01:00.0 Off | 0 | | N/A 38C P0 30W / 300W | 0MiB / 32768MiB | 0% Default | ---------------------------------------------------------------------------注意看Disp.A这一列Tesla卡显示Off是正常的因为它不负责显示输出。关键是nvidia-smi能正常执行不报错。如果还是报错先检查WSL2里有没有残留的Linux版驱动。执行dpkg -l | grep nvidia如果有输出说明你之前装过Linux驱动需要卸载干净sudo apt purge nvidia-* sudo apt autoremove然后重启WSL2wsl --shutdown重新进入WSL2再试。4.3 CUDA工具链的安装nvidia-smi能跑通之后接下来装CUDA工具链。WSL2里装CUDA和原生Linux略有不同不需要装驱动只装工具包。去NVIDIA官网下载WSL2专用的CUDA Toolkit安装包。以CUDA 12.2为例wget https://developer.download.nvidia.com/compute/cuda/12.2.0/local_installers/cuda_12.2.0_535.54.03_linux.run sudo sh cuda_12.2.0_535.54.03_linux.run安装过程中会问你是否安装驱动一定要选No。WSL2不需要Linux驱动装了反而会出问题。装完之后配置环境变量编辑~/.bashrcexport PATH/usr/local/cuda-12.2/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda-12.2/lib64:$LD_LIBRARY_PATH执行source ~/.bashrc生效。然后验证nvcc --version能正常输出版本信息就说明CUDA装好了。4.4 双卡环境下的设备选择双显卡环境下WSL2默认可能会把两块卡都暴露出来。你可以通过CUDA_VISIBLE_DEVICES环境变量来控制程序使用哪块卡。查看WSL2里可见的GPUnvidia-smi -L输出会列出所有可见的GPU。假设Tesla V100是GPU 0消费级卡是GPU 1你想让训练脚本只用Tesla卡export CUDA_VISIBLE_DEVICES0或者在Python代码里指定import os os.environ[CUDA_VISIBLE_DEVICES] 0这样能避免程序误用消费级卡也能防止两块卡之间的显存拷贝带来的额外开销。5. 常见问题与排查技巧实录5.1 nvidia-smi报错速查表我把配置过程中遇到的各种报错和解决方法整理成了一张表方便对照排查报错信息根本原因解决方法couldnt communicate with the nvidia driverTesla卡处于TCC模式切换到WDDM模式后重启couldnt find libnvidia-ml.soWSL2里装了Linux版驱动卸载所有nvidia-*包重启WSL2failed to initialize n驱动版本不匹配或多卡状态不一致统一驱动版本检查每块卡的模式No devices were foundWindows端驱动未正确安装重装Windows端驱动清洁安装GPU is lostWSL2内核与驱动通信中断wsl --shutdown后重新进入5.2 驱动版本选择的经验NVIDIA的驱动版本更新很频繁但并不是越新越好。我在配置过程中试过好几个版本有些版本在双卡环境下会出现消费级卡显示闪烁的问题有些版本则会导致WSL2里只能看到一块卡。最后我锁定在535系列的一个稳定版本上。选择驱动版本时建议去NVIDIA官网查看该版本的发布说明重点关注是否修复了WSL2相关的已知问题。另外Data Center驱动通常比Game Ready驱动更稳定如果你的主要用途是计算优先选Data Center驱动。提示装完驱动后不要急着更新先用一段时间确认稳定。如果Windows自动更新推送了新的显卡驱动建议先暂停更新避免自动升级到有问题的版本。5.3 WSL2保活与资源占用WSL2有一个让人又爱又恨的特性它会在后台保持运行占用一定的内存和CPU资源。对于长时间跑训练任务的场景这其实是好事因为任务不会因为终端关闭而中断。但如果你只是偶尔用一下WSL2常驻后台会白白消耗资源。控制WSL2的资源占用可以创建或编辑C:\Users\你的用户名\.wslconfig文件[wsl2] memory32GB processors8 swap0这个配置限制了WSL2最多使用32GB内存和8个CPU核心。根据你机器的实际配置调整一般建议不超过物理内存的50%。如果想让WSL2在不用时自动释放资源可以设置[experimental] autoMemoryReclaimgradual这个特性在较新的WSL2版本中支持能让WSL2逐步回收未使用的内存。5.4 图形化界面的取舍WSL2支持图形化界面通过WSLg可以直接运行Linux的GUI程序。对于需要可视化调试的场景比如跑Isaac Sim这类仿真工具图形化界面很有用。但开启图形化界面会增加WSL2的资源开销而且在双显卡环境下GUI渲染可能会走消费级卡和计算任务争抢资源。我的建议是如果只是跑训练脚本不需要图形化界面保持纯命令行环境更轻量。确实需要GUI时再单独配置。配置图形化界面需要在Windows端安装VcXsrv或使用WSLg。WSLg在Windows 11上默认启用Windows 10需要手动配置。具体方法这里不展开核心思路是让Linux的GUI程序把画面渲染到Windows的窗口里。6. 实际使用中的几点体会配置完成到现在跑了大概两个月日常使用中又积累了一些经验一并分享出来。第一WSL2里的nvidia-smi显示的显存占用和Windows端的nvidia-smi有时候会对不上。这是因为WSL2的GPU虚拟化层有自己的显存管理机制两边的统计口径不完全一致。排查显存泄漏时以WSL2里的数据为准。第二长时间跑训练任务时建议在WSL2里用nohup或tmux把任务挂起来避免因为SSH断开或终端关闭导致任务中断。WSL2本身不会因为终端关闭而停止运行但任务进程可能会收到SIGHUP信号。第三如果训练过程中出现GPU is lost的报错大概率是WSL2内核和Windows驱动之间的通信断了。这时候nvidia-smi也会失效需要wsl --shutdown之后重新进入。如果频繁出现这个问题检查一下Windows端的驱动日志看是否有GPU重置的记录。第四双卡环境下做多卡训练时NCCL的通信走的是PCIe总线。如果两块卡的PCIe插槽带宽不一致通信效率会受影响。用nvidia-smi topo -m可以查看卡之间的拓扑关系确认通信路径。第五WSL2的磁盘IO性能相比原生Linux有一定损失尤其是大量小文件读写的场景。如果训练任务的数据集很大建议把数据放在Windows的NTFS分区上通过/mnt/路径访问或者考虑用内存盘加速。最后说一个容易被忽略的点WSL2的时钟同步。Windows和WSL2的时钟有时候会漂移导致训练日志的时间戳对不上。可以在WSL2里执行sudo hwclock -s手动同步或者配置systemd-timesyncd自动同步。整个配置过程走下来最深的感受是WSL2的GPU直通虽然方便但它的稳定性和原生Linux还是有差距。如果你的工作场景对稳定性要求极高比如需要连续跑几周的训练任务原生Linux仍然是更可靠的选择。WSL2更适合作为开发调试环境快速验证想法、跑通代码然后再迁移到正式的训练环境里。