Entraîner les modèles avec des GPU en mode GKE Standard


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 Standard 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 en mode Autopilot avec moins d'étapes de configuration.

Avant de commencer

  1. Connectez-vous à votre compte Google Cloud. Si vous débutez sur Google Cloud, créez un compte pour évaluer les performances de nos produits en conditions réelles. Les nouveaux clients bénéficient également de 300 $ de crédits gratuits pour exécuter, tester et déployer des charges de travail.
  2. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  3. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  4. Activer les API Kubernetes Engine and Cloud Storage.

    Activer les API

  5. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  6. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  7. Activer les API Kubernetes Engine and Cloud Storage.

    Activer les API

  8. Dans la console Google Cloud, activez Cloud Shell.

    Activer Cloud Shell

    En bas de la fenêtre de la console Google Cloud, une session Cloud Shell démarre et affiche une invite de ligne de commande. Cloud Shell est un environnement shell dans lequel Google Cloud CLI est déjà installé, et dans lequel des valeurs sont déjà définies pour votre projet actuel. L'initialisation de la session peut prendre quelques secondes.

Cloner l'exemple de dépôt

Dans Cloud Shell, exécutez la commande suivante :

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

Créer un cluster en mode Standard et un pool de nœuds GPU

Utilisez Cloud Shell pour effectuer les opérations suivantes :

  1. Créez un cluster Standard qui utilise la fédération d'identité de charge de travail pour GKE et installe le pilote Cloud Storage FUSE :

    gcloud container clusters create gke-gpu-cluster \
        --addons GcsFuseCsiDriver \
        --location=us-central1 \
        --num-nodes=1 \
        --workload-pool=PROJECT_ID.svc.id.goog
    

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

    La création du cluster peut prendre plusieurs minutes.

  2. Créez un pool de nœuds GPU :

    gcloud container node-pools create gke-gpu-pool-1 \
        --accelerator=type=nvidia-tesla-t4,count=1,gpu-driver-version=default \
        --machine-type=n1-standard-16 --num-nodes=1 \
        --location=us-central1 \
        --cluster=gke-gpu-cluster
    

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
    
  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, sous 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éez un compte de service Google Cloud.
  2. Créer un ServiceAccount Kubernetes dans votre cluster
  3. Associer le ServiceAccount Kubernetes au compte de service Google Cloud

Créer un compte de service Google Cloud

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

    Accéder à la page "Créer un compte de service"

  2. Dans le champ ID du compte de service, saisissez gke-ai-sa.

  3. Cliquez sur Créer et continuer.

  4. Dans la liste Rôle, sélectionnez le rôle Cloud Storage > Service de collecte des insights sur le stockage.

  5. Cliquez sur Ajouter un autre rôle.

  6. Dans la liste Sélectionner un rôle, sélectionnez le rôle Cloud Storage > Administrateur des objets de l'espace de stockage.

  7. Cliquez sur Continue (Continuer), puis sur Done (OK).

Créer un ServiceAccount Kubernetes dans votre cluster

Dans Cloud Shell, procédez comme suit :

  1. Créez un espace de noms Kubernetes :

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

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

Associer le ServiceAccount Kubernetes au compte de service Google Cloud

Dans Cloud Shell, exécutez les commandes suivantes :

  1. Ajoutez une liaison IAM au compte de service Google Cloud :

    gcloud iam service-accounts add-iam-policy-binding gke-ai-sa@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/iam.workloadIdentityUser \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[gke-ai-namespace/gpu-k8s-sa]"
    

    L'option --member fournit l'identité complète du ServiceAccount Kubernetes dans Google Cloud.

  2. Annotez le compte de service Kubernetes :

    kubectl annotate serviceaccount gpu-k8s-sa \
        --namespace gke-ai-namespace \
        iam.gke.io/gcp-service-account=gke-ai-sa@PROJECT_ID.iam.gserviceaccount.com
    

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-ai-namespace apply -f -
    

    Cette commande remplace les variables d'environnement que vous avez créées dans 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.

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

    touch sample-file
    gsutil 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-ai-namespace --timeout=180s
    

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

    pod/test-tensorflow-pod condition met
    
  5. Ouvrez une interface système dans le conteneur Tensorflow :

    kubectl -n gke-ai-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 l'exemple de fichier.

  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-ai-namespace
    

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

Dans cette section, vous exécutez 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 :

    gsutil -m cp -R src/tensorflow-mnist-example gs://PROJECT_ID-gke-gpu-bucket/
    
  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-ai-namespace apply -f -
    

    Cette commande remplace les variables d'environnement que vous avez créées dans 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-ai-namespace --for=condition=Complete job/mnist-training-job --timeout=180s
    

    Le résultat ressemble à ce qui suit :

    job.batch/mnist-training-job condition met
    
  6. Vérifiez les journaux du conteneur Tensorflow :

    kubectl logs -f jobs/mnist-training-job -c tensorflow -n gke-ai-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-ai-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 exploite un exemple d'ensemble de données en entrée et renvoie des prédictions.

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

    gsutil -m cp -R data/mnist_predict gs://PROJECT_ID-gke-gpu-bucket/
    
  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-ai-namespace apply -f -
    

    Cette commande remplace les variables d'environnement que vous avez créées dans 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-ai-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-ai-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 : supprimer 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-ai-namespace delete -f src/gke-config/standard-tf-mnist-batch-predict.yaml
    kubectl delete namespace gke-ai-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 et cliquez sur Supprimer.

  3. Supprimer 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-ai-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 et 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 et cliquez sur Supprimer.

  3. Supprimer 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-ai-sa@PROJECT_ID.iam.gserviceaccount.com.

    4. Cliquez sur Supprimer.

    5. Pour confirmer la suppression, cliquez sur Supprimer.

Supprimer le projet

  1. Dans la console Google Cloud, accédez à la page Gérer les ressources.

    Accéder à la page Gérer les ressources

  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.

Étapes suivantes