NVIDIA 软件栈:一个应用,多份契约
草稿
GPU 容器不会直接和硅片对话。任何一条边界上的失配,都可能表现为“莫名其妙的应用错误”。
应用或框架调用库;库调用 CUDA;CUDA 运行时与驱动交互;容器运行时注入设备访问;内核驱动与硬件对话。排查 GPU 问题的第一课,是先判断故障发生在哪一层,自底向上检查往往最快。
逐层拆解
| 层 | 职责 | 故障信号 |
|---|---|---|
| 固件 / GPU | 供电、内存、引擎、链路、RAS | 硬件错误、复位、链路故障 |
| 内核驱动 | 特权设备访问与内存管理 | 模块失配、Xid、设备消失 |
| Container Toolkit | 向容器注入设备与库 | 容器里没有 GPU |
| CUDA 运行时 | kernel 启动、流、内存、事件、驱动 API | 符号缺失或运行时不匹配 |
| cuBLAS / cuDNN | 优化的线性代数与神经网络原语 | 不支持的路径或糟糕的 kernel 选择 |
| NCCL | 集合与对等通信 | 挂起、超时、扩展缓慢 |
| TensorRT / TRT-LLM | 优化的推理图与引擎执行 | 构建失配或不支持的算子 |
| DCGM | 遥测、诊断、健康、exporter 集成 | 指标或健康状态缺失 |
每一层的故障签名都不同:Xid 错误指向驱动与硬件层(见指标语义),“容器里没有 GPU”指向工具链层(见下一章),符号缺失指向运行时版本失配,扩展缓慢则多半是 NCCL 与互连问题(见互连与集合通信)。
驱动与运行时:兼容性的方向
主机驱动是特权的,与内核和 GPU 绑定。容器通常携带用户态运行时部件和应用库。驱动必须支持运行时与 GPU 架构;基于较新 CUDA 版本构建的镜像,可能在驱动较旧的节点上失败。更新的驱动并不保证所有应用都兼容,但过旧的驱动是常见的头号嫌疑。
工程纪律
锁定节点驱动、基础镜像、框架和 GPU Operator 版本,建立兼容性矩阵。在改动整个机群之前,用诊断镜像加一个代表性工作负载测试升级。
CUDA 库与优化路径
cuBLAS 加速稠密线性代数;cuDNN 提供优化的深度学习原语;NCCL 处理分布式通信;TensorRT 构建优化的推理引擎;TensorRT-LLM 把这些思想专门化用于语言模型服务;DCGM 及其 exporter 暴露健康与遥测;CUDA Toolkit 提供把各层粘合在一起的编译器、运行时、工具和编程接口。
应用很少直接使用所有这些库,但性能与可靠性正是从它们的组合中涌现,这也是为什么版本矩阵管理(详见安全、可靠性与生命周期)是平台团队的核心职责。
总结
把 GPU 栈看成一张契约图,“哪层 owns 这个故障”就有了判定依据。本章的分层表也是全书排障章节的索引:固件与驱动问题走 Xid 路径,工具链问题走 Toolkit 路径,性能问题走互连与调度路径。下一章深入其中的 Container Toolkit 层。