Del prototipo a la producción: Entrenamiento de modelos personalizados con Vertex AI

1. Descripción general

En este lab, usarás Vertex AI para ejecutar un trabajo de entrenamiento personalizado.

Este lab forma parte de la serie de videos Del prototipo a la producción. Compilarás un modelo de clasificación de imágenes mediante el conjunto de datos de flores. Puedes mirar el video complementario para obtener más información:

.

Qué aprenderás

Aprenderás a hacer lo siguiente:

  • Crear un notebook administrado de Vertex AI Workbench
  • Configurar y, luego, iniciar un trabajo de entrenamiento personalizado desde la IU de Vertex AI
  • Configurar y, luego, iniciar un trabajo de entrenamiento personalizado con el SDK de Vertex AI para Python

El costo total de la ejecución de este lab en Google Cloud es de aproximadamente $1.

2. Introducción a Vertex AI

En este lab, se utiliza la oferta de productos de IA más reciente de Google Cloud. Vertex AI integra las ofertas de AA de Google Cloud en una experiencia de desarrollo fluida. Anteriormente, se podía acceder a los modelos personalizados y a los entrenados con AutoML mediante servicios independientes. La nueva oferta combina ambos en una sola API, junto con otros productos nuevos. También puedes migrar proyectos existentes a Vertex AI.

Vertex AI incluye muchos productos distintos para respaldar flujos de trabajo de AA de extremo a extremo. Este lab se enfocará en los productos que se destacan a continuación: Training y Workbench

Descripción general del producto Vertex

3. Configura tu entorno

Para ejecutar este codelab, necesitarás un proyecto de Google Cloud Platform que tenga habilitada la facturación. Para crear un proyecto, sigue estas instrucciones.

Paso 1: Habilita la API de Compute Engine

Ve a Compute Engine y selecciona Habilitar (si aún no está habilitada).

Paso 2: Habilita la API de Artifact Registry

Ve a Artifact Registry y selecciona Habilitar si aún no está habilitada. La usarás para crear un contenedor para tu trabajo de entrenamiento personalizado.

Paso 3: Habilita la API de Vertex AI

Navega hasta la sección Vertex AI en Cloud Console y haz clic en Habilitar API de Vertex AI (Enable Vertex AI API).

Panel de Vertex AI

Paso 4: Crea una instancia de Vertex AI Workbench

En la sección Vertex AI de Cloud Console, haz clic en Workbench:

Menú Vertex AI

Habilita la API de Notebooks si aún no está habilitada.

Notebook_api

Una vez habilitada, haz clic en NOTEBOOKS ADMINISTRADOS (MANAGED NOTEBOOKS):

Notebooks_UI

Luego, selecciona NUEVO NOTEBOOK (NEW NOTEBOOK).

new_notebook

Asígnale un nombre al notebook y en Permiso (Permission), selecciona Cuenta de servicio (Service account).

create_notebook

Selecciona Configuración avanzada.

En Seguridad (Security), selecciona la opción “Habilitar terminal” (Enable terminal) si aún no está habilitada.

enable_terminal

Puedes dejar el resto de la configuración avanzada tal como está.

Luego, haz clic en Crear. La instancia tardará algunos minutos en aprovisionarse.

Una vez que se cree la instancia, selecciona ABRIR JUPYTERLAB (OPEN JUPYTERLAB).

open_jupyterlab

4. Aloja en un contenedor el código de la aplicación de entrenamiento

Para enviar este trabajo de entrenamiento a Vertex AI, deberás colocar el código de la aplicación de entrenamiento en un contenedor de Docker y enviar el contenedor a Google Artifact Registry. Mediante este enfoque, puedes entrenar un modelo compilado con cualquier framework.

Para comenzar, en el menú Selector (Launcher), abre una ventana de terminal en tu instancia de notebook:

Abrir terminal en el notebook

Paso 1 Crea un bucket de Cloud Storage

En este trabajo de entrenamiento, exportarás el modelo de TensorFlow entrenado a un bucket de Cloud Storage. También almacenarás los datos de entrenamiento en este tipo de bucket.

Desde tu terminal, ejecuta lo siguiente para definir una variable de entorno para tu proyecto y asegúrate de reemplazar your-cloud-project con el ID de tu proyecto:

PROJECT_ID='your-cloud-project'

Luego, ejecuta el siguiente comando en tu terminal para crear un bucket nuevo en el proyecto.

BUCKET="gs://${PROJECT_ID}-bucket"
gsutil mb -l us-central1 $BUCKET

Paso 2: Copia los datos en el bucket de Cloud Storage

Necesitamos transferir el conjunto de datos de flores a Cloud Storage. Para la demostración, primero tendrás que descargar el conjunto de datos en esta instancia de Workbench y, luego, copiarlo en un bucket.

Descarga y descomprime los datos.

wget https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz
tar xvzf flower_photos.tgz

Luego, cópialos en el bucket que acabas de crear. Agregamos -r para copiar todo el directorio y -m para realizar una copia de multiprocesamiento que acelerará la operación.

gsutil -m cp -r flower_photos $BUCKET

Paso 3: Escribe el código de entrenamiento

Crea un directorio nuevo llamado flowers y ábrelo con el comando cd:

mkdir flowers
cd flowers

Ejecuta el siguiente comando para crear un directorio para el código de entrenamiento y un archivo de Python en el que agregarás el código.

mkdir trainer
touch trainer/task.py

Ahora, deberías tener lo siguiente en el directorio flowers/:

+ trainer/
    + task.py

Para obtener más información sobre cómo estructurar el código de la aplicación de entrenamiento, consulta la documentación.

A continuación, abre el archivo task.py que acabas de crear y copia el código que aparece más abajo.

Deberás reemplazar {your-gcs-bucket} por el nombre del bucket de Cloud Storage que acabas de crear.

Mediante la herramienta Cloud Storage FUSE, los trabajos de entrenamiento en Vertex AI Training pueden acceder a los datos en Cloud Storage como archivos del sistema de archivos local. Cuando inicias un trabajo de entrenamiento personalizado, este identifica un directorio /gcs que contiene todos tus buckets de Cloud Storage como subdirectorios. Es por eso que las rutas de acceso de los datos del código de entrenamiento comienzan con /gcs.

import tensorflow as tf
import numpy as np
import os

## Replace {your-gcs-bucket} !!
BUCKET_ROOT='/gcs/{your-gcs-bucket}'

# Define variables
NUM_CLASSES = 5
EPOCHS=10
BATCH_SIZE = 32

IMG_HEIGHT = 180
IMG_WIDTH = 180

DATA_DIR = f'{BUCKET_ROOT}/flower_photos'

def create_datasets(data_dir, batch_size):
  '''Creates train and validation datasets.'''

  train_dataset = tf.keras.utils.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="training",
    seed=123,
    image_size=(IMG_HEIGHT, IMG_WIDTH),
    batch_size=batch_size)

  validation_dataset = tf.keras.utils.image_dataset_from_directory(
    data_dir,
    validation_split=0.2,
    subset="validation",
    seed=123,
    image_size=(IMG_HEIGHT, IMG_WIDTH),
    batch_size=batch_size)

  train_dataset = train_dataset.cache().shuffle(1000).prefetch(buffer_size=tf.data.AUTOTUNE)
  validation_dataset = validation_dataset.cache().prefetch(buffer_size=tf.data.AUTOTUNE)

  return train_dataset, validation_dataset

def create_model():
  '''Creates model.'''

  model = tf.keras.Sequential([
    tf.keras.layers.Resizing(IMG_HEIGHT, IMG_WIDTH),
    tf.keras.layers.Rescaling(1./255, input_shape=(IMG_HEIGHT, IMG_WIDTH, 3)),
    tf.keras.layers.Conv2D(16, 3, padding='same', activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(32, 3, padding='same', activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(64, 3, padding='same', activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(NUM_CLASSES, activation='softmax')
  ])
  return model

# CREATE DATASETS
train_dataset, validation_dataset = create_datasets(DATA_DIR, BATCH_SIZE)

# CREATE/COMPILE MODEL
model = create_model()
model.compile(optimizer=tf.keras.optimizers.Adam(),
              loss=tf.keras.losses.SparseCategoricalCrossentropy(),
              metrics=['accuracy'])

# TRAIN MODEL
history = model.fit(
  train_dataset,
  validation_data=validation_dataset,
  epochs=EPOCHS
)

# SAVE MODEL
model.save(f'{BUCKET_ROOT}/model_output')

Paso 4: Crea un Dockerfile

Para alojar tu código en contenedores, deberás crear un Dockerfile. En él, incluirás todos los comandos necesarios para ejecutar la imagen. Se instalarán todas las bibliotecas necesarias y se configurará el punto de entrada para el código de entrenamiento.

En la terminal, crea un Dockerfile vacío en la raíz del directorio de flores.

touch Dockerfile

Ahora, deberías tener lo siguiente en el directorio flowers/:

+ Dockerfile
+ trainer/
    + task.py

Abre el Dockerfile y copia lo siguiente:

FROM gcr.io/deeplearning-platform-release/tf2-gpu.2-8

WORKDIR /

# Copies the trainer code to the docker image.
COPY trainer /trainer

# Sets up the entry point to invoke the trainer.
ENTRYPOINT ["python", "-m", "trainer.task"]

Revisemos los comandos de este archivo.

El comando FROM especifica la imagen base (principal) de la imagen que crearás. Como imagen base, usarás la imagen de Docker de GPU de TensorFlow Enterprise 2.8 de los contenedores de aprendizaje profundo. Los contenedores de aprendizaje profundo en Google Cloud tienen preinstalados muchos frameworks comunes de AA y ciencia de datos.

El comando WORKDIR especifica el directorio en la imagen en la que se ejecutan las instrucciones posteriores.

El comando COPY copia el código de entrenador en la imagen de Docker. Ten en cuenta que en este ejemplo solo tenemos un archivo de Python en el directorio del entrenador, pero, en un ejemplo más realista, probablemente habría archivos adicionales, quizás uno llamado data.py, que controla los datos en procesamiento previo, y uno llamado model.py, que solo tiene el código del modelo, etc. Para obtener un código de entrenamiento más complejo, consulta la documentación de Python sobre el empaquetado de proyectos de Python.

Si quisieras agregar bibliotecas adicionales, podrías usar el comando RUN para instalarlas mediante pip (p. ej.: RUN pip install -r requirements.txt). Sin embargo, no necesitamos elementos adicionales para este ejemplo.

Por último, el comando ENTRYPOINT configura el punto de entrada para invocar al entrenador. Esto es lo que se ejecutará cuando iniciemos el trabajo de entrenamiento. En nuestro caso, es el archivo task.py.

Puedes obtener más información para escribir Dockerfiles para Vertex AI Training aquí.

Paso 4: Compila el contenedor

En la terminal de tu notebook de Workbench, ejecuta lo siguiente con el fin de definir una variable de entorno para tu proyecto y asegúrate de reemplazar your-cloud-project por el ID del proyecto.

PROJECT_ID='your-cloud-project'

Crea un repositorio en Artifact Registry.

REPO_NAME='flower-app'

gcloud artifacts repositories create $REPO_NAME --repository-format=docker \
--location=us-central1 --description="Docker repository"

Define una variable con el URI de la imagen de contenedor en Google Artifact Registry:

IMAGE_URI=us-central1-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/flower_image:latest

Configura el Docker.

gcloud auth configure-docker \
    us-central1-docker.pkg.dev

Luego, ejecuta el siguiente comando para compilar el contenedor desde la raíz de tu directorio flower:

docker build ./ -t $IMAGE_URI

Por último, envíalo a Artifact Registry:

docker push $IMAGE_URI

Ahora que ya enviaste el contenedor a Artifact Registry, puedes iniciar el trabajo de entrenamiento.

5. Ejecuta un trabajo de entrenamiento personalizado en Vertex AI

En este lab, se usa un entrenamiento personalizado mediante un contenedor personalizado en Google Artifact Registry, pero también puedes ejecutar un trabajo de entrenamiento con los contenedores creados previamente.

Para comenzar, ve a Entrenamiento (Training) de la sección de Vertex de la consola de Cloud.

menú de entrenamiento

Paso 1: Configura el trabajo de entrenamiento

Haz clic en Crear (Create) para ingresar los parámetros del trabajo de entrenamiento.

create_training

  • En Conjunto de datos, selecciona No hay ningún conjunto de datos administrado.
  • Selecciona Entrenamiento personalizado (avanzado) como método de entrenamiento y haz clic en Continuar.
  • Selecciona Entrenar un modelo nuevo y, luego, ingresa flowers-model (o el nombre que quieras asignarle a tu modelo) en Nombre del modelo.
  • Haz clic en Continuar.

En el paso Configuración del contenedor, selecciona Contenedor personalizado (Custom container):

Opción de contenedor personalizado

En la primera casilla (Imagen de contenedor), ingresa el valor de la variable IMAGE_URI de la sección anterior. Debería ser us-central1-docker.pkg.dev/{PROJECT_ID}/flower-app/flower_image:latest, con el ID de tu proyecto. Deja el resto de los campos en blanco y haz clic en Continuar.

Omite el paso Hiperparámetros haciendo clic en Continuar otra vez.

Paso 2: Configura el clúster de procesamiento

Configura el Grupo de trabajadores 0 (Worker pool 0) de la siguiente manera:

worker_pool_0

Por ahora, omitirás el paso 6 y configurarás el contenedor de predicciones en el siguiente lab de esta serie.

Haz clic en COMENZAR EL ENTRENAMIENTO para iniciar el trabajo de entrenamiento. En la sección Entrenamiento (Training) de la consola, en la pestaña CANALIZACIONES DE ENTRENAMIENTO (TRAINING PIPELINES), verás el trabajo iniciado recientemente:

Trabajos de entrenamiento

🎉 ¡Felicitaciones! 🎉

Aprendiste a usar Vertex AI para hacer lo siguiente:

  • Iniciar un trabajo de entrenamiento personalizado para entrenar el código de un contenedor personalizado. En este ejemplo, utilizaste un modelo de TensorFlow, pero puedes entrenar un modelo creado con cualquier framework mediante contenedores personalizados o integrados.

Para obtener más información sobre las distintas partes de Vertex, consulta la documentación.

6. Usa el SDK de Vertex AI para Python [opcional]

En la sección anterior, se mostró cómo iniciar el trabajo de entrenamiento con la IU. En esta sección, verás una forma alternativa de enviar el trabajo mediante el SDK de Vertex AI para Python.

Regresa a tu instancia de notebook y crea un notebook de TensorFlow 2 desde Selector (Launcher):

new_notebook

Importa el SDK de Vertex AI.

from google.cloud import aiplatform

Luego, crea un CustomContainerTrainingJob. Deberás reemplazar {PROJECT_ID} en container_uri por el nombre de tu proyecto y {BUCKET} en staging_bucket por el bucket que creaste anteriormente.

my_job = aiplatform.CustomContainerTrainingJob(display_name='flower-sdk-job',
                                               container_uri='us-central1-docker.pkg.dev/{PROJECT_ID}/flower-app/flower_image:latest',
                                               staging_bucket='gs://{BUCKET}')

Luego, ejecuta el trabajo.

my_job.run(replica_count=1,
           machine_type='n1-standard-8',
           accelerator_type='NVIDIA_TESLA_V100',
           accelerator_count=1)

Para la demostración, este trabajo se configuró para ejecutarse en una máquina más grande que la de la sección anterior. Además, se está ejecutando con una GPU. Si no especificas el machine-type, accelerator_type o accelerator_count, el trabajo se ejecutará de forma predeterminada en una n1-standard-4.

En la sección Entrenamiento de la consola, en la pestaña TRABAJOS PERSONALIZADOS, verás el trabajo de entrenamiento.

7. Realiza una limpieza

Debido a que los notebooks administrados de Vertex AI Workbench tienen una función de cierre por inactividad, no necesitas preocuparte por cerrar la instancia. Si quieres cerrar la instancia de forma manual, haz clic en el botón Detener (Stop) en la sección Vertex AI Workbench de la consola. Si quieres borrar el notebook por completo, haz clic en el botón Borrar (Delete).

Detener instancias

Para borrar el bucket de almacenamiento, en el menú de navegación de la consola de Cloud, navega a Almacenamiento, selecciona tu bucket y haz clic en Borrar (Delete):

Borrar almacenamiento