装机这事儿,说难是难在让人摸不着头脑的报错,说简单,其实就是一套固定的流程把它走通。最近给一台装好 Ubuntu 20.04 桌面版的工作站配 CUDA 11.8,折腾了两天,踩了不少坑,所以把这套完整的安装思路、步骤和排查方法整理出来。只要你跟着这篇文章走一遍,基本不需要再去搜索引擎里一段一段地找解决方案。
这篇文章针对的是 Ubuntu 20.04 Desktop(Focal Fossa)配上 CUDA 11.8 的完整安装过程。为什么强调 Desktop 版本?因为桌面版带图形界面,驱动和显示管理器的冲突是很多问题的根源,比如安装完驱动进不了桌面、黑屏、循环登录,这些都是我实际踩过、也帮你提前排除掉的坑。CUDA 11.8 是一个应用非常广泛的版本,很多机器学习和科学计算框架对它的支持非常成熟,这也是我选择这个版本的原因。
1. 安装前的环境检查与准备工作
1.1 先确认你到底要不要装、要装什么
很多人一上来就找教程复制命令,结果装完了也不知道自己装的是什么东西。我们先花两分钟把环境摸清楚,这一步能帮你避开后面一半的坑。
首先是确认显卡型号。打开终端,输入:
lspci | grep -i nvidia如果你看到类似NVIDIA Corporation GA102 [GeForce RTX 3080]这样的输出,说明系统识别到了 NVIDIA 显卡。如果没有任何输出,那就麻烦了,可能是显卡没插好、没有供电、或者 BIOS 里没开启独立显卡。这一点在笔记本双显卡机型上尤其常见,你得进 BIOS 确认显卡模式是不是也勾选了独立显卡这里就不展开讲了。
然后是确认系统版本和内核版本:
lsb_release -a uname -r我这边输出是Ubuntu 20.04.6 LTS,内核是5.15.0-XX-generic。这里要注意,同一个 Ubuntu 版本,内核对驱动和 CUDA 的兼容性会影响比较大。5.15 这个内核版本对 NVIDIA 驱动和 CUDA 11.8 的支持很稳定,推荐使用,新内核或者老内核都可能有一些奇怪的问题。
最后看一下 GCC 编译器版本,因为 CUDA 运行时里有一部分组件需要用到本机编译器,不仅仅是 nvcc。输入:
gcc --versionCUDA 11.8 官方支持到 GCC 10,Ubuntu 20.04 默认安装的是 GCC 9,正好在支持范围内。如果你之前为了别的事情升级了 GCC 到 11、12,编译 CUDA 工程时就会遇到兼容性报错,后面第五节我会讲怎么处理。
1.2 旧驱动和 CUDA 的清理工作
如果你这台机器之前装过 NVIDIA 驱动或者 CUDA,强烈建议先全部清理干净。混装新旧驱动是黑屏和循环登录的头号凶手。
先查看装的什么驱动:
dpkg -l | grep nvidia如果有输出,说明之前装过,用下面的命令清理:
sudo apt-get purge nvidia* libnvidia* sudo apt-get autoremove对于之前用 runfile 方式装的 CUDA,也要手动清理一下:
sudo rm -rf /usr/local/cuda*然后最好把/usr/local/下面的 cuda 目录都看一下,确认清理干净了再往下走。这个步骤不能偷懒,尤其是从 CUDA 10 或者 11 老版本升级到 11.8,残留的库文件会让你在编译的时候遇到各种链接错误。
1.3 禁用 nouveau 驱动:UEFI 安全启动和显示管理器的问题
Ubuntu 系统自带的nouveau是一个开源的 NVIDIA 驱动,它和英伟达官方闭源驱动不兼容。如果不禁用它,安装官方驱动后大概率会出现黑屏、闪屏,甚至在登录界面无限循环。
创建一个配置文件:
sudo bash -c "echo -e 'blacklist nouveau\noptions nouveau modeset=0' > /etc/modprobe.d/blacklist-nouveau.conf"然后再更新内核引导,否则上面的配置不会生效:
sudo update-initramfs -u改完内核参数以后需要重启:
sudo reboot重启之后验证一下 nouveau 是否真的被禁用了:
lsmod | grep nouveau如果没有输出,说明禁用生效了。这一步做完,驱动安装的环境就准备好了。
特别提醒:如果你的机器开了 Secure Boot(安全启动),安装驱动的时候会被卡住,提示需要签名密钥。最简单的方式是进 BIOS 把它关掉,否则你要自己去弄一套 DKMS 签名流程,非常繁琐。
2. NVIDIA 驱动安装策略与实操
2.1 驱动版本到底应该怎么选:别照抄最新版
装 CUDA 之前,显卡驱动是第一道门槛。很多人纠结选哪个版本的驱动,我在这一步也踩过坑——直接装了当时最新的 545 版本,结果和 CUDA 11.8 配合时,虽然能跑,但编译 PyTorch 扩展的时候会出现警告,性能测试的表现也不稳定。
推荐的原则很简单:CUDA 11.8 官方建议的最低驱动版本是 520.61.05,但实际使用中 525、535 这些分支的驱动和 CUDA 11.8 配合都很稳定。你要知道,驱动和 CUDA 的关系是“向下兼容”的,高版本驱动可以跑低版本 CUDA,反过来不行。所以你可以装相对新的驱动,但不能装超过太多。
用ubuntu-drivers工具检测系统推荐的版本:
ubuntu-drivers devices这个命令会列出你的显卡设备和可用的驱动版本,还会推荐一个版本(有recommended标记)。但注意,recommended推荐的往往是最新版本,不一定是最合适的。我的做法是,先去英伟达官网查 CUDA 11.8 的兼容驱动列表,然后选一个在该列表范围内、又不太旧的版本安装。比如这次我装的是 535 系列驱动,非常稳。
2.2 安装驱动:apt 方式还是 runfile 方式?
NVIDIA 驱动安装有两种主流方式,一种是利用 Ubuntu 软件源通过 apt 安装,另一种是去官网下载 runfile 手动安装。我强烈推荐 apt 方式,除非你有特殊需求。
apt 方式的好处是:
- 依赖关系由系统自动处理
- 卸载方便,不会残留
- 和系统内核模块的衔接更平滑,不容易出现模块加载失败
执行安装:
sudo apt install nvidia-driver-535如果你想省事,也可以直接执行sudo ubuntu-drivers autoinstall自动安装推荐版本。
开启 32 位架构(某些应用和 OpenGL 库需要):
sudo dpkg --add-architecture i386 sudo apt update安装完以后重启:
sudo reboot开机后验证:
nvidia-smi如果能正常显示显卡信息、驱动版本和 CUDA 版本号(注意这里显示的 CUDA 版本只是驱动支持的版本,不代表你已经装了 CUDA 11.8),说明驱动安装成功了。
我当时用nvidia-smi看到输出显示Driver Version: 535.XXX CUDA Version: 12.2,其实心里有数,这个 CUDA Version 只是个上限,不是说你已经装好了 12.2。不要被它误导。
2.3 驱动装完以后的黑屏自救方法
很多人装完驱动以后重启,卡在登录界面或者黑屏。这个问题很常见,但绝大多数情况下只是因为 display manager 没有正确加载。
在黑屏的界面按Ctrl + Alt + F2进入虚拟终端,登录你的账户,然后查看日志:
cat /var/log/Xorg.0.log | grep EE常见的原因有两种:
- nouveau 模块没有被正确禁用,重新检查
lsmod | grep nouveau,确保没有输出 - 驱动和当前内核版本不匹配,卸载重装驱动,或者换个版本试试
如果实在救不回来,就在虚拟终端里卸载驱动回到老版本:
sudo apt purge nvidia-driver-* sudo reboot只要 nouveau 禁用的步骤没做错,驱动版本不过于新,这一步一般不会出问题。但备份好这个逃生通道,心理压力会小很多。
3. CUDA 11.8 安装全流程
3.1 下载 cuda_11.8.0_linux.run
这里要说一句,很多人跑去 NVIDIA 官网首页下载,发现最新已经是 CUDA 12.x 系列了,翻半天找不到 11.8。因为 11.8 已经不是“当前版本”了,你需要去官网的归档页面(CUDA Toolkit Archive)才能找到旧版本的链接。
页面里找到 CUDA Toolkit 11.8.0,选择 Linux 操作系统、x86_64 架构、Ubuntu 20.04,系统会给你一个类似这样的下载命令(注意我打码了一部分,实际以官网为准):
wget https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda_11.8.0_520.61.05_linux.run下载后建议先检查一下文件大小和 MD5 校验,确保文件完整。文件大概有 3GB 左右,如果太小,一般是网络中断导致下载不完整,运行的时候会报tar: Error is not recoverable这样的错误。
3.2 runfile 安装器交互式操作要点
下载完后给执行权限:
chmod +x cuda_11.8.0_520.61.05_linux.run开始安装:
sudo sh cuda_11.8.0_520.61.05_linux.run这里有一系列交互式提示,我把关键节点梳理一下。首先它会建议你用--toolkit只装 Toolkit 部分,因为它检测到你已经有驱动了。我建议直接接受这个默认建议,只安装 Toolkit,因为驱动部分我们在第二步已经装好了,重复安装反而可能引起版本冲突。
接下来会打出一大段英文协议说明,让你确认或者拒绝。这里直接输入accept按回车。然后你需要看到组件清单(Component Selection),在这个界面里:
[X] Driver:这个复选框默认是选中的,你必须取消它[X] CUDA Toolkit 11.8:保持选中[X] CUDA Demo Suite和[X] CUDA Documentation:按需选择,我建议都留着,后面验证用到 demo suite
操作方式是按上下键移动光标,按空格切换选中/取消。取消 Driver 后,移到Install按回车,安装过程就会开始。整个安装大概几分钟,看你的硬盘读写速度。
安装完成后会有提示Please make sure that PATH includes /usr/local/cuda-11.8/bin,这就是告诉你下一步要配置环境变量了。
3.3 配置 PATH 和 LD_LIBRARY_PATH:写成软链接才是长久之计
安装目录在/usr/local/cuda-11.8。为了以后多版本切换方便,NVIDIA 默认会在/usr/local/cuda创建一个软链接指向cuda-11.8。如果你装的是唯一的版本,可以只用/usr/local/cuda这个路径,这样版本升级时不用改环境变量。
配置用户级环境变量(不影响系统其他用户):
echo "export PATH=/usr/local/cuda-11.8/bin:$PATH" >> ~/.bashrc echo "export LD_LIBRARY_PATH=/usr/local/cuda-11.8/lib64:$LD_LIBRARY_PATH" >> ~/.bashrc加载配置:
source ~/.bashrc验证是否配置成功:
which nvcc nvcc --version如果which nvcc输出/usr/local/cuda-11.8/bin/nvcc,说明环境变量生效了。
还有一个很多人忽略的点:如果你用的是 zsh,要写进
~/.zshrc而不是~/.bashrc。我见过有人两个都配了,后来切换 shell 的时候环境变量对不上,编译程序的时候老是找不到 nvcc。
4. 验证安装与编译首轮测试
4.1 检查 nvcc 和 nvidia-smi 的版本一致性
打开终端,输入:
nvcc --version正常输出最后会有Cuda compilation tools, release 11.8, V11.8.89,说明 nvcc 编译器已经就位。
同时跑一下:
nvidia-smi右上角显示CUDA Version: 11.8就对了?这里提醒你,不一定。nvidia-smi显示的 CUDA 版本是驱动支持的最高 CUDA 版本,如果驱动版本是 535.xxx,这里可能会显示12.2。这不影响你的 nvcc 工具链是 11.8,两者不冲突。你在跑实际应用的时候,程序会通过运行时 API 请求 CUDA 版本,驱动只要大于等于这个版本就能正常工作。
判断装没装对的唯一标准是:nvcc --version输出 11.8,同时nvidia-smi能正常显示显卡信息,就说明工具链已经通了。
4.2 编译示例程序 deviceQuery
CUDA 自带的示例程序里有一个deviceQuery,用来查询显卡支持的 CUDA 能力,也用来验证整个工具链能不能正常编译运行。
进入示例目录:
cd /usr/local/cuda-11.8/extras/demo_suite/执行编译:
sudo make或者不用 sudo,直接:
make然后运行:
./deviceQuery如果输出最后包含Result = PASS,说明你的 CUDA 运行环境是完全正常的。如果这里失败,那说明虽然 nvcc 能跑,但运行时和驱动的通信有问题,多半是驱动没配对。
4.3 写个最小测试程序验证编译器到运行时全链路
示例程序通过不代表你自己的编译环境没问题。我再习惯性地写一个最小的测试程序,验证一下 nvcc 能不能编译用户代码,并且能调用到各版本的运行时库。
新建一个文件test.cu:
#include <cstdio> __global__ void hello_kernel() { printf("Hello from GPU thread %d\n", threadIdx.x); } int main() { hello_kernel<<<1, 8>>>(); cudaDeviceSynchronize(); return 0; }编译:
nvcc -o test test.cu运行:
./test如果输出 8 行Hello from GPU thread X,说明 nvcc、CUDA 运行时、驱动三个环节全部正常工作。这一步其实比deviceQuery更有意义,因为这模拟了你平时实际开发时遇到的环境要求。
如果你连这一步都通过了,那么恭喜你,CUDA 11.8 安装已经彻底完成,可以放心去编译 PyTorch、TensorFlow 等框架及其扩展模块了。
5. 常见安装问题与排查技巧实录
5.1 为什么我编译时提示找不到cuda_runtime.h
这个报错和安装无关,是环境变量没配好。nvcc在编译时默认会在/usr/local/cuda/include找头文件。如果你安装完 CUDA 后没有配置软链接(或者软链接指向了不存在的目录),就会找不到头文件。
解决方式很简单:
ls -l /usr/local/cuda确认软链接是否存在。如果不存在,手动创建:
sudo ln -s /usr/local/cuda-11.8 /usr/local/cuda另外一个隐蔽的问题是,如果你之前手动设置了CUDA_HOME环境变量,而它指向了错误的路径,也会导致编译时找不到头文件。检查一下:
echo $CUDA_HOME最好让CUDA_HOME指向/usr/local/cuda,这样以后升级版本也不会变。
5.2 编译报错与 GCC 版本不兼容:常见但不是大问题
如果你在编译某些旧项目时出现一堆模板或者内联函数相关的报错,很可能是因为 GCC 版本高于 CUDA 支持范围。CUDA 11.8 支持的 GCC 上限是 10,Ubuntu 20.04 默认 GCC 是 9,一般不踩雷。但有些人手动升级过 GCC,比如升到 11 或 12,就会遇到这种问题。
最简单的处理方法是用 update-alternatives 临时切换 GCC 版本:
sudo apt install gcc-10 g++-10 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 100这里补充一句,除非你有非用不可的理由,否则不用升级系统默认 GCC,Ubuntu 20.04 自带的 GCC 9 搭配 CUDA 11.8 是官方测试过最稳的组合。
5.3 安装 CUDA 时误勾选了 Driver,结果驱动版本冲突
runfile 安装界面默认会勾选 Driver,如果你忽略了这个细节,直接把 Driver 也装上了,它会把已有的 apt 驱动替换成打包的 520.61 版本。这个驱动版本比较老,和你 Ubuntu 20.04 内核的适配程度不如 535,可能出现一些小毛病。
如果发生冲突,处理方式是重新安装一次自己想要的驱动版本,然后确认/usr/local/cuda-11.8里面是不是只有 Toolkit。查看:
ls /usr/local/cuda-11.8/bin/ | grep nvcc如果正常显示nvcc,再跑一下nvidia-smi确认驱动还活着,基本就没问题了。所以再次提醒,在 Component Selection 界面,Driver那一项一定要取消勾选。
5.4 循环登录问题的终极排查思路
这是 NVIDIA 驱动安装最经典的问题之一。表现是你在登录界面输入密码后,屏幕闪一下又回到登录界面。这一步我在第一节提到过,但这里把排查思路讲完整。
首先按Ctrl + Alt + F3进入 tty 终端,登录后查看 Xorg 日志:
cat /var/log/Xorg.0.log | grep -i error如果有(EE) NVIDIA(0): Failed to assign any connected display devices这样的错误,多半是驱动和显示器连接问题,重新拔插 HDMI/DP 线,或者检查是不是显卡供电不足。
如果日志显示模块加载错误,比如Failed to load module "nvidia",重新安装驱动:
sudo apt install --reinstall nvidia-driver-535最后如果实在排查不出来,进入恢复模式,使用sudo apt purge nvidia-*恢复系统,再用本文第二小节的步骤重装一次即可。不要觉得循环登录是不可挽救的问题,它有固定的解决路径,一步一步排查就可以了。
结尾补充:最后分享一点个人经验
装完 CUDA 不是终点,而是开始。真正干活的时候你会发现,光有工具链远远不够——还要适配深度学习框架、装 cuDNN、管理 NCCL,这些后续配置每一个都可能踩坑。但这一切的前提是,你的 CUDA 基础装得足够干净、足够稳定。
我个人在实际安装中最大的体会是:装驱动时不要贪新、装 CUDA 时不要贪全、配置环境变量时不要贪多。一步步来,每装完一个环节就验证一次,即使中间出了问题,你也能立刻定位到是哪一步出错。别像我第一次那样一股脑全装完,黑屏之后完全不知道从哪开始排查,只能重装系统。
最后再分享一个小技巧:在你成功安装完驱动和 CUDA 之后,给系统做一次快照或者备份。比如用 TimeShift 做一个系统备份,以后不管怎么折腾,一条命令就能还原到当前这个干净的状态。这套流程加上备份方法,足够应付实验室、公司环境里大部分深度学习开发机的部署需求了。