Partager des GPU avec plusieurs charges de travail à l'aide du temps partagé des GPU


Cette page explique comment permettre à plusieurs charges de travail d'obtenir un accès temps partagé des GPU à un seul accélérateur matériel de GPU NVIDIA® dans vos nœuds Google Kubernetes Engine (GKE). Pour en savoir plus sur le fonctionnement du temps partagé des GPU, ainsi que sur les limites et exemples de cas dans lesquels vous devez utiliser la fonctionnalité de temps partagé des GPU, consultez la page Temps partagé des GPU sur GKE.

Présentation

Le temps partagé des GPU est une fonctionnalité de GKE qui permet à plusieurs conteneurs de partager un même GPU physique associé à un nœud. L'utilisation de GPU à temps partagé dans GKE vous permet d'utiliser plus efficacement les GPU associés et de réduire les coûts d'exploitation.

À qui ce guide est-il destiné ?

Les instructions de ce guide s'appliquent à vous si vous remplissez l'un des rôles suivants :

  • Administrateur de plate-forme : crée et gère un cluster GKE, planifie les exigences d'infrastructure et de ressources, et surveille les performances du cluster.
  • Développeur d'applications : conçoit et déploie des charges de travail sur des clusters GKE. Si vous souhaitez obtenir des instructions pour demander le temps partagé des GPU, consultez la page Déployer des charges de travail qui utilisent le temps partagé des GPU.

Conditions requises

  • Version de GKE: vous pouvez activer le temps partagé des GPU sur les clusters GKE standards exécutant la version 1.23.7-gke.1400 ou ultérieure de GKE. Vous pouvez utiliser des GPU à partage de temps sur les clusters GKE Autopilot exécutant la version 1.29.3-gke.1093000 et ultérieure de GKE.
  • Type de GPU: vous pouvez activer le partage de temps GPU sur tous les modèles de GPU NVIDIA.

Avant de commencer

Avant de commencer, effectuez les tâches suivantes :

  • Activez l'API Google Kubernetes Engine.
  • Activer l'API Google Kubernetes Engine
  • Si vous souhaitez utiliser Google Cloud CLI pour cette tâche, installez puis initialisez gcloud CLI. Si vous avez déjà installé gcloud CLI, assurez-vous de disposer de la dernière version en exécutant la commande gcloud components update.

Activer le temps partagé des GPU sur les clusters et les pools de nœuds GKE

En tant qu'administrateur de plate-forme, vous devez activer le temps partagé des GPU sur un cluster GKE standard avant que les développeurs puissent déployer des charges de travail pour utiliser les GPU. Pour activer la fonctionnalité de temps partagé des GPU, procédez comme suit :

  1. Activez le temps partagé des GPU sur un cluster GKE.
  2. Installez les pilotes d'appareils GPU NVIDIA (si nécessaire).
  3. Vérifiez les ressources GPU disponibles sur vos nœuds.

Les clusters Autopilot qui exécutent la version 1.29.3-gke.1093000 ou une version ultérieure activent les GPU à partage de temps par défaut. Le partage de temps sur les clusters Autopilot est configuré dans la spécification de la charge de travail. Pour en savoir plus, consultez la section Déployer des charges de travail qui utilisent des GPU à temps partagé.

Activer le temps partagé des GPU sur un cluster GKE Standard

Vous pouvez activer le temps partagé des GPU lorsque vous créez des clusters GKE standards. La fonctionnalité est activée sur le pool de nœuds par défaut du cluster. Vous devez toujours activer le temps partagé des GPU lorsque vous créez manuellement de nouveaux pools de nœuds dans ce 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

Remplacez les éléments suivants :

  • CLUSTER_NAME : nom de votre nouveau cluster
  • COMPUTE_REGION : région Compute Engine du nouveau cluster. Pour les clusters zonaux, spécifiez --zone=COMPUTE_ZONE.
  • CLUSTER_VERSION : version de GKE pour le plan de contrôle et les nœuds du cluster. Utilisez GKE version 1.23.7-gke.1400 ou ultérieure. Vous pouvez également spécifier une version disponible avec cette version de GKE à l'aide de l'option --release-channel=RELEASE_CHANNEL.
  • MACHINE_TYPE : type de machine Compute Engine pour vos nœuds. Nous vous recommandons de sélectionner un type de machine optimisé pour les accélérateurs.
  • GPU_TYPE : type de GPU, qui doit être une plate-forme de GPU NVIDIA, telle que nvidia-tesla-v100.
  • GPU_QUANTITY : nombre de GPU physiques à associer à chaque nœud du pool de nœuds par défaut.
  • CLIENTS_PER_GPU : nombre maximal de conteneurs pouvant partager chaque GPU physique.
  • DRIVER_VERSION : version du pilote NVIDIA à installer. La valeur peut être l'une des suivantes :
    • default : installe la version de pilote par défaut pour votre version de GKE.
    • latest : installe la dernière version de pilote disponible pour votre version de GKE. Disponible seulement pour les nœuds qui utilisent Container-Optimized OS.
    • disabled : passe l'installation automatique du pilote. Vous devez installer manuellement un pilote après avoir créé le pool de nœuds. Si vous omettez la commande gpu-driver-version, cette option est celle configurée par défaut.

Activer le temps partagé des GPU sur un pool de nœuds GKE

Vous pouvez activer le temps partagé des GPU lorsque vous créez manuellement de nouveaux pools de nœuds dans 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

Remplacez les éléments suivants :

  • NODEPOOL_NAME : nom de votre nouveau pool de nœuds.
  • CLUSTER_NAME : nom de votre cluster, qui doit exécuter GKE version 1.23.7-gke.1400 ou ultérieure.
  • COMPUTE_REGION : région Compute Engine du cluster. Pour les clusters zonaux, spécifiez --zone=COMPUTE_ZONE.
  • MACHINE_TYPE : type de machine Compute Engine pour vos nœuds. Nous vous recommandons de sélectionner un type de machine optimisé pour les accélérateurs.
  • GPU_TYPE : type de GPU, qui doit être une plate-forme de GPU NVIDIA, telle que nvidia-tesla-v100.
  • GPU_QUANTITY : nombre de GPU physiques à associer à chaque nœud du pool de nœuds.
  • CLIENTS_PER_GPU : nombre maximal de conteneurs pouvant partager chaque GPU physique.
  • DRIVER_VERSION : version du pilote NVIDIA à installer. Les possibilités suivantes s'offrent à vous :

    • default : installe la version de pilote par défaut pour votre version de GKE.
    • latest : installe la dernière version de pilote disponible pour votre version de GKE. Disponible seulement pour les nœuds qui utilisent Container-Optimized OS.
    • disabled : passe l'installation automatique du pilote. Vous devez installer manuellement un pilote après avoir créé le pool de nœuds. Si vous omettez la commande gpu-driver-version, cette option est celle configurée par défaut.

Installer des pilotes d'appareils GPU NVIDIA

Avant de continuer, connectez-vous à votre cluster en exécutant la commande suivante :

gcloud container clusters get-credentials CLUSTER_NAME

Si vous avez choisi de désactiver l'installation automatique des pilotes lors de la création du cluster, ou si vous utilisez une version de GKE antérieure à la version 1.27.2-gke.1200, vous devez installer manuellement un pilote NVIDIA compatible pour gérer la division à temps partagé des GPU physiques. Pour installer les pilotes, vous devez déployer un DaemonSet d'installation de GKE qui configure les pilotes.

Pour obtenir des instructions, consultez la page Installer des pilotes d'appareils GPU NVIDIA.

Si vous envisagez d'utiliser le provisionnement automatique des nœuds dans votre cluster, vous devez également configurer le provisionnement automatique des nœuds avec les champs d'application permettant à GKE d'installer automatiquement les pilotes d'appareils GPU. Pour obtenir les instructions correspondantes, consultez la page Utiliser le provisionnement automatique des nœuds avec des GPU.

Vérifier les ressources GPU disponibles sur vos nœuds

Pour vérifier que le nombre de GPU visibles dans vos nœuds correspond au nombre que vous avez spécifié lorsque vous avez activé la fonctionnalité de temps partagé des GPU, décrivez vos nœuds :

kubectl describe nodes NODE_NAME

Le résultat ressemble à ce qui suit :

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

Dans cet exemple de résultat, le nombre de ressources GPU sur le nœud est 3, car la valeur spécifiée pour max-shared-clients-per-gpu était 3 et la valeur count des GPU physiques à rattacher au nœud était 1. Autre exemple : si la valeur count des GPU physiques était 2, le résultat afficherait 6 ressources GPU pouvant être allouées, trois sur chaque GPU physique.

Déployer des charges de travail qui utilisent le temps partagé des GPU

En tant qu'opérateur d'application qui déploie des charges de travail GPU, vous pouvez sélectionner le temps partagé des GPU activé en spécifiant les libellés de nœuds appropriés dans un fichier nodeSelector de vos fichiers manifestes. Lorsque vous planifiez vos requêtes, consultez les limites de requêtes pour vous assurer que GKE ne rejette pas vos déploiements.

Pour déployer une charge de travail de sorte qu'elle utilise le temps partagé des GPU, procédez comme suit:

  1. Ajoutez un nodeSelector au fichier manifeste de votre charge de travail pour les libellés suivants :

    • cloud.google.com/gke-gpu-sharing-strategy: time-sharing: sélectionne les nœuds qui utilisent le temps partagé des GPU.
    • cloud.google.com/gke-max-shared-clients-per-gpu: "CLIENTS_PER_GPU" : sélectionne les nœuds qui permettent à un nombre spécifique de conteneurs de partager le GPU sous-jacent.
  2. Ajoutez la demande de ressource GPU nvidia.com/gpu=1 à la spécification de conteneur, dans spec.containers.resources.limits.

Par exemple, les étapes suivantes vous expliquent comment déployer trois pods sur un pool de nœuds GPU avec temps partagé des GPU. GKE alloue chaque conteneur au même GPU physique. Les conteneurs impriment l'UUID du GPU associé à ce conteneur.

  1. Enregistrez le manifeste suivant sous le nom 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
      

Remplacez les éléments suivants :

  • GPU_TYPE : type de GPU.
  • CLIENTS_PER_GPU : nombre de charges de travail qui utiliseront ce GPU. Pour cet exemple, utilisez 3.
  • GPU_COUNT : nombre de GPU physiques à associer au nœud. Pour cet exemple, utilisez 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
      

Remplacez les éléments suivants :

  • SHARING_STRATEGY par "time-sharing" (temps partagé) pour demander le partage de temps pour votre GPU.
  • CLIENTS_PER_GPU : nombre de charges de travail qui utiliseront ce GPU. Pour cet exemple, utilisez 3.
  1. Appliquez le fichier manifeste :

    kubectl apply -f gpu-timeshare.yaml
    
  2. Vérifiez que tous les pods sont en cours d'exécution :

    kubectl get pods -l=app=cuda-simple
    
  3. Consultez les journaux d'un pod pour afficher l'UUID du GPU :

    kubectl logs POD_NAME
    

    Le résultat ressemble à ce qui suit :

    GPU 0: Tesla V100-SXM2-16GB (UUID: GPU-0771302b-eb3a-6756-7a23-0adcae8efd47)
    
  4. Si un nœud physique est associé à vos nœuds, consultez les journaux d'un autre pod sur le même nœud pour vérifier que l'UUID du GPU est identique :

    kubectl logs POD2_NAME
    

    Le résultat ressemble à ce qui suit :

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

Utiliser le temps partagé des GPU avec des GPU multi-instances

En tant qu'administrateur de plate-forme, vous pouvez combiner plusieurs fonctionnalités de GPU GKE. Le temps partagé des GPU fonctionne avec les GPU multi-instances, qui partitionnent un seul GPU physique en sept tranches maximum. Ces partitions sont isolées les unes des autres. Vous pouvez configurer le temps partagé des GPU pour chaque partition GPU multi-instances.

Par exemple, si vous définissez gpu-partition-size sur 1g.5gb, le GPU sous-jacent est divisé en sept partitions. Si vous définissez également max-shared-clients-per-gpu sur 3, chaque partition accepte jusqu'à trois conteneurs, pour un total de 21 appareils avec temps partagé des GPU disponibles à allouer dans ce GPU physique. Pour savoir comment gpu-partition-size effectue la conversion en partitions réelles, consultez la page Partitions GPU multi-instances.

Pour créer un cluster de GPU multi-instance avec le temps partagé des GPU activé, exécutez la commande suivante:

Autopilot

En mode Autopilot, le temps partagé des GPU et les GPU multi-instances peuvent être utilisés conjointement en utilisant les deux ensembles de sélecteurs de nœuds.

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

En mode standard, vous devez créer un cluster multi-instance à temps partagé par GPU en exécutant la commande suivante:

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

Remplacez PARTITION_SIZE par la taille de partition de GPU multi-instance souhaitée, par exemple 1g.5gb.

Limites

  • Avec le temps partagé des GPU, GKE applique une isolation de l'espace d'adressage, des performances et des pannes entre les conteneurs qui partagent un GPU physique. Cependant, les limites de mémoire ne sont pas appliquées aux GPU. Pour éviter les problèmes de mémoire insuffisante, définissez des limites de mémoire de GPU dans vos charges de travail. Pour éviter les problèmes de sécurité, déployez uniquement des charges de travail qui se trouvent dans la même limite de confiance du temps partagé des GPU.
  • Pour éviter tout comportement inattendu lors de l'allocation de capacité, GKE peut rejeter certaines requêtes de temps partagé des GPU. Pour en savoir plus, consultez la section Demandes de GPU pour le temps partagé des GPU.
  • Le nombre maximal de conteneurs pouvant utiliser le temps partagé dans un seul GPU physique est de 48. Lorsque vous planifiez votre configuration de temps partagé des GPU, tenez compte des besoins en ressources de vos charges de travail et de la capacité des GPU physiques sous-jacents afin d'optimiser vos performances et votre réactivité.

Étapes suivantes