Technical note
Ubuntu下搭建CUDA与容器GPU工具链
这台Ubuntu22.04主机既要使用CUDA进行本机开发,也要让Docker容器调用GPU。整套环境除了Toolkit,还涉及驱动、cuDNN和NVIDIAContainerToolkit,其中最容易出问题的是几组版本之间的兼容关系。
下载地址
先核对版本
驱动、CUDA和GCC的对应关系会变化,直接查当前版本的ReleaseNotes比保存一张静态大表可靠:
先看机器上的现状:
nvidia-smi
command -v nvcc && nvcc --version
ls -ld /usr/local/cuda* 2>/dev/null
nvidia-smi顶部的CUDAVersion是驱动支持的最高CUDA版本,不代表已经安装了同版本的Toolkit。Toolkit版本以nvcc --version和安装目录为准。
使用Runfile安装CUDA
Runfile适合离线安装或固定版本。能使用APT的机器还是优先用软件包,后续卸载和内核升级都省事一些。
先安装编译工具和当前内核头文件:
sudo apt-get update
sudo apt-get install -y build-essential linux-headers-"$(uname -r)"
下载完成后核对校验值,再运行安装器:
sha256sum cuda_<version>_linux.run
sudo sh cuda_<version>_linux.run
如果驱动已经通过APT或单独的Runfile装好,在交互界面中取消Driver,只安装CUDAToolkit。不要让两种安装方式同时管理驱动。
安装完成后按实际目录配置环境变量:
export PATH=/usr/local/cuda-X.Y/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-X.Y/lib64:${LD_LIBRARY_PATH:-}
确认nvcc --version正常后,再写入Shell配置文件。
早期配置曾直接修改/usr/bin/gcc软链接来切换GCC。这会影响系统中其他编译任务,现在更合适的做法是并行安装所需版本,并在构建时单独指定:
CC=/usr/bin/gcc-X CXX=/usr/bin/g++-X cmake -S . -B build
Runfile安装的Toolkit可以使用自带卸载器删除:
sudo /usr/local/cuda-X.Y/bin/cuda-uninstaller
cuDNN
cuDNN还要单独核对CUDA版本和系统支持范围:
当前系统如果已经配置NVIDIA软件源,可以直接安装与CUDA主版本对应的软件包。例如cuDNN9配合CUDA12:
sudo apt-get update
sudo apt-get install -y cudnn9-cuda-12
Docker中使用GPU
旧的nvidia-container-runtime仓库已经归档,现在使用nvidia-container-toolkit。这里有一个容易混淆的地方:容器使用宿主机的GPU驱动,CUDA用户态库通常放在镜像里,所以镜像版本仍然受宿主机驱动限制。
Ubuntu下配置APT仓库:
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
ca-certificates curl gnupg2
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
| sudo gpg --dearmor \
-o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -sL https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
| sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
| sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
安装并写入Docker运行时配置:
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
nvidia-ctk会修改/etc/docker/daemon.json,已有自定义配置时先备份这个文件。
从NVIDIACUDA镜像标签中选一个宿主机驱动支持的版本进行验证:
docker run --rm --gpus all \
nvidia/cuda:<toolkit-tag>-base-ubuntu22.04 \
nvidia-smi
宿主机的nvidia-smi正常、容器中却找不到GPU时,检查Docker运行时和Toolkit版本:
docker info | sed -n '/Runtimes/,+3p'
nvidia-ctk --version
journalctl -u docker -n 100 --no-pager