1. 项目概述与配置思路做深度学习这几年我在Windows和Linux双系统之间来回折腾过不少次每次想到要重启切换系统就头疼。直到换了WSL2-Ubuntu20.04这套方案才真正把“Windows日常办公”和“Linux深度学习”整合在了一起。配置CUDA、CUDNN、PyTorch这三件套听起来像是个老生常谈的流程但实际动手时牵扯到驱动架构、版本匹配、环境变量、动态链接库这些细节稍不留神就会在某个环节卡住半天。WSL2全称Windows Subsystem for Linux 2本质是一个跑在轻量虚拟机里的完整Linux内核不再是第一代那种翻译系统调用的兼容层。正因为跑的是真内核深度学习框架在WSL2里的兼容性非常好Pytorch、TensorFlow这些主流框架都能直接运行GPU计算通过透传机制直接调用Windows侧的NVIDIA显卡驱动。对新手来说最大的直观好处是不用给硬盘分区、不用装双系统、不用担心引导记录被搞坏在Windows里装一个Ubuntu镜像就能拥有几乎完整的Linux环境。这篇文章适合三类人阅读第一类是Windows主力机用户想在本地跑深度学习模型但不敢折腾原生Linux第二类是在校学生或研究人员实验室只有一台带NVIDIA显卡的Windows机器想快速搭建训练环境第三类是已经接触过Linux但没有在WSL环境里实际跑过GPU训练的老手想了解这套方案和原生Linux环境的差异。我会按实际动手顺序把整条链路讲清楚从WSL2基础环境准备、Ubuntu20.04初始化到CUDA Toolkit安装、CUDNN部署再到PyTorch安装和GPU验证最后附上我这几年来积累的常见问题排查手册。整个流程走下来大约一到两个小时你就能跑通一个调用GPU训练的小模型。1.1 为什么选择WSL2而不是双系统或纯Linux每个人选择WSL2的理由可能不太一样但核心痛点往往是同一个来回重启太浪费时间日常操作太麻烦。我之前给一台台式机装了纯Ubuntu系统结果发现自己在Windows上用的办公软件、即时通讯工具在Linux上要么体验打折要么干脆没有替代品。那段时间每天做实验要先重启进Linux训练跑完了再重启回Windows处理数据一天的碎片时间全耗在开关机上了。换到WSL2之后终端一开就是Linux命令行图形界面和桌面环境依然由Windows负责两边文件还能互相访问。这种体验很微妙——你坐在Windows桌面面前屏幕里却开着快乐的Ubuntu终端跑着Linux原生的训练脚本GPU计算丝毫不打折。另外还得说清楚一个性能方面的事实WSL2本身是个轻量级虚拟机虽然CPU计算性能接近原生Linux但跨系统文件IO确实有一定开销。后面我会讲到一个关键技巧——把数据集放到Linux侧目录而不是Windows盘里能从很大程度上抵消IO性能损失。1.2 整体环境版本规划配置深度学习环境最忌讳的就是“版本随手装出了错再改”。动手之前先明确目标版本后续每一步都以这个版本组合为基准排查问题时才有据可循。我在这篇教程里使用的组合如下组件版本方案Windows11或10 21H2以上WSL2内核版本5.10.102.1以上Ubuntu20.04 LTSNVIDIA驱动Windows侧525.x以上CUDA Toolkit11.7CUDNN8.6.0 for CUDA 11.xPython3.9PyTorch1.13.1支持CUDA 11.7这套组合的关键逻辑在于WSL2内部不需要单独安装NVIDIA驱动它复用Windows侧的显卡驱动因此Windows侧的驱动版本必须足够新能够支持CUDA 11.7向上兼容。CUDA Toolkit是开发库和编译工具CUDNN是深度学习的加速算子库PyTorch通过调用CUDA运行时和CUDNN来使用GPU算力。有人可能会问为什么不用更新的CUDA 12.x和最新的PyTorch 2.x当然可以但我这篇教程选择11.7的理由非常实际很多老项目、特定版本的CUDA扩展算子库在维护和兼容性上对11.x更友好。如果你是全新上手、没有历史包袱也可以顺着这篇文章的思路换成CUDA 12.x搭配PyTorch 2.x只需把下载链接和安装命令里的版本号替换就行。后面章节我会把版本可控性和匹配原则讲透。2. WSL2与Ubuntu20.04基础环境准备2.1 启用WSL2功能在安装Ubuntu之前先要让Windows系统具备运行WSL2的条件。这一步需要管理员权限。以管理员身份打开PowerShell执行两条命令dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart第一条命令启用Windows Subsystem for Linux功能第二条命令启用虚拟机平台。WSL2依赖虚拟化技术所以VirtualMachinePlatform必须开启。执行完后重启电脑让两项功能真正生效。重启之后再次打开PowerShell把WSL默认版本设置为2wsl --set-default-version 2如果提示需要更新内核按照提示去Windows更新里补装WSL2内核更新包。然后执行wsl --status出现“默认版本2”字样WSL2的环境基础就准备好了。这里有个不少人栽过的坑电脑BIOS里的虚拟化技术Intel VT-x或AMD SVM被关闭了WSL2会一直报找不到虚拟机平台。解决办法是重启进BIOS在CPU设置里把虚拟化开关打开。你要是用虚拟机软件跑过其他系统这个选项大概率已经开了但品牌机有时候默认是关闭的。2.2 安装Ubuntu20.04装Ubuntu20.04的方式比较简单可以直接从Microsoft Store搜索“Ubuntu 20.04”并安装也可以使用命令行wsl --install -d Ubuntu-20.04安装完成后从开始菜单打开Ubuntu终端第一次启动会进入初始化流程设置用户名和密码。这个用户名不需要跟Windows用户名一致自己起一个简单的就行例如developer密码也设一个容易记住的。这个账号就是Ubuntu里的普通用户执行sudo命令时会用到密码。进入Linux终端之后第一步我建议立刻更换软件源。Ubuntu默认的软件源服务器在国外更新和安装软件包时速度不稳定。换成国内源之后后续步骤会省下大量等待时间。执行sudo sed -i s//.*archive.ubuntu.com//mirrors.aliyun.comg /etc/apt/sources.list sudo apt update sudo apt upgrade -y需要注意的是上面的sed命令只替换了archive.ubuntu.com这一段如果sources.list里还存在security.ubuntu.com或ports.ubuntu.com这类地址遇到连接超时也要一并替换。有些教程会把整个源列表一起改掉我建议在改动前先备份sources.list文件万一换源过程出问题可以还原。2.3 基础系统配置系统更新完成后安装一组常用的基础工具包sudo apt install -y build-essential git curl wget vim net-toolsbuild-essential包含了gcc、g和make这套工具链是后续编译Python扩展包时绕不开的依赖。如果你打算在WSL里做C扩展开发或者编译Pytorch的自定义CUDA算子没有它很多步骤都会卡住。接下来配置Shell环境把一些常用的别名和路径提前写好。编辑~/.bashrc文件追加以下内容export PATH$HOME/miniconda3/bin:$PATH alias cdacd ~/workspace保存后执行source ~/.bashrc让配置生效。创建一个工作目录来存放后续的工程和数据集mkdir -p ~/workspace这一步不是必选项但建议养成习惯。因为前面已经提到跨文件系统IO在WSL2里有性能损耗把经常读写的文件放在Linux侧目录中能让训练时的数据加载速度更快。我经历过一次数据集放在Windows桌面导致训练速度只有正常一半的尴尬从那以后所有训练相关文件都默认放Linux侧。3. CUDA环境配置显卡驱动与Toolkit3.1 理解WSL2的GPU透传机制在WSL2里配CUDA最容易让人困惑的一点是“驱动到底装在哪边”。原生Linux环境需要安装独立的NVIDIA Linux驱动但WSL2内部不用安装显卡驱动它通过GPU透传技术直接复用Windows侧已经安装好的NVIDIA驱动。这意味着你要做的第一件事不是去NVIDIA官网下载Linux驱动而是确保Windows侧的NVIDIA驱动版本足够新。在Windows的PowerShell里执行nvidia-smi如果正常输出显卡信息比如显卡名称、驱动版本、显存大小说明Windows侧的驱动状态良好。然后进入WSL2 Ubuntu终端再执行一次nvidia-smi正常情况下应该输出同样的显卡信息只不过这个输出是由Linux侧的工具读取的。如果你的WSL2里执行nvidia-smi看不到任何GPU信息最常见原因就是Windows侧驱动版本过旧。从NVIDIA驱动510.x版本开始官方才加入了对WSL2的完整支持所以我建议至少使用525或更新版本的驱动。去NVIDIA官网下载对应型号的最新驱动在Windows里正常安装重启后再回到WSL2检查。还有一点要特别说明很多人第一次装CUDA时看到安装脚本里有“Driver”组件选项下意识就勾上了。在WSL2环境下千万不要勾选Driver因为安装Linux驱动进去反而可能跟Windows驱动产生冲突。只保留CUDA Toolkit和其余组件就好。3.2 CUDA Toolkit安装流程CUDA Toolkit是深度学习框架调用GPU计算能力的核心依赖里面包含CUDA编译器nvcc、运行时库和各类数学计算库。安装方式我推荐使用runfile安装包而不是deb包管理的方式。runfile操作起来更清晰能自己决定把Toolkit装到哪个目录后面切换CUDA版本也方便。以CUDA 11.7为例下载runfile安装包wget https://developer.download.nvidia.com/compute/cuda/11.7.0/local_installers/cuda_11.7.0-1_linux.run sudo sh cuda_11.7.0-1_linux.run运行后进入交互式安装界面有一个选项列表让你选择要安装的组件。这时候一定取消勾选Driver保留CUDA Toolkit、CUDA Runtime、CUDA Development Tools等选项。安装路径我选择默认最终会产生目录/usr/local/cuda-11.7。安装过程结束后检查目录是否生成ls /usr/local/除了看到cuda-11.7目录外通常还会有一个cuda软链接指向当前默认的CUDA版本目录。这个软链接在后续配置环境变量时很有用但如果你在机器上装了多个CUDA版本要注意软链接指向的是哪个版本别搞混。3.3 环境变量配置与验证CUDA Toolkit装完后还需要把相关的可执行程序和库路径加入系统环境变量否则命令行找不到nvcc运行时库也找不到。编辑~/.bashrc追加export PATH/usr/local/cuda-11.7/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda-11.7/lib64:$LD_LIBRARY_PATH export CUDA_HOME/usr/local/cuda-11.7保存后执行source ~/.bashrc然后验证编译器版本nvcc --version出现CUDA 11.7的版本信息说明CUDA Toolkit安装配置成功。此时做个简单测试通过nvcc编译一个小程序echo #include stdio.h int main() { printf(Hello CUDA\n); return 0; } hello.cu nvcc hello.cu -o hello ./hello看到“Hello CUDA”输出说明nvcc编译链路正常。我在实操中见过很多人在这一环节出现一个认知偏差nvcc显示的版本是11.7而nvidia-smi里驱动信息可能写着“CUDA Version: 12.0”看着不一致就以为装错了。其实这里的逻辑是驱动里的CUDA Version表示该驱动最高可以支持的CUDA版本是一个能力上限nvcc的版本才是你实际使用的开发工具版本。只要驱动版本不低于你使用的CUDA版本需求二者不一致完全正常。CUDNN是深度学习中卷积和循环神经网络算子加速的关键库它专门对卷积、池化、归一化这些高频操作做了底层优化。Pytorch在GPU模式下的推理和训练会自动调用CUDNN没有它虽然也能运行但卷积计算的速度差距能到好几倍。安装前先去NVIDIA官网的CUDNN下载页面选择与CUDA 11.x匹配的版本。我用的是8.6.0版本对应压缩包文件名类似cudnn-linux-x86_64-8.6.0.163_cuda11-archive.tar.xz下载完成后在Ubuntu终端解压tar -xvf cudnn-linux-x86_64-8.6.0.163_cuda11-archive.tar.xz解压后会得到一个目录里面包含include和lib两个子目录。接下来把CUDNN的头文件和动态库复制到CUDA安装目录中sudo cp cudnn-linux-x86_64-8.6.0.163_cuda11-archive/include/cudnn*.h /usr/local/cuda-11.7/include/ sudo cp cudnn-linux-x86_64-8.6.0.163_cuda11-archive/lib/libcudnn* /usr/local/cuda-11.7/lib64/ sudo chmod ar /usr/local/cuda-11.7/include/cudnn*.h /usr/local/cuda-11.7/lib64/libcudnn*复制之后运行ldconfig刷新动态链接库缓存sudo ldconfig第三行的chmod命令很多人会忽略但实际作用很重要。CUDNN的头文件和库文件复制过去后如果权限不够后面用其他用户或者某些虚拟环境跑训练时可能报权限错误提前补齐权限能避免很多麻烦。4.2 验证CUDNN安装验证CUDNN是否安装成功第一关是检查版本头文件cat /usr/local/cuda-11.7/include/cudnn_version.h | grep CUDNN_MAJOR -A 2输出应包含类似#define CUDNN_MAJOR 8 #define CUDNN_MINOR 6 #define CUDNN_PATCHLEVEL 0看到版本号不算完再写一个简单的调用程序做运行时验证。创建一个test_cudnn.cu文件#include cstdio #include cudnn.h int main() { cudnnHandle_t handle; cudnnStatus_t status cudnnCreate(handle); if (status CUDNN_STATUS_SUCCESS) { printf(CUDNN handle created successfully\n); cudnnDestroy(handle); } else { printf(CUDNN error: %s\n, cudnnGetErrorString(status)); } return 0; }用nvcc编译并运行nvcc -o test_cudnn test_cudnn.cu -lcudnn ./test_cudnn看到“CUDNN handle created successfully”说明CUDNN库文件能被正确找到并加载动态链接没有问题。这一步虽然多花了一分钟但能提前排查出库路径和符号链接的问题省得后面在Pytorch里报错时无从下手。如果编译或者运行时出现“cannot find -lcudnn”之类的错误多半是链接路径没设置好。检查LD_LIBRARY_PATH是否真的包含了/usr/local/cuda-11.7/lib64再检查libcudnn相关的so文件是否完整存在。4.3 CUDNN版本匹配的注意事项CUDNN版本匹配问题是深度学习环境里出错的常客。我在这里总结几个关键点。首先CUDNN的版本号要和CUDA主版本对齐。CUDNN 8.x的安装包会细分为“for CUDA 11.x”和“for CUDA 12.x”下载前要看清楚。把面向CUDA 12的CUDNN包装到CUDA 11.7环境里链接阶段很可能直接失败。其次Windows侧驱动、CUDA Toolkit、CUDNN三者之间是向上兼容的。驱动支持版本最高CUDA Toolkit次之CUDNN再次之只要上一层的支持范围覆盖下一层的需求基本都能跑通。我的经验是先把驱动更新到最新再选一个主流的CUDA版本最后找这个CUDA版本对应的CUDNN版本按照这个顺序选型基本不会翻车。最后如果你在同一个Linux环境里管理多个项目的依赖版本不要轻易覆盖系统目录里的CUDNN。更好的做法是让每个项目用独立的Python环境在不同的CUDNN版本之间切换时把LD_LIBRARY_PATH指到对应版本目录。这也是我建议用conda建环境的理由之一。5. PyTorch安装与GPU加速验证5.1 创建Python虚拟环境Pytorch环境最好不要直接装在系统Python里。因为深度学习的包依赖极多、版本变化快如果所有项目都堆在同一个全局环境很容易出现今天装A项目把B项目的依赖版本抬高了、明天又因为某个包降级而崩掉的恶性循环。用conda或者venv创建独立的虚拟环境是基本习惯。按前面章节的方式我们先把Miniconda装上。Miniconda是Anaconda的精简版只包含Python和conda管理工具正好够用wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh -b -p $HOME/miniconda3然后把conda初始化加到~/.bashrc里export PATH$HOME/miniconda3/bin:$PATH source $HOME/miniconda3/etc/profile.d/conda.sh重新加载配置后创建虚拟环境conda create -n dl python3.9 -y conda activate dl创建环境时Python版本我选了3.9这是目前深度学习社区兼容性最好的一个版本大多数预编译的Python包都有3.9对应的wheel文件。如果项目没有特殊要求3.9或3.10都行。5.2 安装PyTorchPytorch安装是整个流程里最需要注意源地址的一个环节。很多人直接用pip install torch结果装成CPU版本GPU检测永远是False。要装GPU版Pytorch必须指定PyTorch官方的CUDA版本wheel源。以CUDA 11.7对应Pytorch 1.13.1为例安装命令是pip install torch1.13.1 torchvision0.14.1 torchaudio0.13.1 --extra-index-url https://download.pytorch.org/whl/cu117如果网络条件不理想下载慢甚至中断可以用一个备选方案先通过其他镜像源安装依赖包但torch本体必须从官方源装。也可以考虑使用更快的下载工具比如配置aria2配合pip或者把安装包先下载到本地再pip安装。这里强烈建议先验证一下torch的版本信息再进入后续步骤python -c import torch; print(torch.__version__)输出应该是“1.13.1cu117”这样带cu117后缀的版本号。如果只显示“1.13.1”没有cu117说明装的是CPU版需要卸载重装。5.3 GPU可用性验证环境装好之后最关键的一步来了验证Pytorch能不能真的用上GPU。在终端里进入Python环境执行python import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))如果输出True以及你的显卡型号说明GPU环境已经全部打通。此时在任务管理器里切到“性能”标签页观察GPU使用率执行一个张量运算a torch.randn(3, 3).cuda() print(a)如果显卡使用率出现跳动说明张量确实被放到了GPU显存中Pytorch正在调用CUDA干活。我经常用这个简单例子来动态演示GPU加速的效果给第一次接触深度学习的朋友看import torch import time n 5000 cpu_tensor torch.randn(n, n) gpu_tensor cpu_tensor.cuda() start time.time() cpu_result torch.mm(cpu_tensor, cpu_tensor) print(CPU time:, round(time.time() - start, 3), s) start time.time() gpu_result torch.mm(gpu_tensor, gpu_tensor) print(GPU time:, round(time.time() - start, 3), s)在NVIDIA中端显卡上5000乘5000的矩阵乘法GPU比CPU快几十倍这个差距会随着计算规模增大越来越明显。跑完这段代码你能非常直观地理解GPU并行计算的意义。5.4 完整训练流程的最小验证只用矩阵乘法验证GPU能用还不够我更建议随便搭一个极小的神经网络走一遍完整的训练流程确认Pytorch的自动求导、数据加载、反向传播全部正常。用MINST数据集跑一个两层卷积网络做数字识别就是很好的测试项目。这类标准测试在Pytorch官方教程里有大量现成示例把网络结构改小一点几个epoch跑下来也就几分钟。如果这一步能顺利走通说明CUDA计算、CUDNN算子、Pytorch框架之间的整合完全没有问题。我在给新电脑配置环境时一定会跑一遍这种最小训练实验确认不是只把环境“装完”而是真正“用起来”。毕竟环境配置的最终目的不是让版本号显示正确而是能实打实地把模型训练跑起来。6. 常见问题与排查技巧实录6.1 GPU不可见排查三步法遇到torch.cuda.is_available()返回False我有一套固定的排查路径按顺序执行能定位大部分问题。第一步在WSL2终端执行nvidia-smi确认Linux侧能看到显卡信息。看不到的话要么是Windows驱动太旧要么是BIOS虚拟化没开回到前面第2章检查。第二步确认CUDNN验证程序能正常运行也就是前面第4章那个test_cudnn程序。如果CUDNN的链接和加载出现问题Pytorch导入时也可能连带出错。第三步检查Pytorch版本是否真的带CUDA支持。用print(torch.version)看有没有cu117这样的后缀确认是在官方cu117源安装的。这三个步骤走完大部分GPU不可见的问题都能定位到具体环节。还有一个容易忽略的点如果你同时装了多个Linux发行版或者多个WSL实例并且在不同实例里分别安装了一套CUDA环境要确认当前激活的实例是配置好的那一套。曾经有个同学折腾一上午没找出问题最后发现打开的是另一个Ubuntu实例。6.2 WSL2内存配置WSL2默认使用物理内存的50%到80%如果你是32G内存的机器默认配置相对够用但如果只有16G内存跑模型时Windows和WSL2之间的内存竞争会很激烈。解决办法是在Windows用户目录下创建.wslconfig文件内容如下[wsl2] memory12GB swap0 localhostForwardingtrue修改完成后在PowerShell执行wsl --shutdown然后重新打开Ubuntu终端使配置生效。内存设置不是越大越好Windows自身的桌面环境也需要内存我一般设置为物理内存的一半左右比如16G物理内存就设8G或10G。如果训练任务确实吃内存可以再往上调但别把Windows逼到内存告急否则两个系统互相拖慢体验极差。6.3 文件系统性能差异与路径设计WSL2的跨文件系统访问性能比原生Linux差这是由虚拟机架构决定的。具体表现是访问/mnt/c/目录下的Windows文件时IO延迟明显偏高大量小文件读写场景差别尤其明显。因此所有训练数据、模型权重、缓存文件都应放在Linux侧。我习惯的目录规划是~/workspace/data存放数据集~/workspace/models存放checkpoint~/workspace/scripts存放训练脚本如果确实需要把Windows侧的目录挂载给Linux使用可以采用WSL2的mount类型配置但性能问题依然存在。我的建议很直接在WSL2里老老实实用Linux侧路径把跨系统操作限制在小型文件的共享和编辑上。6.4 CUDNN算子报错另一种常见问题是在训练时遇到类似“cudnn error: CUDNN_STATUS_NOT_SUPPORTED”的报错。这通常不是环境安装错误而是模型里某些操作在当前CUDNN版本下不受支持或者输入数据的维度、格式触发了CUDNN的某种限制。遇到这类问题首先尝试在Pytorch里关闭CUDNN的自动调优torch.backends.cudnn.enabled False如果关闭后不再报错说明算子不兼容或者数据格式不对可以尝试调整数据维度或换一种CUDNN版本。如果关掉CUDNN后性能损失太大优先考虑换一个更新的CUDNN版本或者降级Pytorch版本以换取CUDNN算子的兼容性。这个问题的排查思路是CUDNN并非对所有操作都有优化实现有些特殊场景会回退到CUDA原生实现而回退机制在特定组合下可能失效。理解了这一点再面对CUDNN相关报错时就有了突破口。6.5 虚拟环境与全局环境的包冲突在深度学习环境配置过程中我强烈建议养成“每个项目一个虚拟环境”的习惯。虚拟环境之间相互隔离即使一个环境里的包依赖被改坏了也不会影响其他项目。如果遇到某个库安装后原本正常的项目报错先用pip check检查当前的依赖冲突情况pip check这个命令会列出当前环境中存在依赖冲突的包。如果确认是新装的某个库破坏了依赖关系可以考虑在虚拟环境里重装指定版本或者回到全局环境检查是不是环境变量配置导致库搜索路径错乱。在WSL2配置深度学习环境这条路上我踩过的坑、绕过的路比教程正文长得多。但有一个体会很明确只要把版本匹配的逻辑理解清楚环境配置并不是玄学而是一套有规律可循的工程流程。如果你在配置过程中遇到了教程里没有覆盖到的问题可以尝试回到“版本匹配”这条主线上去排查——90%的问题都出在驱动、CUDA、CUDNN、PyTorch四者版本对应关系上。7. 个人体会与扩展建议聊到最后说几句题外话。深度学习环境的搭建为什么不讨人喜欢因为它不像模型调参那样有看得见的损失曲线和精度提升而是枯燥的后勤工作。但恰恰是这套后勤工作决定了你后续所有实验的效率。一个配置正确、路径合理、版本清晰的训练环境能让你把宝贵时间花在真正的模型研究上而不是反复和“No module named...”搏斗。我个人现在比较推荐的扩展方向是在WSL2里配合Docker使用深度学习镜像。当你需要快速复现别人的论文代码或者给同学的项目环境做迁移时Docker镜像能极大简化依赖管理。等你把这篇教程里的基础环境跑通之后可以再试试在WSL2里配置Docker Desktop支持到那一层基本就没什么能难住你的环境问题了。
阅读完成 · 觉得有帮助?