1. 项目概述与核心价值

最近在帮几个刚入行的朋友和实验室的师弟配置深度学习环境,发现大家普遍卡在CUDA和cuDNN的安装上,尤其是用Ubuntu系统的新手。网上的教程要么太老,要么步骤跳跃太大,一个依赖没装对或者版本没选对,后面就是一连串的“未找到命令”或者“版本不兼容”。所以,我决定把在Ubuntu 20.04 LTS上,通过官方deb包安装CUDA 12和对应cuDNN的完整流程,以及最重要的验证方法,重新梳理一遍。这个流程最大的优点就是“干净”和“可控”,所有组件都通过系统包管理器管理,升级、卸载都方便,不容易把系统搞乱。即便是对Linux命令行还不太熟悉的“宝宝”们,只要跟着步骤一步步来,也能顺利搭建起自己的AI开发环境。

2. 环境准备与前置检查

在开始安装任何软件之前,做好准备工作是避免后续踩坑的关键。对于CUDA和cuDNN的安装,这一步尤为重要,它决定了你的系统是否具备安装条件,以及应该选择哪个版本的安装包。

2.1 系统与硬件确认

首先,我们需要确认两件事:你的Ubuntu系统版本和你的NVIDIA显卡型号。打开终端,输入以下命令查看系统信息:

lsb_release -a

你应该能看到类似 Description: Ubuntu 20.04.6 LTS 的输出,确认是20.04版本。接着,检查你的显卡是否支持CUDA。虽然大部分NVIDIA独立显卡都支持,但核显或非常老的显卡可能不行。使用 lspci 命令过滤查看:

lspci | grep -i nvidia

如果能看到你的显卡型号(比如 NVIDIA Corporation GA106 [GeForce RTX 3060] ),那就没问题。一个更直接的方法是访问NVIDIA官网的CUDA支持页面,查看你的显卡是否在列表内。

2.2 驱动安装与清理

CUDA Toolkit本身包含了驱动程序,但为了避免冲突,我强烈建议先使用系统源或NVIDIA官方PPA安装一个合适的驱动,或者至少确保没有陈旧的驱动残留。如果你之前用 runfile 方式装过驱动或CUDA,最好先清理一下。

首先,检查当前已安装的NVIDIA驱动版本:

nvidia-smi

如果这个命令能正常执行并输出显卡信息,说明驱动已经存在。记下右上角显示的CUDA Version(例如12.4),这表示当前驱动最高支持的CUDA运行时版本。 注意:这个CUDA Version是驱动支持的CUDA运行时最高版本,不是你将要安装的CUDA Toolkit版本,但你的CUDA Toolkit版本不能超过它。

如果你想使用Ubuntu仓库的驱动,可以这样安装:

sudo apt update
sudo ubuntu-drivers devices # 查看推荐驱动
sudo apt install nvidia-driver-535 # 安装一个推荐版本,例如535

安装后需要重启。如果你想追求最新驱动,可以添加NVIDIA官方PPA,但稳定性可能稍逊于系统仓库版本。

关键注意事项: 如果你之前通过任何非 deb 方式(比如.run文件)安装过CUDA或驱动,在安装deb包之前,最好运行官方的清理脚本或手动卸载,否则极易导致冲突。NVIDIA提供了卸载脚本,通常位于 /usr/local/cuda/bin 下,名为 cuda-uninstaller 。在安装新的deb包前,一个干净的环境至关重要。

2.3 安装必要依赖项

为了保证deb包安装过程顺畅,我们需要先安装一些基础工具和依赖。这些工具主要用于密钥管理、包验证和传输。

sudo apt update
sudo apt install -y build-essential software-properties-common
sudo apt install -y gcc make perl dkms linux-headers-$(uname -r)

build-essential 包含了编译所需的基本工具(gcc, g++, make等), dkms 是动态内核模块支持,对于内核更新后自动重建设备驱动非常重要。 linux-headers-$(uname -r) 则是安装当前运行内核的头文件,这是编译内核模块(比如NVIDIA驱动模块)所必需的。

3. CUDA Toolkit 12的deb方式安装

这是整个流程的核心部分。我们将采用NVIDIA官方提供的网络deb仓库进行安装。这种方式的好处是,未来可以通过 apt upgrade 来更新CUDA,并且所有文件都遵循Linux文件系统标准,管理起来非常清晰。

3.1 添加NVIDIA官方CUDA仓库

首先,我们需要获取并添加NVIDIA的包仓库密钥和地址。这一步确保了我们将从官方源下载安装包,保证了安全性和兼容性。

  1. 下载并添加密钥 :NVIDIA使用公钥来签名他们的软件包,我们需要将这个公钥添加到系统的可信密钥列表中。

    wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-keyring_1.1-1_all.deb
    sudo dpkg -i cuda-keyring_1.1-1_all.deb
    

    这个 .deb 文件包含了仓库密钥和源信息。安装后,它会自动在 /etc/apt/trusted.gpg.d/ 和 /etc/apt/sources.list.d/ 下放置相应文件。

  2. 更新软件包列表 :添加新仓库后,必须更新本地的包索引,这样 apt 才能知道这个新源里有哪些可用的软件包。

    sudo apt update
    

3.2 选择并安装CUDA包

更新后,我们就可以搜索和安装CUDA了。这里有一个非常重要的选择:安装 cuda 还是 cuda-toolkit-12-x ?在NVIDIA的deb仓库中, cuda 是一个 元包 ,它本身不包含太多内容,而是依赖于当前最新的CUDA Toolkit完整包(例如 cuda-toolkit-12-5 )。安装元包的好处是,当你下次执行 sudo apt upgrade 时,如果仓库里有新版本的CUDA(比如12.6),它会自动升级到新版本。但这可能带来不确定性,因为新版本可能引入不兼容的变更。

对于生产环境或希望环境长期稳定的用户,我推荐安装 特定版本 的Toolkit包。我们先查看可用的版本:

apt search cuda-toolkit-12- | grep ^cuda-toolkit

假设我们想安装CUDA 12.5,则执行:

sudo apt install -y cuda-toolkit-12-5

如果你想使用最新的12.x版本并接受自动更新,可以安装元包:

sudo apt install -y cuda

安装过程详解 :执行安装命令后, apt 会解析出这个包所需的所有依赖,包括特定版本的NVIDIA驱动、CUDA运行时库、编译器、工具等。它会提示你将安装一系列软件包(如 cuda-drivers-550, cuda-runtime-12-5, cuda-compiler-12-5, cuda-libraries-12-5 等),并显示需要下载的数据量和磁盘空间占用。确认后,安装过程会自动进行,这可能需要一些时间,取决于你的网速。

3.3 配置环境变量

安装完成后,CUDA的可执行文件和库文件被安装到了 /usr/local/cuda-12.5 (版本号可能不同)目录下。为了让系统在任何位置都能识别到CUDA的命令和动态链接库,我们需要将相关路径添加到环境变量中。

最常用的方法是修改用户家目录下的 ~/.bashrc 文件(如果你使用zsh,则是 ~/.zshrc )。

  1. 打开配置文件:

    nano ~/.bashrc
    
  2. 在文件末尾添加以下几行:

    export PATH=/usr/local/cuda-12.5/bin${PATH:+:${PATH}}
    export LD_LIBRARY_PATH=/usr/local/cuda-12.5/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
    

    参数解释 :

    • PATH :添加CUDA的 bin 目录,这样你可以在终端直接运行 nvcc (CUDA编译器)、 nvidia-smi 等命令。
    • LD_LIBRARY_PATH :添加CUDA的 lib64 目录,这样运行时系统才能找到CUDA的动态链接库(如 libcudart.so )。
  3. 保存文件(在nano中按 Ctrl+O ,回车,然后 Ctrl+X 退出),并让配置立即生效:

    source ~/.bashrc
    

实操心得 :有些教程会建议你创建一个软链接 /usr/local/cuda 指向具体的版本目录(如 cuda-12.5 )。这样做的好处是,当你切换CUDA版本时,只需要更改这个软链接的目标,而无需修改环境变量。deb安装方式通常会自动创建这个软链接。你可以用 ls -l /usr/local/cuda 检查。如果存在且指向正确,那么你的环境变量可以直接设置为 /usr/local/cuda ,这样会更灵活。

4. cuDNN的deb方式安装

cuDNN是NVIDIA提供的深度神经网络加速库,它实现了高度优化的标准例程(如前向/反向卷积、池化、归一化等)。大多数深度学习框架(如TensorFlow, PyTorch)在GPU上运行时都依赖于cuDNN。它的版本必须与已安装的CUDA版本严格匹配。

4.1 下载正确的cuDNN deb包

与CUDA不同,cuDNN的deb包需要从NVIDIA开发者网站手动下载。你需要注册一个免费的NVIDIA开发者账号。

  1. 访问 NVIDIA cuDNN下载页面 。
  2. 登录后,在筛选条件中选择:
    • CUDA Version :选择你刚刚安装的CUDA版本,例如 CUDA 12.x 。
    • Operating System :选择 Linux 。
    • Architecture :选择 x86_64 。
    • Distribution :选择 Ubuntu 。
    • Version :选择 20.04 。
    • Installer Type :这里我们选择 Deb (Local) ,即本地deb包。
  3. 你会看到几个可选的deb包。通常有三个:
    • libcudnn8 :运行时库。
    • libcudnn8-dev :开发文件(头文件和静态库),编译深度学习框架时需要。
    • libcudnn8-samples :示例代码。 对于深度学习环境,前两个是必须的。请下载它们,例如:
    • libcudnn8_8.x.x.x-1+cuda12.x_amd64.deb
    • libcudnn8-dev_8.x.x.x-1+cuda12.x_amd64.deb

版本匹配黄金法则 :cuDNN的主版本号(如8)和次版本号必须与你的深度学习框架所要求的版本兼容。例如,TensorFlow 2.15.0 要求 cuDNN 8.9。请务必查阅你将要使用的框架的官方安装文档,确认其支持的cuDNN版本,然后下载对应的包。下载页面上的“CUDA Version”是它 兼容 的CUDA版本,而包名里的 cuda12.x 是它 设计运行于 的CUDA环境,两者必须一致。

4.2 安装cuDNN deb包

下载完成后,在终端中进入存放deb文件的目录,按顺序安装它们。先安装运行时库,再安装开发包。

sudo dpkg -i libcudnn8_8.x.x.x-1+cuda12.x_amd64.deb
sudo dpkg -i libcudnn8-dev_8.x.x.x-1+cuda12.x_amd64.deb

dpkg -i 是Debian/Ubuntu系统安装本地deb包的命令。安装过程会将cuDNN的库文件复制到系统目录(如 /usr/lib/x86_64-linux-gnu/ 和 /usr/include/ ),并将头文件链接到CUDA的include目录下。

常见问题处理 :如果安装过程中报告依赖错误(例如 dpkg: dependency problems prevent configuration of... ),可以运行 sudo apt --fix-broken install 或 sudo apt install -f 来自动安装缺失的依赖并完成配置。这是因为deb包可能依赖一些其他系统库,而 dpkg 本身不解决依赖关系, apt 可以。

4.3 验证cuDNN安装

安装完成后,如何确认cuDNN已正确安装并与CUDA链接呢?最直接的方法是检查头文件和库文件。

  1. 验证头文件 :cuDNN的头文件应该被链接到了CUDA的include目录。

    cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR -A 2
    

    或者,如果上述文件不存在,可以尝试:

    cat /usr/include/cudnn_version.h | grep CUDNN_MAJOR -A 2
    

    这条命令会输出cuDNN的主版本、次版本和补丁版本号,例如:

    #define CUDNN_MAJOR 8
    #define CUDNN_MINOR 9
    #define CUDNN_PATCHLEVEL 6
    

    这表示你安装的是 cuDNN 8.9.6。

  2. 验证库文件 :检查动态链接库是否存在且可被识别。

    ldconfig -p | grep cudnn
    

    这条命令会列出系统中所有名为 libcudnn 的库缓存。你应该能看到类似 libcudnn.so.8 (libc6,x86-64) 的输出。

5. 完整环境验证与测试

安装完所有组件后,我们必须进行系统性验证,确保从驱动到CUDA运行时,再到cuDNN,整个链条都是通畅的。这是将环境投入实际使用前的最后一道,也是最重要的一道检查。

5.1 驱动与CUDA运行时验证

我们之前用过的 nvidia-smi 是驱动层面的工具。要验证CUDA运行时,我们需要使用CUDA Toolkit自带的工具。

  1. 基础命令验证 :

    nvidia-smi
    

    确认命令能运行,并检查右上角的“CUDA Version”,它应 大于或等于 你安装的CUDA Toolkit版本(如12.5)。

    nvcc --version
    

    这是CUDA编译器驱动(NVCC)的版本。它输出的版本号应该与你安装的CUDA Toolkit版本一致(如 release 12.5 )。如果提示“命令未找到”,请检查你的环境变量 PATH 是否设置正确。

  2. 编译并运行CUDA样例 :CUDA Toolkit自带了许多示例代码,位于 /usr/local/cuda-12.5/samples (或 /usr/local/cuda/samples )。我们可以编译一个最简单的例子来测试。

    # 切换到示例目录
    cd /usr/local/cuda/samples/1_Utilities/deviceQuery
    # 编译示例(这需要一些时间)
    sudo make
    # 运行编译好的程序
    ./deviceQuery
    

    如果一切正常,这个程序会输出你GPU的详细信息,并在最后显示 Result = PASS 。这表明CUDA驱动和运行时通信正常,GPU可以被CUDA程序访问。

5.2 cuDNN功能验证

验证cuDNN不仅需要检查文件是否存在,最好能运行一个实际调用cuDNN API的程序。我们可以使用之前安装的cuDNN示例包(如果安装了 libcudnn8-samples ),或者自己写一个简单的测试程序。

  1. 使用官方示例(如果已安装) :

    # 解压示例代码(假设示例包已安装)
    cp -r /usr/src/cudnn_samples_v8/ $HOME
    cd $HOME/cudnn_samples_v8/mnistCUDNN
    # 编译示例
    make clean && make
    # 运行测试
    ./mnistCUDNN
    

    如果输出 Test passed! ,则证明cuDNN安装成功且功能正常。

  2. 编写简易Python测试脚本(更常用) :对于深度学习用户,通过Python接口测试更直接。首先确保你安装了 cuda-python 或深度学习框架。

    pip install nvidia-cudnn-cu12==8.9.6 # 安装对应版本的cuDNN Python包(PyTorch等框架会自带)
    

    然后,在一个Python交互环境中尝试导入:

    import torch
    print(torch.cuda.is_available()) # 应返回 True
    print(torch.backends.cudnn.version()) # 应输出你安装的cuDNN版本号,如 8906(对应8.9.6)
    

    如果这两步都成功,那么你的PyTorch + CUDA + cuDNN环境就完全就绪了。对于TensorFlow,可以类似地使用 tf.config.list_physical_devices('GPU') 和检查版本来验证。

5.3 环境隔离与多版本管理建议

在实际工作中,你可能需要为不同的项目维护不同的CUDA环境。虽然deb安装方式将CUDA安装在系统路径,但我们可以通过环境变量和虚拟环境来隔离。

  • 使用环境变量切换 :如果你安装了多个CUDA版本(如11.8和12.5),可以创建不同的shell脚本,在脚本中设置不同的 PATH 和 LD_LIBRARY_PATH ,指向不同的CUDA目录。运行项目前,先 source 对应的脚本。
  • 结合Conda虚拟环境 :这是更推荐的做法。在Conda虚拟环境中安装深度学习框架(如PyTorch, TensorFlow)时,使用 conda install 命令。Conda会自动为该环境安装匹配的CUDA和cuDNN库(这些库被安装在虚拟环境内部,与系统隔离)。这样,你可以轻松拥有多个互不干扰的深度学习环境。系统通过deb安装的CUDA更多是作为一个“后备”或“编译器”存在。

6. 安装后常见问题深度排查

即使按照步骤操作,也可能会遇到一些问题。这里我总结几个最常见的问题及其排查思路,这往往是教程里不会细说的“坑”。

6.1 NVIDIA-SMI 可以运行,但 NVCC 报错“未找到命令”

问题现象 : nvidia-smi 正常显示,但 nvcc --version 提示命令未找到。 根本原因 :环境变量 PATH 没有包含CUDA的bin目录,或者 .bashrc 修改后没有 source 。 排查步骤 :

  1. 检查CUDA安装路径是否存在: ls -l /usr/local/cuda* 。确认 /usr/local/cuda 这个软链接是否存在并指向正确的版本目录(如 cuda-12.5 )。
  2. 检查当前shell的PATH: echo $PATH ,查看输出中是否包含 /usr/local/cuda/bin 或 /usr/local/cuda-12.5/bin 。
  3. 如果PATH中没有,请确认 ~/.bashrc 中的设置是否正确,并执行 source ~/.bashrc 。
  4. 如果使用的是zsh,请确保修改的是 ~/.zshrc 并 source 它。
  5. 极端情况下,可能是CUDA Toolkit没有安装完整。可以尝试重新安装: sudo apt install --reinstall cuda-toolkit-12-5 。

6.2 运行程序时报错“libcudnn.so.8: cannot open shared object file”

问题现象 :在导入PyTorch或运行自己编译的程序时,提示找不到cuDNN的某个库文件。 根本原因 :动态链接器找不到cuDNN库。 LD_LIBRARY_PATH 环境变量未设置或设置错误,或者cuDNN库未正确安装/链接。 排查步骤 :

  1. 首先确认库文件是否存在: ls -l /usr/lib/x86_64-linux-gnu/libcudnn* 。你应该能看到 libcudnn.so.8 -> libcudnn.so.8.x.x 这样的软链接和实体文件。
  2. 检查 LD_LIBRARY_PATH : echo $LD_LIBRARY_PATH ,确认它包含了CUDA的lib64目录(如 /usr/local/cuda/lib64 )。cuDNN的库通常会被链接到系统库目录,但CUDA的库需要这个路径。
  3. 更新动态链接器缓存:运行 sudo ldconfig 。这个命令会重建库的缓存,有时安装新库后需要手动执行。
  4. 如果上述步骤都正确,问题可能出在程序的运行时链接上。你可以尝试直接指定库路径运行程序: LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH ./your_program 。如果能运行,则证明是环境变量问题。

6.3 系统内核更新后,NVIDIA驱动失效

问题现象 :执行了 sudo apt upgrade 升级了系统内核后,重启电脑无法进入图形界面,或者 nvidia-smi 无法运行。 根本原因 :内核升级后,之前为旧内核编译的NVIDIA内核模块(由 dkms 管理)与新内核不兼容。虽然我们通过deb方式安装,驱动通常配置了DKMS,但有时自动构建会失败。 解决方案 :

  1. 重启系统,在GRUB引导界面选择 高级选项 ,然后选择 之前的内核版本 启动。进入系统后,再处理驱动问题。
  2. 为当前新内核重新编译NVIDIA内核模块:
    sudo dkms install -m nvidia -v $(modinfo nvidia | grep version | awk '{print $2}')
    
    或者,更直接的方法是重新安装驱动包:
    sudo apt install --reinstall nvidia-driver-535 # 替换成你的驱动版本
    
  3. 重启系统,选择新的内核启动,检查是否恢复正常。 预防措施 :对于重要的生产机器,可以考虑暂时禁止自动内核更新,或者在更新内核后预留一个恢复用的旧内核启动项。

6.4 深度学习框架无法检测到GPU

问题现象 :在Python中, torch.cuda.is_available() 返回 False 。 排查思路 :这是一个综合性问题,需要按顺序排查。

  1. 驱动层面 : nvidia-smi 是否正常工作?如果不工作,回到问题6.3。
  2. CUDA运行时层面 :运行 /usr/local/cuda/samples/1_Utilities/deviceQuery 是否通过?如果不通过,说明CUDA运行时安装或配置有问题。
  3. 框架层面 :
    • PyTorch :检查安装的PyTorch版本是否支持你的CUDA版本。访问 PyTorch官网 ,查看版本匹配矩阵。使用 conda install pytorch torchvision torchaudio cudatoolkit=12.1 -c pytorch 这样的命令时, cudatoolkit=12.1 必须与你系统的CUDA版本兼容(可以略低,不能更高)。
    • TensorFlow :TensorFlow 2.x之后,GPU支持直接打包在 tensorflow 包中,但其对CUDA/cuDNN的版本要求非常严格。必须严格按照 TensorFlow官网 列出的版本对应表来安装。使用 pip install tensorflow 安装的是支持CUDA的版本,但其依赖的CUDA动态库需要你系统预先安装好。
  4. 虚拟环境隔离 :如果你在Conda虚拟环境中,请确认你是在该环境中运行的Python和框架。有时在终端激活了环境,但在Jupyter Notebook或IDE中可能没有。

整个安装和验证过程,最需要耐心和细致的就是版本匹配。记住一个简单的链条: 深度学习框架版本 -> 所需CUDA版本 -> 所需cuDNN版本 -> 所需NVIDIA驱动版本 。任何一个环节版本不匹配,都可能导致失败。养成在安装前先查阅框架官方安装文档的习惯,能节省大量排查时间。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐