跳转至

GPU 软件栈全景

当你在一台服务器上使用 GPU 时,你面对的并不是单一的软件或硬件,而是围绕 NVIDIA GPU 构建的一整套软件栈。从最底层的物理硬件到最上层的 Kubernetes 调度,大致可以分为 5 层:

硬件层Linux 内核驱动层用户态库/工具层容器运行时层Kubernetes / HAMi 调度层

理解这个分层结构,是排查 GPU 问题、理解 HAMi 工作原理的基础。

5 层架构总览

下图展示了 GPU 软件栈的完整分层结构:

%% title: GPU 软件栈 5 层架构
graph TB
    subgraph L5["第 5 层:Kubernetes 调度"]
        K8sScheduler["Kubernetes Scheduler"]
        HAMiScheduler["HAMi Scheduler"]
        Pod["Pod"]
    end

    subgraph L4["第 4 层:容器运行时"]
        containerd["containerd"]
        NVIDIAToolkit["NVIDIA Container Toolkit"]
        Container["Container"]
    end

    subgraph L3["第 3 层:用户态库/工具"]
        CUDA["CUDA Runtime / Toolkit"]
        NVML["NVML (libnvidia-ml.so)"]
        nvidia_smi["nvidia-smi"]
        DCGM["DCGM"]
        MIG["MIG"]
    end

    subgraph L2["第 2 层:内核驱动"]
        nvidia_ko["nvidia.ko (Kernel Module)"]
        nvidia_uvm["nvidia-uvm.ko"]
        nvidia_modeset["nvidia-modeset.ko"]
    end

    subgraph L1["第 1 层:硬件"]
        GPU["NVIDIA GPU"]
        PCIe["PCIe Bus"]
        NVLink["NVLink (可选)"]
    end

    %% 层间连接
    Pod --> Container
    K8sScheduler --> Pod
    HAMiScheduler --> Pod

    Container --> NVIDIAToolkit
    NVIDIAToolkit --> containerd

    Container --> CUDA
    Container --> NVML
    nvidia_smi --> NVML
    DCGM --> NVML

    CUDA --> nvidia_ko
    NVML --> nvidia_ko

    nvidia_ko --> nvidia_uvm
    nvidia_ko --> nvidia_modeset
    nvidia_ko --> GPU
    GPU --- PCIe
    GPU --- NVLink

各层详解

第 1 层:硬件层

物理硬件是一切的基础:

  • GPU:NVIDIA GPU 芯片(如 A100、H100、L40 等),负责并行计算。
  • PCIe Bus:GPU 通过 PCIe 插槽与 CPU 通信,是数据传输的主要通道。
  • NVLink(可选):多 GPU 之间的高速互联通道,带宽远高于 PCIe。

第 2 层:Linux 内核驱动层

内核驱动是用户态程序访问 GPU 的桥梁:

  • nvidia.ko:NVIDIA 核心内核模块,管理 GPU 硬件资源、显存分配和命令提交。
  • nvidia-uvm.ko:统一虚拟内存(Unified Virtual Memory)模块,支持 CPU 和 GPU 之间透明地共享内存地址空间。
  • nvidia-modeset.ko:显示模式设置模块,用于 GPU 的图形输出管理。

内核驱动向上暴露 /dev/nvidia* 设备节点,用户态程序通过这些设备节点与 GPU 交互。

第 3 层:用户态库/工具层

这一层包含了开发者和管理员最常接触的工具和库:

  • CUDA:NVIDIA 的并行计算平台和编程模型,包括编译器(nvcc)、运行时库和开发工具。几乎所有 GPU 应用都通过 CUDA 调用 GPU。
  • NVML(NVIDIA Management Library):GPU 管理库(libnvidia-ml.so),提供查询 GPU 状态(温度、显存、利用率等)的 API。nvidia-smi、DCGM 等工具都依赖它。
  • nvidia-smi:命令行管理工具,用于查看 GPU 状态、进程、显存使用情况等。它是 NVML 的 CLI 前端。
  • DCGM(Data Center GPU Manager):数据中心 GPU 管理工具,提供健康状态监控、诊断、组管理等功能,适用于大规模 GPU 集群。
  • MIG(Multi-Instance GPU):多实例 GPU 技术,将一块 A100/H100 物理上划分为多个隔离的 GPU 实例,每个实例拥有独立的显存和计算核心。

第 4 层:容器运行时层

为了让 GPU 在容器中可用,需要额外的运行时组件:

  • containerd:容器运行时,负责镜像管理和容器生命周期管理。Kubernetes 默认使用 containerd。
  • NVIDIA Container Toolkit(原 nvidia-docker2):在容器启动时,自动将 GPU 设备节点、CUDA 库和 NVIDIA 驱动库挂载到容器内。它是容器使用 GPU 的关键桥梁。
  • Container:运行中的应用容器,通过 Toolkit 获得对 GPU 的访问能力。

第 5 层:Kubernetes / HAMi 调度层

在 Kubernetes 集群中管理 GPU 需要:

  • NVIDIA Device Plugin:Kubernetes 设备插件,向 kubelet 上报节点上的 GPU 资源,使 Kubernetes 能够感知 GPU 并调度 GPU 任务。
  • GPU Operator:NVIDIA 提供的 Kubernetes Operator,自动化部署和管理驱动、Container Toolkit、Device Plugin、DCGM 等组件。
  • HAMi Device Plugin:HAMi 的设备插件,支持 GPU 显存和算力的细粒度切分与共享。
  • HAMi Scheduler:HAMi 的调度器扩展,支持 Binpack/Spread、优先级、指定卡调度等高级调度策略。

关键调用链

理解 GPU 软件栈中几条关键的调用链,有助于排查问题和理解各组件的关系。

完整依赖链

一个使用 GPU 的 Pod 从创建到运行,经历了以下依赖链:

%% title: 完整 GPU Pod 依赖链
graph LR
    Pod --> containerd
    containerd --> NVIDIAToolkit["NVIDIA Container Toolkit"]
    NVIDIAToolkit --> CUDA
    CUDA --> Driver["用户态驱动库"]
    Driver --> nvidia_ko["nvidia.ko"]
    nvidia_ko --> PCIe
    PCIe --> GPU

nvidia-smi 调用链

nvidia-smi 查询 GPU 信息的完整路径:

%% title: nvidia-smi 调用链
graph LR
    SMI["nvidia-smi"] --> NVML
    NVML --> lib["libnvidia-ml.so"]
    lib --> nvidia_ko["nvidia.ko"]
    nvidia_ko --> GPU

管理工具调用链

多个管理工具都通过 NVML 访问 GPU:

%% title: 管理工具调用链
graph LR
    nvidia_smi["nvidia-smi"] --> NVML
    DCGM --> NVML
    DevicePlugin["Device Plugin"] --> NVML
    NVML --> lib["libnvidia-ml.so"]
    lib --> nvidia_ko["nvidia.ko"]
    nvidia_ko --> GPU

可以看到,无论是命令行工具、监控组件还是 Kubernetes 设备插件,最终都通过 NVML → 内核驱动 → GPU 这条路径来访问硬件。

Kubernetes GPU 调度链

在 Kubernetes 中,GPU 资源从硬件到 Pod 的调度流程:

%% title: Kubernetes GPU 调度链
graph LR
    GPU --> Driver["Driver"]
    Driver --> DevicePlugin["Device Plugin"]
    DevicePlugin --> kubelet
    kubelet --> K8s["Kubernetes API"]
    K8s --> Scheduler["K8s Scheduler"]
    Scheduler --> Pod

HAMi 增强调度链

HAMi 在原生调度链基础上,替换了 Device Plugin 和 Scheduler,实现 GPU 切分与共享:

%% title: HAMi 增强调度链
graph LR
    GPU --> Driver["Driver"]
    Driver --> HAMiDP["HAMi Device Plugin"]
    HAMiDP --> kubelet
    kubelet --> K8s["Kubernetes API"]
    K8s --> HAMiScheduler["HAMi Scheduler"]
    HAMiScheduler --> Pod

组件速查表

组件 一句话说明
GPU NVIDIA GPU 硬件,执行并行计算任务
PCIe 连接 GPU 和 CPU 的总线,负责数据传输
nvidia.ko NVIDIA 内核模块,管理 GPU 硬件资源,向上暴露设备节点
nvidia-smi 命令行工具,查看 GPU 状态、显存、进程等信息
NVML NVIDIA Management Library,GPU 管理的 C 语言 API
libnvidia-ml.so NVML 的共享库实现,所有管理工具都通过它与驱动通信
CUDA NVIDIA 并行计算平台,GPU 应用的核心编程和运行时框架
MIG Multi-Instance GPU,将一块 GPU 物理划分为多个隔离实例
DCGM 数据中心 GPU 管理工具,提供监控、诊断和健康检查
containerd 容器运行时,管理容器镜像和生命周期
NVIDIA Container Toolkit 容器 GPU 支持,启动时自动挂载 GPU 设备和库到容器内
Device Plugin K8s 设备插件,向集群上报节点 GPU 资源信息
GPU Operator NVIDIA Operator,自动化部署和管理 GPU 相关的全栈组件
HAMi GPU 虚拟化中间件,支持显存和算力的细粒度切分与共享
HAMi Device Plugin HAMi 的设备插件,替代原生 Device Plugin,支持 GPU 切分上报