使用 GPU 分时在多个工作负载间共享 GPU


本页面介绍如何允许多个工作负载以 GPU 分时方式访问 Google Kubernetes Engine (GKE) 节点中的单个 NVIDIA® GPU 硬件加速器。如需详细了解 GPU 分时的工作原理,以及何时应使用 GPU 分时的限制和示例,请参阅 GKE 上的 GPU 分时

概览

GPU 分时是一项 GKE 功能,可让多个容器共享一个挂接到某个节点的物理 GPU。通过在 GKE 中使用 GPU 分时,您可以更高效地使用挂接的 GPU 并节省运行费用。

本指南的适用对象

如果您属于以下对象,则本指南中的说明适用于您:

  • 平台管理员:创建和管理 GKE 集群、规划基础架构和资源要求,并监控集群的性能。
  • 应用开发者:在 GKE 集群上设计和部署工作负载。如需查看有关请求 GPU 分时的说明,请参阅部署使用 GPU 分时的工作负载

要求

  • GKE 版本:您可以在运行 GKE 1.23.7-gke.1400 及更高版本的 GKE Standard 集群上启用 GPU 分时。您可以在运行 GKE 1.29.3-gke.1093000 及更高版本的 GKE Autopilot 集群上使用分时 GPU。
  • GPU 类型:您可以在所有 NVIDIA GPU 型号上启用 GPU 分时。

准备工作

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。

在 GKE 集群和节点池上启用 GPU 分时

作为平台管理员,您必须先在 GKE 标准集群上启用 GPU 分时,然后开发者才能部署工作负载以使用 GPU。如需启用 GPU 分时,您必须执行以下操作:

  1. 在 GKE 集群上启用 GPU 分时
  2. 安装 NVIDIA GPU 设备驱动程序(如果需要)
  3. 验证节点上可用的 GPU 资源

默认情况下,运行 1.29.3-gke.1093000 及更高版本的 Autopilot 集群会启用分时 GPU。Autopilot 集群上的分时在工作负载规范中配置。如需了解详情,请参阅部署使用分时 GPU 的工作负载部分。

在 GKE Standard 集群上启用 GPU 分时

您可以在创建 GKE Standard 集群时启用 GPU 分时。集群中的默认节点池已启用该功能。在该集群中手动创建新的节点池时,您仍然需要启用 GPU 分时。

gcloud container clusters create CLUSTER_NAME \
    --region=COMPUTE_REGION \
    --cluster-version=CLUSTER_VERSION \
    --machine-type=MACHINE_TYPE \
    --accelerator=type=GPU_TYPE,count=GPU_QUANTITY,gpu-sharing-strategy=time-sharing,max-shared-clients-per-gpu=CLIENTS_PER_GPU,gpu-driver-version=DRIVER_VERSION

替换以下内容:

  • CLUSTER_NAME:新集群的名称。
  • COMPUTE_REGION:新集群的 Compute Engine 区域。对于区域级集群,请指定 --zone=COMPUTE_ZONE
  • CLUSTER_VERSION:集群控制平面和节点的 GKE 版本。使用 GKE 1.23.7-gke.1400 或更高版本。或者,您可以使用 --release-channel=RELEASE_CHANNEL 标志指定具有该 GKE 版本的发布渠道
  • MACHINE_TYPE:节点的 Compute Engine 机器类型。我们建议您选择加速器优化机器类型
  • GPU_TYPE:GPU 类型,必须是 NVIDIA GPU 平台,例如 nvidia-tesla-v100
  • GPU_QUANTITY:要挂接到默认节点池中每个节点的物理 GPU 数量。
  • CLIENTS_PER_GPU:可以共享每个物理 GPU 的容器数量上限。
  • DRIVER_VERSION:要安装的 NVIDIA 驱动程序版本。可以是以下各项之一:
    • default:为您的 GKE 版本安装默认驱动程序版本。
    • latest:为您的 GKE 版本安装最新可用的驱动程序版本。仅适用于使用 Container-Optimized OS 的节点。
    • disabled:跳过自动驱动程序安装。创建节点池后,您必须手动安装驱动程序。 如果您省略 gpu-driver-version,则这是默认选项。

在 GKE 节点池上启用 GPU 分时

您可以在 GKE 集群中手动创建新节点池时启用 GPU 分时。

gcloud container node-pools create NODEPOOL_NAME \
    --cluster=CLUSTER_NAME \
    --machine-type=MACHINE_TYPE \
    --region=COMPUTE_REGION \
    --accelerator=type=GPU_TYPE,count=GPU_QUANTITY,gpu-sharing-strategy=time-sharing,max-shared-clients-per-gpu=CLIENTS_PER_GPU,gpu-driver-version=DRIVER_VERSION

替换以下内容:

  • NODEPOOL_NAME:新节点池的名称。
  • CLUSTER_NAME:您的集群的名称,该集群必须运行 GKE 1.23.7-gke.1400 或更高版本。
  • COMPUTE_REGION:集群的 Compute Engine 区域。对于可用区级集群,请指定 --zone=COMPUTE_ZONE
  • MACHINE_TYPE:节点的 Compute Engine 机器类型。我们建议您选择加速器优化机器类型
  • GPU_TYPE:GPU 类型,必须是 NVIDIA GPU 平台,例如 nvidia-tesla-v100
  • GPU_QUANTITY:要挂接到节点池中每个节点的物理 GPU 数量。
  • CLIENTS_PER_GPU:可以共享每个物理 GPU 的容器数量上限。
  • DRIVER_VERSION:要安装的 NVIDIA 驱动程序版本。可以是下列选项之一:

    • default:为您的 GKE 版本安装默认驱动程序版本。
    • latest:为您的 GKE 版本安装最新可用的驱动程序版本。仅适用于使用 Container-Optimized OS 的节点。
    • disabled:跳过自动驱动程序安装。创建节点池后,您必须手动安装驱动程序。 如果您省略 gpu-driver-version,则这是默认选项。

安装 NVIDIA GPU 设备驱动程序

在继续操作之前,请通过运行以下命令连接到集群:

gcloud container clusters get-credentials CLUSTER_NAME

如果您在创建集群时选择了停用自动驱动程序安装,或者如果您使用低于 1.27.2-gke.1200 的 GKE 版本,则必须手动安装兼容的 NVIDIA 驱动程序来管理物理 GPU 的 GPU 分时。如需安装驱动程序,请部署用于设置驱动程序的 GKE 安装 DaemonSet。

如需了解相关说明,请参阅安装 NVIDIA GPU 设备驱动程序

如果您打算在集群中使用节点自动配置功能,还必须使用允许 GKE 为您安装 GPU 设备驱动程序的范围配置节点自动配置。如需查看相关说明,请参阅将节点自动预配与 GPU 搭配使用

验证节点上可用的 GPU 资源

如需验证节点中可见的 GPU 数量是否与启用 GPU 分时时指定的数量一致,请描述您的节点:

kubectl describe nodes NODE_NAME

输出类似于以下内容:

...
Capacity:
  ...
  nvidia.com/gpu:             3
Allocatable:
  ...
  nvidia.com/gpu:             3

在此示例输出中,节点上 GPU 资源的数量为 3,因为为 max-shared-clients-per-gpu 指定的值为 3,且物理 GPU 的 count 为挂接到节点的时间为 1。再举一例,如果 count 的物理 GPU 为 2,则输出将显示 6 可分配的 GPU 资源,每个物理 GPU 上有三个。

部署使用 GPU 分时的工作负载

作为部署 GPU 工作负载的应用操作员,您可以通过在清单的 nodeSelector 中指定适当的节点标签,来选择启用 GPU 分时。规划请求时,请查看请求限制,以确保 GKE 不会拒绝您的部署。

如需部署工作负载以使用 GPU 分时,请完成以下步骤:

  1. 在工作负载清单中为以下标签添加 nodeSelector

    • cloud.google.com/gke-gpu-sharing-strategy: time-sharing:选择使用 GPU 分时的节点。
    • cloud.google.com/gke-max-shared-clients-per-gpu: "CLIENTS_PER_GPU":选择允许特定数量的容器共享底层 GPU 的节点。
  2. nvidia.com/gpu=1 GPU 资源请求添加到 spec.containers.resources.limits 中的容器规范。

例如,以下步骤展示了如何将三个 Pod 部署到 GPU 分时节点池。GKE 会将每个容器分配给同一物理 GPU。容器将输出挂接到该容器的 GPU 的 UUID。

  1. 将以下清单保存为 gpu-timeshare.yaml

Autopilot

        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: cuda-simple
        spec:
          replicas: 3
          selector:
            matchLabels:
              app: cuda-simple
          template:
            metadata:
              labels:
                app: cuda-simple
            spec:
              nodeSelector:
                cloud.google.com/gke-accelerator: "GPU_TYPE"
                cloud.google.com/gke-gpu-sharing-strategy: "time-sharing"
                cloud.google.com/gke-max-shared-clients-per-gpu: "CLIENTS_PER_GPU"
                cloud.google.com/gke-accelerator-count: "GPU_COUNT"
              containers:
              - name: cuda-simple
                image: nvidia/cuda:11.0.3-base-ubi7
                command:
                - bash
                - -c
                - |
                  /usr/local/nvidia/bin/nvidia-smi -L; sleep 300
                resources:
                  limits:
                    nvidia.com/gpu: 1
      

替换以下内容:

  • GPU_TYPE:GPU 类型。
  • CLIENTS_PER_GPU:将使用此 GPU 的工作负载数量。本示例使用的是 3
  • GPU_COUNT:要连接到节点的物理 GPU 数量。本示例使用的是 1

标准

        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: cuda-simple
        spec:
          replicas: 3
          selector:
            matchLabels:
              app: cuda-simple
          template:
            metadata:
              labels:
                app: cuda-simple
            spec:
              nodeSelector:
                cloud.google.com/gke-gpu-sharing-strategy: "SHARING_STRATEGY"
                cloud.google.com/gke-max-shared-clients-per-gpu: "CLIENTS_PER_GPU"
              containers:
              - name: cuda-simple
                image: nvidia/cuda:11.0.3-base-ubi7
                command:
                - bash
                - -c
                - |
                  /usr/local/nvidia/bin/nvidia-smi -L; sleep 300
                resources:
                  limits:
                    nvidia.com/gpu: 1
      

替换以下内容:

  • SHARING_STRATEGY 替换为“分时”,以为 GPU 请求分时。
  • CLIENTS_PER_GPU:将使用此 GPU 的工作负载数量。 本示例使用的是 3
  1. 应用清单:

    kubectl apply -f gpu-timeshare.yaml
    
  2. 检查所有 Pod 是否正在运行:

    kubectl get pods -l=app=cuda-simple
    
  3. 检查任何 Pod 的日志以查看 GPU 的 UUID:

    kubectl logs POD_NAME
    

    输出类似于以下内容:

    GPU 0: Tesla V100-SXM2-16GB (UUID: GPU-0771302b-eb3a-6756-7a23-0adcae8efd47)
    
  4. 如果您的节点挂接了一个物理 GPU,请检查同一节点上任何其他 Pod 的日志,以验证 GPU UUID 是否相同:

    kubectl logs POD2_NAME
    

    输出类似于以下内容:

    GPU 0: Tesla V100-SXM2-16GB (UUID: GPU-0771302b-eb3a-6756-7a23-0adcae8efd47)
    

将 GPU 分时用于多实例 GPU

作为平台管理员,您可能需要组合多个 GKE GPU 功能。GPU 分时用于多实例 GPU,可将单个物理 GPU 划分为最多七个切片。这些分区彼此隔离。您可以为每个多实例 GPU 分区配置 GPU 分时。

例如,如果将 gpu-partition-size 设置为 1g.5gb,则底层 GPU 将拆分为七个分区。如果您还将 max-shared-clients-per-gpu 设置为 3,则每个分区最多支持三个容器,在该物理 GPU 中总共可分配最多 21 个 GPU 分时设备。如需了解 gpu-partition-size 如何转换为实际分区,请参阅多实例 GPU 分区

如需创建启用了 GPU 分时的多实例 GPU 集群,请运行以下命令:

Autopilot

借助 Autopilot,您可以通过使用两组节点选择器来结合使用 GPU 分时和多实例 GPU。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cuda-simple
spec:
  replicas: 7
  selector:
    matchLabels:
      app: cuda-simple
  template:
    metadata:
      labels:
        app: cuda-simple
    spec:
      nodeSelector:
        cloud.google.com/gke-gpu-partition-size: 1g.5gb
        cloud.google.com/gke-gpu-sharing-strategy: time-sharing
        cloud.google.com/gke-max-shared-clients-per-gpu: "3"
        cloud.google.com/gke-accelerator: nvidia-tesla-a100
        cloud.google.com/gke-accelerator-count: "1"
      containers:
      - name: cuda-simple
        image: nvidia/cuda:11.0.3-base-ubi7
        command:
        - bash
        - -c
        - |
          /usr/local/nvidia/bin/nvidia-smi -L; sleep 300
        resources:
          limits:
            nvidia.com/gpu: 1

标准

使用 Standard 时,您需要通过运行以下命令来创建 GPU 分时、多实例集群:

gcloud container node-pools create NODEPOOL_NAME \
    --cluster=CLUSTER_NAME \
    --machine-type=MACHINE_TYPE \
    --region=COMPUTE_REGION \
    --accelerator=type=nvidia-tesla-a100,count=GPU_QUANTITY,gpu-partition-size=PARTITION_SIZE,gpu-sharing-strategy=time-sharing,max-shared-clients-per-gpu=CLIENTS_PER_GPU,gpu-driver-version=DRIVER_VERSION

PARTITION_SIZE 替换为所需的多实例 GPU 分区大小,例如 1g.5gb

限制

  • 使用 GPU 分时,GKE 会在共同使用一个物理 GPU 的各容器之间强制执行地址空间隔离、性能隔离和故障隔离。但是,GPU 不会强制执行内存限制。为避免发生内存不足 (OOM) 问题,请在工作负载中设置 GPU 内存限制。为了避免安全问题,请仅将位于同一信任边界的工作负载部署到 GPU 分时。
  • 为防止在容量分配期间出现意外行为,GKE 可能会拒绝某些 GPU 分时请求。如需了解详情,请参阅 GPU 分时的 GPU 请求
  • 可在单个物理 GPU 中使用分时的容器数量上限为 48 个。在规划您的 GPU 分时配置时,请考虑工作负载的资源需求以及底层物理 GPU 的容量,从而优化性能和响应速度。

后续步骤