Ubuntu22.04 安装CUDA 和cuDNN(答惑版)
一、前言
在我的上一篇文章《Ubuntu22.04 安装NVIDIA驱动》中提过,我自己装了一台电脑,并想用它跑一些AI相关的项目,比如stable-diffusion,而在完成NVIDIA驱动的安装后,下一步就是安装CUDA和cuDNN了,我原以为NVIDIA驱动安装的水已经够深了,没想到CUDA和cuDNN的水也同样深不可测。
我们在网上看到的一些教程可能会让你去NVIDIA官网下载CUDA和cuDNN的安装包,然后按照官网的说明执行命令,配置环境变量,最终通过 nvcc -V 等命令校验是否安装成功,可这就是正确的装法吗,其实并不尽然,在我看来这只能说是不会犯错的做法,具体还需要看你用 CUDA 来做什么。
二、什么是CUDA和cuDNN
CUDA全称Compute Unified Device Architecture,翻译成中文是统一计算架构。但这个翻译其实看不出它的作用,简单来说,CUDA是英伟达推出的一个适用于自家GPU的GPU并行计算框架,能够加快GPU的计算,像现在主流的深度学习框架大部分都是基于CUDA进行GPU并行加速的。cuDNN全称 CUDA Deep Neural Network,它是一个针对深度卷积神经网络的GPU加速框架。
而我们进入CUDA的官网,经常能看到一个 CUDA Toolkit 的东西,这个简单来讲就是一个CUDA工具包,里面包含了一些跟CUDA相关的套件,比如 CUDA-C和CUDA-C++编译器(nvcc) 等,我们要安装的其实是这个 CUDA Toolkit,但我们也不一定要安装这个CUDA Toolkit,具体要看你的使用场景,后面会讲到。
CUDA的版本需要跟NVIDIA驱动的版本适配,目前最新的版本对应关系如下,这张图只展示了部分对应关系,完整版可以点这里[1]
如果你想下载CUDA的历史版本[2],可以点这个链接查看。
三、CUDA的种类
CUDA其实可以分为三种,第一种是安装NVIDIA显卡驱动的时候自带的CUDA,第二种是我们通过NVIDIA官网下载的CUDA ToolKit 安装包,最后一种就是通过 conda/pip 安装的 nvidia-cuda。
第一种CUDA可以通过 nvidia-smi命令查看,比如我的是 12.3:
$ nvidia-smi
Sat Dec 16 13:42:57 2023
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 545.29.06 Driver Version: 545.29.06 CUDA Version: 12.3 |
|-----------------------------------------+----------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
第二种CUDA可以通过 nvcc -V 命令查看,也就是网上常看到的方式:
$ nvcc -V
之所以有这两种CUDA,是因为CUDA存在两种API,分别是 runtime API和driver API。这两种API 在很多情况非常相似,也就是说用起来的效果是等价的,但是你不能混合使用这两个API,因为二者是互斥的,也就是说在开发过程中,你只能选择其中一种API(但两者是能共存的,只是运行的时候要选择一种API)。简单来说就是:runtime API是更高级的封装,开发人员用起来更方便,而driver API更接近底层,速度可能会更快。
用于支持driver API的必要文件(如libcuda.so)是由 GPU driver installer安装的,也就是显卡驱动自带的CUDA支持的是drive API,它的版本就是通过 nvidia-smi 看到的版本
# 我前面装了显卡驱动,可以看到有 libcuda.so 文件
$ sudo find / -name libcuda.so
/usr/lib/i386-linux-gnu/libcuda.so
/usr/lib/x86_64-linux-gnu/libcuda.so
用于支持runtime API的必要文件(如libcudart.so以及 nvcc )是由CUDA Toolkit installer安装的。CUDA Toolkit 安装的时候只知道它自身构建时的CUDA runtime版本,它不知道现在这台电脑安装了什么版本的GPU driver,甚至不知道是否安装了GPU driver。
# 我的电脑还没装,所以没有这个命令
$ nvcc -V
zsh: command not found: nvcc
综上,如果你安装显卡驱动后,又手动安装了CUDA Toolkit,则你的电脑会出现两个CUDA,一个支持runtime API,一个支持driver API。它们的版本可能一致,也可能不一致,具体取决于你安装时选择的版本。
那么第三种CUDA(通过Conda/pip 安装)又与前面两种有什么区别呢?
简单来说,Nvidia 官方提供安装的 CUDA Toolkit 是比较全面的,它包含了进行 CUDA 相关程序开发的编译、调试等过程相关的所有组件。
但对于 Pytorch 之类的深度学习框架而言,其在大多数需要使用 GPU 的情况中只需要使用 CUDA 的动态链接库支持程序的运行,也就是安装显卡驱动时安装的 libcuda.so,而通过 conda 或者 pip 下载 Pytorch的时候,我们看到的 nvidia-cuda 之类的库,这些与CUDA相关的部分是提前编译好的 ,不需要重新进行编译,只要系统上存在与当前的 nvidia-cuda所兼容的 Nvidia 驱动,就可以直接运行,所以我们其实用不着自己通过CUDA编译程序,自然用不到 NVIDIA 官网的CUDA Toolkit。
或者更直白的讲,如果你的使用场景只是使用 Pytorch 这类的深度学习框架,你只要装了显卡驱动,再通过 Conda/pip 安装 Pytorch[3] 就可以使用了
# 比如我现在电脑就没装NVIDIA官网的CUDA Toolkit,但是我的cuda仍然是可用的
>>> import torch
>>> torch.cuda.is_available()
True
>>> print(torch.version.cuda)
### 12.1 # 或者通过 pip 查看
$ pip list | grep cuda
nvidia-cuda-cupti-cu12 12.1.105
nvidia-cuda-nvrtc-cu12 12.1.105
nvidia-cuda-runtime-cu12 12.1.105
$ pip list | grep cudnn
nvidia-cudnn-cu12 8.9.2.26
但如果你的要求比较特殊,比如需要为 Pytorch 框架添加 CUDA 相关的拓展时,或者需要对编写的 CUDA 相关的程序进行编译等操作,就得安装 Nvidia 官方提供的 CUDA Toolkit!
四、CUDA Toolkit的安装
为了文章的完整性,这里也尝试在云服务器上进行CUDA Toolkit 的安装,仅供参考!CUDA的安装有两种安装类型,第一种是通过 deb 文件,第二种是通过 runfile 文件,两种方式的安装指令不同,以及后续要卸载的指令也不同,这点要谨记!
这里我稍微推荐 runfile 的安装方式,因为 runfile 的方式可以控制是否安装显卡驱动,如果你电脑没装显卡驱动,这不失为另一种安装驱动的方式,还有就是感觉 deb 方式的驱动安装命令有点坑,执行后驱动并没有安装成功,所以综合比较稍微推荐 runfile 的方式。
4.1 通过 deb 文件安装
指令如下:
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-ubuntu2204.pin
sudo mv cuda-ubuntu2204.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/12.3.1/local_installers/cuda-repo-ubuntu2204-12-3-local_12.3.1-545.23.08-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu2204-12-3-local_12.3.1-545.23.08-1_amd64.deb
sudo cp /var/cuda-repo-ubuntu2204-12-3-local/cuda-*-keyring.gpg /usr/share/keyrings/
sudo apt-get update
sudo apt-get -y install cuda-toolkit-12-3
安装完毕后 /usr/local 有三个cuda目录:
/usr/local$ cd cuda
cuda/ cuda-12/ cuda-12.3/
接下来需要配置环境变量:
$ vim ~/.bashrc
# 写入以下内容,注意替换成自己的版本
export PATH=/usr/local/cuda-12.3/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-12.3/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
# 生效
source ~/.bashrc
检验成果:
$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2023 NVIDIA Corporation
Built on Fri_Nov__3_17:16:49_PDT_2023
Cuda compilation tools, release 12.3, V12.3.103
Build cuda_12.3.r12.3/compiler.33492891_0
随后我再通过官网的命令安装驱动(相当于先装CUDA再装显卡驱动)
# 第一种
To install the legacy kernel module flavor:
sudo apt-get install -y cuda-drivers
# 第二种,我选择的是这种
To install the open kernel module flavor:
sudo apt-get install -y nvidia-kernel-open-545
sudo apt-get install -y cuda-drivers-545
我安装完成后,输入 nvidia-smi 后,并没有显示成功,并且在重启服务器后,SSH等了几分钟才能连上,驱动也没有安装成功!猜测应该是服务器用的是T4显卡,用的驱动版本不匹配导致的,不过后续就没有试了
$ nvidia-smi
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running
4.2 通过 runfile 文件安装
注:这里是云服务器重装系统后再安装的,而且改为 12.2 版本是后面安装 cuDNN 的时候发现没有 12.3 的版本
执行命令如下:
$ wget https://developer.download.nvidia.com/compute/cuda/12.2.0/local_installers/cuda_12.2.0_535.54.03_linux.run
$ sudo sh cuda_12.2.0_535.54.03_linux.run
输入 accept 同意协议
安装成功后的输出:
$ sudo sh cuda_12.2.0_535.54.03_linux.run
= Summary =
Driver: Installed
Toolkit: Installed in /usr/local/cuda-12.2/
Please make sure that
- PATH includes /usr/local/cuda-12.2/bin
- LD_LIBRARY_PATH includes /usr/local/cuda-12.2/lib64, or, add /usr/local/cuda-12.2/lib64 to /etc/ld.so.conf and run ldconfig as root
To uninstall the CUDA Toolkit, run cuda-uninstaller in /usr/local/cuda-12.2/bin
To uninstall the NVIDIA Driver, run nvidia-uninstall
Logfile is /var/log/cuda-installer.log
配置环境变量
$ vim ~/.bashrc
# 写入以下内容,注意替换成自己的版本
export PATH=/usr/local/cuda-12.2/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-12.2/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
# 生效
source ~/.bashrc
检验成果:
$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2023 NVIDIA Corporation
Built on Tue_Jun_13_19:16:58_PDT_2023
Cuda compilation tools, release 12.2, V12.2.91
Build cuda_12.2.r12.2/compiler.32965470_0
显卡驱动安装正常:
$ nvidia-smi
Sat Dec 16 20:27:41 2023
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.54.03 Driver Version: 535.54.03 CUDA Version: 12.2 |
|-----------------------------------------+----------------------+----------------------+
五、cuDNN的安装
cuDNN的安装需要注册一个NVIDIA账户,下载地址是:https://developer.nvidia.com/rdp/cudnn-download
cuDNN版本需要和CUDA对应,所以我选了v8.9.7
下载安装包
我这里只讲述Ubuntu的安装,如果想看其他系统的安装方式,可以看官方教程[4],说得也非常详细
1、安装依赖
sudo apt-get install zlib1g
2、安装deb包
sudo dpkg -i cudnn-local-repo-ubuntu2204-8.9.7.29_1.0-1_amd64.deb
... 会有一个提示让你cp 密钥
3、cp密钥
sudo cp /var/cudnn-local-repo-ubuntu2204-8.9.7.29/cudnn-local-08A7D361-keyring.gpg /usr/share/keyrings/
sudo apt-get update
4、安装各种库
这里有个问题就是版本号的替换,它的模板是 8.x.x.x-1+cudaX.Y,你需要把 x.x.x 替换为 cudnn 的版本号(这个可以在deb包的名字上找到),X.Y 替换为 cuda 的版本号
sudo apt-get install libcudnn8=8.9.7.29-1+cuda12.2
sudo apt-get install libcudnn8-dev=8.9.7.29-1+cuda12.2
sudo apt-get install libcudnn8-samples=8.9.7.29-1+cuda12.2
这里其实还有点问题,就是你替换后的版本不一定找得到,就比如我一开始的版本号是 8.9.7.29-1+cuda12.3,然后安装时提示这个(可以在这里查看版本号是否存在[5]):
$ sudo apt-get install libcudnn8=8.9.7.29-1+cuda12.3
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Package libcudnn8 is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
E: Version '8.9.7.29-1+cuda12.3' for 'libcudnn8' was not found
解决办法一是安装 cuda12.2,这样上面执行 apt-get install 时候会自动把cudnn拷贝到 /usr/local/cuda-12.2/include 和 /usr/local/cuda-12.2/lib64/ 下(亲测OK,但是麻烦); 解决办法二是下载 tar.xz 格式的cudnn 包,然后把 include 和 lib64 拷贝到 /usr/local/cuda-12.3 目录下,但这种我没试过,不保证可行
5、检验是否安装成功
$ cp -r /usr/src/cudnn_samples_v8/ $HOME
$ cd $HOME/cudnn_samples_v8/mnistCUDNN
$ make clean && make
# 编译成功后会生成一个mnistCUDNN文件,如果执行后显示 Test passed! 就说明安装成功
$ ./mnistCUDNN
如果编译时遇到下面的问题,安装缺失依赖重新编译即可:
$ sudo apt-get install libfreeimage3 libfreeimage-dev
参考教程
注:非常感谢下面教程对我的帮助,本文有部分内容也是摘抄自里面
Ubuntu20.04下CUDA、cuDNN的详细安装与配置过程(图文)_ubuntu cudnn安装-CSDN博客[6]
Ubuntu22.04安装CUDA、cudnn详细步骤_ubuntu安装cuda和cudnn-CSDN博客[7]
显卡,显卡驱动,nvcc, cuda driver,cudatoolkit,cudnn到底是什么?[8]
conda安装的cudatoolkit与Nvidia官方提供的cudatoolkit的区别_conda cudatoolkit与cuda的区别-CSDN博客[9]
显卡,显卡驱动,nvcc, cuda driver,cudatoolkit,cudnn到底是什么? – marsggbo – 博客园[10]
linux/ubuntu/centos 系统下,cuda多版本共存问题详解_centos cuda 多版本-CSDN博客[11]
Ubuntu下CUDA的卸载以及安装(deb方式和run方式) – 掘金[12]
[从0到1]Ubuntu20.04搭建深度学习环境(2)[13]
Installation Guide[14]
Ubuntu22.04安装CUDA、cudnn详细步骤_ubuntu安装cuda和cudnn-CSDN博客[15]
参考资料
[1]完整版可以点这里: https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html
[2]CUDA的历史版本: https://developer.nvidia.com/cuda-toolkit-archive
[3]Conda/pip 安装 Pytorch: https://pytorch.org/get-started/locally/
[4]官方教程: https://www.notion.so/8ae6aed4cf6d45bd87a02a17554505f3?pvs=25
[5]在这里查看版本号是否存在: https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/
[6]Ubuntu20.04下CUDA、cuDNN的详细安装与配置过程(图文)_ubuntu cudnn安装-CSDN博客: https://blog.csdn.net/weixin_37926734/article/details/123033286
[7]Ubuntu22.04安装CUDA、cudnn详细步骤_ubuntu安装cuda和cudnn-CSDN博客: https://blog.csdn.net/takedachia/article/details/130375718
[8]显卡,显卡驱动,nvcc, cuda driver,cudatoolkit,cudnn到底是什么?: https://zhuanlan.zhihu.com/p/91334380
[9]conda安装的cudatoolkit与Nvidia官方提供的cudatoolkit的区别_conda cudatoolkit与cuda的区别-CSDN博客: https://blog.csdn.net/qq_40947610/article/details/114707085
[10]显卡,显卡驱动,nvcc, cuda driver,cudatoolkit,cudnn到底是什么? – marsggbo – 博客园: https://www.cnblogs.com/marsggbo/p/11838823.html
[11]linux/ubuntu/centos 系统下,cuda多版本共存问题详解_centos cuda 多版本-CSDN博客: https://blog.csdn.net/qq_40947610/article/details/114706170?spm=1001.2014.3001.5501
[12]Ubuntu下CUDA的卸载以及安装(deb方式和run方式) – 掘金: https://juejin.cn/post/7085691913004646413
[13][从0到1]Ubuntu20.04搭建深度学习环境(2): https://zhuanlan.zhihu.com/p/564504790
[14]Installation Guide: https://docs.nvidia.com/deeplearning/cudnn/install-guide/index.html
[15]Ubuntu22.04安装CUDA、cudnn详细步骤_ubuntu安装cuda和cudnn-CSDN博客: https://blog.csdn.net/takedachia/article/details/130375718