GKE 中的 GPU 共享策略简介


本页面介绍了 Google Kubernetes Engine (GKE) 中提供的每种 GPU 共享策略(例如多实例 GPU、GPU 分时和 NVIDIA MPS)的特征和最佳工作负载类型。

在阅读本页面之前,请确保您熟悉以下内容:

GPU 请求在 Kubernetes 中的工作原理

Kubernetes 使工作负载能够精确请求应用正常运行所需的资源量。虽然您可以为工作负载请求少于一个 CPU 单位,但您不能请求少于一个 GPU 单位。Pod 清单必须请求整数单位的 GPU 资源,这意味着一个物理 GPU 会完整分配给一个容器,即使该容器只需要其中部分资源便可正常运行也是如此。这种方式效率低下且费用高昂,尤其是当您运行具有类似低 GPU 要求的多个工作负载时。

最佳实践

当工作负载不需要所有 GPU 资源时,请使用 GPU 共享策略来提高 GPU 利用率。

什么是 GPU 共享策略?

GPU 共享策略可让多个容器高效地使用挂接的 GPU 并节省运行费用。GKE 提供以下 GPU 共享策略:

  • 多实例 GPU:GKE 将单个受支持的 GPU 划分为最多七个切片。每个切片可以独立分配给节点上的一个容器,每个 GPU 最多支持 7 个容器。多实例 GPU 在工作负载之间提供硬件隔离,并为 GPU 上运行的所有容器提供一致且可预测的服务质量 (QoS)。
  • GPU 分时:GKE 使用 NVIDIA GPU 和软件栈提供的内置分时功能。从 Pascal 架构开始,NVIDIA GPU 支持指令级抢占。在 GPU 上运行的进程之间进行上下文切换时,指令级抢占可确保每个进程都获得公平的时间片。GPU 分时功能会以地址空间隔离、性能隔离和故障隔离的形式在工作负载之间提供软件级隔离。
  • NVIDIA MPS:GKE 使用 NVIDIA 的多进程服务 (MPS)。NVIDIA MPS 是 CUDA API 的二进制兼容替代实现,旨在以透明方式使协作多进程 CUDA 工作负载能够在单个 GPU 设备上并发运行。采用 NVIDIA MPS 的 GPU 会以资源限制(活跃线程百分比固定设备内存)的形式提供软件级隔离。

使用哪种 GPU 共享策略

下表总结并比较了可用的 GPU 共享策略的特征:

多实例 GPU GPU 分时 NVIDIA MPS
常规 在容器之间共享并行 GPU 快速上下文切换 在容器之间共享并行 GPU
隔离 单个 GPU 最多可划分为七个切片,同一物理 GPU 上的每个容器都有专用的计算、内存和带宽。因此,即使其他容器已使其他分区饱和,一个分区中的容器也具有可预测的吞吐量和延迟时间。

每个容器都可以通过在 GPU 上运行的进程之间进行上下文切换来访问底层物理 GPU 的全部容量。

但是,分时在共享作业之间不强制执行内存限制,并且共享访问的快速上下文切换可能会带来开销。

NVIDIA MPS 的资源隔离虽然有限,但在其他维度上可以获得更大的灵活性(例如 GPU 类型和最大共享单元),从而简化了资源分配。
适合的工作负载 建议用于并行运行且需要特定弹性和 QoS 的工作负载。例如,运行 AI 推理工作负载时,多实例 GPU 多实例 GPU 允许同时运行多个推理查询以实现快速响应,而不会相互减慢速度。

建议用于具有空闲时间段的突发性和交互式工作负载。如果使用完全专用 GPU,这些工作负载不具备成本效益。通过使用分时,工作负载可以在处于活跃阶段时快速访问 GPU。

对于可能不需要完全隔离和连续 GPU 访问的场景(例如,多个用户在没有空闲昂贵的 GPU 的情况下测试工作负载或设计工作负载原型时),GPU 分时功能是最佳选择。

使用分时功能的工作负载需要容忍牺牲某些性能和延迟时间。

建议用于小型作业的批处理,因为 MPS 可以最大限度地提高 GPU 的吞吐量和并发使用数。MPS 支持高效地并行处理中小型工作负载的批量作业。

NVIDIA MPS 最适合作为单个应用的协作进程。例如,利用 MPI 队列并行性的 MPI 作业。借助这些作业,每个小型 CUDA 进程(通常是 MPI 队列)可以在 GPU 上并发运行,以使整个 GPU 完全饱和。

使用 CUDA MPS 的工作负载需要容忍内存保护和错误控制限制

监控 GPU 利用率指标不适用于多实例 GPU。 使用 Cloud Monitoring 监控 GPU 分时的性能。如需详细了解可用指标,请参阅监控 GPU 分时或 NVIDIA MPS 节点 使用 Cloud Monitoring 监控 NVIDIA MPS 的性能。如需详细了解可用指标,请参阅监控 GPU 分时或 NVIDIA MPS 节点
在工作负载中请求共享 GPU 运行多实例 GPU 使用分时功能运行 GPU 使用 NVIDIA MPS 运行 GPU
最佳实践

如需最大限度地提高 GPU 利用率,请组合使用 GPU 共享策略。对于每个多实例 GPU 分区,请使用分时或 NVIDIA MPS。然后,您可以在每个分区上运行多个容器,这些容器会共享对该分区中的资源的访问权限。我们建议您使用以下任一组合:

  • 多实例 GPU 和 GPU 分时。
  • 多实例 GPU 和 NVIDIA MPS。

GPU 共享策略的工作原理

您可以指定可共享一个物理 GPU 的容器数量上限:

  • 在 Autopilot 集群上,这在工作负载规范中配置。
  • 在 Standard 集群上,系统会在创建挂接 GPU 的新节点池时进行配置。系统会根据您在节点池级层指定的设置共享节点池中的每个 GPU。

以下部分介绍了每个 GPU 共享策略的调度行为和操作。

多实例 GPU

如需在工作负载中请求多实例 GPU,您可以在 spec: nodeSelector 下的 Pod 规范 nodeSelector 字段中指定 cloud.google.com/gke-gpu-partition-size 标签。

GKE 会通过匹配这些标签将工作负载安排到适当的可用节点。如果没有适当的可用节点,GKE 将使用自动扩缩和节点自动预配功能来创建与此标签匹配的新节点或节点池。

GPU 分时或 NVIDIA MPS

如需在工作负载中请求 GPU 分时或 NVIDIA MPS,你可以在 spec:nodeSelector 下的 Pod 规范 nodeSelector 字段中指定以下标签。

  • cloud.google.com/gke-max-shared-clients-per-gpu:选择允许特定数量的客户端共享底层 GPU 的节点。
  • cloud.google.com/gke-gpu-sharing-strategy:选择使用 GPU 分时或 NVIDIA MPS 策略的节点。

下表介绍了安排行为会如何随您在清单中指定的节点标签组合而发生变化。

节点标签
cloud.google.com/gke-max-shared-clients-per-gpu



cloud.google.com/gke-gpu-sharing-strategy

GKE 会将工作负载安排到与这两个标签匹配的可用节点上。

如果没有可用节点,GKE 将使用自动扩缩和节点自动预配功能来创建与这两个标签匹配的新节点或节点池。

仅限 cloud.google.com/gke-max-shared-clients-per-gpu

Autopilot:GKE 会拒绝工作负载。

Standard:GKE 会将工作负载安排到与该标签匹配的可用节点上。 如果没有可用节点,GKE 将使用自动扩缩和节点自动预配功能来创建与该标签匹配的新节点或节点池。默认情况下,系统会为自动预配的节点提供每个策略的以下标签和值:

  • GPU 分时cloud.google.com/gke-gpu-sharing-strategy=TIME_SHARING
  • NVIDIA MPScloud.google.com/gke-gpu-sharing-strategy=MPS
仅限 cloud.google.com/gke-gpu-sharing-strategy

Autopilot:GKE 会拒绝工作负载。

Standard:GKE 会在使用特定共享策略的可用节点中调度工作负载。

  • 如果有多个共享节点池具有不同的 cloud.google.com/gke-max-shared-clients-per-gpu 值,则可以将工作负载安排到任何可用节点上。
  • 如果所有节点池中都没有可用节点,集群自动扩缩器就会对具有最小 cloud.google.com/gke-max-shared-clients-per-gpu 值的节点池进行扩容。
  • 如果所有节点池都已达到容量上限,则节点自动预配功能便会创建一个具有默认 cloud.google.com/gke-max-shared-clients-per-gpu=2 值的新节点池

对于 GPU 分时和 NVIDIA MPS 策略,您完成的 GPU 请求过程是相同的。

如果您要开发基于 GPU 分时或 NVIDIA MPS 运行的 GPU 应用,则只能为每个容器请求一个 GPU。 GKE 会拒绝在一个容器中请求多个 GPU,以避免意外行为。此外,使用分时和 NVIDIA MPS 请求的 GPU 数量并不能衡量容器可提供的计算能力。

下表显示了请求特定数量的 GPU 时会发生什么情况。

适用于 GPU 分时和 NVIDIA MPS 的 GPU 请求
每个容器一个 GPU 分时或 NVIDIA MPS 即使节点具有一个物理 GPU 或多个物理 GPU,GKE 也会允许该请求。
每个容器多个 GPU 分时

GKE 会拒绝该请求。

在一个容器中请求多个多实例 GPU 实例时,此行为也是相同的,因为每个 GPU 实例都被视为一个独立的物理 GPU。

每个容器多个 NVIDIA MPS

根据节点中的物理 GPU 数量,GKE 会执行以下操作:

  • 当节点只有一个物理 GPU 时,GKE 会允许请求。
  • 当节点具有多个物理 GPU 时,GKE 会拒绝请求。在一个容器中请求多个多实例 GPU 实例时,此行为也是相同的,因为每个 GPU 实例都被视为一个独立的物理 GPU。

如果 GKE 拒绝工作负载,您会看到类似于以下内容的错误消息:

status:
  message: 'Pod Allocate failed due to rpc error: code = Unknown desc = [invalid request
    for sharing GPU (time-sharing), at most 1 nvidia.com/gpu can be requested on GPU nodes], which is unexpected'
  phase: Failed
  reason: UnexpectedAdmissionError

监控 GPU 分时或 NVIDIA MPS 节点

使用 Cloud Monitoring 监控 GPU 分时节点或 NVIDIA MPS 节点的性能。GKE 会将每个 GPU 节点的指标发送到 Cloud Monitoring。这些 GPU 分时或 NVIDIA MPS 节点指标适用于节点级别 (node/accelerator/)。

您可以在 Cloud Monitoring 中查看每个 GPU 分时或 NVIDIA MPS 节点的以下指标:

  • 工作周期 (node/accelerator/duty_cycle):GPU 节点活跃处理的时间占上一个采样周期(10 秒)的百分比。范围介于 1% 到 100% 之间。
  • 内存用量 (node/accelerator/memory_used):为每个 GPU 节点分配的加速器内存量(以字节为单位)。
  • 内存容量 (node/accelerator/memory_total):每个 GPU 节点的加速器内存总量(以字节为单位)。

这些指标不同于常规 GPU 的指标(非分时节点或 NVIDA MPS 节点指标)。常规物理 GPU 指标适用于容器级别 (container/accelerator),并且不会针对使用 GPU 分时或 NVIDIA MPS 的 GPU 上调度的容器进行收集。

后续步骤