Entrena un modelo con GPU en el modo GKE Standard

En este instructivo de inicio rápido, se muestra cómo implementar un modelo de entrenamiento con GPU en Google Kubernetes Engine (GKE) y almacenar las predicciones en Cloud Storage. En este instructivo, se usa un modelo de TensorFlow y clústeres de GKE Standard. También puedes ejecutar estas cargas de trabajo en clústeres de Autopilot con menos pasos de configuración. Para obtener instrucciones, consulta Entrena un modelo con GPUs en el modo GKE Autopilot.

Este documento está dirigido a los administradores de GKE que tienen clústeres Standard existentes y desean ejecutar cargas de trabajo de GPU por primera vez.

Antes de comenzar

  • 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.
  • In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  • Verify that billing is enabled for your Google Cloud project.

  • Enable the Kubernetes Engine and Cloud Storage APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  • In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  • Verify that billing is enabled for your Google Cloud project.

  • Enable the Kubernetes Engine and Cloud Storage APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  • 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.

  • Clona el repositorio de muestra

    En Cloud Shell, ejecuta el siguiente comando:

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

    Crea un clúster de modo Standard y un grupo de nodos de GPU

    Usa Cloud Shell para realizar las siguientes acciones:

    1. Crea un clúster de Standard que use la federación de identidades para cargas de trabajo para GKE e instale el controlador de 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
      

      Reemplaza PROJECT_ID por el ID del proyecto Google Cloud.

      La creación del clúster puede tomar varios minutos.

    2. Crea un grupo de nodos de 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
      

    Cree un bucket de Cloud Storage

    1. En la consola de Google Cloud , ve a la página Crear un bucket:

      Ir a Crear un bucket

    2. En el campo Asigna un nombre a tu bucket, ingresa el siguiente nombre:

      PROJECT_ID-gke-gpu-bucket
      
    3. Haz clic en Continuar.

    4. En Tipo de ubicación, selecciona Región.

    5. En la lista Región, selecciona us-central1 (Iowa) y haz clic en Continuar.

    6. En la sección Elegir una clase de almacenamiento para tus datos, haz clic en Continuar.

    7. En la sección Elige cómo controlar el acceso a los objetos, en Control de acceso, selecciona Uniforme.

    8. Haz clic en Crear.

    9. En el diálogo Se evitará el acceso público, asegúrate de que la casilla de verificación Aplicar la prevención de acceso público a este bucket esté seleccionada y haz clic en Confirmar.

    Configura tu clúster a fin de acceder al bucket mediante la federación de identidades para cargas de trabajo para GKE

    Para permitir que tu clúster acceda al bucket de Cloud Storage, haz lo siguiente:

    1. Crea una cuenta de servicio Google Cloud .
    2. Crea una ServiceAccount de Kubernetes en tu clúster.
    3. Vincula la ServiceAccount de Kubernetes a la cuenta de servicio de Google Cloud .

    Crea una cuenta de servicio Google Cloud

    1. En la consola de Google Cloud , ve a la página Crear cuenta de servicio:

      Ve a Crear cuenta de servicio

    2. En el campo ID de cuenta de servicio, ingresa gke-ai-sa.

    3. Haz clic en Crear y continuar.

    4. En la lista Rol, selecciona el rol Cloud Storage > Servicio de recopilador de Storage Insights.

    5. Haz clic en Agregar otro rol.

    6. En la lista Seleccionar un rol, selecciona el rol Cloud Storage > Administrador de objetos de almacenamiento.

    7. Haz clic en Continuar y, luego, en Listo.

    Crea una ServiceAccount de Kubernetes en tu clúster

    En Cloud Shell, haz lo siguiente:

    1. Crea un espacio de nombres de Kubernetes:

      kubectl create namespace gke-ai-namespace
      
    2. Crea una ServiceAccount de Kubernetes en el espacio de nombres:

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

    Vincula la ServiceAccount de Kubernetes a la cuenta de servicio Google Cloud

    En Cloud Shell, ejecuta los siguientes comandos:

    1. Agrega una vinculación de IAM a la cuenta de servicio 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]"
      

      La marca --member proporciona la identidad completa de la ServiceAccount de Kubernetes en Google Cloud.

    2. Anota la ServiceAccount de 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
      

    Verifica que los Pods puedan acceder al bucket de Cloud Storage

    1. En Cloud Shell, crea las siguientes variables de entorno:

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

      Reemplaza PROJECT_ID por el ID del proyecto Google Cloud.

    2. Crea un Pod que tenga un contenedor de TensorFlow:

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

      Este comando sustituye las variables de entorno que creaste en las referencias correspondientes del manifiesto. También puedes abrir el manifiesto en un editor de texto y reemplazar $K8S_SA_NAME y $BUCKET_NAME por los valores correspondientes.

    3. Crea un archivo de muestra en el bucket:

      touch sample-file
      gcloud storage cp sample-file gs://PROJECT_ID-gke-gpu-bucket
      
    4. Espera a que el Pod esté listo:

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

      Cuando el Pod está listo, el resultado es el siguiente:

      pod/test-tensorflow-pod condition met
      
    5. Abre una shell en el contenedor de TensorFlow:

      kubectl -n gke-ai-namespace exec --stdin --tty test-tensorflow-pod --container tensorflow -- /bin/bash
      
    6. Intenta leer el archivo de muestra que creaste:

      ls /data
      

      El resultado muestra el archivo de muestra.

    7. Verifica los registros para identificar la GPU conectada al Pod:

      python3 -m pip install 'tensorflow[and-cuda]'
      python -c "import tensorflow as tf; print(tf.config.list_physical_devices('GPU'))"
      

      El resultado muestra la GPU adjunta al Pod, similar a lo siguiente:

      ...
      PhysicalDevice(name='/physical_device:GPU:0',device_type='GPU')
      
    8. Sal del contenedor:

      exit
      
    9. Borra el Pod de muestra:

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

    Entrena y realiza predicciones con el conjunto de datos MNIST

    En esta sección, ejecutarás una carga de trabajo de entrenamiento en el conjunto de datos de ejemplo MNIST.

    1. Copia los datos de ejemplo en el bucket de Cloud Storage:

      gcloud storage cp src/tensorflow-mnist-example gs://PROJECT_ID-gke-gpu-bucket/ --recursive
      
    2. Crea las siguientes variables de entorno:

      export K8S_SA_NAME=gpu-k8s-sa
      export BUCKET_NAME=PROJECT_ID-gke-gpu-bucket
      
    3. Revisa el trabajo de entrenamiento:

      # 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. Implementa el trabajo de entrenamiento:

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

      Este comando sustituye las variables de entorno que creaste en las referencias correspondientes del manifiesto. También puedes abrir el manifiesto en un editor de texto y reemplazar $K8S_SA_NAME y $BUCKET_NAME por los valores correspondientes.

    5. Espera hasta que el trabajo tenga el estado Completed:

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

      El resultado es similar a este:

      job.batch/mnist-training-job condition met
      
    6. Verifica los registros del contenedor de TensorFlow:

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

      En el resultado, se muestran los siguientes eventos:

      • Instala los paquetes obligatorios de Python
      • Descarga el conjunto de datos de MNIST
      • Entrena el modelo con una GPU
      • Guarda el modelo.
      • Evaluar el modelo
      ...
      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. Borra la carga de trabajo de entrenamiento:

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

    Implementa una carga de trabajo de inferencia

    En esta sección, implementarás una carga de trabajo de inferencia que tome un conjunto de datos de muestra como entrada y muestre predicciones.

    1. Copia las imágenes para la predicción en el bucket:

      gcloud storage cp data/mnist_predict gs://PROJECT_ID-gke-gpu-bucket/ --recursive
      
    2. Revisa la carga de trabajo de inferencia:

      # 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. Implementa la carga de trabajo de inferencia:

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

      Este comando sustituye las variables de entorno que creaste en las referencias correspondientes del manifiesto. También puedes abrir el manifiesto en un editor de texto y reemplazar $K8S_SA_NAME y $BUCKET_NAME por los valores correspondientes.

    4. Espera hasta que el trabajo tenga el estado Completed:

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

      El resultado es similar a este:

      job.batch/mnist-batch-prediction-job condition met
      
    5. Verifica los registros del contenedor de TensorFlow:

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

      El resultado es la predicción para cada imagen y la confianza del modelo en la predicción, que es similar a lo siguiente:

      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.
      

    Limpia

    Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos que creaste en esta guía, haz una de las siguientes acciones:

    • Mantén el clúster de GKE: Borra los recursos de Kubernetes en el clúster y los recursos de Google Cloud
    • Mantén el proyecto Google Cloud : Borra el clúster de GKE y los recursos Google Cloud .
    • Borra el proyecto

    Borra los recursos de Kubernetes en el clúster y los recursos de Google Cloud

    1. Borra el espacio de nombres de Kubernetes y las cargas de trabajo que implementaste:

      kubectl -n gke-ai-namespace delete -f src/gke-config/standard-tf-mnist-batch-predict.yaml
      kubectl delete namespace gke-ai-namespace
      
    2. Borra el bucket de Cloud Storage:

      1. Ve a la página Buckets:

        Ir a Buckets

      2. Selecciona la casilla de verificación correspondiente a PROJECT_ID-gke-gpu-bucket.

      3. Haz clic en Borrar.

      4. Para confirmar la eliminación, escribe DELETE y haz clic en Borrar.

    3. Borra la cuenta de servicio Google Cloud :

      1. Ve a la página Cuentas de servicio:

        Ir a Cuentas de servicio

      2. Selecciona tu proyecto.

      3. Selecciona la casilla de verificación correspondiente a gke-ai-sa@PROJECT_ID.iam.gserviceaccount.com.

      4. Haz clic en Borrar.

      5. Para confirmar la eliminación, haz clic en Borrar.

    Borra el clúster de GKE y los recursos de Google Cloud

    1. Borra el clúster de GKE:

      1. Ve a la página Clústeres:

        Ir a los clústeres

      2. Selecciona la casilla de verificación correspondiente a gke-gpu-cluster.

      3. Haz clic en Borrar.

      4. Para confirmar la eliminación, escribe gke-gpu-cluster y haz clic en Borrar.

    2. Borra el bucket de Cloud Storage:

      1. Ve a la página Buckets:

        Ir a Buckets

      2. Selecciona la casilla de verificación correspondiente a PROJECT_ID-gke-gpu-bucket.

      3. Haz clic en Borrar.

      4. Para confirmar la eliminación, escribe DELETE y haz clic en Borrar.

    3. Borra la cuenta de servicio Google Cloud :

      1. Ve a la página Cuentas de servicio:

        Ir a Cuentas de servicio

      2. Selecciona tu proyecto.

      3. Selecciona la casilla de verificación correspondiente a gke-ai-sa@PROJECT_ID.iam.gserviceaccount.com.

      4. Haz clic en Borrar.

      5. Para confirmar la eliminación, haz clic en Borrar.

    Borra el proyecto

    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.

    ¿Qué sigue?