Entrena un modelo con GPU en el modo GKE Standard


En esta guía 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. Este documento está dirigido a los administradores de GKE que tienen clústeres de modo Standard existentes y desean ejecutar cargas de trabajo de GPU por primera vez.

También puedes ejecutar estas cargas de trabajo en clústeres de modo Autopilot con menos pasos de configuración.

Antes de comenzar

  1. Accede a tu cuenta de Google Cloud. Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
  2. En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  3. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  4. Habilita las API de Kubernetes Engine and Cloud Storage.

    Habilita las API

  5. En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  6. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  7. Habilita las API de Kubernetes Engine and Cloud Storage.

    Habilita las API

  8. En la consola de Google Cloud, activa Cloud Shell.

    Activar Cloud Shell

    En la parte inferior de la consola de Google Cloud, se inicia una sesión de Cloud Shell en la que se muestra una ventana de línea de comandos. Cloud Shell es un entorno de shell con Google Cloud CLI ya instalada y con valores ya establecidos para el proyecto actual. La sesión puede tardar unos segundos en inicializarse.

Clone 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 de 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
    

Crea un bucket de Cloud Storage

  1. En la consola de Google Cloud, ve a la página Crea 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 Elige 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, selecciona Uniforme en Control de acceso.

  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 de 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 de 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 de Google Cloud

En Cloud Shell, ejecute los siguientes comandos:

  1. Agrega una vinculación de IAM a la cuenta de servicio de 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 de 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 en el 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
    gsutil cp sample-file gs://PROJECT_ID-gke-gpu-bucket
    
  4. Espera a que tu 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 adjunta al Pod:

    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 predice 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:

    gsutil -m cp -R src/tensorflow-mnist-example gs://PROJECT_ID-gke-gpu-bucket/
    
  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 en el 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
    

    El resultado muestra los siguientes eventos:

    • Instala los paquetes de Python obligatorios
    • Descarga el conjunto de datos MNIST
    • Entrena el modelo mediante 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 toma un conjunto de datos de muestra como entrada y muestra predicciones.

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

    gsutil -m cp -R data/mnist_predict gs://PROJECT_ID-gke-gpu-bucket/
    
  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 en el 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 generen cargos en tu cuenta de Google Cloud por los recursos que creaste en esta guía, lleva a cabo 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 de Google Cloud: Borra el clúster de GKE y los recursos de 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 de 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 de 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. En la consola de Google Cloud, ve a la página Administrar recursos.

    Ir a Administrar recursos

  2. En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
  3. En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.

¿Qué sigue?