从云原生走向 AI 原生:一套面向未来的架构方法论 → 阅读《AI 原生基础设施》

准备 GPU 运行环境:Linux、驱动与 CUDA 工具链

草稿

GPU 环境里一半的故障不是硬件坏了,而是驱动、工具链、镜像各说各话。先让机器诚实地报告它的状态,再谈优化与调度。

本章不追求覆盖所有安装方式,只做三件事:建立 GPU 软件栈的分层心智模型、给出验证环境的最小命令集、澄清版本兼容规则。读完本章,你应当能在任何一台 GPU 机器上用五分钟判断“环境是否正常、问题出在哪一层”。

GPU 软件栈的四个层次

从硬件到应用,GPU 软件栈可以拆成四层。这个分层是全书的基础 vocabulary:后面讨论容器注入(Container Toolkit)、设备插件、调度时,每一步都在这几层之间搬运“访问权”。

层次内容谁安装它出问题的典型表现
内核驱动nvidia.ko 内核模块,唯一能直接控制硬件的软件宿主机管理员(OS 包管理器或官方仓库)nvidia-smi 报错、设备不可见
用户态运行时CUDA Driver API、libcuda、nvidia-smi随驱动一起安装驱动与库版本不匹配
工具链与加速库nvcc 编译器、cuBLAS/cuDNN/NCCL通常在容器镜像里,而非宿主机编译失败、库找不到
框架层PyTorch、vLLM 等容器镜像 / 虚拟环境CUDA driver version is insufficient
表 1: GPU 软件栈的四个层次

一个容易混淆的点:日常说“装 CUDA”可能指三层不同的东西——驱动里的 CUDA 支持能力、nvcc 为代表的工具链、cuDNN 这类加速库。云上 GPU 虚拟机通常三者都已配好;而自己管理的机器上,宿主机只需要第一层(驱动),这一点本章末尾会展开。

三条版本规则,先于一切命令

在敲任何命令之前,先记住三条规则。它们能解释你将来遇到的大多数版本报错:

  1. 驱动版本决定 CUDA 上限。nvidia-smi 右上角显示的 CUDA Version 不是“已安装的 CUDA 版本”,而是“该驱动最高支持的 CUDA 版本”。应用实际使用的 CUDA 版本可以更低。
  2. 工具链版本 ≠ 驱动版本。nvcc --versionnvidia-smi 显示的版本可以不一致,这是正常现象:nvcc 属于工具链层,nvidia-smi 属于驱动层,两者各自演进。
  3. **容器镜像自带工具链,宿主机驱动是唯一硬约束。**PyTorch 官方镜像里带着完整的 CUDA 运行时与加速库,但容器内进程最终仍要通过宿主机的内核驱动访问 GPU。因此“镜像 CUDA 版本 ≤ 驱动支持的最高版本”即可运行。
工程含义
规则 3 是“GPU 容器化”的价值来源:版本矩阵中变化最快的部分(工具链、加速库、框架)被装进镜像随应用走,变化最慢、权限最高的部分(内核驱动)留在宿主机由平台统一管理。Kubernetes 的一切 GPU 方案都建立在这个分工上,详见容器与 GPU 的根本矛盾

验证环境的最小命令集

拿到一台 GPU 机器,先用这组命令建立基线。它们分别回答四个问题:

# 1. 硬件在不在:确认 PCI 总线上能看到 NVIDIA 设备
lspci | grep -i nvidia

# 2. 驱动好不好:查看驱动版本、支持的 CUDA 上限、显存占用
nvidia-smi

# 3. 工具链装没装(可选,容器化路径下宿主机可以没有)
nvcc --version

# 4. 框架能不能用:在容器里跑一次真实断言(在“用 Docker 运行 GPU 工作负载”一章展开)
docker run --rm --gpus all pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime \
  python -c "import torch; print(torch.cuda.is_available())"

nvidia-smi 的输出值得逐字段读一遍,它是后续所有排障的起点:

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 580.xx.xx    Driver Version: 580.xx.xx    CUDA Version: 13.0     |
|-------------------------------+----------------------+----------------------|
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Memory-Usage         |
|   0  NVIDIA A10          On   | 00000000:00:04.0 Off |  512MiB / 23028MiB   |
|-------------------------------+----------------------+----------------------|
| Processes:                                                       GPU Memory |
|  GPU   PID   Type   Process name                       Usage               |
|    0   1234      C   python                                440MiB           |
+-----------------------------------------------------------------------------+

三个字段最重要:Driver Version(与库版本是否匹配)、CUDA Version(驱动支持的 CUDA 上限)、Memory-Usage(显存占用——注意“进程列表里的占用之和 ≠ 总占用”是常态,因为还有每进程底噪与预留,详见显存管理)。

安装驱动:推荐路径与示例

如果拿到的是一台没装驱动的机器(自建机房、部分云镜像),Ubuntu 上最省心的方式是发行版驱动或 NVIDIA 官方仓库:

# 方式一:发行版自动推荐(适合快速起步)
sudo ubuntu-drivers install

# 方式二:NVIDIA 官方 CUDA 仓库,版本可钉住(适合生产,以 580 系列为例)
# 命令与版本随时间演进,以 NVIDIA 官方文档为准
sudo apt install nvidia-driver-580
sudo reboot

重启后用 nvidia-smi 确认驱动加载成功。数据中心场景建议用方式二并钉住大版本:驱动升级需要卸载正在使用的内核模块,属于变更窗口内的事,不应混在应用发布里顺带发生。

常见故障速查

现象常见原因第一反应
nvidia-smi: command not found未装驱动或未在 PATH回到上一节安装驱动
No devices were found驱动与卡不匹配、PCI 直通未配置好(虚机场景)lspci 确认设备可见;核对驱动支持的型号
Driver/library version mismatch驱动升级后旧模块仍在内存中重启,或停止 GPU 进程后重载模块
nvidia-smi 正常但应用报 insufficient应用要求的 CUDA 版本高于驱动支持上限升级驱动,或换低版本 CUDA 的镜像
显存占用高但进程列表为空僵尸进程、MIG 配置残留sudo fuser -v /dev/nvidia* 找持有者
表 2: 驱动层常见故障与第一反应

虚机场景(云上 GPU 实例)还有一个高频坑:实例类型带 GPU 不等于镜像里有驱动。下一章会给出各云自带驱动的镜像选择建议。

动手实验:五分钟体检一台 GPU 机器

实验目标

在一台 GPU Linux 机器(物理机或云上实例)上完成环境体检,产出一张“环境基线卡”:硬件型号、驱动版本、CUDA 上限、当前占用。这张卡是后续所有实验的对照基线。

前置条件与成本预估

  • 一台有 NVIDIA GPU 的 Linux 机器(Ubuntu 22.04/24.04 为例)。本地机器成本为零;云上实例按小时计费,开机与验证在十分钟内完成,成本通常不足一美元(下一章会专门练习开机与关机)。
  • 具备 sudo 权限。

操作步骤

# 步骤 1:确认 PCI 总线可见 GPU,记下型号
lspci | grep -i nvidia
# 预期输出示例:0000:00:04.0 3D controller: NVIDIA Corporation GA102GL [A10]

# 步骤 2:读取驱动基线
nvidia-smi --query-gpu=name,driver_version,memory.total,memory.used --format=csv
# 预期输出:一行 CSV,包含型号、驱动版本、显存总量与已用量

# 步骤 3:核对 CUDA 上限,记下该数字(后续选容器镜像时要用)
nvidia-smi | grep -o "CUDA Version: [0-9.]*"

# 步骤 4:确认没有异常的显存残留(used 应接近 0,除非你已知有任务在跑)
nvidia-smi --query-gpu=memory.used --format=csv

如果 nvidia-smi 报错,先按上一节的故障速查表处理;驱动未装的机器先完成安装并重启。

验证清单

  • lspci 能看到 NVIDIA 设备,型号与预期一致
  • nvidia-smi 正常输出,记下 driver_version
  • 记下驱动支持的 CUDA 上限,确认 ≥ 你计划使用的镜像 CUDA 版本
  • 空闲机器的 memory.used 低于 500MiB
  • 把以上四个数字记入你的环境基线卡(一台机器一行)

原理速览

nvidia-smi 读取的是驱动通过 procfs/devfs 暴露的状态,它只依赖内核驱动与用户态管理库(NVML),不需要 CUDA 工具链。这就是为什么“nvidia-smi 正常但应用崩”几乎总是工具链/镜像层的问题,而不是驱动层的问题。NVML 与 DCGM exporter(Kubernetes 监控用)的关系见可观测与验收

清理与止损

本实验只读不写,无资源需要清理。云上实例如果不继续用,记得按下一章的流程关机或销毁。

总结

本章建立了全书的环境基线:GPU 软件栈四层模型、三条版本规则、最小验证命令集。最重要的工程结论是——容器时代宿主机只需要维护好驱动这一层,其余交给镜像。下一章云上第一台 GPU 机器解决“去哪里拿卡”:按用途选型、看懂计费、设置止损线,并完成从开机到彻底清理的第一个完整闭环。驱动与 CUDA 执行模型的深入原理,见CUDA 执行模型NVIDIA 软件栈分层

创建于 2026/09/14 更新于 2026/09/14 2674 字 阅读约 6 分钟