从没想过装显卡驱动会变成一门"玄学"。上周我给一台只装了 Ubuntu 22.04 的机器配 RTX 3090,网上一搜,教程确实多,可大部分都默认你是 Windows + Ubuntu 双系统,动不动就让你回 Windows 关快速启动、备份 EFI 分区、处理时间同步。我这边是干净到不能再干净的纯 Linux 环境,照着做反而绕了远路。折腾完之后回头看,发现纯 Ubuntu 系统装这块卡,真正容易翻车的地方根本不是引导、也不是双系统共存的那些问题,而是 Secure Boot、Nouveau 这类的细节。这篇就是给同样想在干净 Linux 环境下把 3090 用起来的朋友做的补充,我尽量把官方文档和常规教程里一笔带过的部分写透。
1. 为什么说"纯Ubuntu"反而是最容易翻车的前提
1.1 双系统教程的惯性思维,坑了多少纯Linux用户
大多数搜索到的装机教程,默认场景都在双系统:先装 Windows,然后折腾 Ubuntu。于是教程里会告诉你"关闭 Secure Boot,否则 Windows 和 Linux 的引导可能出问题""不要格式化整个硬盘""保留 Microsoft Reserved 分区"。
这些建议对双系统来说没毛病,但对纯 Ubuntu 单系统用户来说,很多步骤是多余甚至有害的。举个例子:双系统教程会让你在 BIOS 里把 UEFI 引导模式改来改去,而纯 Ubuntu 环境下你只需要保证 UEFI 模式和 Secure Boot 状态统一即可。还有一个更隐蔽的点:双系统下,如果你在 Ubuntu 侧装了 NVIDIA 驱动,重启后 Windows 的 grub 菜单可能消失;反过来纯 Ubuntu 系统虽然没有 Windows 的干扰,但如果 Secure Boot 没有处理好,重启后连 grub 都进不了,直接黑屏或者卡在主板 logo。两种环境的故障表现完全不同,排查思路自然也不一样。
1.2 纯Ubuntu环境下三个被忽略的状态
纯 Ubuntu 系统装 3090 之前,有三个状态是我建议提前确认的,它们决定后续用哪套安装方案:
- Secure Boot 是否开启:Ubuntu 默认镜像的 shim 签名机制,会决定你装第三方 NVIDIA 驱动时需不需要走 MOK 签名流程。
- Nouveau 开源驱动是否占用显卡:几乎每个用桌面版 Ubuntu 的用户都会在安装后有这个隐藏占用,它会让 NVIDIA 官方驱动安装器直接报"找不到可用的显卡"或者编译失败。
- 内核头文件是否匹配当前内核:这一步大多数人会忘,结果一重启,驱动没了,或者在安装 runfile 时提示需要"kernel source tree"。
把这三点摸清楚,后面两个大坑(黑屏、和 nvidia-smi 通信失败)基本就都避开了。这也是为什么我坚持把这篇叫"补充教程"——官方文档只告诉你"装这个包",但这些前置条件往往一句都没有。
1.3 我的实测感受:单系统不是更容易,而是坑更少但更致命
从操作的舒适度来说,纯 Ubuntu 确实比双系统省心:不用维护两套引导、不用在 Windows 里折腾磁盘分区、GPT 分区表只需要挂一个根分区加一个 EFI 分区就够。
但"更致命"这几个字不是乱说的。双系统下驱动装坏了,你还能切回 Windows 下载工具、查资料再想办法;纯 Ubuntu 下如果驱动和系统核心模块冲突,轻则进不了图形界面,重则连 TTY 都要靠 recovery 模式才能恢复。所以我后面所有步骤,都会带着"万一出问题怎么退回来"的思路来讲。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 装驱动前必须做完的五项检查
2.1 确认显卡被主板和系统正确识别
开机先确认 BIOS 能看到这张 3090。有些主板默认把 PCIe 插槽的链路速度调在较低档位(比如 PCIe 3.0、甚至 Gen1),虽然不影响安装,但后面性能测试数值会很难看。进入系统后,两步验证:
bash复制lspci | grep -i nvidia
lshw -C display | grep -i product
如果 lspci 看不到设备,请先检查供电、PCIe 插槽是否插紧。这步最容易被忽略,尤其是从二手市场收回来的 3090,接触不良的概率比新卡高很多。我看到过太多案例,驱动装了一晚上,最后发现是供电没插到位。
2.2 补齐编译工具链和内核头文件
NVIDIA 官方 runfile 安装器本质上是一个内核模块编译过程。系统里没有 gcc、make 或者和当前内核版本完全一致的头文件,安装器会在最后一步报错,而且报错信息非常模糊。一个可靠的顺序是:
bash复制sudo apt update
sudo apt install build-essential dkms
sudo apt install linux-headers-$(uname -r)
请注意,这里用 $(uname -r) 自动匹配当前内核版本,不要手动指定一个旧版本号然后发现"明明装了头文件却还是编译失败"。如果你打算长期使用这个系统,还建议装 dkms,它就是用来在系统内核升级时自动重编第三方驱动的。没有 dkms 的坑,我会在第五节专门讲。
2.3 确认 Secure Boot 状态
这个问题太容易被跳过了。执行:
bash复制mokutil --sb-state
输出可能是 SecureBoot enabled 也可以是 SecureBoot disabled。
- 如果是 disabled,你可以用最轻松的 apt 源方式安装。
- 如果是 enabled,并且你打算用官方 runfile,就必须提前生成一对 MOK 密钥并给驱动模块签名;或者干脆进入 BIOS 暂时关掉 Secure Boot。
很多帖子一上来就说"为了装驱动必须关 Secure Boot",这对纯 Ubuntu 用户来说不完全对。如果你只是通过 Ubuntu 官方仓库装 nvidia-driver,这些包是经过签名的,Secure Boot 开着也没问题。只有当你使用 NVIDIA 官方 runfile 时,才需要认真考虑签名或临时关闭的问题。
所以这步的价值在于:先判断,再决定安装路线,而不是无脑关。无脑关掉 Secure Boot 虽然也能装好,但对安全敏感的用户、或者日后想保持系统完整性的人来说,会有额外的顾虑。
2.4 软件源更新和镜像加速
apt 源这一步不多说,但有个细节值得记一下:安装完系统之后不要急着装驱动,先把软件源里的配置检查一遍,然后执行一次完整升级再回来看驱动。因为 Ubuntu 22.04 有许多基础修复和安全补丁,它们会依赖新的内核头文件。如果先装驱动再升级内核,驱动版本匹配会变得混乱。
2.5 排查已有驱动残留
如果你的机器之前折腾过显卡,装新驱动前把旧东西清干净:
bash复制dpkg -l | grep -i nvidia
ls /etc/modprobe.d/ | grep -i nvidia
ls /usr/local/ | grep -i cuda
有残留的旧包,建议直接卸掉,否则新旧模块冲突的时候,错误日志会复杂到你根本看不出问题在哪。这条我深有体会:某天新装好驱动一切正常,结果一重启就黑屏,日志里全是旧模块的符号冲突。后来发现是之前留下的旧版本模块没删干净,和新版的一起挂在 initramfs 里。
3. 驱动安装:仓库源与官方runfile两条路怎么选
3.1 路线一:Ubuntu 仓库安装,稳定省心
对绝大多数用户,我推荐先用这条。检查系统推荐版本:
bash复制ubuntu-drivers devices
输出里会列出若干候选,比如 nvidia-driver-535、nvidia-driver-550。直接装推荐项:
bash复制sudo apt install nvidia-driver-550
sudo reboot
重启后 nvidia-smi 能看到显卡信息和驱动版本,就说明成功了。仓库方式的优势很明显:
- 内核模块已经签名,Secure Boot 开着也能正常加载;
- 系统内核升级后,dkms 会自动重新编译模块;
- 卸载干净,一条
apt remove --purge就能把相关包清理掉。
缺点则是版本滞后。官方驱动可能到了 560 或更高,仓库里可能还停在你安装时的稳定版。如果你需要最新驱动来支持新显卡、新特性,仓库源往往跟不上。
3.2 路线二:NVIDIA 官方 runfile,精确但曲折
如果你确定要自己控制版本,可以用 runfile。这里我把完整流程按顺序写出来,少一步都有坑。
第一步,停用 Nouveau。Nouveau 是内核自带的 NVIDIA 开源驱动,会和官方闭源驱动抢设备。创建黑名单文件:
bash复制sudo tee /etc/modprobe.d/blacklist-nouveau.conf <<EOF
blacklist nouveau
options nouveau modeset=0
EOF
然后更新 initramfs 并重启:
bash复制sudo update-initramfs -u
sudo reboot
第二步,准备纯文本模式。官方驱动安装器在图形界面运行时容易出现各种冲突,建议在登录界面按 Ctrl+Alt+F3 进入 tty3,用终端登录后先停掉显示管理器:
bash复制sudo systemctl stop gdm3 # 如果你用的是 lightdm,就 stop lightdm
第三步,运行安装器:
bash复制chmod +x NVIDIA-Linux-x86_64-*.run
sudo ./NVIDIA-Linux-x86_64-*.run
安装过程中有几个交互选项,很多人没注意就直接回车了:
- 是否安装 32 位兼容库:如果你不做 32 位应用兼容,可以不装;
- 是否更新 X 配置:建议选否,Ubuntu 的 Wayland 和 Xorg 配置由系统统一管理,让 NVIDIA 安装器改可能引入冲突;
- 是否生成 DKMS 模块:建议选是,这样和仓库安装一样具备内核升级自动重编能力。
第四步,重启前确认模块能正常加载:
bash复制sudo modprobe nvidia
nvidia-smi
最后重启。如果这步 nvidia-smi 已经能看到显卡,重启大概率不会翻车。
3.3 两条路线到底怎么选:我给三种人群的建议
| 你的情况 | 推荐路线 | 原因 |
|---|---|---|
| 只是想稳定使用、跑跑图形加速 | Ubuntu 仓库驱动 | 省心、签名完整、容易回滚 |
| 要跑深度学习/CUDA 特定版本 | NVIDIA 官方 runfile | 精确控制驱动版本和 CUDA 兼容性 |
| 对版本有新功能强需求 | 官方 runfile | 仓库源滞后明显 |
另外补充一点:如果你已经决定用 CUDA 12.x,驱动版本其实不用太纠结。3090 是 Ampere 架构,从较早期的 470 版本开始官方就支持了,仓库里的 535/550 完全够用。除非你要追最新的 CUDA,否则我经验上不建议为了"最新"而去折腾 runfile。
4. CUDA/cuDNN配套:别再盯着nvidia-smi顶部的版本号
4.1 nvidia-smi 显示的不是"已装CUDA版本"
这个误区太常见了。nvidia-smi 右上角确实有一行 CUDA Version: 12.4,但那是当前驱动最大能支持的 CUDA 运行时版本,并不是系统里已经安装的 CUDA Toolkit 版本。你可以驱动是 550、但系统里根本没有安装任何 CUDA Toolkit 也能看到这行字。
真正要确认 CUDA Toolkit 是否可用,执行:
bash复制nvcc -V
如果提示找不到命令,说明你还需要单独装 CUDA Toolkit。
4.2 装 CUDA Toolkit 的两种方式和环境变量管理
推荐用官方 runfile 方式安装 CUDA Toolkit,因为它不会污染 apt 源。下载对应版本后:
bash复制chmod +x cuda_12.4.0_550.54.14_linux.run
sudo ./cuda_12.4.0_550.54.14_linux.run --toolkit --silent
注意我在命令行里加了 --toolkit,意思是只安装 CUDA 工具包本身,而不顺带重新安装驱动。驱动已经有了,再装一遍反而容易出问题。
安装完成后,把环境变量写进 ~/.bashrc:
bash复制export PATH=/usr/local/cuda-12.4/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-12.4/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
这里有个值得注意的设计:/usr/local/cuda 是一个软链接,指向 /usr/local/cuda-12.4。以后如果你同时装了 11.8 和 12.4,切换版本只需要改软链接,环境变量里的路径可以保持不变。
4.3 cuDNN:其实只是几个头文件和库文件的集合
cuDNN 看起来是个大东西,实际安装说到底就是把解压出来的 include 和 lib64 目录内容复制到 CUDA 目录下:
bash复制sudo cp -r cudnn-linux-x86_64-8.9.7.29_cuda12-archive/include/* /usr/local/cuda/include/
sudo cp -r cudnn-linux-x86_64-8.9.7.29_cuda12-archive/lib/* /usr/local/cuda/lib64/
sudo ldconfig
然后验证:
bash复制cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR -A 2
从头文件和库文件的角度去理解 cuDNN 的安装,你就不会被那一堆压缩包名搞晕了。总之核心就是把新版本的头文件和库覆盖旧版本,ldconfig 刷新动态库缓存。
4.4 版本匹配的一个可靠经验
我曾经被"必须装最新 CUDA"这句话带偏过好几天。实际操作下来,深度学习框架对 CUDA 版本的要求并没有那么苛刻,只要驱动版本不低于某个最低值、CUDA Toolkit 版本不低于框架要求的版本,就能正常工作。
所以更实用的做法是:先看你要用的框架要求什么 CUDA 版本,再回来装对应或更高的、匹配的 Toolkit。比如框架要求 CUDA 11.8,那你装 12.1 也能跑,因为新版本通常兼容旧接口。反过来,框架要求 12.1,你却装 11.8,那就可能报错。
5. 跑起来之后:验证与稳定性检查
5.1 读懂 nvidia-smi 的几个关键字段
装好驱动后第一件事,当然是 nvidia-smi。别只看显卡名字认不认识,还要看:
- Driver Version:确认是你装的版本;
- CUDA Version:确认驱动能支持的上限;
- Memory Usage:3090 的 24GB 显存,待机时一般是几百 MB,如果待机就占了七八个 G,可能有别的进程占用或者驱动状态异常;
- Temp:待机温度一般三四十度,如果一开机就 70 度以上,看一下机箱风道。
如果要持续观察,我习惯:
bash复制watch -n 1 nvidia-smi
5.2 用框架快速验证 GPU 是否真能干活
驱动显示正常,不代表实际计算可用。我用一个简单的矩阵运算验证 GPU 计算能被正常调度:
python复制import torch
x = torch.randn(4096, 4096, device='cuda')
y = torch.randn(4096, 4096, device='cuda')
z = x @ y
torch.cuda.synchronize()
print(torch.cuda.get_device_name(0))
print(z.sum().item())
如果这段代码能正常跑完,说明从驱动到 CUDA 运行时再到框架调用层面都是通的。如果 device='cuda' 直接报错,那问题大概率还是出在驱动或者 CUDA 安装上。
5.3 持久模式、温度和功耗的日常管理
如果是工作站、服务器这类固定电源的场景,可以打开 GPU 持久模式,减少驱动初始化开销,也能让高频状态在空闲时更快降回来:
bash复制sudo nvidia-smi -pm 1
想要更细的功耗信息,可以用:
bash复制nvidia-smi -q -d POWER
3090 在满载时能到 350W 以上,机箱风道要求很高。如果你的机器是普通的塔式机箱,建议把侧板留好进风空间,或者考虑加装一个针对显卡的进风风扇。我吃过这个亏:某个 3090 满载跑深度学习模型时核心温度直接冲上 88 度,后来加了一个机箱风扇降到 72 度,稳定性算是稳住了。
5.4 内核升级后必须复查的一项
Ubuntu 会经常推送内核更新。如果之前不是用 dkms 方式安装的驱动,那么内核一升级,驱动模块就可能会失效,nvidia-smi 直接报 unable to communicate。
养成习惯,每次升级完系统重启之前,先跑:
bash复制dkms status
这个命令列出了所有由 dkms 管理的模块和状态。看到 nvidia/xxx, installed 就说明驱动模块会在新内核下自动重编。改动了内核或驱动相关的任何操作,都建议顺手看一眼这个输出。
6. 黑屏、模块加载失败、内核升级翻车:最常见坑的排查链路
6.1 重启后黑屏或卡在登录界面
这个场景一般出现在驱动安装器强制替换了 X 配置,或者 Nouveau 没有完全禁掉的时候。我建议的排查顺序是:
- 在登录界面按 Ctrl+Alt+F2 进入 TTY,确认系统本身还活着;
- 执行
dmesg | grep -i nvidia,看看有没有 module verification failed 或者 failed to load 之类; - 查
/var/log/Xorg.0.log,重点搜索(EE)开头的错误行; - 如果确认是模块加载不了,先回滚:
sudo apt remove --purge nvidia-driver-550,再重新装。
一个提示:纯 Ubuntu 系统没有 Windows 可以"保底",所以从第一次装驱动开始,保留一个能进入 TTY 的 recovery 入口很重要。grub 里一般会有 recovery mode,熟练用它进 root shell,就能把坏掉的驱动清掉。
6.2 nvidia-smi 报 unable to communicate with NVIDIA driver
这是最常见、也最容易误导人的错误。它不代表显卡坏了,通常是内核模块没加载:
bash复制lsmod | grep nvidia
sudo modprobe nvidia
dmesg | tail -30
如果你执行 modprobe 之后模块加载成功、nvidia-smi 恢复正常,那问题多半是 Secure Boot 开启导致驱动模块无法被加载,或者 initramfs 里没有把模块装进去。解决方式是重新生成 initramfs:
bash复制sudo update-initramfs -u
然后重启看是否还复现。这个坑在纯 Ubuntu 环境下比重装系统还要常见,我一度怀疑自己的 3090 有毛病,最后排掉这个原因之后一切安静。
6.3 CUDA 能编译但运行时找不到设备
编译你的程序没问题,运行时设备列表是空的,大概率原因包括:
- CUDA 工具包版本和驱动上限不匹配(比如驱动只支持到某版本,工具包却要求更高);
- 环境变量里的 LD_LIBRARY_PATH 指向了错误的 CUDA 版本;
- 当前 shell 里
source ~/.bashrc没有生效。
排查时可以一条条验证,最后用第五节写到的小例子跑通为止。这类问题基本不会和硬件相关,不要一上来就怀疑显卡坏了。
6.4 升级内核后驱动丢失
如果你用官方 runfile 安装时没有勾选 DKMS,那内核升级后驱动肯定会丢。修复方式也很简单:重新跑一遍安装器,让它只安装缺失模块:
bash复制sudo ./NVIDIA-Linux-x86_64-*.run --no-opengl-files --dkms
这里 --dkms 会把模块注册给 dkms 管理,以后内核升级自动重编,不用再来手动补一遍。所以我的建议是:runfile 安装时就直接用 --dkms,别嫌麻烦。
6.5 一个容易忽略的"残留模块冲突"
最后说一个我在实测过程中遇到、非常隐蔽的情况:系统同时存在多个 NVIDIA 模块版本,导致即使 modprobe nvidia 成功,加载的却是旧模块,图形界面依旧黑屏。
排查时需要进入 /lib/modules/$(uname -r)/kernel/drivers/video/ 查看现有 nvidia 模块文件的时间戳。如果是旧版本残留,删掉并让 dkms 重新生成。这种情况在反复装卸驱动后出现概率很高,建议大家操作前记录好 dkms status 的输出,别盲目重装。
如果只能记住一个习惯,那就是"每次动驱动之前,先看一眼 dkms status 和 Secure Boot 的状态"。这两条提前检查好,比什么高级排错命令都管用。我到现在装 GPU 机器,都会在内存里留一句:先确认环境,再动手,翻车的概率少一半。希望这篇补充教程能帮你在自己的纯 Ubuntu 22.04 + 3090 环境上少折腾几个深夜。
