Addestra un modello con GPU in modalità GKE Autopilot


Questa guida rapida mostra come eseguire il deployment di un modello di addestramento con GPU in Google Kubernetes Engine (GKE) e archiviare le previsioni in Cloud Storage. Questo documento è destinato agli amministratori GKE che hanno cluster in modalità Autopilot esistenti e vogliono eseguire carichi di lavoro GPU per la prima volta.

Puoi anche eseguire questi carichi di lavoro su cluster Standard se crei node pool GPU separati nei cluster. Per istruzioni, vedi Addestra un modello con GPU in modalità GKE Standard.

Prima di iniziare

  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. Se utilizzi un provider di identità (IdP) esterno, devi prima accedere alla gcloud CLI con la tua identità federata.

  7. Per inizializzare gcloud CLI, esegui questo comando:

    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. Se utilizzi un provider di identità (IdP) esterno, devi prima accedere alla gcloud CLI con la tua identità federata.

  13. Per inizializzare gcloud CLI, esegui questo comando:

    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. Clona il repository di esempio

    In Cloud Shell, esegui questo comando:

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

    Crea un cluster

    1. Nella console Google Cloud , vai alla pagina Crea un cluster Autopilot:

      Vai a Crea un cluster Autopilot

    2. Nel campo Nome, inserisci gke-gpu-cluster.

    3. Nell'elenco Regione, seleziona us-central1.

    4. Fai clic su Crea.

    Crea un bucket Cloud Storage

    1. Nella console Google Cloud , vai alla pagina Crea un bucket:

      Vai a Crea un bucket

    2. Nel campo Assegna un nome al bucket, inserisci il seguente nome:

      PROJECT_ID-gke-gpu-bucket
      

      Sostituisci PROJECT_ID con l'ID progetto Google Cloud.

    3. Fai clic su Continua.

    4. Per Tipo di località, seleziona Regione.

    5. Nell'elenco Regione, seleziona us-central1 (Iowa) e fai clic su Continua.

    6. Nella sezione Scegli una classe di archiviazione per i tuoi dati, fai clic su Continua.

    7. Nella sezione Scegli come controllare l'accesso agli oggetti, seleziona Uniforme per Controllo dell'accesso.

    8. Fai clic su Crea.

    9. Nella finestra di dialogo L'accesso pubblico verrà vietato, assicurati che la casella di controllo Applica la prevenzione dell'accesso pubblico in questo bucket sia selezionata e fai clic su Conferma.

    Configura il cluster per accedere al bucket utilizzando Workload Identity Federation for GKE

    Per consentire al cluster di accedere al bucket Cloud Storage, procedi come segue:

    1. Crea un ServiceAccount Kubernetes nel cluster.
    2. Crea un criterio di autorizzazione IAM che consenta a ServiceAccount di accedere al bucket.

    Crea un ServiceAccount Kubernetes nel tuo cluster

    In Cloud Shell:

    1. Connettiti al cluster:

      gcloud container clusters get-credentials gke-gpu-cluster \
          --location=us-central1
      
    2. Crea uno spazio dei nomi Kubernetes:

      kubectl create namespace gke-gpu-namespace
      
    3. Crea un ServiceAccount Kubernetes nello spazio dei nomi:

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

    Crea un criterio di autorizzazione IAM sul bucket

    Concedi il ruolo Amministratore oggetti Storage (roles/storage.objectAdmin) sul bucket al service account Kubernetes:

    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
    

    Sostituisci PROJECT_NUMBER con il numero del tuo progetto Google Cloud.

    Verifica che i pod possano accedere al bucket Cloud Storage

    1. In Cloud Shell, crea le seguenti variabili di ambiente:

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

      Sostituisci PROJECT_ID con l'ID progetto Google Cloud.

    2. Crea un pod con un container TensorFlow:

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

      Questo comando inserisce le variabili di ambiente che hai creato nei riferimenti corrispondenti nel manifest. Puoi anche aprire il manifest in un editor di testo e sostituire $K8S_SA_NAME e $BUCKET_NAME con i valori corrispondenti.

    3. Crea un file di esempio nel bucket:

      touch sample-file
      gcloud storage cp sample-file gs://PROJECT_ID-gke-gpu-bucket
      
    4. Attendi che il pod sia pronto:

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

      Quando il pod è pronto, l'output è il seguente:

      pod/test-tensorflow-pod condition met
      

      Se il comando scade, GKE potrebbe comunque creare nuovi nodi per eseguire i pod. Esegui di nuovo il comando e attendi che il pod sia pronto.

    5. Apri una shell nel container TensorFlow:

      kubectl -n gke-gpu-namespace exec --stdin --tty test-tensorflow-pod --container tensorflow -- /bin/bash
      
    6. Prova a leggere il file di esempio che hai creato:

      ls /data
      

      L'output mostra il file di esempio.

    7. Controlla i log per identificare la GPU collegata al pod:

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

      L'output mostra la GPU collegata al pod, in modo simile al seguente:

      ...
      PhysicalDevice(name='/physical_device:GPU:0',device_type='GPU')
      
    8. Esci dal container:

      exit
      
    9. Elimina il pod di esempio:

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

    Addestra e prevedi utilizzando il set di dati MNIST

    In questa sezione, esegui un carico di lavoro di addestramento sul set di dati di esempio MNIST.

    1. Copia i dati di esempio nel bucket Cloud Storage:

      gcloud storage cp src/tensorflow-mnist-example gs://PROJECT_ID-gke-gpu-bucket/ --recursive
      
    2. Crea le seguenti variabili di ambiente:

      export K8S_SA_NAME=gpu-k8s-sa
      export BUCKET_NAME=PROJECT_ID-gke-gpu-bucket
      
    3. Esamina il job di addestramento:

      # 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. Esegui il deployment del job di addestramento:

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

      Questo comando sostituisce le variabili di ambiente che hai creato con i riferimenti corrispondenti nel manifest. Puoi anche aprire il manifest in un editor di testo e sostituire $K8S_SA_NAME e $BUCKET_NAME con i valori corrispondenti.

    5. Attendi che il job abbia lo stato Completed:

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

      Quando il job è pronto, l'output è simile al seguente:

      job.batch/mnist-training-job condition met
      

      Se il comando scade, GKE potrebbe comunque creare nuovi nodi per eseguire i pod. Esegui di nuovo il comando e attendi che il job diventi pronto.

    6. Controlla i log del container TensorFlow:

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

      L'output mostra i seguenti eventi:

      • Installa i pacchetti Python richiesti
      • Scarica il set di dati MNIST
      • Addestra il modello utilizzando una GPU
      • Salva il modello
      • Valuta il modello
      ...
      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. Elimina il workload di addestramento:

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

    Esegui il deployment di un carico di lavoro di inferenza

    In questa sezione, esegui il deployment di un carico di lavoro di inferenza che accetta un set di dati di esempio come input e restituisce le previsioni.

    1. Copia le immagini per la previsione nel bucket:

      gcloud storage cp data/mnist_predict gs://PROJECT_ID-gke-gpu-bucket/ --recursive
      
    2. Esamina il workload di inferenza:

      # 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. Esegui il deployment del carico di lavoro di inferenza:

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

      Questo comando sostituisce le variabili di ambiente che hai creato con i riferimenti corrispondenti nel manifest. Puoi anche aprire il manifest in un editor di testo e sostituire $K8S_SA_NAME e $BUCKET_NAME con i valori corrispondenti.

    4. Attendi che il job abbia lo stato Completed:

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

      L'output è simile al seguente:

      job.batch/mnist-batch-prediction-job condition met
      
    5. Controlla i log del container TensorFlow:

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

      L'output è la previsione per ogni immagine e l'affidabilità del modello nella previsione, simile alla seguente:

      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.
      

    Esegui la pulizia

    Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse che hai creato in questa guida, procedi in uno dei seguenti modi:

    • Mantieni il cluster GKE: elimina le risorse Kubernetes nel cluster e le risorse Google Cloud
    • Mantieni il progetto Google Cloud : elimina il cluster GKE e le risorse Google Cloud
    • Eliminare il progetto

    Elimina le risorse Kubernetes nel cluster e le risorse Google Cloud

    1. Elimina lo spazio dei nomi Kubernetes e i carichi di lavoro di cui hai eseguito il deployment:

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

      1. Vai alla pagina Bucket:

        Vai a Bucket

      2. Seleziona la casella di controllo per PROJECT_ID-gke-gpu-bucket.

      3. Fai clic su Elimina.

      4. Per confermare l'eliminazione, digita DELETE e fai clic su Elimina.

    3. Elimina il service account Google Cloud :

      1. Vai alla pagina Service Accounts:

        Vai ad Account di servizio

      2. Seleziona il progetto.

      3. Seleziona la casella di controllo per gke-gpu-sa@PROJECT_ID.iam.gserviceaccount.com.

      4. Fai clic su Elimina.

      5. Per confermare l'eliminazione, fai clic su Elimina.

    Elimina il cluster GKE e le Google Cloud risorse

    1. Elimina il cluster GKE:

      1. Vai alla pagina Cluster:

        Vai a Cluster

      2. Seleziona la casella di controllo per gke-gpu-cluster.

      3. Fai clic su Elimina.

      4. Per confermare l'eliminazione, digita gke-gpu-cluster e fai clic su Elimina.

    2. Elimina il bucket Cloud Storage:

      1. Vai alla pagina Bucket:

        Vai a Bucket

      2. Seleziona la casella di controllo per PROJECT_ID-gke-gpu-bucket.

      3. Fai clic su Elimina.

      4. Per confermare l'eliminazione, digita DELETE e fai clic su Elimina.

    3. Elimina il service account Google Cloud :

      1. Vai alla pagina Service Accounts:

        Vai ad Account di servizio

      2. Seleziona il progetto.

      3. Seleziona la casella di controllo per gke-gpu-sa@PROJECT_ID.iam.gserviceaccount.com.

      4. Fai clic su Elimina.

      5. Per confermare l'eliminazione, fai clic su Elimina.

    Elimina il progetto

    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.

    Passaggi successivi