Condividi GPU con più carichi di lavoro utilizzando la condivisione del tempo delle GPU


Questa pagina mostra come consentire a più carichi di lavoro di ottenere l'accesso per la condivisione del tempo GPU a un singolo acceleratore hardware GPU NVIDIA® nei tuoi nodi Google Kubernetes Engine (GKE). Per saperne di più su come funziona la condivisione del tempo della GPU, nonché sulle limitazioni ed esempi di quando utilizzare la condivisione del tempo della GPU, consulta Condivisione del tempo della GPU su GKE.

Panoramica

La condivisione del tempo della GPU è una funzionalità di GKE che consente a più container di condividere una singola GPU fisica collegata a un nodo. L'utilizzo della condivisione del tempo della GPU in GKE ti consente di utilizzare in modo più efficiente le GPU collegate e di risparmiare sui costi di esecuzione.

Chi dovrebbe utilizzare questa guida

Le istruzioni riportate in questa guida si applicano agli utenti in uno dei seguenti modi:

Requisiti

  • Versione di GKE: puoi abilitare la condivisione del tempo della GPU nei cluster GKE Standard che eseguono GKE versione 1.23.7-gke.1400 e successive. Puoi utilizzare GPU con condivisione del tempo su cluster GKE Autopilot che eseguono GKE versione 1.29.3-gke.1093000 e successive.
  • Tipo di GPU: puoi attivare la condivisione del tempo della GPU su tutti i modelli GPU NVIDIA.

Prima di iniziare

Prima di iniziare, assicurati di aver eseguito le seguenti attività:

  • Abilita l'API Google Kubernetes Engine.
  • Abilita l'API Google Kubernetes Engine
  • Se vuoi utilizzare Google Cloud CLI per questa attività, installa e initialize gcloud CLI. Se hai già installato gcloud CLI, scarica la versione più recente eseguendo gcloud components update.

Abilita la condivisione del tempo della GPU sui cluster GKE e sui pool di nodi

In qualità di amministratore di piattaforma, devi abilitare la condivisione del tempo delle GPU su un cluster GKE Standard prima che gli sviluppatori possano eseguire il deployment dei carichi di lavoro per utilizzare le GPU. Per abilitare la condivisione del tempo delle GPU, devi:

  1. Abilita la condivisione del tempo della GPU su un cluster GKE.
  2. Installa i driver di dispositivi GPU NVIDIA (se richiesto).
  3. Verifica le risorse GPU disponibili sui tuoi nodi.

I cluster Autopilot che eseguono la versione 1.29.3-gke.1093000 e successive abilitano le GPU con condivisione del tempo per impostazione predefinita. La condivisione del tempo sui cluster Autopilot è configurata nella specifica del carico di lavoro. Per scoprire di più, consulta la sezione Eseguire il deployment di carichi di lavoro che utilizzano GPU condivise in base al tempo.

Abilita la condivisione del tempo della GPU su un cluster GKE Standard

Puoi abilitare la condivisione del tempo delle GPU quando crei cluster GKE Standard. Il pool di nodi predefinito nel cluster ha la funzionalità abilitata. Devi comunque abilitare la condivisione del tempo della GPU quando crei manualmente nuovi pool di nodi nel cluster.

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

Sostituisci quanto segue:

  • CLUSTER_NAME: il nome del nuovo cluster.
  • COMPUTE_REGION: la regione di Compute Engine per il nuovo cluster. Per i cluster a livello di zona, specifica --zone=COMPUTE_ZONE.
  • CLUSTER_VERSION: la versione di GKE per il piano di controllo e i nodi del cluster. Usa GKE versione 1.23.7-gke.1400 o successiva. In alternativa, specifica un canale di rilascio con quella versione di GKE utilizzando il flag --release-channel=RELEASE_CHANNEL.
  • MACHINE_TYPE: il tipo di macchina Compute Engine per i nodi. Ti consigliamo di selezionare un tipo di macchina ottimizzata per l'acceleratore.
  • GPU_TYPE: il tipo di GPU, che deve essere una piattaforma GPU NVIDIA come nvidia-tesla-v100.
  • GPU_QUANTITY: il numero di GPU fisiche da collegare a ciascun nodo nel pool di nodi predefinito.
  • CLIENTS_PER_GPU: numero massimo di container che possono condividere ciascuna GPU fisica.
  • DRIVER_VERSION: la versione del driver NVIDIA da installare. Può essere uno dei seguenti:
    • default: installa la versione predefinita del driver per la tua versione di GKE.
    • latest: installa la versione più recente del driver disponibile per la tua versione di GKE. Disponibile solo per i nodi che utilizzano Container-Optimized OS.
    • disabled: salta l'installazione automatica del driver. Devi installare manualmente un driver dopo aver creato il pool di nodi. Se ometti gpu-driver-version, questa è l'opzione predefinita.

Abilita la condivisione del tempo della GPU su un pool di nodi GKE

Puoi abilitare la condivisione del tempo della GPU quando crei manualmente nuovi pool di nodi in un cluster GKE.

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

Sostituisci quanto segue:

  • NODEPOOL_NAME: il nome del nuovo pool di nodi.
  • CLUSTER_NAME: il nome del cluster, che deve eseguire GKE versione 1.23.7-gke.1400 o successiva.
  • COMPUTE_REGION: la regione di Compute Engine del cluster. Per i cluster a livello di zona, specifica --zone=COMPUTE_ZONE.
  • MACHINE_TYPE: il tipo di macchina Compute Engine per i nodi. Ti consigliamo di selezionare un tipo di macchina ottimizzata per l'acceleratore.
  • GPU_TYPE: il tipo di GPU, che deve essere una piattaforma GPU NVIDIA come nvidia-tesla-v100.
  • GPU_QUANTITY: il numero di GPU fisiche da collegare a ciascun nodo nel pool di nodi.
  • CLIENTS_PER_GPU: numero massimo di container che possono condividere ciascuna GPU fisica.
  • DRIVER_VERSION: la versione del driver NVIDIA da installare. Può corrispondere a uno dei seguenti:

    • default: installa la versione predefinita del driver per la tua versione di GKE.
    • latest: installa la versione più recente del driver disponibile per la tua versione di GKE. Disponibile solo per i nodi che utilizzano Container-Optimized OS.
    • disabled: salta l'installazione automatica del driver. Devi installare manualmente un driver dopo aver creato il pool di nodi. Se ometti gpu-driver-version, questa è l'opzione predefinita.

Installa i driver di dispositivi GPU NVIDIA

Prima di procedere, connettiti al cluster eseguendo questo comando:

gcloud container clusters get-credentials CLUSTER_NAME

Se hai scelto di disabilitare l'installazione automatica dei driver durante la creazione del cluster o se utilizzi una versione di GKE precedente alla 1.27.2-gke.1200, devi installare manualmente un driver NVIDIA compatibile per gestire la divisione di condivisione del tempo delle GPU delle GPU fisiche. Per installare i driver, esegui il deployment di un DaemonSet di installazione GKE che li configura.

Per le istruzioni, consulta Installazione dei driver di dispositivi GPU NVIDIA.

Se prevedi di utilizzare il provisioning automatico dei nodi nel tuo cluster, devi anche configurarne il provisioning automatico con gli ambiti che consentono a GKE di installare automaticamente i driver di dispositivi GPU. Per le istruzioni, consulta Utilizzare il provisioning automatico dei nodi con GPU.

Verifica le risorse GPU disponibili sui tuoi nodi

Per verificare che il numero di GPU visibili nei nodi corrisponda al numero specificato quando hai abilitato la condivisione del tempo della GPU, descrivi i nodi:

kubectl describe nodes NODE_NAME

L'output è simile al seguente:

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

In questo output di esempio, il numero di risorse GPU sul nodo è 3 perché il valore specificato per max-shared-clients-per-gpu era 3, mentre il count di GPU fisiche da collegare al nodo era 1. Come ulteriore esempio, se il count delle GPU fisiche fosse 2, l'output mostrerebbe 6 risorse GPU allocabili, tre per ciascuna GPU fisica.

Esegui il deployment di carichi di lavoro che utilizzano la condivisione del tempo della GPU

In qualità di operatore di applicazioni che esegue il deployment dei carichi di lavoro GPU, puoi selezionare la condivisione del tempo GPU abilitata specificando le etichette dei nodi appropriate in un nodeSelector nei manifest. Quando pianifichi le tue richieste, esamina i limiti per le richieste per assicurarti che GKE non rifiuti i tuoi deployment.

Per eseguire il deployment di un carico di lavoro per utilizzare la condivisione del tempo della GPU, completa questi passaggi:

  1. Aggiungi nodeSelector al manifest del carico di lavoro per le seguenti etichette:

    • cloud.google.com/gke-gpu-sharing-strategy: time-sharing: seleziona i nodi che utilizzano la condivisione del tempo della GPU.
    • cloud.google.com/gke-max-shared-clients-per-gpu: "CLIENTS_PER_GPU": seleziona i nodi che consentono a un numero specifico di container di condividere la GPU sottostante.
  2. Aggiungi la richiesta di risorsa GPU nvidia.com/gpu=1 alla specifica del container in spec.containers.resources.limits.

Ad esempio, i passaggi seguenti mostrano come eseguire il deployment di tre pod in un pool di nodi di condivisione del tempo della GPU. GKE alloca ogni container alla stessa GPU fisica. I container stampano l'UUID della GPU collegata al container.

  1. Salva il seguente manifest come 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
      

Sostituisci quanto segue:

  • GPU_TYPE: il tipo di GPU.
  • CLIENTS_PER_GPU: il numero di carichi di lavoro che utilizzeranno questa GPU. Per questo esempio, utilizza 3.
  • GPU_COUNT: il numero di GPU fisiche da collegare al nodo. Per questo esempio, utilizza 1.

Standard

        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
      

Sostituisci quanto segue:

  • SHARING_STRATEGY con "condivisione del tempo" per richiedere la condivisione del tempo per la tua GPU.
  • CLIENTS_PER_GPU: il numero di carichi di lavoro che utilizzeranno questa GPU. Per questo esempio, utilizza 3.
  1. Applica il manifest:

    kubectl apply -f gpu-timeshare.yaml
    
  2. Verifica che tutti i pod siano in esecuzione:

    kubectl get pods -l=app=cuda-simple
    
  3. Controlla i log di qualsiasi pod per visualizzare l'UUID della GPU:

    kubectl logs POD_NAME
    

    L'output è simile al seguente:

    GPU 0: Tesla V100-SXM2-16GB (UUID: GPU-0771302b-eb3a-6756-7a23-0adcae8efd47)
    
  4. Se ai nodi è collegata una GPU fisica, controlla i log di qualsiasi altro pod sullo stesso nodo per verificare che l'UUID GPU sia lo stesso:

    kubectl logs POD2_NAME
    

    L'output è simile al seguente:

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

Utilizzare la condivisione del tempo della GPU con GPU multiistanza

In qualità di amministratore di piattaforma, potresti voler combinare più funzionalità GPU GKE. La condivisione del tempo della GPU funziona con GPU multi-istanza, che suddividono una singola GPU fisica in un massimo di sette sezioni. Queste partizioni sono isolate tra loro. Puoi configurare la condivisione del tempo della GPU per ogni partizione GPU multi-istanza.

Ad esempio, se imposti gpu-partition-size su 1g.5gb, la GPU sottostante verrebbe suddivisa in sette partizioni. Se imposti anche max-shared-clients-per-gpu su 3, ogni partizione supporterà fino a tre container, per un totale di massimo 21 dispositivi di condivisione del tempo GPU disponibili da allocare in quella GPU fisica. Per scoprire in che modo gpu-partition-size esegue la conversione in partizioni effettive, consulta Partizioni GPU multi-istanza.

Per creare un cluster GPU multi-istanza con la condivisione del tempo della GPU abilitata, esegui questo comando:

Autopilot

Con Autopilot, è possibile utilizzare insieme le GPU multi-istanza e la condivisione del tempo della GPU utilizzando entrambi i set di selettori dei nodi.

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

Con Standard, devi creare un cluster multi-istanza con condivisione temporale della GPU eseguendo questo 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

Sostituisci PARTITION_SIZE con la dimensione della partizione GPU multi-istanza che ti interessa, ad esempio 1g.5gb.

Limitazioni

  • Con la condivisione del tempo della GPU, GKE applica l'isolamento dello spazio degli indirizzi, delle prestazioni e degli errori tra i container che condividono una GPU fisica. Tuttavia, i limiti di memoria non vengono applicati alle GPU. Per evitare problemi di esaurimento della memoria (OOM), imposta i limiti di memoria GPU nei carichi di lavoro. Per evitare problemi di sicurezza, esegui il deployment per la condivisione del tempo della GPU solo su carichi di lavoro che si trovano nello stesso confine di attendibilità.
  • Per evitare comportamenti imprevisti durante l'allocazione della capacità, GKE potrebbe rifiutare determinate richieste di condivisione del tempo della GPU. Per i dettagli, consulta Richieste GPU per la condivisione del tempo della GPU.
  • Il numero massimo di container che possono utilizzare la condivisione del tempo in una singola GPU fisica è 48. Quando pianifichi la configurazione di condivisione del tempo della GPU, considera le esigenze di risorse dei carichi di lavoro e la capacità delle GPU fisiche sottostanti di ottimizzare prestazioni e reattività.

Passaggi successivi