主题
第二部分 GPU 服务器与驱动环境(第 5~8 章)
本部分对应学习路线的第二阶段(第 3~4 周)。学完第一部分后,你已经理解了 GPU 硬件架构与 CUDA 生态的概念。从本部分开始,我们将进入"动手"阶段:从一台 GPU 服务器到货上架,到装好驱动、CUDA Toolkit、容器工具链,最终交付一个可以运行 GPU 容器的环境。这是 GPU 运维工程师最日常、最基础的工作,也是面试必问内容。
第 5 章 GPU 服务器硬件与上架检查
本章目标
- 认识 GPU 服务器的常见形态和 8 卡机的内部结构
- 理解 PCIe 拓扑与 NVLink/NVSwitch 拓扑的区别,读懂
nvidia-smi topo -m输出 - 掌握服务器到货验收的完整检查清单
- 学会使用 BMC/IPMI 进行带外管理
- 了解 GPU 服务器 BIOS 的推荐基线设置
5.1 GPU 服务器形态:1U/2U/4U 与 8 卡机典型结构
是什么:U(Unit)是机架服务器的高度单位,1U ≈ 4.45 cm。GPU 服务器按形态大致分为:
| 形态 | 典型 GPU 数量 | GPU 安装方式 | 典型场景 |
|---|---|---|---|
| 1U/2U | 1~4 张 PCIe 卡 | PCIe 插槽 | 推理、轻量训练、开发机 |
| 4U | 4~10 张 PCIe 卡 | PCIe 插槽(机箱更高,散热更好) | 训练、推理 |
| 4U/6U/8U | 8 张 SXM 卡 | SXM 模组 + NVSwitch 底板 | 大模型训练(NVIDIA HGX 8 卡机) |
PCIe 卡与 SXM 卡的区别(重要概念):
- PCIe 卡:长得像普通显卡,插在主板 PCIe 插槽上,卡间默认走 PCIe 总线通信,部分型号可选配 NVLink 桥接器。
- SXM 卡:无金手指的模组形态,直接安装在专用底板(Baseboard)上,供电散热能力更强,原生支持完整 NVLink + NVSwitch 互联。数据中心旗舰卡(A100/H100 SXM 版)都是这种形态。
典型 8 卡训练服务器(HGX 架构)的内部组成:
- GPU 底板区:8 张 SXM GPU + 若干颗 NVSwitch 高速互联芯片
- 主机区:2 颗 x86 CPU、1~2TB 内存、4~8 张 400G/800G 网卡(InfiniBand/RoCE)、NVMe SSD
- 供电散热区:多个冗余电源模块(N+N)、暴力风扇墙或液冷管路
运维要点:
- 电源冗余:8 卡机满载功耗可达数千瓦(具体以厂商规格为准),机房供电和 PDU 规划必须提前确认,通常是多路供电分别接入不同 PDU。
- 散热:高功耗意味着高热量,机房冷通道温度、风道组织直接影响 GPU 是否降频。
- 网卡配比:大模型训练通常要求"GPU : 网卡 = 1 : 1"(如 8 卡配 8 张 400G IB 网卡),第五部分会详细讲。
5.2 GPU 互联拓扑详解:nvidia-smi topo -m 逐行解读
为什么重要:分布式训练时 GPU 之间要频繁交换梯度数据。两张卡之间走 NVLink 还是走 PCIe、是否跨 NUMA 节点,通信带宽可能相差数倍。NCCL 会根据拓扑自动选择通信路径,运维人员需要能看懂拓扑来判断"这台机器的卡间通信是否健康"。
两类典型拓扑:
- PCIe 拓扑:GPU 挂在 PCIe Switch 或 CPU 的 PCIe Root Complex 下,卡间通信走 PCIe 总线。同交换机下的卡通信较快,跨 CPU(跨 NUMA)最慢。
- NVLink/NVSwitch 拓扑:SXM 卡之间通过 NVLink 直连或经 NVSwitch 全互联,任意两卡之间带宽一致且远高于 PCIe。
查看拓扑:
bash
nvidia-smi topo -mNVSwitch 8 卡机的典型输出(示意):
GPU0 GPU1 GPU2 ... CPU Affinity NUMA Affinity
GPU0 X NV18 NV18 0-95 0
GPU1 NV18 X NV18 0-95 0
GPU2 NV18 NV18 X 96-191 1
...图例(Legend)各标识的含义:
| 标识 | 含义 | 通信质量 |
|---|---|---|
X | 自己(Self) | — |
NV# | 通过 NVLink 互联,# 为链路数(如 NV18 表示 18 条链路) | 最优 |
NODE | 同一 NUMA 节点内(不跨 PCIe 主机桥) | 较好 |
PHB | 经过 PCIe 主机桥(Host Bridge),同一 CPU 下 | 一般 |
PXB | 经过多个 PCIe Switch(同一主机桥) | 一般 |
PIX | 经过一个 PCIe Switch | 较好(PCIe 机型中算好的) |
SYS | 跨 NUMA 节点,需经过 CPU 间互联(如 UPI) | 最差 |
运维关注点:
- 8 卡 SXM 机正常应显示
NV#全互联。如果出现PHB/SYS,说明 NVLink 链路掉了或 NVSwitch 异常(结合第七部分的 XID 错误排查)。 CPU Affinity列表示该 GPU 亲和的 CPU 核与 NUMA 节点,绑核、绑网卡都要参考它。
搭配查看 NVLink 状态:
bash
nvidia-smi nvlink --status # 每张卡的 NVLink 链路状态
nvidia-smi nvswitch -l # NVSwitch 状态(仅 NVSwitch 机型)5.3 上架与验收检查清单
GPU 服务器单价高昂,到货验收一定要留痕。推荐按以下清单执行:
1. 外观与物流验收:外包装无破损受潮,开箱拍照;机身无磕碰变形;核对序列号(SN)与采购合同一致:
bash
sudo dmidecode -t system | grep -E "Manufacturer|Product Name|Serial Number"2. 硬件配置核对:GPU 数量与型号、CPU、内存、磁盘、网卡:
bash
lspci | grep -i nvidia | wc -l # 应等于采购的 GPU 数量
lspci | grep -i nvidia | head -3 # 查看型号(装好驱动后可用 nvidia-smi -L)
lscpu | grep -E "Model name|^CPU\(s\)" && free -h && lsblk
lspci | grep -i -E "ethernet|infiniband"3. 固件版本记录:记录 BIOS、BMC、GPU VBIOS、NVSwitch、网卡固件版本,与厂商基线比对:
bash
sudo dmidecode -t bios | grep -E "Version|Release Date" # BIOS 版本
nvidia-smi -q | grep -i -E "VBIOS|Firmware" # GPU 固件(需先装驱动)4. 上电与散热检查:
- 多路供电分别接入不同 PDU,逐一断电测试冗余电源切换正常
- 风扇自检无异常噪音,进风口无遮挡
- 空载运行 30 分钟,观察 BMC 温度传感器无高温告警(见 5.4 节)
- 有条件时跑一轮 GPU 压测(如
gpu-burn),确认满载温度不触顶、不降频
5.4 带外管理:BMC/IPMI 基础
是什么:BMC(Baseboard Management Controller,基板管理控制器)是服务器主板上的一颗独立芯片,有独立的网口和固件。即使操作系统死机、甚至机器关机(接了电),你依然可以通过 BMC 远程查看状态、开关机、挂载 ISO 装系统——这就叫"带外管理"。IPMI 是与 BMC 通信的标准协议,常用工具是 ipmitool。
为什么重要:GPU 机房的服务器一旦死机(GPU 运维中并不罕见),没有带外管理就得跑机房。BMC 是所有远程运维操作的基础。
bash
sudo apt install -y ipmitool以下命令中 -H 是 BMC 管理 IP,-U/-P 是 BMC 账号密码(新机请第一时间修改默认密码!):
bash
BMC="ipmitool -I lanplus -H 192.168.1.100 -U admin -P 'password'"
$BMC power status # 查看电源状态
$BMC power on # 远程开机(off/soft/reset 分别为关机/优雅关机/硬重启)
$BMC sdr type temperature # 温度传感器(重点关注 CPU/GPU 进风温度)
$BMC sensor list | head -30 # 全部传感器(风扇转速、电压等)
$BMC sel list | tail -20 # 硬件事件日志 SEL:掉电、过热、内存 ECC 错误都在这里提示:除 IPMI 外,现代服务器还支持 Redfish API(基于 HTTPS/JSON),更适合自动化;各厂商 BMC 均有 Web 管理界面(如 iDRAC、iLO、XClarity),建议熟悉。
5.5 基线固化:BIOS 设置建议
新服务器交付前,应将 BIOS 配置固化为基线,保证同一批次机器行为一致。GPU 训练服务器的常见建议(不同厂商菜单名称略有差异,以厂商手册为准):
| 设置项 | 建议值 | 原因 |
|---|---|---|
| 电源/性能模式(Power Profile) | Performance | 节能模式导致 CPU/GPU 降频,训练性能抖动 |
| C-States / P-States(CPU 节能) | 关闭或限制 | 避免 CPU 频率波动影响数据加载 |
| Above 4G Decoding | 开启 | GPU 显存 BAR 空间巨大,不开会导致多卡机认不全卡(常见坑) |
| Resizable BAR | 按 GPU/主板支持情况开启 | 允许 CPU 访问完整显存 |
| IOMMU(VT-d / AMD-Vi) | 默认关闭;做 GPU 直通时开启 | 可能影响 GPUDirect RDMA,按需配置(第三部分细讲) |
| ACS | 做直通时关注 | ACS 会阻止同 IOMMU 组设备拆分,PCIe 拓扑规划要注意 |
| NUMA | 开启 | 训练任务要利用 NUMA 亲和性 |
| 串口重定向(SOL) | 按需开启 | 无 KVM 时可通过串口排查系统问题 |
实践建议:用 Redfish API 或厂商批量工具导出一份"标准 BIOS 配置",新机到货直接导入,避免逐台手工设置。
本章小结
- GPU 服务器分为 PCIe 卡机型(1U~4U)和 SXM + NVSwitch 8 卡机(HGX 架构),后者是大模型训练主力。
nvidia-smi topo -m中的NV#/NODE/PHB/PXB/PIX/SYS描述卡间通信路径质量,NVSwitch 机型应全NV#互联。- 验收要留痕:外观、序列号、硬件配置、固件版本、电源冗余、散热压测缺一不可。
- BMC/IPMI 是带外管理基础,
ipmitool的电源控制、传感器、SEL 日志是日常必备命令。 - BIOS 基线要固化,特别注意 Above 4G Decoding 必须开启,否则多卡机认不全卡。
动手实验
- 在有 GPU 的机器上执行
nvidia-smi topo -m,对照图例说明你的机器属于哪种拓扑;再执行nvidia-smi nvlink --status查看链路状态。 - 执行
lspci | grep -i nvidia和sudo dmidecode -t system,记录 GPU 数量、厂商、序列号,写一份"验收记录"Markdown 文档。 - 安装
ipmitool,浏览ipmitool help各子命令;如有真实 BMC 权限,完成一次远程开关机和 SEL 日志查看。 - 进入一次 BIOS 设置界面(或查阅厂商文档),找到 Above 4G Decoding 和电源模式选项,理解其作用。
第 6 章 NVIDIA 驱动安装与管理
本章目标
- 理解 NVIDIA 驱动的类型与选择原则
- 掌握 Ubuntu 安装驱动的三种方式,独立完成生产推荐的仓库安装
- 逐项读懂
nvidia-smi首屏输出 - 掌握驱动升级、回滚、DKMS 与内核升级后驱动失效的处理
- 能排查 Secure Boot、nouveau 冲突等常见安装问题
6.1 驱动类型:先搞清楚装的是什么
按内核模块开放程度分:
- 专有(闭源)内核模块:传统方式,NVIDIA 提供预编译二进制内核模块。
- 开源内核模块(Open GPU Kernel Modules):NVIDIA 自 R515 起开源了内核模块部分(用户态库仍闭源)。Turing 及以后架构两种都支持;Hopper(H100)及更新架构推荐开源模块,部分新特性依赖它。生产选择遵循 NVIDIA 官方对所用 GPU 架构的建议。
按产品线/发布分支分:
- 数据中心驱动(Data Center Driver):面向 T4/V100/A100/H100 等数据中心 GPU,提供 LTSB(长期支持分支),更新慢、稳定,生产环境首选。
- 桌面/GeForce 驱动:面向消费级显卡,更新频繁。
- "Tesla 驱动":NVIDIA 早年对数据中心产品线叫 Tesla,老文档里的"Tesla 驱动"就是数据中心驱动。
关键认知:驱动版本号(如 535.xx、550.xx、570.xx)决定能支持的最高 CUDA 版本(见 8.4 节)。生产选版本原则:数据中心 LTSB 分支 + 满足业务所需 CUDA 版本 + 全集群统一。
6.2 Ubuntu 安装驱动的三种方式
| 方式 | 做法 | 优点 | 缺点 | 适用 |
|---|---|---|---|---|
发行版 apt(ubuntu-drivers) | Ubuntu 官方仓库的 nvidia-driver-xxx 包 | 最简单 | 版本偏旧 | 桌面、快速实验 |
| NVIDIA 官方 CUDA 仓库 | 添加 NVIDIA apt 仓库后安装 | 版本新且全、有 DKMS、可精确选版本 | 需配置仓库 | 生产推荐 |
| runfile(.run 安装包) | 官网下载直接执行 | 离线可用 | 不走包管理,升级卸载麻烦 | 离线隔离环境 |
生产建议:统一使用 NVIDIA CUDA 仓库方式,用 Ansible 等工具固化流程,保证全集群驱动版本一致。
6.3 完整安装示例(NVIDIA 仓库方式,Ubuntu 22.04)
以下流程假设全新安装的 Ubuntu 22.04。驱动包名请替换为目标版本(如 nvidia-driver-570-server 数据中心分支,具体可用版本以仓库为准)。
第 1 步:禁用 nouveau(开源 NVIDIA 驱动,与官方驱动冲突):
bash
cat <<EOF | sudo tee /etc/modprobe.d/blacklist-nouveau.conf
blacklist nouveau
options nouveau modeset=0
EOF
sudo update-initramfs -u && sudo reboot
lsmod | grep nouveau # 重启后验证:无输出即成功第 2 步:安装内核头文件与编译工具(DKMS 编译驱动模块需要):
bash
sudo apt update
sudo apt install -y build-essential linux-headers-$(uname -r) dkms第 3 步:添加 NVIDIA CUDA 官方仓库(24.04 请把 ubuntu2204 换成 ubuntu2404):
bash
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb
sudo apt update第 4 步:安装驱动并重启:
bash
apt-cache search nvidia-driver | grep -E "nvidia-driver-[0-9]+" | sort # 查看可用版本
sudo apt install -y nvidia-driver-570-server # 数据中心服务器分支,版本以仓库为准
sudo reboot第 5 步:验证——执行 nvidia-smi,能看到 GPU 列表即成功;失败则看 6.6 节排查。
6.4 验证与版本管理:nvidia-smi 首屏逐项解读
nvidia-smi 是 GPU 运维的第一命令,首屏每个字段都要能看懂:
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 570.86.15 Driver Version: 570.86.15 CUDA Version: 12.8 |
|-----------------------------------------+----------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
|=================================+======================+======================|
| 0 NVIDIA A100-SXM... On | 00000000:10:00.0 Off | 0 |
| N/A 32C P0 60W / 400W | 0MiB / 40960MiB | 0% Default |
+--------------------------------+----------------------+----------------------+
| Processes: ... |
+---------------------------------------------------------------------------------------+| 字段 | 含义 | 运维关注点 |
|---|---|---|
| Driver Version | 当前内核驱动版本 | 故障定位首先要报这个号 |
| CUDA Version | 该驱动最高支持的 CUDA 版本(不是已装 Toolkit 版本!) | 判断容器/程序能否运行的关键(见 8.4) |
| Persistence-M | 持久模式是否开启(见 7.5) | 生产建议 On |
| Bus-Id | GPU 的 PCI 总线地址 | 定位物理卡、掉卡排查要用 |
| Uncorr. ECC | 不可纠正 ECC 错误计数(Volatile=重启清零) | 非 0 要警惕,配合 XID 排查 |
| Fan / Temp | 风扇转速 / 核心温度 | 数据中心卡多为被动散热显示 N/A;接近阈值会降频 |
| Perf | 性能状态 P0(最高)~P12(最低) | 空载长期 P0 可能浪费电 |
| Pwr:Usage/Cap | 当前功耗 / 功耗上限 | 触顶说明功耗墙限制 |
| Memory-Usage | 显存占用 / 总显存 | 日常盯得最紧的指标 |
| GPU-Util | GPU 利用率(采样周期内有 kernel 执行的时间占比) | 高利用率 ≠ 高效利用(第八部分细讲) |
| MIG M. | MIG 模式开关(仅 A100/H100 等支持) | 第三部分细讲 |
| Processes | 占用 GPU 的进程及显存 | 排查"显存被谁占了" |
常用进阶查询:
bash
# 只查关键指标,适合写巡检脚本
nvidia-smi --query-gpu=index,name,temperature.gpu,utilization.gpu,memory.used,memory.total,power.draw --format=csv
watch -n 1 nvidia-smi # 持续监控6.5 驱动升级与回滚、DKMS、内核升级后驱动失效
DKMS 是什么:DKMS(Dynamic Kernel Module Support)是"动态内核模块支持"框架。NVIDIA 驱动包含内核模块,必须与当前内核版本匹配编译。DKMS 的作用就是:每次系统内核升级后,自动为新内核重新编译 NVIDIA 内核模块——这就是 6.3 节要先装 dkms 和内核头文件的原因。
升级驱动(仓库方式):建议停掉 GPU 业务后操作。
bash
apt-cache policy nvidia-driver-570-server # 查看可升级版本
sudo apt update && sudo apt install -y nvidia-driver-570-server
sudo reboot回滚驱动:
bash
sudo apt purge -y "nvidia-driver-*" "nvidia-dkms-*" && sudo apt autoremove -y
sudo apt install -y nvidia-driver-550-server # 目标旧版本需在仓库中存在
sudo reboot生产建议:操作前记录当前版本(
nvidia-smi --query-gpu=driver_version --format=csv,noheader),先单台验证再批量。
内核升级后驱动失效:典型症状是重启后 nvidia-smi 报 NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver。排查修复:
bash
dkms status
# 正常应显示: nvidia/570.xx, 6.8.0-xx-generic, x86_64: installed
# 若只有 added 没有 installed,说明没为新内核编译
sudo apt install -y linux-headers-$(uname -r) # 常见原因:新内核头文件没装
sudo dkms autoinstall # 手动触发 DKMS 重新编译
sudo modprobe nvidia && nvidia-smi # 加载模块验证预防措施:生产环境建议锁定内核版本(
sudo apt-mark hold linux-image-generic linux-headers-generic),内核升级作为有计划的维护操作,随驱动一起验证。
6.6 常见安装问题
问题 1:Secure Boot 导致驱动加载失败
症状:驱动安装成功、DKMS 显示 installed,但 nvidia-smi 连不上驱动;dmesg | grep -i nvidia 可见模块签名错误。原因:UEFI Secure Boot 要求内核模块必须签名,DKMS 本地编译的模块默认未签名。
bash
mokutil --sb-state # 查看 Secure Boot 状态(enabled/disabled)
# 处理:进 BIOS 关闭 Secure Boot(数据中心推荐);
# 或安装时按提示注册 MOK 密码,重启时在蓝色 MOK 界面完成 Enroll问题 2:nouveau 冲突——lsmod | grep nouveau 有输出。处理:回到 6.3 节第 1 步,确认黑名单文件存在、执行过 update-initramfs -u 并重启。
问题 3:gcc / 内核头文件缺失——DKMS 编译失败,日志在 /var/lib/dkms/nvidia/*/build/make.log。处理:
bash
sudo apt install -y build-essential linux-headers-$(uname -r) && sudo dkms autoinstall问题 4:装了桌面驱动而非服务器驱动——数据中心卡应装 -server 后缀分支。装错时 purge 后重装即可。
本章小结
- 驱动分开源/闭源内核模块、数据中心/桌面分支;生产选数据中心 LTSB 分支,全集群版本统一。
- 三种安装方式中 NVIDIA CUDA 仓库方式最适合生产;完整流程:禁 nouveau → 装头文件和 DKMS → 加仓库 → 装驱动 → 重启验证。
nvidia-smi首屏的 CUDA Version 是"驱动支持的最高 CUDA";ECC 错误数、功耗、显存是日常关注点。- DKMS 负责内核升级后自动重编驱动模块;失效时先补内核头文件再
dkms autoinstall;生产建议锁定内核。 - Secure Boot、nouveau、缺头文件是三大经典安装坑。
动手实验
- 在一台带 NVIDIA 显卡的 Ubuntu 机器上,完整走一遍 6.3 节仓库安装流程,记录每步输出。
- 执行
nvidia-smi,对照 6.4 节表格,把首屏每个字段的含义用自己的话写进笔记。 - 执行 6.4 节
--query-gpu命令,把输出保存为 CSV,模拟一次"巡检"。 - 执行
dkms status和mokutil --sb-state,理解当前机器 DKMS 与 Secure Boot 状态。 - 思考题:机房不允许联网时,如何给 100 台新服务器装驱动?(提示:runfile + 本地 apt 镜像 + Ansible)
第 7 章 CUDA Toolkit 与 Fabric Manager
本章目标
- 独立安装 CUDA Toolkit 并配置环境变量
- 会用 CUDA Samples 验证 GPU 计算与带宽
- 掌握多版本 CUDA 共存与切换
- 理解 Fabric Manager 的作用场景与版本匹配要求
- 掌握持久模式与 GPU 时钟管理
7.1 CUDA Toolkit 安装与环境变量
是什么、为什么:驱动(第 6 章)只解决"内核认识 GPU";CUDA Toolkit 提供编译器 nvcc、CUDA 运行时库(libcudart 等)、数学库和开发工具。需要在本机编译 CUDA 程序、裸金属跑训练的开发机需要装它。
注意区分:宿主机只跑 CUDA 容器时不需要装 CUDA Toolkit(容器自带运行时,见第 8 章),只有驱动是必需的。
安装(接续第 6 章已配好的仓库):
bash
sudo apt install -y cuda-toolkit-12-4 # 只装 Toolkit,不含驱动,便于独立控制驱动版本
# 想一步到位装"驱动+Toolkit"可用 meta 包:sudo apt install -y cuda-12-4环境变量配置:
bash
cat <<'EOF' | sudo tee /etc/profile.d/cuda.sh
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
EOF
source /etc/profile.d/cuda.sh
nvcc --version # 验证,输出示例:Cuda compilation tools, release 12.4, V12.4.xxx再次提醒:
nvcc --version显示的是本机安装的 Toolkit 版本;nvidia-smi右上角是驱动支持的最高 CUDA 版本。两者不要求一致,规则见 8.4 节。
7.2 用 CUDA Samples 验证:deviceQuery / bandwidthTest
CUDA Samples 是 NVIDIA 官方示例程序集,装完环境后跑一遍,可同时验证"编译链可用、GPU 能算、带宽正常"。新版 Samples 托管在 GitHub,需自行编译:
bash
sudo apt install -y git cmake
git clone https://github.com/NVIDIA/cuda-samples.git
cd cuda-samples/Samples/1_Utilities/deviceQuery
make -j$(nproc) && ./deviceQuerydeviceQuery 输出 GPU 型号、计算能力(Compute Capability)、SM 数量、显存等,最后打印 Result = PASS 即正常。
带宽测试(关键交付指标):
bash
cd ../bandwidthTest && make -j$(nproc) && ./bandwidthTest它输出 Host↔Device(内存到显存)带宽。验收对照:PCIe 4.0 x16 理论约 32 GB/s(双向 64),实测略低于理论值属正常;如果只有几百 MB/s,往往是插在了低速插槽、Above 4G Decoding 没开或硬件故障——这是新机器交付前的必测项,具体数值以官方规格和实测为准。
多卡机可用 p2pBandwidthLatencyTest(位于 Samples/5_Domain_Specific)验证 GPU↔GPU 通信,NVLink 机型应远高于 PCIe 机型。
7.3 多版本 CUDA 共存管理
现实场景:老业务要 CUDA 11.8,新业务要 CUDA 12.4,同一台机器怎么办?
方案:多版本并存 + 软链接切换。apt 安装的不同版本 Toolkit 放在 /usr/local/cuda-11.8、/usr/local/cuda-12.4 等目录,/usr/local/cuda 是软链接:
bash
ls -l /usr/local/ | grep cuda
# lrwxrwxrwx cuda -> /usr/local/cuda-12.4
# drwxr-xr-x cuda-11.8/
# drwxr-xr-x cuda-12.4/
sudo ln -sfn /usr/local/cuda-11.8 /usr/local/cuda # 切换默认版本
nvcc --version # 确认已切换更好的实践:让用户/任务在自己的环境或作业脚本中显式指定版本,而不是改全局软链接:
bash
export PATH=/usr/local/cuda-11.8/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-11.8/lib64:$LD_LIBRARY_PATH生产经验:能容器化的业务尽量用容器隔离 CUDA 版本(第 8 章),宿主机保持单一 Toolkit 甚至不装,管理成本最低。
7.4 Fabric Manager:NVSwitch 机型必装组件
是什么、为什么:Fabric Manager 是 NVIDIA 的系统服务(nvidia-fabricmanager),负责初始化 NVSwitch 交换矩阵,让 8 张 GPU 通过 NVSwitch 全互联。适用机型:采用 NVSwitch 的 SXM 8 卡机,如 HGX A100 / HGX H100 / DGX 系列。PCIe 卡机型不需要安装。
不装的后果:驱动能装上、nvidia-smi 也能看到 8 张卡,但 NVLink 不通,多卡训练报错或退化——nvidia-smi topo -m 里看不到 NV# 互联。
版本必须严格匹配:Fabric Manager 版本号必须与驱动完全一致(驱动 570.86.15 对应 Fabric Manager 570.86.15),否则服务启动失败。用同一仓库安装可自动对齐:
bash
sudo apt install -y nvidia-fabricmanager-570 # 与驱动同版本
sudo systemctl enable --now nvidia-fabricmanager # 启动并开机自启
sudo systemctl status nvidia-fabricmanager # Active: active (running) 即正常
nvidia-smi topo -m # 验证:8 卡之间应全为 NV# 互联升级驱动时必须同步升级 Fabric Manager,否则重启后服务起不来——这是生产常见事故点,升级脚本里务必把两个包一起更新。
7.5 持久模式与 GPU 时钟
持久模式(Persistence Mode):默认情况下,没有进程使用 GPU 时,Linux 会卸载 GPU 驱动状态以省电,下次使用时重新初始化,带来数百毫秒级延迟。开启持久模式让驱动常驻:
bash
sudo nvidia-smi -pm 1 # 开启(-i 可指定单卡)
nvidia-smi -q -d PERFORMANCE | grep -i persistence # 查看生产建议:所有 GPU 服务器开启持久模式。重启保持方式:写入 systemd 单元或启动脚本(新驱动也可使用 nvidia-persistenced 服务)。
GPU 时钟管理:GPU 时钟会根据负载、温度、功耗动态调整。对性能有严格要求的场景可以锁定:
bash
nvidia-smi -q -d SUPPORTED_CLOCKS # 查看支持的时钟范围(单位 MHz,以实际输出为准)
sudo nvidia-smi -lgc 1500,1980 # 锁定 Graphics 时钟区间
sudo nvidia-smi -lgc 1980,1980 # 锁死最高频率
sudo nvidia-smi -lmc 1215,1215 # 锁定显存时钟
sudo nvidia-smi -rgc && sudo nvidia-smi -rmc # 恢复自动调节应用时钟(Application Clocks):指定 GPU 运行应用时的目标时钟,与 -lgc(锁定范围)不同:
bash
sudo nvidia-smi -ac 1215,1410 # <显存时钟,图形时钟>运维建议:
- 性能基准测试/交付验收时锁定时钟,保证结果可复现;日常生产一般不锁死最高频(费电、发热大)。
- 发现 GPU 莫名变慢,先查
nvidia-smi -q -d PERFORMANCE里的 Clocks Event Reasons(降频原因:温度、功耗、空闲等)。
本章小结
- CUDA Toolkit 提供 nvcc 与运行时库;裸金属开发/编译需要装,纯跑容器可以不装。装后配置
PATH与LD_LIBRARY_PATH,用nvcc --version验证。 - 用
deviceQuery和bandwidthTest验证计算与带宽;带宽明显偏低要查插槽、Above 4G Decoding 和硬件。 - 多版本 CUDA 通过
/usr/local/cuda-x.y共存,软链接或环境变量切换;更推荐容器隔离。 - NVSwitch 机型必须装 Fabric Manager,版本与驱动严格一致,用 systemd 管理,升级驱动时同步升级。
- 生产开启持久模式(
nvidia-smi -pm 1);时钟可锁定(-lgc)用于基准测试,异常变慢先查降频原因。
动手实验
- 安装 CUDA Toolkit,配置环境变量,执行
nvcc --version并与nvidia-smi的 CUDA Version 对比,解释两者区别。 - 编译运行
deviceQuery和bandwidthTest,记录 GPU 型号、计算能力和实测带宽,判断是否符合 PCIe 代际预期。 - 安装两个版本的 cuda-toolkit,练习用软链接和环境变量两种方式切换
nvcc版本。 - 执行
sudo nvidia-smi -pm 1并验证;思考如何让它开机自动生效(写一个 systemd unit)。 - 执行
nvidia-smi -q -d PERFORMANCE,查看当前时钟与降频原因字段。
第 8 章 NVIDIA Container Toolkit(容器运行 GPU)
本章目标
- 理解容器使用宿主机 GPU 的原理
- 独立完成 nvidia-container-toolkit 安装与 containerd/Docker 配置
- 掌握 GPU 容器验证命令与
NVIDIA_VISIBLE_DEVICES卡分配控制 - 讲清楚容器内 CUDA 版本与宿主机驱动的兼容性规则
- 掌握生产镜像选择与"容器里不装驱动"的原则
8.1 原理:容器如何使用宿主机 GPU
问题背景:容器本质是宿主机上隔离的进程,共享宿主机内核。容器里的 CUDA 程序要访问 GPU,需要两样东西:
- 设备文件:
/dev/nvidia0、/dev/nvidia1(每张卡一个)、/dev/nvidiactl、/dev/nvidia-uvm等,由宿主机驱动创建。 - 用户态驱动库:
libcuda.so等,版本必须与宿主机内核驱动完全匹配。
nvidia-container-toolkit 的作用:启动容器时,它作为"钩子"自动把宿主机上的设备文件和驱动库注入容器,容器内程序就能像物理机一样调用 GPU。
记住两条铁律:
- 驱动只装在宿主机,容器镜像里绝不装驱动。
- 容器内自带 CUDA Runtime(在镜像里),宿主机驱动决定"最高支持到哪个 CUDA"。
8.2 安装 nvidia-container-toolkit 与配置运行时
安装(Ubuntu 22.04/24.04):
bash
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \
sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L 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
sudo apt update && sudo apt install -y nvidia-container-toolkit配置 Docker 运行时:
bash
sudo nvidia-ctk runtime configure --runtime=docker # 自动修改 /etc/docker/daemon.json
sudo systemctl restart docker配置 containerd 运行时(K8s 节点常用):
bash
sudo nvidia-ctk runtime configure --runtime=containerd # 自动修改 /etc/containerd/config.toml
sudo systemctl restart containerd在 Kubernetes 集群中,第四部分会讲用 NVIDIA GPU Operator 自动完成这一切;但手动安装的原理必须掌握,排错时用得上。
8.3 验证与 GPU 分配控制
基础验证:
bash
docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi能打印出宿主机 GPU 列表即成功。
控制容器能看到哪些卡:
bash
docker run --rm --gpus '"device=0"' nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi # 只分配 0 号卡
docker run --rm --gpus '"device=0,2"' nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi # 分配 0 和 2 号卡NVIDIA_VISIBLE_DEVICES 环境变量(底层机制,K8s Device Plugin 注入的也是它):
bash
# 效果等同 --gpus '"device=1"'
docker run --rm -e NVIDIA_VISIBLE_DEVICES=1 nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi
# 经典坑:设成 none 后即使 --gpus all 也看不到卡
docker run --rm --gpus all -e NVIDIA_VISIBLE_DEVICES=none nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi
# 输出:Failed to initialize NVML ...注意:容器内
nvidia-smi显示的 GPU 编号是重映射后的(容器内从 0 开始),与宿主机编号不一定一致。排查任务占错卡时,用NVIDIA_VISIBLE_DEVICES的值对照宿主机编号。
8.4 容器内 CUDA 版本与宿主机驱动的兼容性规则
核心规则(务必记住):
- 宿主机驱动决定上限:
nvidia-smi右上角 CUDA Version 是驱动支持的最高 CUDA 版本。容器内 CUDA Runtime 版本 ≤ 该值即可运行。 - 小版本兼容(Minor Version Compatibility):同一 CUDA 大版本内(如 12.x),低版本 Toolkit 编译的程序可在更高版本驱动上运行;跨大版本不行(CUDA 12 的镜像不能在只支持 CUDA 11 的老驱动上跑)。
- 向前兼容包(Forward Compatibility):老驱动跑新 CUDA 的特例方案,通过
cuda-compat包实现,主要用于特定场景(如 vGPU),不作为常规手段。
实操检查方法:
bash
nvidia-smi | grep "CUDA Version" # 宿主机驱动支持的最高 CUDA
docker run --rm nvidia/cuda:12.4.1-base-ubuntu22.04 bash -c "cat /usr/local/cuda/version.json | head -5"运维决策:升级业务镜像(CUDA 更高)前,先确认全集群驱动支持;驱动升级计划要先盘点容器镜像的 CUDA 需求。兼容性矩阵以 NVIDIA 官方文档(CUDA Compatibility)为准。
8.5 生产建议:镜像选择与"不要往容器里装驱动"
nvidia/cuda 官方镜像的 tag 构成:nvidia/cuda:<CUDA版本>-<类型>-<系统>,三种类型:
| 类型 | 内容 | 体积 | 适用 |
|---|---|---|---|
base | 最小 CUDA Runtime(libcudart 等) | 最小 | 运行已编译好的 CUDA 程序 |
runtime | base + CUDA 数学库(cuBLAS、cuDNN 等) | 中 | 跑深度学习框架,生产镜像首选基础 |
devel | runtime + nvcc 编译器、头文件 | 最大 | 编译期使用(多阶段构建的 builder 阶段) |
典型做法(多阶段构建,编译与运行分离):
dockerfile
FROM nvidia/cuda:12.4.1-devel-ubuntu22.04 AS builder # 编译阶段用 devel
COPY . /src
RUN make -C /src
FROM nvidia/cuda:12.4.1-runtime-ubuntu22.04 # 运行阶段用 runtime,镜像小、攻击面小
COPY --from=builder /src/app /usr/local/bin/app
CMD ["app"]生产建议清单:
- [ ] 镜像基于官方
nvidia/cuda或 NGC(nvcr.io)框架镜像(如nvcr.io/nvidia/pytorch:xx.xx-py3),不要自己从零组装 CUDA。 - [ ] 绝不在 Dockerfile 里
apt install nvidia-driver-*或执行.run驱动包——驱动必须且只能来自宿主机注入。镜像里装驱动导致库版本错乱,是最经典的新手事故。 - [ ] 镜像 tag 锁定到具体版本(不用
latest),保证可复现。 - [ ] 推理服务优先用 TensorRT-LLM / Triton 等 NGC 优化镜像。
- [ ] 镜像安全扫描纳入 CI;devel 镜像不进生产运行时。
本章小结
- 容器用 GPU 的原理:宿主机驱动创建
/dev/nvidia*设备文件,nvidia-container-toolkit 在容器启动时注入设备文件和匹配的用户态驱动库。 - 安装
nvidia-container-toolkit后用nvidia-ctk runtime configure配置 docker/containerd;用docker run --rm --gpus all nvidia/cuda:... nvidia-smi验证。 --gpus device=N与NVIDIA_VISIBLE_DEVICES控制卡分配,容器内卡号会重映射。- 兼容性铁律:容器 CUDA Runtime 版本不超过驱动支持的最高 CUDA(跨大版本不行);镜像升级与驱动升级要互相盘点。
- 镜像选
runtime跑业务、devel做编译;容器里永远不装驱动。
动手实验
- 在装好驱动的机器上安装 nvidia-container-toolkit,配置 Docker,执行
docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi并记录输出。 - 用
--gpus '"device=0"'和NVIDIA_VISIBLE_DEVICES各做一次单卡分配实验,观察容器内nvidia-smi卡号变化。 - 找一个含 PyTorch 的镜像,执行
python -c "import torch; print(torch.cuda.is_available())",验证框架可用 GPU。 - 查看宿主机
nvidia-smi的 CUDA Version,再分别拉一个 CUDA 11.8 和 CUDA 12.x 镜像跑nvidia-smi,用实验验证 8.4 节兼容性规则。 - 思考题:为什么 K8s 里通过
resources.limits.nvidia.com/gpu: 1申请 GPU 的 Pod,最终也是靠NVIDIA_VISIBLE_DEVICES实现分配的?(预习第四部分)
本部分回顾
至此,你已经完成了一台 GPU 服务器从到货上架、验收检查、BIOS 基线、驱动安装、CUDA Toolkit、Fabric Manager 到容器运行 GPU 的完整环境搭建。这套流程是 GPU 运维工程师的"基本功",后续第三部分(虚拟化与共享)和第四部分(Kubernetes GPU 调度)都建立在这个环境之上。
下一部分预告:一张昂贵的 A100/H100 只跑一个小任务太浪费——第三部分将学习 GPU 直通、vGPU、MIG、MPS、时间片共享等技术,让一张卡安全高效地服务多个用户。