Comparte GPU con múltiples cargas de trabajo con el uso compartido de tiempo


En esta página, se muestra cómo permitir que varias cargas de trabajo obtengan acceso de tiempo compartido a un solo acelerador de hardware de GPU de NVIDIA® en los nodos de Google Kubernetes Engine (GKE). Para obtener más información sobre cómo funciona el uso compartido de tiempo de GPU, así como las limitaciones y los ejemplos de cuándo debes usar el uso compartido de tiempo de GPU, consulta Uso compartido de tiempo de GPU en GKE.

Descripción general

El uso compartido de tiempo es una función de GKE que permite que varios contenedores compartan una sola GPU física conectada a un nodo. El uso compartido de la GPU en GKE te permite usar las GPU adjuntas de forma más eficiente y ahorrar costos de ejecución.

Quién debe usar esta guía

Las instrucciones de este tema se aplican si eres uno de los siguientes casos:

  • Administrador de la plataforma: Crea y administra un clúster de GKE, planifica los requisitos de infraestructura y recursos y supervisa el rendimiento del clúster.
  • Desarrollador de aplicaciones: Diseña e implementa cargas de trabajo en clústeres de GKE. Si deseas obtener instrucciones para solicitar el uso compartido de tiempo de GPU, consulta Implementa cargas de trabajo que usan el uso compartido de tiempo de GPU.

Requisitos

  • Versión de GKE: Puedes habilitar el uso compartido de tiempo de GPU en clústeres de GKE Estándar que ejecutan la versión 1.23.7-gke.1400 de GKE y versiones posteriores. Puedes usar GPU de tiempo compartido en clústeres de GKE en modo Autopilot que ejecutan la versión 1.29.3-gke.1093000 y versiones posteriores de GKE.
  • Tipo de GPU: Puedes habilitar el uso compartido de tiempo de GPU en nodos que usan tipos de GPU posteriores a NVIDIA Tesla® K80.

Antes de empezar

Antes de comenzar, asegúrate de haber realizado las siguientes tareas:

  • Habilita la API de Kubernetes Engine de Google.
  • Habilitar la API de Kubernetes Engine de Google
  • Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste gcloud CLI, ejecuta gcloud components update para obtener la versión más reciente.

Habilita el uso compartido de tiempo de GPU en clústeres de GKE y grupos de nodos

Como administrador de la plataforma, debes habilitar las GPU de tiempo compartido en un clúster de GKE Estándar antes de que los desarrolladores puedan implementar cargas de trabajo para usar las GPU. Para habilitar el uso compartido, debes hacer lo siguiente:

  1. Habilita el uso compartido de tiempo de GPU en un clúster de GKE.
  2. Instala los controladores de dispositivos de GPU de NVIDIA (si es necesario).
  3. Verifica los recursos de GPU disponibles en tus nodos.

Los clústeres de Autopilot que ejecutan la versión 1.29.3-gke.1093000 y, luego, habilitan las GPUs de tiempo compartido de forma predeterminada. El uso compartido de tiempo en los clústeres en modo Autopilot se configura en la especificación de la carga de trabajo. Para obtener más información, consulta la sección Implementa cargas de trabajo que usan GPU de tiempo compartido.

Habilita el uso compartido de tiempo de GPU en un clúster de GKE Estándar

Puedes habilitar el uso compartido de tiempo de GPU cuando creas clústeres de GKE Estándar. El grupo de nodos predeterminado en el clúster tiene la función habilitada. Aún debes habilitar el uso compartido de tiempo de GPU cuando creas grupos de nodos nuevos de forma manual en ese clúster.

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

Reemplaza lo siguiente:

  • CLUSTER_NAME: Es el nombre del clúster nuevo.
  • COMPUTE_REGION: es la región de Compute Engine para el clúster nuevo. Para los clústeres zonales, especifica --zone=COMPUTE_ZONE.
  • CLUSTER_VERSION: Es la versión de GKE para el plano de control y los nodos del clúster. Usa la versión 1.23.7-gke.1400 de GKE o una posterior. Como alternativa, puedes especificar un canal de versiones con esa versión de GKE mediante la marca --release-channel=RELEASE_CHANNEL.
  • MACHINE_TYPE: es el tipo de máquina de Compute Engine para tus nodos. Te recomendamos que elijas un tipo de máquina optimizado para aceleradores.
  • GPU_TYPE: el tipo de GPU, que debe ser una plataforma de GPU de NVIDIA Tesla, como nvidia-tesla-v100.
  • GPU_QUANTITY: Es la cantidad de GPU físicas que se conectarán a cada nodo en el grupo de nodos predeterminado.
  • CLIENTS_PER_GPU: La cantidad máxima de contenedores que pueden compartir cada GPU física.
  • DRIVER_VERSION: Es la versión del controlador NVIDIA que se instalará. Puede ser uno de los datos siguientes:
    • default: Instala la versión predeterminada del controlador para tu versión de GKE.
    • latest: Instala la última versión del controlador disponible para tu versión de GKE. Disponible solo para los nodos que usan Container-Optimized OS.
    • disabled: Omite la instalación automática del controlador. Debes instalar un controlador de forma manual después de crear el grupo de nodos. Si omites gpu-driver-version, esta es la opción predeterminada.

Habilita el uso compartido de tiempo de GPU en un grupo de nodos de GKE

Puedes habilitar el uso compartido de tiempo de GPU cuando crees grupos de nodos nuevos en un clúster de GKE de forma manual.

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

Reemplaza lo siguiente:

  • NODEPOOL_NAME: es el nombre de tu grupo de nodos nuevo.
  • CLUSTER_NAME: Es el nombre de tu clúster, que debe ejecutar la versión 1.23.7-gke.1400 de GKE o una posterior.
  • COMPUTE_REGION: La región de Compute Engine del clúster. En el caso de los clústeres zonales, especifica --zone=COMPUTE_ZONE.
  • MACHINE_TYPE: es el tipo de máquina de Compute Engine para tus nodos. Te recomendamos que elijas un tipo de máquina optimizado para aceleradores.
  • GPU_TYPE: el tipo de GPU, que debe ser una plataforma de GPU de NVIDIA Tesla, como nvidia-tesla-v100.
  • GPU_QUANTITY: la cantidad de GPU físicas que se conectará a cada nodo en el grupo de nodos.
  • CLIENTS_PER_GPU: La cantidad máxima de contenedores que pueden compartir cada GPU física.
  • DRIVER_VERSION: Es la versión del controlador NVIDIA que se instalará. Puede ser una de los siguientes:

    • default: Instala la versión predeterminada del controlador para tu versión de GKE.
    • latest: Instala la última versión del controlador disponible para tu versión de GKE. Disponible solo para los nodos que usan Container-Optimized OS.
    • disabled: Omite la instalación automática del controlador. Debes instalar un controlador de forma manual después de crear el grupo de nodos. Si omites gpu-driver-version, esta es la opción predeterminada.

Instala los controladores de GPU de NVIDIA

Antes de continuar, conéctate al clúster con la ejecución del siguiente comando:

gcloud container clusters get-credentials CLUSTER_NAME

Si eliges inhabilitar la instalación automática del controlador cuando creas el clúster o si usas una versión de GKE anterior a la 1.27.2-gke.1200, debes instalar de forma manual un controlador de NVIDIA compatible para administrar la división de tiempo compartido de las GPU físicas. Para instalar los controladores, debes implementar un DaemonSet de instalación de GKE que configure los controladores.

Para obtener instrucciones, consulta la página sobre cómo instalar controladores de dispositivos de GPU de NVIDIA.

Si planeas usar el aprovisionamiento automático de nodos en tu clúster, también debes configurar el aprovisionamiento automático de nodos con los permisos que permiten que GKE instale los controladores de dispositivos de GPU por ti. Para obtener instrucciones, consulta Usa el aprovisionamiento automático de nodos con GPU.

Verifica los recursos de GPU disponibles en tus nodos

Para verificar que la cantidad de GPU visibles en tus nodos coincida con la cantidad que especificaste cuando habilitaste el uso compartido de tiempo, describe tus nodos:

kubectl describe nodes NODE_NAME

El resultado es similar a este:

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

En este resultado de ejemplo, la cantidad de recursos de GPU en el nodo es 3 porque el valor que se especificó para max-shared-clients-per-gpu fue 3 y el count de las GPU físicas el adjunto al nodo era 1. Otro ejemplo, si el count de las GPU físicas fuera 2, el resultado mostraría 6 recursos de GPU asignables, tres en cada GPU física.

Implementa cargas de trabajo que empleen el uso compartido de tiempo de GPU

Como operador de aplicaciones que implementa cargas de trabajo de GPU, puedes elegir el uso compartido de tiempo de GPU habilitado con la especificación de las etiquetas de nodo adecuadas en un nodeSelector en tus manifiestos. Cuando planifiques tus solicitudes, revisa los límites de solicitudes para asegurarte de que GKE no rechace tus implementaciones.

Para implementar una carga de trabajo y consumir el uso compartido de tiempo de GPU, completa los siguientes pasos:

  1. Agrega un nodeSelector a tu manifiesto de carga de trabajo para las siguientes etiquetas:

    • cloud.google.com/gke-gpu-sharing-strategy: time-sharing: Elige los nodos que emplean el uso compartido de tiempo de GPU.
    • cloud.google.com/gke-max-shared-clients-per-gpu: "CLIENTS_PER_GPU": Elige los nodos que permiten que una cantidad específica de contenedores comparta la GPU subyacente.
  2. Agrega la solicitud de recurso de GPU nvidia.com/gpu=1 a la especificación del contenedor, en spec.containers.resources.limits.

Por ejemplo, en los siguientes pasos se muestra cómo implementar tres Pods en un grupo de nodos de tiempo compartido de GPU. GKE asigna cada contenedor a la misma GPU física. Los contenedores imprimen el UUID de la GPU conectada a ese contenedor.

  1. Guarda el siguiente manifiesto como 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
      

Reemplaza lo siguiente:

  • GPU_TYPE es el tipo de GPU.
  • CLIENTS_PER_GPU: La cantidad de cargas de trabajo que usarán esta GPU. Para este ejemplo, usa 3.
  • GPU_COUNT: la cantidad de GPU para adjuntar al nodo. Para este ejemplo, usa 1.

Estándar

        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
      

Reemplaza lo siguiente:

  • SHARING_STRATEGY por “uso compartido de tiempo” a fin de solicitar el uso compartido de tiempo para tu GPU.
  • CLIENTS_PER_GPU: la cantidad de cargas de trabajo que usarán esta GPU. Para este ejemplo, usa 3.
  1. Aplica el manifiesto

    kubectl apply -f gpu-timeshare.yaml
    
  2. Verifica que todos los Pods se estén ejecutando:

    kubectl get pods -l=app=cuda-simple
    
  3. Verifica los registros de cualquier Pod para ver el UUID de la GPU:

    kubectl logs POD_NAME
    

    El resultado es similar a este:

    GPU 0: Tesla V100-SXM2-16GB (UUID: GPU-0771302b-eb3a-6756-7a23-0adcae8efd47)
    
  4. Si tus nodos tienen una GPU física conectada, comprueba los registros de cualquier otro Pod en el mismo nodo para verificar que el UUID de la GPU sea el mismo:

    kubectl logs POD2_NAME
    

    El resultado es similar a este:

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

Usa el uso compartido de tiempo de GPU con GPU de varias instancias

Como administrador de la plataforma, es posible que desees combinar varias características de GPU de GKE. El uso compartido de tiempo de GPU funciona con GPU de varias instancias, que particionan una sola GPU física en hasta siete porciones. Estas particiones están aisladas entre sí. Puedes configurar el uso compartido de tiempo de GPU para cada partición de GPU de varias instancias.

Por ejemplo, si estableces gpu-partition-size en 1g.5gb, la GPU subyacente se divide en siete particiones. Si también configuras max-shared-clients-per-gpu como 3, cada partición admitiría hasta tres contenedores, lo que da un total de hasta 21 dispositivos de uso compartido de GPU disponibles para asignar en esa GPU física. Para obtener información sobre cómo gpu-partition-size se convierte en particiones reales, consulta Particiones de GPU de varias instancias.

Para crear un clúster de GPU de varias instancias con el uso compartido de tiempo de GPU habilitado, ejecuta el siguiente comando:

Autopilot

Con Autopilot, las GPU de tiempo compartido y de varias instancias se pueden usar juntas con ambos conjuntos de selectores de nodos.

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

Estándar

Con Estándar, debes crear un clúster de varias instancias de tiempo compartido de GPU con la ejecución del siguiente comando:

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

Reemplaza PARTITION_SIZE por el tamaño de partición de GPU de varias instancias que desees, como 1g.5gb.

Limitaciones

  • Con el uso compartido de tiempo de GPU, GKE aplica el aislamiento de memoria (espacio de direcciones), de rendimiento y de falla entre contenedores que comparten una GPU física. Sin embargo, los límites de memoria no se aplican en las GPU. Para evitar problemas de memoria insuficiente (OOM), configura límites de memoria de GPU en tus cargas de trabajo. Para evitar problemas de seguridad, solo implementa cargas de trabajo que se encuentren en el mismo límite de confianza que el uso compartido de tiempo de GPU.
  • Para evitar comportamientos inesperados durante la asignación de capacidad, GKE puede rechazar ciertas solicitudes de uso compartido de tiempo de GPU. Si deseas obtener más detalles, consulta Solicitudes de GPU para el uso compartido de tiempo de GPU.
  • La cantidad máxima de contenedores que pueden usar el uso compartido de tiempo en una sola GPU física es 48. Cuando planifiques tu configuración de uso compartido de tiempo, considera las necesidades de recursos de tus cargas de trabajo y la capacidad de las GPU físicas subyacentes para optimizar tu rendimiento y capacidad de respuesta.

¿Qué sigue?