1. RTX 5060 在海光 3490 平台上的驱动门槛到底卡在哪
RTX 5060 装到海光 3490 平台上跑 Ubuntu 22.04,这件事听起来只是"装个显卡驱动",实际操作过的都知道它同时踩在三个雷区上:显卡是 Blackwell 新架构、平台是海光 x86 服务器/工作站方案、系统是 22.04 这个已经偏老但生态最稳的 LTS。我在自己的海光 3490 工作站上完整走了一遍这条路,从最开始下载 ubuntu22.04 镜像、做启动盘、装系统,到把 ubuntu22.04 英伟达驱动彻底跑通,中间翻了不少车。
先说结论,省得你走弯路:在 ubuntu22.04 上装 nvidia535 驱动给 RTX 5060 用,是百分之百装不上的。这不是你命令敲错了,也不是源配错了,是 NVIDIA 在驱动分支上做的硬性切割。我见过太多人在这上面耗一整天,最后怀疑显卡坏了、怀疑海光平台不支持独显,其实只是驱动版本选错了代际。
这篇文章适合三类人:一是在国产 x86 平台上要加一张新显卡做推理或者图形渲染的运维;二是自己攒了台海光 3490 工作站、想上 50 系显卡做深度学习或者本地大模型跑推理的开发者;三是手上只有一台机器,想装 ubuntu22.04 双系统顺便把 RTX 5060 用起来的折腾党。下面按实际操作顺序来,从装机前准备一直讲到 CUDA 环境落地。
1.1 535 驱动注定装不上,这不是配置问题是硬件代际问题
RTX 50 系(Blackwell 核心)在 Linux 下的驱动支持有一条明确的分界线。570 系列是第一个正式支持 Blackwell 的驱动分支,而 535、550 这些在 Ubuntu 22.04 官方源里能直接apt install到的版本,发布时间早于 Blackwell 上市,驱动内部根本没有对应 GPU 的 device ID。你把卡插上去,lspci能看到设备在总线上,但nvidia-smi永远报No devices were found。
更麻烦的是一层"二次分界":RTX 5060 和 5060 Ti 的上市时间比 5080/5090 更晚,所以早期 570 系列的部分小版本里也还没收录 5060 的 ID。我这边实测的结论是,这张卡至少要 576 以后的版本才能被正常识别,而且是走-open后缀的开源内核模块包。从 570 这一代开始,Blackwell 只提供 open 内核模块,闭源模块的分支已经不再覆盖新核心。
所以当你看到网上大量"ubuntu22.04 安装 nvidia 显卡驱动"的教程,里面清一色写着apt install nvidia-driver-535,要清楚那些教程面向的是 30 系、40 系用户,跟 5060 完全不是一回事。这是我建议你把这篇看完再动手的第一个理由。
1.2 海光平台给这件事额外加了三道锁
海光 3490 是标准 x86_64 平台,指令集层面没任何兼容性问题,uname -m出来就是x86_64,Ubuntu 的 amd64 镜像直接用。但平台层面的差异体现在三个地方,每一个都可能让你卡住:
第一是BIOS/固件相对保守。不少海光整机的默认固件里,"Above 4G Decoding" 和 "Re-Size BAR Support" 这两个选项是关着或者藏起来的。50 系显卡的显存映射对地址空间的要求比较高,关掉这两个选项,常见的表现是驱动能装上、nvidia-smi也能跑,但显存只认出一部分,或者一跑负载就掉卡。
第二是内核对新硬件的支持滞后。Ubuntu 22.04 的 GA 内核停在 5.15,这个内核对 Blackwell 显卡的 BAR 分配、电源管理都不够友好,而且nvidia-open的 DKMS 模块在 5.15 上编译失败的概率相当高。所以我在正式装驱动之前,一定先把 HWE 的 6.8 内核装上,这一步不能省。
第三是PCIe 拓扑需要确认。海光 3490 平台的 PCIe 通道分配跟消费级主板不一样,CPU 直连的 x16 槽位和芯片组引出的槽位在带宽、延迟上差距明显。5060 本身是 PCIe 5.0 x8 的接口,插在芯片组槽位上大概率只能跑 x4,性能直接砍一半。
1.3 动手前的五分钟自检清单
在拆机箱之前,先用几条命令把现状摸清楚,能省掉后面大量返工。下面这张表是我每次装新卡都会先过一遍的内容。
| 检查项 | 命令 | 期望结果 | 不达标怎么办 |
|---|---|---|---|
| 架构确认 | uname -m/lscpu | x86_64,CPU 型号为海光 3490 | 若异常,先查系统是否装成 ARM 镜像 |
| 内核版本 | uname -r | 6.8.x 开头 | sudo apt install linux-generic-hwe-22.04 |
| 显卡识别 | lspci -nn | grep -i nvidia | 出现 NVIDIA 设备与 device ID | 不出现先查 BIOS 与插槽 |
| 链路宽度 | sudo lspci -vv -s <BDF> | grep LnkSta | 与显卡规格匹配 | 换到 CPU 直连槽位 |
| 安全启动 | mokutil --sb-state | 按计划选择开关 | 关闭或准备导入 MOK |
| 编译环境 | gcc --version/dpkg -l linux-headers-$(uname -r) | 有 gcc 与对应 headers | 一次性装齐 |
注意:这些命令里最容易被忽略的是链路宽度。我遇到过一台机器,显卡插在第二条物理 x16 槽上,实际电气只有 x4,其他什么都对,就是跑分只有别人一半,排查了两个晚上才发现是插槽问题。
2. 装系统这一步就得为 5060 让路
很多人以为驱动是装完系统以后的事,其实从你开始做 ubuntu22.04 启动盘的那一刻,5060 就已经在影响你的选择了。特别是热搜里那个高频词"5060 安装 ubuntu22.04 黑屏",非常典型,而且完全可以在装机阶段规避掉。
2.1 镜像与内核:为什么必须选 22.04.5 并对齐 HWE
ubuntu22.04 有多个小版本镜像,22.04.0 到 22.04.2 用的是 5.15 GA 内核,22.04.3 之后开始带 HWE 内核。如果你下载的是早期小版本的 iso,装完系统第一件事就是升级内核,中间还要重启、换源、处理依赖,纯属自找麻烦。建议直接下 22.04.5 的 desktop 或 server 镜像,HWE 内核 6.8 开箱即用。
如果你已经装好了老版本,也别重装,两条命令搞定:
sudo apt update sudo apt install -y linux-generic-hwe-22.04 linux-headers-generic-hwe-22.04 sudo reboot重启之后uname -r应该能看到 6.8 系列。这一步做完,nvidia-open的 DKMS 编译成功率会高很多。顺便说一句,如果你用的是 22.04 的双系统方案,务必在安装时确认引导分区没有覆盖掉原有系统,这个坑我身边至少三个人踩过。
2.2 海光主板 BIOS 里那几个必须动的开关
海光平台的固件界面各有差异,但核心选项不外乎这几个,进 BIOS 之后按这个顺序找:
- Above 4G Decoding:必须 Enabled。这是让系统能把 64 位地址空间分配给 PCIe 设备的前提,关着的时候大显存卡基本没法正常工作。
- Re-Size BAR Support / Large BAR:能开就开。开启后显存可以作为一整块 BAR 暴露给系统,对 50 系的性能发挥有实际帮助。
- CSM:Disabled。CSM 是兼容老系统的模式,开着会强制走传统引导,配合新显卡容易出问题。
- IOMMU:如果这台机器要用虚拟化直通,开着;纯粹本地跑推理,可以先 Disabled,减少地址翻译带来的额外变量,排查问题时变量越少越好。
- Secure Boot:这一步需要做个决定,见 3.3 节的说明。
改完 BIOS 之后先别急着装驱动,进系统跑一次lspci -vv看 BAR 分配情况。如果看到类似Region 1: Memory at ... (64-bit, prefetchable) [size=8G]这种大块分配,说明 Above 4G 生效了;如果只有 256M 级别的小 BAR,回去检查固件选项。
2.3 安装盘启动参数:把黑屏挡在门外
"5060 装 ubuntu22.04 黑屏"这个问题的根因很清楚:ubuntu22.04 引导阶段会尝试用 nouveau 开源驱动去点亮显卡,而 nouveau 对 Blackwell 核心完全没有支持,于是显示器在加载显卡驱动的那一刻失去信号。这不是显卡坏了,也不是镜像坏了。
处理方法是在启动菜单停住,进 Ubuntu 安装项按e编辑启动参数,在linux那一行末尾加上:
nomodeset module_blacklist=nouveau两个参数的作用不同:nomodeset让内核不要去设置显示模式,交给通用的 framebuffer;module_blacklist=nouveau直接阻止 nouveau 加载。装完系统之后,如果你暂时还没装官方驱动,每次启动都要带上这两个参数,否则还是会黑屏。所以下一步就是把"启动参数"和"屏蔽 nouveau"这两件事做彻底。
对于用虚拟机折腾 ubuntu22.04 的朋友(比如 VMware、WSL2 环境),情况不一样:虚拟机里通常没直通物理显卡,那个黑屏词条跟这个场景关系不大。真要在虚拟机里用 5060 的算力,得配 PCIe 直通,那就是另一套活了,后面第 6.3 节会提到 IOMMU 相关的注意点。
3. 系统落地后的第一轮清理:让 nouveau 彻底出局
系统装好、能进桌面之后,别急着敲安装命令。我一般的做法是先花十分钟做一轮"清场",把 nouveau、残留驱动、签名问题一次性处理干净,后面出问题的概率会低很多。
3.1 先确认硬件真的被认出来了
lspci -nn | grep -i -E "nvidia|vga|3d" lspci -vv -s 01:00.0 | grep -E "LnkCap|LnkSta|Region" lspci -k -s 01:00.0第一眼看device ID。RTX 5060 的 PCI ID 在 lspci 里可能显示为[10de:2d05]这类编号(具体以你手上的卡为准),只要能看到10de这个厂商前缀,说明卡的物理连接没问题。看不到就回到 BIOS 和插槽。
第二眼看LnkSta,理想状态下速度应该匹配卡的规格。如果显示Speed 2.5GT/s, Width x4这种明显偏低的值,十有八九是插槽或者电源管理降频,先别管,等驱动装完再用nvidia-smi复核一次链路。
第三眼看lspci -k的Kernel driver in use。如果显示的是nouveau,说明屏蔽动作没生效;如果显示vfio-pci,说明卡被 IOMMU 抓去做直通准备了,本地使用要先解绑。
3.2 屏蔽 nouveau、卸干净残留、重建 initramfs
sudo tee /etc/modprobe.d/blacklist-nouveau.conf > /dev/null <<'EOF' blacklist nouveau options nouveau modeset=0 EOF sudo apt purge -y '^nvidia-.*' '^libnvidia-.*' '^cuda-.*' sudo apt autoremove -y sudo update-initramfs -u -k all sudo reboot这几步里有两个细节值得说清楚。
一是update-initramfs -u -k all里的-k all。默认只更新当前内核的 initramfs,如果你装了 HWE 内核但默认启动的还是老内核,nouveau 可能只在其中一个上被屏蔽,切内核之后又冒出来。加-k all一次性全刷,代价是多花几秒。
二是apt purge那三个通配。很多人是在装驱动失败之后才来清理,这时候系统里可能已经躺着半装的 nvidia 包和 cuda 包,不清干净直接装新版本,会出现新旧模块混在一起、modprobe nvidia报版本不匹配的怪问题。我遇到过一次,症状是nvidia-smi有时能跑有时不能,最后发现是 dkms 目录下有 535 和 570 两个版本的模块在抢。
重启之后用lsmod | grep nouveau验证,没有输出就说明屏蔽成功。
3.3 Secure Boot 与模块签名,先做个决定
NVIDIA 的 DKMS 模块需要被内核信任才能加载。如果你机器开着 Secure Boot,装完驱动重启后大概率会看到insmod: ERROR: could not insert module nvidia.ko: Key was rejected by service。
两条路:
- 关掉 Secure Boot:简单直接,适合自己用的开发机、工作站。BIOS 里设 Disabled 就行。
- 保留 Secure Boot 并导入 MOK:在 install 过程中程序会提示你设置一次密码,重启时会出现蓝底的 MOK 管理界面,选 Enroll MOK 输入密码即可。如果当时跳过了,可以手动补:
sudo mokutil --import /var/lib/shim-signed/mok/MOK.der sudo reboot我个人的做法是:开发机直接关掉 Secure Boot,因为后续可能要频繁换驱动版本、编译自定义内核模块,每次都走 MOK 流程太费时间。如果是给别人交付的机器,就保留 Secure Boot 并导入 MOK,安全策略更完整。
4. 三条驱动获取路线的取舍
到了最关键的一步:驱动从哪来。ubuntu22.04 环境下能拿到 570+/576+ 驱动的路径其实只有三条,各自适合的场景差别很大。
4.1 路线对比表与我的选择理由
| 路线 | 驱动版本上限 | 优点 | 缺点 | 适合谁 |
|---|---|---|---|---|
| Ubuntu 官方源 | 535 / 550 | 命令最简单,依赖自动处理 | 版本太老,完全无法支持 50 系 | 30/40 系用户 |
| NVIDIA CUDA 仓库 | 跟随官方最新 | 版本新、apt 管理、可指定版本 | 会引入 cuda 源,需注意 pin | 长期使用的生产机 |
| 官方 .run 包 | 完全跟随官方 | 版本最自由、可精细控制 | 手动编译、升级内核要重装 | 需要特定版本、容器宿主机 |
我自己的主力机走的是第二条路线,理由有三个:apt 能统一管理依赖关系,后续卸载干净;仓库里有-open后缀的包,不用自己加参数;apt-mark hold可以把版本锁住,避免哪天顺手apt upgrade把驱动升到一个没验证过的版本上。
第三条路线我一般只在两种情况下用:一是客户要求复现某个特定的生产环境版本;二是这台机器的内核是我们自己编译的,需要手动指定内核源码路径。.run包的灵活性高,但代价是每次内核升级都得重装驱动,这点后面 6.4 节会详细说。
4.2 apt 路线:NVIDIA CUDA 仓库的完整操作
# 1. 添加 NVIDIA CUDA 仓库的 key 与源 wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb sudo dpkg -i cuda-keyring_1.1-1_all.deb sudo apt update # 2. 查看源里到底有哪些驱动版本可选 apt-cache search '^nvidia-driver-[0-9]*-open' | sort -V # 3. 安装(版本号按上一步的结果替换,这里以 576 系列为例) sudo apt install -y nvidia-driver-576-open # 4. 锁住版本,防止被后续 upgrade 顶掉 sudo apt-mark hold nvidia-driver-576-open nvidia-dkms-576-open几个必须解释清楚的点:
为什么要带-open后缀。前面说过,Blackwell 只走开源内核模块分支。不带后缀的包在部分版本里仍然提供闭源模块,装上之后会直接报找不到设备。这个后缀不是可选项。
为什么用apt-cache search先看一眼。CUDA 仓库里的驱动版本会滚动更新,今天的 576 明天可能就有 580,直接照抄别人教程里的版本号很容易碰到"包不存在"。先搜后装,这一步花十秒钟。
apt-mark hold这一步别省。CUDA 仓库里有一个cuda-drivers元包,一旦你后面为了装 CUDA 而执行apt install cuda,它会把驱动升到仓库里最新的那一版。如果那一版刚好跟你验证过的版本不一致,就可能出现莫名其妙的性能下降或者休眠唤醒异常。锁住版本,主动权在自己手里。
4.3 .run 路线:open 内核模块参数与编译细节
如果你决定走.run,下面是我实测可用的流程:
# 准备工作:进纯命令行,停掉图形界面 sudo systemctl isolate multi-user.target sudo apt install -y build-essential dkms linux-headers-$(uname -r) pkg-config libglvnd-dev # 关掉可能干扰的加载器 sudo modprobe -r nvidia_drm nvidia_modeset nvidia # 执行安装,关键参数是 kernel-module-type sudo sh NVIDIA-Linux-x86_64-576.xx.xx.run \ --kernel-module-type=open \ --dkms \ --no-x-check \ --no-nouveau-check--kernel-module-type=open是这条路线能不能成功的分水岭。不加这个参数,安装程序默认编译闭源模块,在 Blackwell 上编译能过、加载能过、nvidia-smi直接报错,非常误导人。
--dkms的作用是让驱动跟随内核版本自动重编。装了 DKMS 之后,内核升级时驱动模块会重新构建,这是.run路线里少有的能省心的地方。
编译失败最常见的原因有两个:gcc版本和内核头文件不匹配,以及内核源码不是"干净"状态。前者用sudo apt install gcc-12并sudo update-alternatives指定一下通常能解决;后者多见于你自己打过补丁的内核,需要把.config和Module.symvers准备好。
提示:
.run安装在纯命令行下做最稳妥。图形界面跑着的时候装驱动,X server 会占用显卡,安装程序往往要强制卸载模块,中断之后状态很难恢复,最后只能重装系统。
5. 安装后的验证链路与典型报错对照
装完不验证等于没装。我一般用三层验证,从驱动层到应用层逐级确认。
5.1 验证三连:驱动、显存、算力
# 第一层:驱动是否加载、GPU 是否识别 nvidia-smi nvidia-smi --query-gpu=name,driver_version,memory.total,pcie.link.gen.current,pcie.link.width.current \ --format=csv # 第二层:内核模块状态 lsmod | grep -E 'nvidia|nvidia_drm|nvidia_modeset' cat /proc/driver/nvidia/version # 第三层:实际算力验证 sudo apt install -y nvidia-cuda-toolkit nvidia-smi -q -d PERFORMANCE,POWER,TEMPERATURE | head -60第一层的输出里重点看三样:driver_version是不是你预期的版本,memory.total是不是完整显存(5060 是 8GB,如果显示只有几百 MB 说明 BAR 分配有问题,回到 6.1 节),pcie.link.width.current是不是符合卡的规格。
第二层很多人跳过,但当nvidia-smi能跑而某些应用报错的时候,lsmod就能告诉你到底是哪个模块没起来。正常情况下应该能看到nvidia、nvidia_modeset、nvidia_drm、nvidia_uvm四个。
第三层是真正跑业务的验证。我会用一个小的 CUDA 程序或者 PyTorch 张量运算把卡拉起来,同时用nvidia-smi dmon观察利用率曲线。只跑 nvidia-smi 不算验证通过,那个命令只查询状态,不触发真正的计算负载。
5.2 常见报错与对应处理
| 报错信息 | 大概率原因 | 处理方式 |
|---|---|---|
No devices were found | 驱动版本不支持该卡 / 用了闭源模块 | 换 576+ 且带-open的包 |
couldn't communicate with the NVIDIA driver | 模块未加载 / 内核与驱动不匹配 | lsmod查模块,必要时重编 DKMS |
Key was rejected by service | Secure Boot 未处理签名 | 关闭 Secure Boot 或导入 MOK |
Failed to initialize NVML: Driver/library version mismatch | 运行时模块与用户态库版本不一致 | 重启,或卸载重装对齐版本 |
Module nvidia not found | 安装后未重建模块依赖 | sudo depmod -a && sudo modprobe nvidia |
no NVIDIA GPU found但 lspci 能看到 | 卡被 vfio-pci 或其他驱动占用 | lspci -k查占用者,解绑 |
这个表里最值得展开的是Driver/library version mismatch。它的典型场景是:你装了驱动但没重启,内核里还是旧模块,用户态的nvidia-smi却是新版本,两者对不上。直接重启通常就好了。如果重启还报,那就是 dkms 目录里有多个版本残留,sudo dkms status看一眼,把多余的卸载掉。
5.3 一次真实的踩坑复盘:驱动装上但 nvidia-smi 报错
我把这次折腾的排查链路完整写出来,因为过程比结论更有参考价值。
现象:apt 装完nvidia-driver-576-open,重启后nvidia-smi报No devices were found,但lspci能看到卡,lsmod里nvidia模块也在。
第一步,确认不是版本问题:cat /proc/driver/nvidia/version输出的模块版本和nvidia-smi --version的用户态版本一致,排除了版本不匹配。
第二步,看内核日志:sudo dmesg | grep -i nvidia输出了几行关键信息,其中出现NVRM: GPU at PCI:01:00:0 has been assigned to a different IOMMU domain类似的提示。这一步是转折点,说明卡被 IOMMU 分组抓走了。
第三步,验证假设:ls -l /sys/bus/pci/devices/0000:01:00.0/driver指向的是vfio-pci而不是nvidia。基本确认。
第四步,处理:BIOS 里把 IOMMU 关掉,同时清掉之前为直通配置写的vfio-pci绑定规则(通常放在/etc/modprobe.d/下的某个 conf 文件里),重建 initramfs 后重启。
结果:nvidia-smi正常输出,显存 8GB 完整识别,链路跑到预期规格。
这次的经验是:在本地使用独显的机器上,IOMMU 和 vfio 配置是隐性杀手。如果你之前在这台机器上折腾过虚拟机直通,那些配置文件会一直生效,装新卡的时候就把卡截走了。排查顺序上,dmesg比任何教程都有用。
6. 海光平台上真实会遇到的四类坑
前面讲的都是通用流程,这一节专门讲海光平台结合 RTX 5060 时特有的几个坑。这几个问题我在不同机器上遇到过至少两个,都是能复现的。
6.1 显存只认出一半:Above 4G 与 Large BAR
现象是nvidia-smi能跑,但memory.total显示的值明显偏小,或者跑大模型加载权重时直接报内存分配失败。
根因在地址空间分配。GPU 的显存需要被映射到系统物理地址空间,如果固件没有打开 Above 4G Decoding,可用地址空间不够,BAR 只能分配一小块。先确认 BIOS 里 Above 4G Decoding 和 Re-Size BAR 都开了,然后用lspci -vv复核 BAR 区域的 size 字段。
如果 BIOS 已经开了但还是不行,可以试试在内核命令行加参数:
pci=realloc=on这个参数让内核重新分配 PCI 资源,对某些固件分配不合理的情况有效。加到/etc/default/grub的GRUB_CMDLINE_LINUX_DEFAULT里,然后sudo update-grub && sudo reboot。
还有一个容易被忽略的点:显存被其他设备占用。如果这台机器上还有别的显卡或者带显存的加速卡,地址空间会被竞争。我在一台双卡机器上遇到过,两张卡都插着的时候其中一张只能认出 4GB,单独插就没问题。这种情况下只能调整插槽或者升级固件。
6.2 满载自动重启与黑屏:供电、ASPM 与内核参数
热搜里的"ubuntu22.04 会自动重启"和"黑屏"两个词,在 5060 这个场景下经常是同一个问题的不同表现:电源或者 PCIe 链路在高负载下不稳。
排查顺序我一般是这样的:
先看物理供电。RTX 5060 的整卡功耗在一百多瓦量级,需要独立供电接口。海光整机的电源有时候是按原配配置选的,加了显卡之后余量不足。用一个能测功率的插座实测一下满载功耗,比猜靠谱。
再看 PCIe 电源管理。Linux 默认会打开 ASPM 省电,某些海光平台的固件 ASPM 实现和 NVIDIA 驱动配合得不好,表现为负载一上来就掉链路。内核参数关掉它:
pcie_aspm=off还有一个是 NVIDIA 驱动自己的电源管理。可以试着在服务配置里关掉持久化模式的反向操作,即让它按要求运行:
# 查看当前电源限制与状态 nvidia-smi -q -d POWER # 若出现 ECC 或掉卡日志,看看是不是撞了功耗墙 nvidia-smi -q -d PERFORMANCE | grep -A5 "Clocks Event Reasons"如果nvidia-smi dmon里看到持续出现SW Power Cap或者Thermal的标记,说明卡在被限制运行,需要检查散热和电源余量。海光平台机箱风道跟消费级机箱不一样,显卡进风经常被挡,温度上得快。
6.3 插错 PCIe 槽位,性能直接腰斩
RTX 5060 是 PCIe 5.0 x8 的接口。这个设计本身没问题,但意味着它对插槽的通道数非常敏感。插在 CPU 直连的 x16 物理槽位(电气至少 x8)上,能跑满;插在芯片组引出的 x4 槽位上,带宽直接砍到四分之一。
判断方法:
# 查看当前链路宽度与速率 nvidia-smi --query-gpu=pcie.link.gen.current,pcie.link.width.current --format=csv # 与规格对比 nvidia-smi --query-gpu=pcie.link.gen.max,pcie.link.width.max --format=csv如果 current 明显低于 max,先看是不是空闲时降速(这是正常省电行为,跑负载时会自动升上去),跑个负载再看。如果跑负载还是低,那就是插槽问题。
海光 3490 平台的 PCIe 拓扑,建议查一下主板手册确认哪个槽位是 CPU 直连。一般来说离 CPU 最近的那个长槽是直连的,但不同厂商设计差别很大,别猜。
6.4 内核一升级,驱动就掉了
这个坑跟前三个不一样,它不会立刻出现,但迟早会来。某天你执行了一次apt upgrade,内核从 6.8.0-45 升到 6.8.0-51,重启之后黑屏或者nvidia-smi报模块找不到。
原因有两层。apt 路线下,如果驱动装了 DKMS 支持,升级内核时会自动重编模块,一般能自动恢复;但如果你的apt-mark hold只锁了驱动主包没锁 dkms 包,版本对不上就会失败。.run路线下,如果安装时没加--dkms,那就必然掉,得重新跑一遍安装程序。
我的做法是给自己写一个自检脚本,开机后自动检查:
#!/bin/bash # /usr/local/bin/gpu-check.sh if ! nvidia-smi >/dev/null 2>&1; then echo "[$(date)] NVIDIA driver check FAILED" >> /var/log/gpu-check.log lsmod | grep nvidia >> /var/log/gpu-check.log dmesg | grep -i nvidia | tail -20 >> /var/log/gpu-check.log fi配一个 systemd timer 每天跑一次,出问题的时候日志里能直接看到是哪次升级之后坏的,省得靠回忆。
7. 驱动之后的事:CUDA 12.8、深度学习栈与日常维护
驱动跑通只是第一关。如果你这张 RTX 5060 是要用来做推理或者训练的,后面的版本咬合关系才是真正耗时间的地方。
7.1 CUDA 与 PyTorch 的版本咬合关系
Blackwell 架构需要 CUDA 12.8 及以上。这个约束会往上传染:
- CUDA Toolkit:装 12.8 或更新版本,
sudo apt install cuda-toolkit-12-8。注意别用apt install cuda,那个元包会连带升级驱动。 - PyTorch:需要装 cu128 的 wheel,
pip install torch --index-url https://download.pytorch.org/whl/cu128。老版本 PyTorch 的 cu118/cu121 wheel 里没有 Blackwell 的 kernel,装上去能 import 但一跑就报错。 - cuDNN:跟随 CUDA 12.8 对应的版本,别用更老的。
验证环境是否真的可用:
python -c "import torch; print(torch.__version__, torch.version.cuda, torch.cuda.is_available()); print(torch.cuda.get_device_name(0))"cuda.is_available()返回 True 且设备名正确,才算这条链路打通。我见过不少人卡在这一步,torch.cuda.is_available()一直是 False,最后发现是 pip 装的是 CPU 版本的 wheel,跟驱动一点关系都没有。
注意:
apt install cuda会装一大堆你可能用不到的东西(nsight、samples 等),而且会拉动驱动版本。用cuda-toolkit-12-8更干净,只装编译器、库和头文件。
7.2 持久化模式与开机自检脚本
对于常驻跑推理服务的机器,建议打开持久化模式:
sudo nvidia-smi -pm 1 # 或者用守护进程方式 sudo systemctl enable --now nvidia-persistenced持久化模式的作用是让驱动一直保持加载状态,避免频繁请求时每次都要重新初始化 GPU。对于低频调用的场景,省掉的是每次几百毫秒的初始化开销;对高频服务,主要是避免掉卡。
nvidia-persistenced和nvidia-smi -pm 1的区别在于前者是系统服务,能跟随系统启动,后者重启就没了。生产机器用前者。
顺便说个我自己的习惯:每台跑 GPU 的机器上都放一个gpu-check.sh,内容就是前面 6.4 节那个脚本,再加几行把nvidia-smi的关键字段和时间戳记到日志里。半年后回头查某次异常,有日志和没日志的排查效率差着数量级。
7.3 升级节奏:什么时候该动,什么时候别动
最后聊聊维护节奏。这台机器如果已经在跑服务,我的原则是驱动不追新,内核不追新。
驱动只在你遇到具体问题时升:新游戏或者新框架要求更高版本、遇到明确的 bug 修复、或者官方发布了对你这张卡的重要性能优化。升级前先在测试机上验证,确认nvidia-smi、实际负载、休眠唤醒都正常,再推给生产机。
内核方面,HWE 分支每几个月会推新版本,如果驱动是 DKMS 装的,升级会自动重编。但我一般会把 HWE 内核也apt-mark hold,跟驱动保持一个稳定的组合。真到要升级的时候,一次性升内核和驱动,然后完整跑一遍验证流程。
数据库备份、配置备份这类常规操作之外,GPU 机器上值得额外备份的是/etc/modprobe.d/目录和内核命令行。我遇到过驱动装好后忘记记录 BIOS 改了哪些选项,后来固件被重置,花了半天重新摸索。现在我的做法是每台机器改动完之后,把 BIOS 关键选项、内核参数、驱动版本拍张照或者写进一个 README,放在/root/下。这个习惯看起来土,但真的省事。