ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CUDA 11.3 + PyTorch GPU 环境搭建、验证与排错指南

CUDA 11.3 + PyTorch GPU 环境搭建、验证与排错指南 1. 环境选型为什么CUDA 11.3和PyTorch GPU搭配值得单独聊装深度学习环境这件事说难不难说简单也真不简单。我见过太多人在第一步就卡住显卡明明在手torch.cuda.is_available()却永远返回False。CUDA 11.3加PyTorch GPU这套组合在过去相当长一段时间里是大量项目的默认选择很多开源仓库的README里直接写着建议CUDA 11.3一些模型训练代码也只在这个版本上验证过。这就带来一个很现实的问题你不是想选它而是不得不选它。这篇文章面向的是准备在本地或服务器上搭建PyTorch GPU环境的人不管你是刚拿到一张新显卡的新手还是需要复现某个特定项目的开发者都能从这套流程里找到能直接用的步骤和避坑点。我会把驱动、CUDA Toolkit、cuDNN、PyTorch四者之间的关系讲清楚因为大部分人装不对根源不在于命令敲错而在于没搞明白这几个东西谁依赖谁、谁决定谁。内容会覆盖版本对应关系、驱动检查与升级、CUDA 11.3的安装方式选择、conda环境隔离、PyTorch安装命令的推导、GPU是否真正生效的验证方法以及我实际踩过的那些坑。整个过程以LinuxUbuntu为主因为绝大多数训练服务器跑的是这个系统Windows的差异我也会在关键处标注出来。读完之后你应该能做到拿到一台机器从零把环境搭到能跑通一个GPU张量运算并且知道每一步为什么这么做。2. 先把版本关系捋顺驱动、CUDA、cuDNN、PyTorch到底谁管谁2.1 四层依赖的真实结构很多人一上来就急着敲安装命令结果装完发现版本对不上又全部卸载重来。我建议你先花五分钟理解这套依赖链因为它决定了你后面每一步的选择。从底层往上看显卡驱动是最底层的它由显卡厂商提供决定了你的机器最高能支持到哪个CUDA版本。这里有个关键概念叫驱动版本对应的最高CUDA运行时版本。比如某个驱动版本可能最高支持CUDA 11.7那么你装CUDA 11.3是完全没问题的向下兼容。但反过来如果驱动太老只支持到CUDA 10.2那你硬装CUDA 11.3就会在初始化时报错。CUDA Toolkit是建立在驱动之上的一层它提供了编译器nvcc、各种数学库和运行时。PyTorch在编译时是链接到某个特定CUDA版本的这就是为什么PyTorch官网的安装命令里会带cu113、cu118这样的后缀。cuDNN则是专门为深度学习优化的库PyTorch的卷积等操作会调用它它必须和CUDA版本匹配。用一个生活化的类比驱动像是你家小区的供电容量CUDA像是你买的电器标称功率cuDNN是这个电器里的一个专用模块PyTorch则是整套家电系统。供电容量必须大于等于电器功率否则一开就跳闸。2.2 版本对应关系表与查询方式下面这张表是我整理的关键对应关系以CUDA 11.3为中心组件推荐版本说明显卡驱动 465.19.01 (Linux)支持CUDA 11.3的最低驱动CUDA Toolkit11.3本文核心cuDNN8.2.x for CUDA 11.3必须对应11.3编译PyTorch1.10.x / 1.11.x cu113官方提供cu113轮子Python3.8 - 3.9兼容性最好查询驱动支持的最高CUDA版本用这条命令最直接nvidia-smi输出右上角会显示CUDA Version: 11.x注意这个数字是驱动支持的最高版本不是你已经安装的CUDA版本。这个区别坑过无数人很多人以为这里显示11.3就代表CUDA装好了其实只是驱动能力上限。想看你实际安装的CUDA版本要查编译器nvcc -V如果这条命令报command not found说明CUDA Toolkit没装或者环境变量没配好这又是另一个常见分叉。2.3 为什么大家不直接装最新版新手常问既然有新版本为什么还抱着11.3不放原因很实际。一是很多论文代码和开源项目在那个时间点开发依赖的PyTorch版本只提供到cu113二是某些服务器集群的驱动是统一维护的管理员不会为你单独升级三是新版本CUDA在某些老显卡上反而会有兼容性问题。所以选11.3很多时候不是技术最优而是生态最稳。提示如果你手上是完全自由的新机器没有历史项目约束其实可以直接上更新的CUDA版本配合新版PyTorch。但如果你要复现的项目明确写了11.3那就老老实实按它的来别自作聪明。到这里你应该明白了安装这件事的核心不是装最新的而是装对得上号的。接下来的所有操作都是围绕这个匹配关系展开。3. 安装前的体检确认驱动和系统环境3.1 显卡识别与驱动状态检查动手之前先做体检这一步能帮你省掉后面大量的返工。先确认系统认不认你的显卡lspci | grep -i nvidia正常的话会列出你的显卡型号。如果这条命令什么都没输出先别急着装环境检查显卡是否插好、是否被系统识别。接着看驱动nvidia-smi这条命令返回的信息量很大我通常重点看三块。第一是驱动版本在表格左上角第二是驱动支持的CUDA上限在右上角第三是下方进程列表能看出有没有别的程序正在占着显存。如果这条命令直接报错说找不到命令说明驱动根本没装或者装崩了。这种情况下的正确顺序是先装驱动再装CUDA顺序反了会出各种玄学问题。注意不要在没装驱动的情况下先装CUDA Toolkit虽然技术上可行但会导致你在验证阶段各种碰壁。驱动是一切的基础。另外提醒一个细节如果你用的是云服务器或者别人维护的机器nvidia-smi能跑通但版本很老别急着升级驱动。先问清楚这台机器还有没有别人在用、升级会不会影响他们的任务。升级驱动是全局性的可能让别人的训练进程中断。3.2 驱动升级的正确做法与风险如果确认驱动版本太低需要升级。Ubuntu下我推荐用系统仓库的方式比官网runfile稳sudo ubuntu-drivers devices这条命令会列出可用的驱动版本选一个推荐的sudo apt install nvidia-driver-470装完必须重启不重启驱动不生效。重启后再跑nvidia-smi确认。我在这里踩过一个很典型的坑在没有彻底卸载旧驱动的情况下直接装新驱动结果系统进不了图形界面。后来才明白runfile安装和apt安装混用是重灾区。如果你之前是用官网runfile装的先用它自带的卸载参数清干净再用apt装。两种方式别混着来。还有个情况是服务器没有图形界面装驱动时不需要装OpenGL相关的组件可以加--no-opengl-files选项避免一些依赖冲突。这个细节在纯计算服务器上很实用。3.3 系统层面的几个检查点除了显卡和驱动还有几件事要在装之前确认。第一是gcc版本。CUDA 11.3对gcc有版本要求太高或太低都可能编译失败。查一下gcc --versionUbuntu 20.04默认的gcc 9通常没问题如果系统默认是gcc 11及以上可能需要装一个gcc 9并切换。第二是内核头文件。如果你要用.run方式安装CUDA并选择编译内核模块需要linux-headers装好对应的头文件能避免安装中途报错。第三是磁盘空间CUDA Toolkit装下来好几个G别到装到一半发现空间不够。这几个检查点看着琐碎但每一个都对应着一种常见的安装失败场景。4. CUDA 11.3安装实操方式选择与逐步落地4.1 三种安装方式的取舍CUDA 11.3在Ubuntu上有几种安装方式我用下来各有适用场景。第一种是deb本地包下载一个几G的deb文件用dpkg安装。这种方式的好处是依赖管理交给系统包管理器卸载也干净适合有root权限的个人机器。缺点是包比较大下载慢。第二种是deb网络包先装一个仓库配置包再用apt从网络上拉。适合网络条件好的环境能自动处理依赖。第三种是runfile一个.run可执行文件交互式安装可以自定义安装哪些组件、装到哪个路径。适合没有root权限、或者需要装多个CUDA版本共存的场景。缺点是卸载不那么自动容易残留。我的建议是个人机器、有root权限、只要一个CUDA版本用deb本地包最省心服务器上要装多个版本共存用runfile装到自定义路径。下面以runfile为例走一遍因为它最能体现安装过程的细节。4.2 runfile安装的详细步骤先下载对应的runfile注意选11.3的版本下载地址在官方归档页里能找到文件名类似wget https://developer.download.nvidia.com/compute/cuda/11.3.0/local_installers/cuda_11.3.0_465.19.01_linux.run下载完先给执行权限再运行chmod x cuda_11.3.0_465.19.01_linux.run sudo sh cuda_11.3.0_465.19.01_linux.run接下来是关键的交互环节。安装程序会先检测系统然后弹出一个组件选择界面。这里有个大坑它会默认勾选安装驱动。如果你已经装好了驱动一定要把Driver那一项的勾去掉否则它会尝试再装一遍驱动覆盖掉你现有的极大概率导致图形界面起不来。[x] Driver [ ] CUDA Toolkit 11.3 [ ] CUDA Samples 11.3 [ ] CUDA Demo Suite 11.3正确的是只勾选CUDA ToolkitSamples可选建议勾上方便验证把Driver去掉。然后继续安装程序会问安装路径默认是/usr/local/cuda-11.3保持默认即可。如果你没有root权限可以改到自己的home目录下。安装过程中如果提示install NVIDIA Accelerated Graphics Driver一定要选No。这一步选错了前面所有的谨慎都白费。4.3 环境变量配置与验证装完之后CUDA不会自动加到PATH里需要手动配置。编辑用户目录下的环境文件vim ~/.bashrc在末尾加上export PATH/usr/local/cuda-11.3/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda-11.3/lib64:$LD_LIBRARY_PATH保存后使其生效source ~/.bashrc然后验证编译器nvcc -V看到release 11.3就说明装好了。再验证一下运行时库是否被正确找到ldconfig -p | grep cuda提示如果你机器上有多个CUDA版本/usr/local/cuda这个软链接指向哪个版本很关键。可以用ls -l /usr/local/cuda看一下需要切换时用ln -sfn重新指向你想要的版本。到这里CUDA 11.3本身就算落地了。但我还要强调一件事CUDA Toolkit装好了不代表PyTorch就能用GPU因为PyTorch用的是它自己打包的CUDA运行时。这两者的关系在下一节会讲清楚。5. PyTorch-GPU安装虚拟环境与命令推导5.1 用conda建一个干净的环境我强烈建议不要在base环境里装PyTorch原因有两个。一是不同项目的PyTorch版本需求可能冲突base环境只有一个混着装迟早出问题。二是conda环境可以整体导出和删除出错了直接删掉重建代价很小。创建一个指定Python版本的虚拟环境conda create -n torch113 python3.9 conda activate torch113Python选3.9是因为它在PyTorch 1.10/1.11时代兼容性最好既有较新的语言特性又不会因为太新导致某些包没有对应轮子。5.2 安装命令是怎么推导出来的打开PyTorch官网的安装页面你会看到一堆选项。关键是选对三个PyTorch版本、CUDA版本、安装方式。对于CUDA 11.3命令类似pip install torch1.10.1 torchvision0.11.2 torchaudio0.10.1 --extra-index-url https://download.pytorch.org/whl/cu113这里每个部分都有讲究。torch1.10.1是主包torchvision和torchaudio的版本必须和torch严格对应混版本会报奇怪的错。cu113后缀告诉pip去下载为CUDA 11.3编译的轮子。最后的--extra-index-url指向PyTorch自己的轮子仓库因为PyPI上的默认版本往往是CPU版。很多人装完发现是CPU版就是因为没加这个index或者选错了后缀。等你装完跑torch.version.cuda如果显示的是11.3说明装对了。注意conda安装方式conda install pytorch cudatoolkit11.3 -c pytorch和pip方式有个重要区别。conda的cudatoolkit是打包在conda环境里的运行时它不需要你系统里装了完整的CUDA Toolkit理论上更省事。但很多自定义CUDA扩展比如某些需要nvcc编译的库在conda方式下会找不到编译器。我的经验是纯用官方PyTorch就用conda需要自己编译扩展就用pip配合系统CUDA。5.3 网络慢的应对方案下载轮子动辄几百M甚至上G网络不好会很痛苦。几个实用做法换用国内镜像源比如清华源对PyTorch的wheel有同步或者用下载工具先下好whl文件再本地安装pip install torch-1.10.1cu113-cp39-cp39-linux_x86_64.whl本地安装的好处是断了还能续而且可以放到多台机器上复用。我一般在给一批服务器部署时会先在某台机器上把whl下好再分发到其他机器省去重复下载的时间。5.4 验证GPU是否真正生效装完之后别急着跑训练先做最小验证import torch print(torch.__version__) print(torch.version.cuda) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))这四行分别输出PyTorch版本、编译用的CUDA版本、GPU是否可用、显卡型号。如果is_available()返回True并且get_device_name能打印出你的显卡那恭喜你环境是通的。再进一步做个实际的张量运算确保不是假可用x torch.randn(1000, 1000).cuda() y torch.randn(1000, 1000).cuda() z x y print(z.mean().item())这段代码把两个大矩阵放到GPU上做乘法如果顺利输出一个数值说明GPU计算链路完全正常。如果这里报错多半是显存不够或者CUDA运行时有问题下一节会专门讲排查。6. 常见问题排查实录那些让人抓狂的报错6.1 典型报错速查表我把这些年遇到的高频问题整理成一张表方便你对照排查。报错现象可能原因解决思路torch.cuda.is_available()为FalsePyTorch装成CPU版检查安装命令的cu113后缀CUDA driver version is insufficient驱动版本过低升级驱动到支持11.3以上libcudart.so.11.0 not found环境变量没配或版本不符检查LD_LIBRARY_PATH指向nvcc: command not foundCUDA Toolkit未装或PATH没配配置PATH并source安装PyTorch时编译报错gcc版本不兼容切换到gcc 9显存瞬间占满但利用率低有残留进程占用检查nvidia-smi进程列表6.2 显存被占用却找不到进程这个情况特别常见也特别气人。你刚准备跑训练nvidia-smi显示显存被占了几个G但下面进程列表里那个PID你却找不到对应程序。通常是因为程序异常退出后显存没有被及时释放或者有个僵尸进程挂着。处理办法是先找到占用显存的PIDnvidia-smi看进程列表里的PID然后确认这个进程是什么ps -p PID -o pid,cmd如果确认是自己的残留进程直接杀掉kill -9 PID如果PID都查不到但显存还占着说明是驱动层面的残留这种情况重启驱动或者机器最干脆。我遇到过几次跑崩了的训练脚本留下显存没释放nvidia-smi --gpu-reset都不一定管用最后重启才干净。提示养成好习惯脚本里用try/finally确保异常时释放显存或者干脆用torch.cuda.empty_cache()主动清理。虽然它不能解决所有问题但能减少很多麻烦。6.3 多卡环境与设备可见性控制服务器上多张卡是常态但默认情况下程序会看到所有卡。如果你只想用其中某几张用环境变量控制export CUDA_VISIBLE_DEVICES0,1注意这个变量里的编号是重新映射的。你设置成0,1之后程序里的cuda:0其实对应物理上的第0张卡cuda:1对应物理第1张。如果你写成2,3程序里的cuda:0就变成了物理上的第2张卡。这个映射关系搞不清会导致你明明指定了卡程序却跑到别的卡上去了。还有个坑是CUDA_VISIBLE_DEVICES必须在程序启动前设置好程序运行中再改是无效的。我见过有人在Python里用os.environ改这个变量结果发现没用就是因为改晚了。6.4 cuDNN相关的隐性问题PyTorch的卷积操作依赖cuDNN。如果你系统的cuDNN版本和PyTorch期望的不一致可能不会报错但性能会明显下降或者在某些特定尺寸的输入上出错。排查cuDNN版本cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR不过要提醒一句PyTorch pip包自带了它需要的cuDNN所以通常不需要你单独装。只有在你用conda方式或者自己编译扩展时系统cuDNN才会被用到。这个区分很多人不清楚白白花时间在装cuDNN上。如果你用的是pip装的cu113版本PyTorch其实可以跳过单独装cuDNN这一步。7. 环境固化与长期维护的一些经验7.1 把可用环境导出成文件环境一旦跑通第一件事就是导出依赖清单方便以后重建conda env export environment.yml但这个文件会带上本地路径等平台相关的信息跨机器可能出问题。我通常还会额外导一份pip的pip freeze requirements.txt重建时用pip的清单更可靠尤其是纯Python依赖。这两个文件一起保存将来换机器或者环境崩了能快速恢复。我把environment.yml和requirements.txt连同安装时用的CUDA版本记在一个README里包括nvcc -V的输出和nvidia-smi的驱动版本截图。这么做是因为几个月后再回来看你根本不记得当时装的哪个版本。有一次我隔了半年重装就是因为当初没记录多花了半天重新对版本。7.2 环境隔离的边界conda环境能隔离Python包但隔离不了系统级的CUDA和驱动。这意味着如果你在同一台机器上给不同项目用不同的CUDA Toolkit版本光靠conda环境是不够的得靠runfile装到不同路径加环境变量切换。这个边界要清楚不然会出现A环境好好的切到B环境就报错实际上是系统CUDA被改动了。对于多版本共存的场景我一般会写个小脚本切换环境的同时切换PATH和LD_LIBRARY_PATH#!/bin/bash export PATH/usr/local/cuda-11.3/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda-11.3/lib64:$LD_LIBRARY_PATH conda activate torch113每个项目一个这样的脚本用的时候source一下比手动改环境变量靠谱。7.3 一个很少被提到但很实用的技巧最后分享一个我实际用下来很有价值的做法装完环境后写一个自检脚本把所有验证步骤串起来。import torch def check_env(): assert torch.cuda.is_available(), GPU不可用检查驱动和PyTorch版本 print(PyTorch:, torch.__version__) print(CUDA:, torch.version.cuda) print(Device:, torch.cuda.get_device_name(0)) print(Count:, torch.cuda.device_count()) x torch.randn(512, 512).cuda() print(Matmul OK:, (x x).sum().item()) if __name__ __main__: check_env()这个脚本的好处是以后每次环境出问题跑一下就知道坏在哪一层。是驱动没了、还是PyTorch装错了、还是显存被占了一次性定位。我在多台服务器上部署时把这脚本放到每台机器上出问题先跑它排查效率比一条条命令试高太多了。整个流程走下来你会发现CUDA 11.3加PyTorch GPU的安装本质上是一场版本对齐的游戏。驱动决定上限CUDA Toolkit提供编译和运行时PyTorch自带它需要的那部分运行时cuDNN在背后加速卷积。每一层的版本都必须与相邻层匹配任何一处错位都会在某个环节爆发出来。理解了这套关系报错的时候你就不是在盲目搜索而是能顺着依赖链一层层往下查。这套环境我前后在十几台机器上装过从个人工作站到集群节点最耗时的从来不是敲命令而是排查那些版本错位导致的隐性故障。所以我越来越倾向于在装之前先把版本清单列清楚装完立刻固化快照别等到出问题了才回头找原因。
返回列表