Entraîner un modèle avec des GPU en mode GKE Autopilot


Ce guide de démarrage rapide explique comment déployer un modèle d'entraînement avec des GPU dans Google Kubernetes Engine (GKE) et stocker les prédictions dans Cloud Storage. Ce document est destiné aux administrateurs GKE qui possèdent des clusters en mode Autopilot existants et qui souhaitent exécuter des charges de travail GPU pour la première fois.

Vous pouvez également exécuter ces charges de travail sur des clusters Standard si vous créez des pools de nœuds GPU distincts dans vos clusters. Pour obtenir des instructions, consultez Entraîner les modèles avec des GPU en mode GKE Standard.

Avant de commencer

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the GKE and Cloud Storage APIs.

    Enable the APIs

  5. Install the Google Cloud CLI.

  6. Si vous utilisez un fournisseur d'identité (IdP) externe, vous devez d'abord vous connecter à la gcloud CLI avec votre identité fédérée.

  7. Pour initialiser la gcloud CLI, exécutez la commande suivante :

    gcloud init
  8. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  9. Make sure that billing is enabled for your Google Cloud project.

  10. Enable the GKE and Cloud Storage APIs.

    Enable the APIs

  11. Install the Google Cloud CLI.

  12. Si vous utilisez un fournisseur d'identité (IdP) externe, vous devez d'abord vous connecter à la gcloud CLI avec votre identité fédérée.

  13. Pour initialiser la gcloud CLI, exécutez la commande suivante :

    gcloud init
  14. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  15. Cloner l'exemple de dépôt

    Dans Cloud Shell, exécutez la commande suivante :

    git clone https://github.com/GoogleCloudPlatform/ai-on-gke && \
    cd ai-on-gke/tutorials-and-examples/gpu-examples/training-single-gpu
    

    Créer un cluster

    1. Dans la console Google Cloud , accédez à la page Créer un cluster Autopilot :

      Accéder à la page "Créer un cluster Autopilot"

    2. Dans le champ Nom, saisissez gke-gpu-cluster.

    3. Dans la liste Région, sélectionnez us-central1.

    4. Cliquez sur Créer.

    Créer un bucket Cloud Storage

    1. Dans la console Google Cloud , accédez à la page Créer un bucket :

      Accéder à la page Créer un bucket

    2. Dans le champ Attribuer un nom au bucket, saisissez le nom suivant :

      PROJECT_ID-gke-gpu-bucket
      

      Remplacez PROJECT_ID par l'ID de votre projet Google Cloud.

    3. Cliquez sur Continuer.

    4. Pour Type d'emplacement, sélectionnez Région.

    5. Dans la liste Région, sélectionnez us-central1 (Iowa), puis cliquez sur Continuer.

    6. Dans la section Choisir une classe de stockage pour vos données, cliquez sur Continuer.

    7. Dans la section Choisir comment contrôler l'accès aux objets, pour Contrôle des accès, sélectionnez Uniforme.

    8. Cliquez sur Créer.

    9. Dans la boîte de dialogue L'accès public sera bloqué, assurez-vous que la case Appliquer la protection contre l'accès public sur ce bucket est cochée, puis cliquez sur Confirmer.

    Configurer votre cluster pour accéder au bucket à l'aide de la fédération d'identité de charge de travail pour GKE

    Pour permettre à votre cluster d'accéder au bucket Cloud Storage, procédez comme suit :

    1. Créer un ServiceAccount Kubernetes dans votre cluster
    2. Créez une stratégie d'autorisation IAM qui permet au compte de service d'accéder au bucket.

    Créer un ServiceAccount Kubernetes dans votre cluster

    Dans Cloud Shell, procédez comme suit :

    1. Connectez-vous à votre cluster :

      gcloud container clusters get-credentials gke-gpu-cluster \
          --location=us-central1
      
    2. Créez un espace de noms Kubernetes :

      kubectl create namespace gke-gpu-namespace
      
    3. Créez un ServiceAccount Kubernetes dans l'espace de noms :

      kubectl create serviceaccount gpu-k8s-sa --namespace=gke-gpu-namespace
      

    Créer une stratégie d'autorisation IAM sur le bucket

    Attribuez le rôle Administrateur des objets de l'espace de stockage (roles/storage.objectAdmin) au compte de service Kubernetes sur le bucket :

    gcloud storage buckets add-iam-policy-binding gs://PROJECT_ID-gke-gpu-bucket \
        --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/gke-gpu-namespace/sa/gpu-k8s-sa \
        --role=roles/storage.objectAdmin \
        --condition=None
    

    Remplacez PROJECT_NUMBER par le numéro de votre projet Google Cloud.

    Vérifier que les pods peuvent accéder au bucket Cloud Storage

    1. Dans Cloud Shell, créez les variables d'environnement suivantes :

      export K8S_SA_NAME=gpu-k8s-sa
      export BUCKET_NAME=PROJECT_ID-gke-gpu-bucket
      

      Remplacez PROJECT_ID par l'ID de votre projet Google Cloud.

    2. Créez un pod contenant un conteneur TensorFlow :

      envsubst < src/gke-config/standard-tensorflow-bash.yaml | kubectl --namespace=gke-gpu-namespace apply -f -
      

      Cette commande insère les variables d'environnement que vous avez créées dans les références correspondantes du fichier manifeste. Vous pouvez également ouvrir le fichier manifeste dans un éditeur de texte et remplacer $K8S_SA_NAME et $BUCKET_NAME par les valeurs correspondantes.

    3. Créez un exemple de fichier dans le bucket :

      touch sample-file
      gcloud storage cp sample-file gs://PROJECT_ID-gke-gpu-bucket
      
    4. Attendez que votre pod soit prêt :

      kubectl wait --for=condition=Ready pod/test-tensorflow-pod -n=gke-gpu-namespace --timeout=180s
      

      Lorsque le pod est prêt, le résultat est le suivant :

      pod/test-tensorflow-pod condition met
      

      Si la commande expire, il est possible que GKE soit toujours en train de créer des nœuds pour exécuter les pods. Exécutez à nouveau la commande et attendez que le pod soit prêt.

    5. Ouvrez une interface système dans le conteneur TensorFlow :

      kubectl -n gke-gpu-namespace exec --stdin --tty test-tensorflow-pod --container tensorflow -- /bin/bash
      
    6. Essayez de lire l'exemple de fichier que vous avez créé :

      ls /data
      

      Le résultat affiche le fichier exemple.

    7. Consultez les journaux pour identifier le GPU associé au pod :

      python -c "import tensorflow as tf; print(tf.config.list_physical_devices('GPU'))"
      

      La sortie affiche le GPU associé au pod, semblable à ceci :

      ...
      PhysicalDevice(name='/physical_device:GPU:0',device_type='GPU')
      
    8. Quittez le conteneur :

      exit
      
    9. Supprimez l'exemple de pod :

      kubectl delete -f src/gke-config/standard-tensorflow-bash.yaml \
          --namespace=gke-gpu-namespace
      

    Entraîner et prédire à l'aide de l'ensemble de données MNIST

    Dans cette section, vous allez exécuter une charge de travail d'entraînement sur l'exemple d'ensemble de données MNIST.

    1. Copiez les exemples de données dans le bucket Cloud Storage :

      gcloud storage cp src/tensorflow-mnist-example gs://PROJECT_ID-gke-gpu-bucket/ --recursive
      
    2. Créez les variables d'environnement suivantes :

      export K8S_SA_NAME=gpu-k8s-sa
      export BUCKET_NAME=PROJECT_ID-gke-gpu-bucket
      
    3. Examinez le Job d'entraînement :

      # Copyright 2023 Google LLC
      #
      # Licensed under the Apache License, Version 2.0 (the "License");
      # you may not use this file except in compliance with the License.
      # You may obtain a copy of the License at
      #
      #      http://www.apache.org/licenses/LICENSE-2.0
      #
      # Unless required by applicable law or agreed to in writing, software
      # distributed under the License is distributed on an "AS IS" BASIS,
      # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      # See the License for the specific language governing permissions and
      # limitations under the License.
      
      apiVersion: batch/v1
      kind: Job
      metadata:
        name: mnist-training-job
      spec:
        template:
          metadata:
            name: mnist
            annotations:
              gke-gcsfuse/volumes: "true"
          spec:
            nodeSelector:
              cloud.google.com/gke-accelerator: nvidia-tesla-t4
            tolerations:
            - key: "nvidia.com/gpu"
              operator: "Exists"
              effect: "NoSchedule"
            containers:
            - name: tensorflow
              image: tensorflow/tensorflow:latest-gpu 
              command: ["/bin/bash", "-c", "--"]
              args: ["cd /data/tensorflow-mnist-example; pip install -r requirements.txt; python tensorflow_mnist_train_distributed.py"]
              resources:
                limits:
                  nvidia.com/gpu: 1
                  cpu: 1
                  memory: 3Gi
              volumeMounts:
              - name: gcs-fuse-csi-vol
                mountPath: /data
                readOnly: false
            serviceAccountName: $K8S_SA_NAME
            volumes:
            - name: gcs-fuse-csi-vol
              csi:
                driver: gcsfuse.csi.storage.gke.io
                readOnly: false
                volumeAttributes:
                  bucketName: $BUCKET_NAME
                  mountOptions: "implicit-dirs"
            restartPolicy: "Never"
    4. Déployez le Job d'entraînement :

      envsubst < src/gke-config/standard-tf-mnist-train.yaml | kubectl -n gke-gpu-namespace apply -f -
      

      Cette commande remplace les variables d'environnement que vous avez créées par les références correspondantes dans le fichier manifeste. Vous pouvez également ouvrir le fichier manifeste dans un éditeur de texte et remplacer $K8S_SA_NAME et $BUCKET_NAME par les valeurs correspondantes.

    5. Attendez que le Job ait l'état Completed :

      kubectl wait -n gke-gpu-namespace --for=condition=Complete job/mnist-training-job --timeout=180s
      

      Une fois le job prêt, le résultat ressemble à ce qui suit :

      job.batch/mnist-training-job condition met
      

      Si la commande expire, il est possible que GKE soit toujours en train de créer des nœuds pour exécuter les pods. Exécutez à nouveau la commande et attendez que le Job soit prêt.

    6. Vérifiez les journaux du conteneur TensorFlow :

      kubectl logs -f jobs/mnist-training-job -c tensorflow -n gke-gpu-namespace
      

      Le résultat indique que les événements suivants se produisent :

      • Installer les packages Python requis
      • Télécharger l'ensemble de données MNIST
      • Entraîner le modèle à l'aide d'un GPU
      • Enregistrer le modèle
      • Évaluer le modèle
      ...
      Epoch 12/12
      927/938 [============================>.] - ETA: 0s - loss: 0.0188 - accuracy: 0.9954
      Learning rate for epoch 12 is 9.999999747378752e-06
      938/938 [==============================] - 5s 6ms/step - loss: 0.0187 - accuracy: 0.9954 - lr: 1.0000e-05
      157/157 [==============================] - 1s 4ms/step - loss: 0.0424 - accuracy: 0.9861
      Eval loss: 0.04236088693141937, Eval accuracy: 0.9861000180244446
      Training finished. Model saved
      
    7. Supprimez la charge de travail d'entraînement :

      kubectl -n gke-gpu-namespace delete -f src/gke-config/standard-tf-mnist-train.yaml
      

    Déployer une charge de travail d'inférence

    Dans cette section, vous allez déployer une charge de travail d'inférence qui utilise un exemple d'ensemble de données en tant qu'entrée et renvoie des prédictions.

    1. Copiez les images pour la prédiction dans le bucket :

      gcloud storage cp data/mnist_predict gs://PROJECT_ID-gke-gpu-bucket/ --recursive
      
    2. Examinez la charge de travail d'inférence :

      # Copyright 2023 Google LLC
      #
      # Licensed under the Apache License, Version 2.0 (the "License");
      # you may not use this file except in compliance with the License.
      # You may obtain a copy of the License at
      #
      #      http://www.apache.org/licenses/LICENSE-2.0
      #
      # Unless required by applicable law or agreed to in writing, software
      # distributed under the License is distributed on an "AS IS" BASIS,
      # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      # See the License for the specific language governing permissions and
      # limitations under the License.
      
      apiVersion: batch/v1
      kind: Job
      metadata:
        name: mnist-batch-prediction-job
      spec:
        template:
          metadata:
            name: mnist
            annotations:
              gke-gcsfuse/volumes: "true"
          spec:
            nodeSelector:
              cloud.google.com/gke-accelerator: nvidia-tesla-t4
            tolerations:
            - key: "nvidia.com/gpu"
              operator: "Exists"
              effect: "NoSchedule"
            containers:
            - name: tensorflow
              image: tensorflow/tensorflow:latest-gpu 
              command: ["/bin/bash", "-c", "--"]
              args: ["cd /data/tensorflow-mnist-example; pip install -r requirements.txt; python tensorflow_mnist_batch_predict.py"]
              resources:
                limits:
                  nvidia.com/gpu: 1
                  cpu: 1
                  memory: 3Gi
              volumeMounts:
              - name: gcs-fuse-csi-vol
                mountPath: /data
                readOnly: false
            serviceAccountName: $K8S_SA_NAME
            volumes:
            - name: gcs-fuse-csi-vol
              csi:
                driver: gcsfuse.csi.storage.gke.io
                readOnly: false
                volumeAttributes:
                  bucketName: $BUCKET_NAME
                  mountOptions: "implicit-dirs"
            restartPolicy: "Never"
    3. Déployez la charge de travail d'inférence :

      envsubst < src/gke-config/standard-tf-mnist-batch-predict.yaml | kubectl -n gke-gpu-namespace apply -f -
      

      Cette commande remplace les variables d'environnement que vous avez créées par les références correspondantes dans le fichier manifeste. Vous pouvez également ouvrir le fichier manifeste dans un éditeur de texte et remplacer $K8S_SA_NAME et $BUCKET_NAME par les valeurs correspondantes.

    4. Attendez que le Job ait l'état Completed :

      kubectl wait -n gke-gpu-namespace --for=condition=Complete job/mnist-batch-prediction-job --timeout=180s
      

      Le résultat ressemble à ce qui suit :

      job.batch/mnist-batch-prediction-job condition met
      
    5. Vérifiez les journaux du conteneur TensorFlow :

      kubectl logs -f jobs/mnist-batch-prediction-job -c tensorflow -n gke-gpu-namespace
      

      Le résultat correspond à la prédiction associée à chaque image et à la fiabilité du modèle, semblable à celle-ci :

      Found 10 files belonging to 1 classes.
      1/1 [==============================] - 2s 2s/step
      The image /data/mnist_predict/0.png is the number 0 with a 100.00 percent confidence.
      The image /data/mnist_predict/1.png is the number 1 with a 99.99 percent confidence.
      The image /data/mnist_predict/2.png is the number 2 with a 100.00 percent confidence.
      The image /data/mnist_predict/3.png is the number 3 with a 99.95 percent confidence.
      The image /data/mnist_predict/4.png is the number 4 with a 100.00 percent confidence.
      The image /data/mnist_predict/5.png is the number 5 with a 100.00 percent confidence.
      The image /data/mnist_predict/6.png is the number 6 with a 99.97 percent confidence.
      The image /data/mnist_predict/7.png is the number 7 with a 100.00 percent confidence.
      The image /data/mnist_predict/8.png is the number 8 with a 100.00 percent confidence.
      The image /data/mnist_predict/9.png is the number 9 with a 99.65 percent confidence.
      

    Effectuer un nettoyage

    Pour éviter que les ressources que vous avez créées dans ce guide soient facturées sur votre compte Google Cloud , effectuez l'une des opérations suivantes :

    • Conserver le cluster GKE : supprimez les ressources Kubernetes du cluster et les ressources Google Cloud .
    • Conserver le projet Google Cloud  : supprimez le cluster GKE et les ressources Google Cloud .
    • Supprimer le projet

    Supprimer les ressources Kubernetes du cluster et les ressources Google Cloud

    1. Supprimez l'espace de noms Kubernetes et les charges de travail que vous avez déployées :

      kubectl -n gke-gpu-namespace delete -f src/gke-config/standard-tf-mnist-batch-predict.yaml
      kubectl delete namespace gke-gpu-namespace
      
    2. Supprimez le bucket Cloud Storage :

      1. Accédez à la page Buckets :

        Accéder à la page "Buckets"

      2. Sélectionnez la case à cocher correspondant à PROJECT_ID-gke-gpu-bucket.

      3. Cliquez sur Supprimer.

      4. Pour confirmer la suppression, saisissez DELETE, puis cliquez sur Supprimer.

    3. Supprimez le compte de service Google Cloud  :

      1. Accédez à la page Comptes de service :

        Accéder à la page "Comptes de service"

      2. Sélectionnez votre projet.

      3. Sélectionnez la case à cocher correspondant à gke-gpu-sa@PROJECT_ID.iam.gserviceaccount.com.

      4. Cliquez sur Supprimer.

      5. Pour confirmer la suppression, cliquez sur Supprimer.

    Supprimer le cluster GKE et les ressources Google Cloud

    1. Supprimez le cluster GKE :

      1. Accédez à la page Clusters :

        accéder aux clusters

      2. Sélectionnez la case à cocher correspondant à gke-gpu-cluster.

      3. Cliquez sur Supprimer.

      4. Pour confirmer la suppression, saisissez gke-gpu-cluster, puis cliquez sur Supprimer.

    2. Supprimez le bucket Cloud Storage :

      1. Accédez à la page Buckets :

        Accéder à la page "Buckets"

      2. Sélectionnez la case à cocher correspondant à PROJECT_ID-gke-gpu-bucket.

      3. Cliquez sur Supprimer.

      4. Pour confirmer la suppression, saisissez DELETE, puis cliquez sur Supprimer.

    3. Supprimez le compte de service Google Cloud  :

      1. Accédez à la page Comptes de service :

        Accéder à la page "Comptes de service"

      2. Sélectionnez votre projet.

      3. Sélectionnez la case à cocher correspondant à gke-gpu-sa@PROJECT_ID.iam.gserviceaccount.com.

      4. Cliquez sur Supprimer.

      5. Pour confirmer la suppression, cliquez sur Supprimer.

    Supprimer le projet

    1. In the Google Cloud console, go to the Manage resources page.

      Go to Manage resources

    2. In the project list, select the project that you want to delete, and then click Delete.
    3. In the dialog, type the project ID, and then click Shut down to delete the project.

    Étapes suivantes