ARTICLE DETAIL

资讯详情

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

Linux NVIDIA 驱动与 CUDA 安装:runfile 避坑与多版本管理

Linux NVIDIA 驱动与 CUDA 安装:runfile 避坑与多版本管理 上周帮同事收拾一台被 apt 源反复折腾过的训练机nvidia-smi直接甩出一句has failed because it couldnt communicate with the NVIDIA driver图形界面黑屏、CUDA 也认不到卡机器上还残留着三个不同来源的驱动包。折腾了大半天把系统盘的包管理器清理干净最后用 runfile 一步到位装好跑通了 PyTorch GPU 版和 PaddleOCR 的 GPU 推理。这件事之后我就一直用 runfile 这套流程从单机到几十张卡的 GPU 集群都用它。这篇东西写给正在 Linux 上装、卸 NVIDIA 显卡驱动和 CUDA 的人尤其是那些被 apt 自动升级搞崩过、或者要给多台机器做统一版本的人。内容偏实操所有命令都能直接抄重点讲清楚每一步为什么要这么干以及踩过的坑长什么样。1. 为什么我把 runfile 当作首选安装方式1.1 三条安装路径的真实差异Linux 上装 NVIDIA 驱动常见路子就三条发行版自带仓库、NVIDIA 提供的 CUDA 官方 apt/yum 仓库、官网下载的.run单文件安装器。三条路都能装成但在运维视角里完全是三种东西。发行版自带仓库比如 Ubuntu 的nvidia-driver-550最大的好处是省事apt install就完事依赖由发行版维护者帮你理顺和系统内核版本也是配套测试过的。坏处是版本滞后而且一旦你装了nvidia-driver-550又去装了 CUDA 官方仓库两套源会互相打架——一个说libnvidia-compute-550另一个说cuda-driversapt的依赖解析器就开始给你演杂技。CUDA 官方仓库的方式比发行版仓库新一些装 CUDA Toolkit 时顺手把驱动也带上apt install cuda-toolkit-12-4这种写法很舒服。它的问题是驱动和 CUDA 绑定得比较死你想换一个驱动分支就得动源配置而且它同样逃不开apt upgrade把驱动升到另一个大版本、结果和运行中的内核模块不匹配的经典事故。runfile 就是一个自解压的可执行文件不带包管理器不碰系统源装哪儿、装什么版本、装不装 OpenGL 库全由你决定。代价是它也不会帮你处理依赖、不会自动写进包管理器数据库卸载得靠自带的卸载脚本。1.2 runfile 的核心优势与要接受的代价我把 runfile 当默认真有几个具体原因。第一是版本可控。生产环境最怕的不是旧版本是某天早上起来版本变了。用 runfile驱动版本号写在文件名里装完之后不会因为任何一次系统更新而悄悄变化除非你自己去跑那个.run。第二是驱动与 CUDA 彻底解耦。驱动只管驱动CUDA Toolkit 只管 Toolkit我可以留一个稳定的 550 驱动分支同时挂 12.1、12.4、12.6 三个 Toolkit 目录靠环境变量切换。这套灵活性在 apt 体系里做起来非常别扭。第三是离线可复制。机房里的机器往往不能直连外网.run文件拷进去就能装不需要配一堆源、不需要解决依赖。做 GPU 集群的时候这一点很关键——一份文件几十台机器同一个 md5。代价也要说清楚。runfile 装完后dpkg -l | grep nvidia是空的也就是说包管理器不知道你装了驱动别人接手这台机器会一脸懵驱动和内核模块的绑定需要 DKMS 帮忙否则内核一升级模块就找不到了还有 Secure Boot 的签名问题apt 渠道装的驱动是有签名的runfile 装出来的是自己编译的模块需要额外处理。1.3 先把驱动版本和 CUDA 版本的对应关系记清楚这是新手最容易翻车的地方。CUDA Toolkit 对驱动有最低版本要求驱动版本不够Toolkit 装上了也跑不起来。下面这张表是常用的对应关系建议截图存手机。CUDA ToolkitLinux 最低驱动版本常见生产分支CUDA 11.8450.80.02520 / 525CUDA 12.1530.30.02535CUDA 12.2535.54.03535CUDA 12.3545.23.06550CUDA 12.4550.54.14550CUDA 12.5555.42.02555CUDA 12.6560.28.03560还有一句话必须刻进脑子里nvidia-smi右上角那个CUDA Version是当前驱动支持的最高运行时版本不是你装的 Toolkit 版本。很多人在机器上看到CUDA Version: 12.4就以为自己装了 CUDA 12.4然后nvcc -V一跑发现是 11.8就开始怀疑人生。这两个数字本来就来自不同的地方nvcc的版本由PATH里的 Toolkit 决定nvidia-smi的数字由驱动决定。注意选驱动版本时按就低不就高来。想要 CUDA 12.1 和 12.4 都能跑装 550 分支的驱动就够了它向下兼容 12.1 到 12.4 的运行时。反过来装了 525 驱动却想跑 CUDA 12.4nvidia-smi会直接报错说驱动版本不够。2. 动手之前的准备清单2.1 先把机器的底细摸清楚别急着下载先用几条命令把情况确认一遍能省掉后面一半的排查时间。# 显卡型号和数量 lspci | grep -i nvidia # 系统版本 cat /etc/os-release # 当前内核版本重要后面选头文件用 uname -r # 是否已经装过驱动有没有残留 lsmod | grep -i nvidia nvidia-smi # 是否装了 nouveau开源驱动必须禁掉 lsmod | grep nouveaulspci这条命令的输出里会带显卡型号比如NVIDIA Corporation GA102 [GeForce RTX 3090]记下来等会儿在官网下载页要对照着选。如果是数据中心卡比如 A100、H100、L40S驱动分支选择上和消费卡略有区别得用数据中心驱动分支。lsmod | grep nouveau如果有输出说明开源驱动还没被禁用这是后面安装失败的常见根因之一。lsmod | grep nvidia如果有输出说明之前装过驱动得先清理干净再装新的两套驱动同时存在的机器上nvidia-smi报的错会非常迷惑。2.2 禁用 nouveau 的完整做法nouveau 是内核自带的开源 NVIDIA 驱动它会在系统启动时抢占显卡。只要它还在闭源驱动的编译安装就会失败或者装上之后加载不了。做法是写一个黑名单配置文件sudo tee /etc/modprobe.d/blacklist-nouveau.conf EOF blacklist nouveau options nouveau modeset0 EOF第一行告诉内核不要自动加载 nouveau第二行彻底关掉内核模式设置。写完还没生效得重建 initramfs# Debian / Ubuntu 系 sudo update-initramfs -u # RHEL / CentOS / 麒麟 系 sudo dracut --force重建完必须重启重启后再lsmod | grep nouveau没有任何输出才算干净。提示这一步是整个流程里最不能省的一步。我见过至少三次安装卡在正在编译内核模块半小时不动、最后报错追下去都是 nouveau 没禁干净。禁用后重启是硬要求modprobe -r nouveau手动卸载在图形界面运行时基本不会成功因为 X 或者 Wayland 正占着它。2.3 依赖包和内核头文件runfile 安装驱动时会现场编译一个内核模块所以编译器和当前内核的头文件必须先备好。# Ubuntu / Debian sudo apt update sudo apt install -y build-essential gcc make dkms \ linux-headers-$(uname -r) pkg-config libglvnd-dev # RHEL / CentOS 系 sudo yum install -y gcc make kernel-devel-$(uname -r) kernel-headers-$(uname -r) dkmslinux-headers-$(uname -r)这个写法很讲究$(uname -r)展开成当前运行内核的版本号。如果你装的是linux-headers-generic它可能会拉到比当前运行内核更新的版本编译时找不到/lib/modules/$(uname -r)/build这个软链接安装就会失败并报找不到内核源码。dkms这个包很关键它负责在内核升级后自动重新编译 NVIDIA 模块。不装 DKMS 的话你升级一次内核机器重启后nvidia-smi立刻罢工而且报错信息完全看不出原因。2.4 下载与文件校验驱动去 NVIDIA 官方驱动下载页按显卡型号和系统选下载页面会直接给出.run文件。CUDA Toolkit 去 CUDA 归档页面找对应版本注意选runfile (local)而不是deb (local)。服务器上如果下载慢用aria2c开多线程加断点续传aria2c -x 16 -s 16 -c NVIDIA-Linux-x86_64-550.127.05.run-c是继续未完成的下载这个参数能救命。.run文件动辄几百 MB 到几个 GB下载中断后用浏览器重下容易拿到一个半截文件而半截文件的报错信息非常隐蔽——最常见的就是后面会讲的gzip: stdin: invalid compressed>sha256sum NVIDIA-Linux-x86_64-550.127.05.run拿这个值和下载页上的 SHA256 对一下。不要跳过这一步一个比特的错误在编译阶段会变成一堆看不懂的报错。3. 驱动安装全流程实录3.1 关掉图形界面进纯文本模式闭源驱动安装时要卸载当前的显示模块如果 X 或者 Wayland 正在运行卸载会失败。# 临时切到多用户文本模式systemd 系统 sudo systemctl isolate multi-user.target # 或者直接停掉显示管理器 sudo systemctl stop gdm3 # Ubuntu GNOME sudo systemctl stop lightdm # 部分发行版 sudo systemctl stop sddm # KDE如果是远程 SSH 连着服务器isolate multi-user.target不影响你的 SSH 会话只关图形部分。如果是本地坐在机器前面执行完会切到黑底白字的 tty正常。还有一种更彻底的姿势重启进 GRUB在内核参数行末尾加3或者systemd.unitmulti-user.target进 runlevel 3。这个方法在图形界面已经崩了、压根进不去桌面的时候特别有用。3.2 runfile 安装时的参数怎么选基础命令长这样sudo sh NVIDIA-Linux-x86_64-550.127.05.run \ --no-x-check \ --no-nouveau-check \ --dkms \ --silent逐个说清楚每个参数在干什么。--no-x-check让安装器跳过X 服务是否在运行的检查。你是按 3.1 的步骤关掉图形的正常情况下这个检查会通过但如果关不干净加上这个参数能强行走下去。--no-nouveau-check跳过 nouveau 检查。这个参数我一般只在确认 nouveau 已经禁干净的前提下才加因为它是把安全检查关掉出了问题报错会更难定位。新手建议先不加让安装器帮你检查。--dkms是强烈建议加的。它会让安装器把内核模块注册进 DKMS 框架以后内核升级时自动重新编译。不加这个参数内核一升级你就得重装一次驱动。--silent静默安装不在交互界面里问你任何问题。加上它安装日志直接刷到终端适合脚本化。不加也行会进一个基于 ncurses 的界面一路选继续。如果是纯计算节点桌面完全不跑 NVIDIA 显卡用集成显卡或者 BMC 输出画面额外加一个--no-opengl-files这个参数不安装 OpenGL 相关的库文件。它的作用是避免驱动把系统的 GLX 库覆盖掉导致原本用集成显卡跑得好好的桌面突然起不来。但反过来如果你打算用这张卡跑图形界面或者做渲染、跑需要 OpenGL 的可视化千万别加这个参数不加它装了 OpenGL 库桌面才能用独显。这一点后面在第 6 章还会提到它和glxserver_nvidia加载失败直接相关。安装过程大约三到五分钟中间会现场编译内核模块看到Building kernel modules就是在干活。结束时会提示Installation has completed successfully。3.3 32 位兼容库装不装安装过程中会问你要不要装 32 位兼容库。纯计算场景PyTorch、PaddleOCR、大模型微调不需要直接选 No。做图形渲染、跑部分老游戏或者 Wine 场景才需要。选错的后果不严重只是多占几十 MB 空间和一点点安装时间。但如果你在脚本化安装--silent时想知道默认会怎么选答案是默认装。要显式跳过加上--no-libglx-indirect --no-install-libglvnd这类参数组合不过大部分情况下没必要折腾。3.4 DKMS 装完之后确认一下如果加了--dkms装完后确认注册是否成功dkms status正常输出类似nvidia/550.127.05, 5.15.0-91-generic, x86_64: installed。看到installed就对了。如果显示的是built但没installed说明模块编译出来了但没装上可以手动补一下sudo dkms install -m nvidia -v 550.127.05还有一种情况是内核升级后dkms status里出现added状态说明新内核上还没编译。手动触发sudo dkms autoinstalldkms autoinstall这个命令值得记住它是内核升级后驱动失效的第一时间救援命令比重新跑一遍.run快得多。3.5 安装后的验证三件套装完先别急着装 CUDA把驱动本身验证清楚。# 一、模块是否加载 lsmod | grep nvidia # 二、显卡信息能不能读出来 nvidia-smi # 三、驱动版本和内核模块版本是否一致 cat /proc/driver/nvidia/version modinfo nvidia | head -5nvidia-smi输出的表格里会有驱动版本、CUDA Version、每张卡的显存占用、温度、功耗。多卡机器会按 GPU 0、GPU 1 一路列下去。显存那一列如果是N/A或者报错说明模块加载有问题。cat /proc/driver/nvidia/version和modinfo nvidia的版本号必须一致。如果/proc里显示 550 但modinfo显示 535说明系统里有两套驱动共存这是最难排查的一类问题必须彻底清理后重装。提示nvidia-smi有个隐藏用法nvidia-smi -q -d TEMPERATURE,POWER,CLOCK可以看详细的温度和功耗跑 GPU 压力测试gpu-burn的时候配合watch -n 1 nvidia-smi观察比盯着默认界面强。4. CUDA 的安装与多版本共存4.1 用 runfile 装 CUDA 时要绕开的坑CUDA 的 runfile 和驱动 runfile 是两回事。下载 CUDA Toolkit 时拿到的是一个体积更大的.run比如cuda_12.4.0_550.54.14_linux.run——注意文件名里那串550.54.14它是这个 Toolkit 配套的驱动版本。如果直接双击运行、全选安装它会把驱动再装一遍覆盖掉你辛苦装好的那套并且可能装上另一个版本。正确的做法是显式指定只装 toolkitsudo sh cuda_12.4.0_550.54.14_linux.run \ --silent \ --toolkit \ --toolkitpath/usr/local/cuda-12.4 \ --no-opengl-libs \ --override--toolkit是核心它告诉安装器只装 Toolkit 组件驱动、samples 都不碰。指定了具体组件之后驱动就不会被安装。--toolkitpath指定安装目录我习惯按版本号建独立目录/usr/local/cuda-12.4而不是默认的/usr/local/cuda。这样多版本可以并存切换只改环境变量。--no-opengl-libs在这里同意的意思不装 CUDA 附带的 OpenGL 头文件和库避免和系统 GL 库冲突。计算场景一律加上。--override跳过编译器版本兼容性检查。新版发行版自带的 gcc 版本往往比 CUDA 官方支持列表里的新不加这个参数会直接报unsupported compiler然后退出。这个参数的代价是可能遇到编译问题但绝大多数场景下没事。4.2 环境变量怎么配、怎么切换装完 CUDA 后要把nvcc加进 PATH。推荐写到/etc/profile.d/下这样所有用户都能用sudo tee /etc/profile.d/cuda.sh EOF export CUDA_HOME/usr/local/cuda-12.4 export PATH$CUDA_HOME/bin:$PATH export LD_LIBRARY_PATH$CUDA_HOME/lib64:$LD_LIBRARY_PATH EOF然后source /etc/profile.d/cuda.sh或者重新登录一次验证nvcc -V输出里的release 12.4说明配置生效了。多版本切换最土也最可靠的办法是做个软链接加函数。先建软链接sudo ln -sfn /usr/local/cuda-12.4 /usr/local/cuda然后按需切换版本时写两个小脚本放到/usr/local/binsudo tee /usr/local/bin/cuda-switch EOF #!/bin/bash if [ -z $1 ]; then echo 用法: cuda-switch 12.4 exit 1 fi TARGET/usr/local/cuda-$1 if [ ! -d $TARGET ]; then echo 找不到 $TARGET exit 1 fi sudo ln -sfn $TARGET /usr/local/cuda echo 已切换到 $TARGET EOF sudo chmod x /usr/local/bin/cuda-switch之后cuda-switch 12.1就切过去了环境变量用的是/usr/local/cuda跟着软链接变。这个方案的好处是所有脚本里写的都是/usr/local/cuda不需要改任何配置。注意切换软链接不会影响已经编译好的程序因为编译好的二进制要么静态链接要么会通过 RPATH 找到具体版本路径。切换主要影响新编译的程序和依赖LD_LIBRARY_PATH的运行时。另外切换后 PyTorch 这类预编译框架通常不受影响因为它们自带 CUDA 运行时库。4.3 cuDNN 和 NCCL 的对应关系cuDNN 是深度学习算子的加速库装它的第一原则是版本必须匹配 CUDA 主版本。cuDNN 8.9.x 对应 CUDA 12.xcuDNN 9.x 也对应 CUDA 12.x但具体小版本之间有不兼容情况。下载 cuDNN 现在有两个渠道。老办法是从开发者页面下载 tar 包解压后手动拷贝tar -xvf cudnn-linux-x86_64-9.1.0.70_cuda12-archive.tar.xz sudo cp cudnn-*-archive/include/cudnn*.h /usr/local/cuda-12.4/include/ sudo cp -P cudnn-*-archive/lib/libcudnn* /usr/local/cuda-12.4/lib64/ sudo chmod ar /usr/local/cuda-12.4/include/cudnn*.h /usr/local/cuda-12.4/lib64/libcudnn*新办法是直接用 pip 装 wheel省掉手动拷贝pip install nvidia-cudnn-cu129.1.0.70这种方式装进的是 Python 环境PyTorch 会自动找到做实验很方便但如果你要编译 C 程序就得用回手动拷贝的办法。验证 cuDNN 版本cat /usr/local/cuda/include/cudnn_version.h | grep -E CUDNN_MAJOR|CUDNN_MINOR|CUDNN_PATCHLEVEL或者用 Python 直接问 PyTorchpython -c import torch; print(torch.backends.cudnn.version())NCCL 只在多卡通信时才是必需的单卡训练可以先不管。多卡场景下它需要和 CUDA 主版本匹配装法和 cuDNN 类似下载 tar 包拷贝到 CUDA 目录或者用pip install nvidia-nccl-cu12。4.4 目录规划让多版本共存不乱套多版本共存最怕的就是文件乱放。我自己的规矩是这样/usr/local/cuda-12.1/ # 老项目用 /usr/local/cuda-12.4/ # 主力版本 /usr/local/cuda-12.6/ # 试新框架用 /usr/local/cuda - cuda-12.4 # 软链接每个版本目录都是完整的 toolkit互不干涉。Python 虚拟环境里锁死框架版本和 CUDA 版本的组合比如torch 2.4 cu124对应/usr/local/cuda-12.4。这样一套机器上可以同时跑几个不同年代的项目不会因为升级环境把老项目搞崩。CUDA 版本和框架的对应也要心里有数。PyTorch 官网给的pip install torch --index-url https://download.pytorch.org/whl/cu124这种写法cu124指的就是 CUDA 12.4 运行时它自带运行时库不依赖你本地装的 Toolkit但依赖本地驱动版本够新。这个细节很多人搞混以为本地必须装 12.4 的 Toolkit其实不是驱动够新就行。5. 卸载与回滚干净地拆掉重来5.1 驱动卸载的标准动作runfile 装的驱动自带卸载器路径在/usr/bin/nvidia-uninstall。sudo systemctl isolate multi-user.target sudo /usr/bin/nvidia-uninstall卸载器会问你确不确定选 Yes。跑完之后检查lsmod | grep nvidia nvidia-smilsmod无输出、nvidia-smi报 command not found说明卸干净了。如果卸载器找不到或者执行失败可以直接用原安装文件sudo sh NVIDIA-Linux-x86_64-550.127.05.run --uninstall还有一个更暴力的清理办法用于安装崩了、卸载器也崩了的场景sudo rm -rf /usr/lib/x86_64-linux-gnu/libnvidia* sudo rm -rf /usr/lib/x86_64-linux-gnu/libcuda* sudo rm -rf /usr/bin/nvidia-* sudo rm -rf /etc/ld.so.conf.d/nvidia* sudo rm -f /etc/X11/xorg.conf sudo rm -f /etc/modprobe.d/nvidia*.conf sudo dkms remove -m nvidia --all sudo depmod -a sudo update-initramfs -u sudo reboot这套命令我一般只在机器已经彻底乱掉的时候用跑之前确认一下没有别的软件依赖这些库。dkms remove -m nvidia --all那一条特别重要它把 DKMS 里注册的模块也一并清理了不做这一步下次装驱动可能直接冲突。5.2 CUDA 卸载和 apt 残留处理CUDA Toolkit 也自带卸载器sudo /usr/local/cuda-12.4/bin/cuda-uninstaller交互式界面里把你装的组件勾上卸载器会把目录删掉。如果卸载器不在了直接删目录也算数sudo rm -rf /usr/local/cuda-12.4 sudo rm -f /etc/profile.d/cuda.sh删完之后把软链接也处理掉别留一个指向不存在目录的悬空链接。apt 残留是另一类麻烦。如果之前用 apt 装过驱动dpkg -l | grep -i nvidia能列出一堆包清理方式sudo apt purge -y ^nvidia-.* ^libnvidia-.* ^cuda-.* sudo apt autoremove -y sudo apt autocleanpurge比remove多删配置文件这一步不能省因为残留的/etc/modprobe.d/nvidia-*.conf会在下次装驱动时干扰模块加载。5.3 卸载事故的几个典型场景第一种是卸载后不重启就重装。旧的模块文件可能还在内存里或者/lib/modules里没清干净新驱动编译时和旧的冲突。卸载和安装之间一定要重启这条没有例外。第二种是卸载一半中断了。nvidia-uninstall跑到一半按了 CtrlC结果/usr/lib下的库删了一半/usr/bin下的工具还在。这时候nvidia-smi能执行但报错奇葩解决方法是按 5.1 的暴力清理流程走一遍。第三种是系统里同时有 apt 版和 runfile 版。判断方法dpkg -l | grep -i nvidia ls /usr/bin/nvidia-uninstall两条都有输出说明两套都在。这时候必须先apt purge清掉包管理器那套再跑nvidia-uninstall清 runfile 那套顺序反了会把包管理器数据库搞乱之后apt install什么都装不上。提示把驱动和 CUDA 的版本号、安装日期、安装方式记进一个文本文件放在/root/下比如GPU_ENV.md。三个月后你或者接手的人排查问题时这份记录能省一小时。我吃过这个亏接手一台机器花了两天才搞清它装了什么。6. 常见故障排查实录6.1 nvidia-smi 报 communicate with the NVIDIA driver 失败这是最高频的报错完整信息是NVIDIA-SMI has failed because it couldnt communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.。字面意思是找不到能通信的驱动但真实原因有五六种得按顺序排查。第一步查模块有没有加载lsmod | grep nvidia没输出说明内核模块没加载。再查 DKMS 状态dkms status如果显示added或者干脆没有记录说明内核升级后模块没重建sudo dkms autoinstall补一下就完事。第二步查是不是 nouveau 又回来了lsmod | grep nouveau有输出说明黑名单没生效检查/etc/modprobe.d/blacklist-nouveau.conf是否还在以及 initramfs 有没有重建。第三步查 Secure Bootmokutil --sb-state如果输出SecureBoot enabled那问题就找到了。runfile 编译出来的模块没有经过微软签名Secure Boot 会拒绝加载它。两个选择进 BIOS 关掉 Secure Boot或者用mokutil --import把自己的签名公钥注册进去重启时在蓝屏界面确认一次。生产环境我一般直接在 BIOS 里关掉简单省事。第四步看内核日志dmesg | grep -i nvidia | tail -30这里有最直接的线索常见的有module verification failed签名问题、NVRM: API mismatch用户态库和内核模块版本不一致、disagrees about version of symbol内核版本不匹配。6.2 gzip: stdin: invalid compressed data 报错这个报错完整形态是gzip: stdin: invalid compressed># 先校验 sha256sum cuda_12.4.0_550.54.14_linux.run # 不匹配就重新下载用断点续传 aria2c -x 16 -s 16 -c https://developer.download.nvidia.com/compute/cuda/12.4.0/local_installers/cuda_12.4.0_550.54.14_linux.run注意校验和必须和官方页面上给的一致不要觉得差不多就行。我踩过一次坑文件大小看起来对但 sha256 差了两位装到一半报奇怪的错排查了两个小时才发现是下载文件的最后一小段被截断了。注意用wget或者curl下载大文件时加上-c参数支持续传。wget -c或者curl -C - -O。不加的话中断后重下还是从头开始反复中断的话很容易拿到坏文件。6.3 glxserver_nvidia 模块加载失败Xorg 日志里出现这种报错[ 7.125] (EE) NVIDIA: Failed to load module glxserver_nvidia (module does not exist, 0)这个报错的根源几乎都是安装驱动时加了--no-opengl-files但仍希望用独显跑图形界面。--no-opengl-files不装 GLX 相关的模块文件Xorg 启动时找不到glxserver_nvidia.so就报错结果就是图形界面起不来或者只能跑软件渲染。修复方式是重装驱动去掉--no-opengl-filessudo sh NVIDIA-Linux-x86_64-550.127.05.run --no-x-check --dkms重装完检查那个模块在不在find /usr/lib -name glxserver_nvidia*如果有输出重启图形界面应该就正常了。如果希望桌面用集成显卡、独显只跑计算那就保持--no-opengl-files但要去 Xorg 里明确配置用集成显卡输出不要让 Xorg 尝试去加载 NVIDIA 的 GLX 模块。这两个目标要一开始就想清楚别装完了才纠结。6.4 安装卡在奇怪的地方安装过程中卡住不动常见有几个卡点。卡在正在编译内核模块一般是 nouveau 没禁干净或者内核头文件版本不对。打断安装CtrlC检查ls /lib/modules/$(uname -r)/build这个软链接是否指向存在的目录。卡在3D Vision相关的选项界面这是驱动交互界面里的一个组件问询。旧版本驱动会问你要不要装 3D Vision 驱动选 No 就行。如果整个界面卡住无响应可能是终端类型不兼容换一个纯净的 ttyCtrlAltF3 进再跑或者直接加--silent走静默安装绕过界面。卡在正在更新 initramfs这一步本身耗时能到几分钟尤其是磁盘慢的机器。判断是真卡还是慢另开一个 SSH 窗口ps aux | grep -E update-initramfs|dracut看进程在不在跑CPU 占用有没有变化。6.5 故障速查表把上面这些整理成一张表出问题的时候直接从表里找。报错/现象最可能的原因快速验证命令处理办法communicate with driver 失败DKMS 模块未随内核重建dkms statussudo dkms autoinstall后重启同上Secure Boot 拦截未签名模块mokutil --sb-stateBIOS 关闭 Secure Boot同上nouveau 抢占显卡lsmodgrep nouveaugzip invalid compressed data下载文件不完整sha256sum xxx.run断点续传重下并校验glxserver_nvidia 加载失败装驱动时加了--no-opengl-filesfind /usr/lib -name glxserver_nvidia*去掉该参数重装API mismatch用户态库与内核模块版本不一致cat /proc/driver/nvidia/version彻底卸载后重装同一版本内核升级后驱动失效没装 DKMS 或 DKMS 注册失败dkms status装 DKMS 后重装驱动多卡只识别到一张拓扑或驱动问题nvidia-smi -L检查lspci和驱动分支nvcc 找不到PATH 没配which nvcc配/etc/profile.d/cuda.shnvcc 版本与 nvidia-smi 不符两者来源不同属正常现象nvcc -V无需处理理清概念即可7. GPU 集群与容器场景的补充做法7.1 多机统一版本管理机器一多最头疼的是版本漂移。今天这台升了驱动明天那台换了 CUDA跑分布式训练时一个节点报版本不匹配整个任务挂掉。我的做法是把安装过程脚本化一份脚本管所有机器。脚本里版本号是变量其他全是常量#!/bin/bash set -e DRIVER_VER550.127.05 CUDA_VER12.4.0 CUDA_PATCH550.54.14 PKG_DIR/opt/gpu-pkgs # 禁用 nouveau tee /etc/modprobe.d/blacklist-nouveau.conf EOF blacklist nouveau options nouveau modeset0 EOF update-initramfs -u # 装依赖 apt install -y build-essential dkms linux-headers-$(uname -r) pkg-config # 装驱动 sh ${PKG_DIR}/NVIDIA-Linux-x86_64-${DRIVER_VER}.run \ --no-x-check --dkms --silent # 装 CUDA sh ${PKG_DIR}/cuda_${CUDA_VER}_${CUDA_PATCH}_linux.run \ --silent --toolkit --toolkitpath/usr/local/cuda-${CUDA_VER%.*} \ --no-opengl-libs --override # 环境变量 tee /etc/profile.d/cuda.sh EOF export CUDA_HOME/usr/local/cuda-${CUDA_VER%.*} export PATH\$CUDA_HOME/bin:\$PATH export LD_LIBRARY_PATH\$CUDA_HOME/lib64:\$LD_LIBRARY_PATH EOF echo 安装完成请重启用 Ansible 或者简单点的 pdsh 批量推这个脚本装完统一重启。所有机器的nvidia-smi输出应该完全一致这才能保证分布式训练不出幺蛾子。对于集群还有一个建议是把驱动版本和 CUDA 版本写进监控。用nvidia-smi --query-gpudriver_version --formatcsv定期采集版本和基线不一致就告警。这个做法能提前发现有人手动改了某台机器。7.2 容器里跑 PyTorch 和 PaddleOCR 的 GPU 版本容器场景下有个反直觉的知识点容器里不需要装驱动只需要装 CUDA Toolkit 对应的运行时库。驱动由宿主机提供通过 NVIDIA Container Toolkit 挂进容器。宿主机装好驱动之后装容器运行时# 添加仓库并安装 apt install -y nvidia-container-toolkit nvidia-ctk runtime configure --runtimedocker systemctl restart docker验证docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi能打出显卡表格就说明通了。接下来跑 PyTorch GPU 版用官方镜像最省心docker run --rm -it --gpus all \ -v /data:/data \ pytorch/pytorch:2.4.0-cuda12.4-cudnn9-runtime \ python -c import torch; print(torch.cuda.is_available(), torch.cuda.device_count())输出True和显卡数量就对了。PaddleOCR 的 GPU 版稍微麻烦一点因为它对 CUDA 和 cuDNN 版本要求比较具体官方推荐的是 CUDA 11.8 或 12.x 配特定 cuDNN。稳妥做法是用 PaddlePaddle 官方镜像起步docker run --rm -it --gpus all \ -v /data:/data \ paddlepaddle/paddle:2.6.1-gpu-cuda12.0-cudnn8.9-trt8.6 \ bash进去之后pip install paddleocr然后跑一段识别验证python -c from paddleocr import PaddleOCR ocr PaddleOCR(use_angle_clsTrue, langch, use_gpuTrue) print(ocr.ocr(/data/test.png, clsTrue)) 如果报CUDA error或者找不到 GPU八成是镜像里的 CUDA 版本和宿主机驱动不匹配换一个 cu12 的低版本镜像试试。PaddleOCR 对 cuDNN 版本挺敏感镜像版本选对了能省很多时间。7.3 大模型微调场景的几个实用参数现在很多人拿单卡或者几卡跑大模型微调装完环境后有几个点值得注意。跑之前先用nvidia-smi确认显存是空的。如果有残留进程占着显存# 找到占显存的进程 nvidia-smi --query-compute-appspid,used_memory --formatcsv # 优雅结束 kill -15 pid # 杀不掉再强杀 kill -9 pid微调时如果出现 GPU 利用率忽高忽低、CPU 和内存占用也不高但整体很卡通常是数据加载成了瓶颈。DataLoader的num_workers调大一点pin_memoryTrue打开数据放在内存盘或者 NVMe 上改善会很明显。还有一个容易忽略的点是CPU 与 GPU 之间的数据拷贝。用torch.cuda.Stream做预取或者直接把小批量数据提前搬到显存能省掉不少等待。这些都不能解决根本的带宽瓶颈但实测下来对单卡训练速度有 5% 到 15% 的提升。跑压力测试验证稳定性的时候gpu-burn挺好用git clone https://github.com/wilicc/gpu-burn cd gpu-burn make ./gpu_burn 600跑十分钟同时另开窗口watch -n 1 nvidia-smi看温度和功耗。温度顶到 85 度以上、功耗被降频就要考虑机箱散热或者机房空调的问题了。这个测试在新机器上机的时候跑一遍能提前发现硬件问题。提示如果机器上有其他加速卡比如各种国产 AI 加速卡它们的驱动和软件栈跟 NVIDIA 这套完全不通用装的时候别把两边的环境变量和库路径混在一起很容易出现库冲突。有条件的话一台机器专注一种加速卡省心。8. 几个我踩过坑之后形成的习惯安装顺序上我现在的固定动作是禁 nouveau → 重启 → 装依赖 → 装驱动 → 重启 → 验证nvidia-smi→ 装 CUDA → 装 cuDNN → 装框架。中间两次重启不能省。尤其是装完驱动那次重启很多人图快直接往下装 CUDA结果后面出一堆模块冲突的怪问题。版本选择上我不追新。生产机上永远选一个 NVIDIA 官网上标注为 Production Branch 的驱动版本比如 550 系列然后就在这个分支里待着。新分支出来了先在小机器上试没问题再考虑换。驱动这种东西稳定比新功能重要得多。记录习惯上每台 GPU 机器装完之后我都会在/root/GPU_ENV.md里写清楚显卡型号和数量、驱动版本、CUDA 版本、cuDNN 版本、安装日期、安装方式、当时用的内核版本。写这几行字花两分钟能省下未来无数个小时。还有一个小技巧是关于远程操作的。如果你 SSH 远程给一台没接显示器的机器装驱动全程用--silent并且在脚本里加上nohup和输出重定向nohup sh install_gpu.sh /var/log/gpu-install.log 21 tail -f /var/log/gpu-install.log这样就算 SSH 断了安装也不会中断日志还在。装驱动这种动辄十几分钟的操作SSH 断线导致安装中断是纯纯的时间浪费而且中断后系统状态可能半死不活清理起来更麻烦。最后说一句关于nvidia-smi的心得。这个命令除了看基本信息还有几个查询模式值得记住nvidia-smi -L列出所有卡nvidia-smi topo -m看卡之间的互联拓扑做多卡并行时判断通信路径用nvidia-smi --query-gpuindex,name,memory.total,memory.used,temperature.gpu --formatcsv做脚本化采集。把这几个组合起来写成监控脚本GPU 集群的日常巡检基本就不用人工盯着了。
返回列表