Crea e implementa un modelo con Vertex AI

1. Descripción general

En este lab, aprenderás a usar Vertex AI, la nueva plataforma de AA administrada anunciada por Google Cloud, para compilar flujos de trabajo de AA de extremo a extremo. Aprenderás a pasar de los datos sin procesar al modelo implementado y dejarás este taller listo para desarrollar y producir tus propios proyectos de AA con Vertex AI. En este lab, usaremos Cloud Shell para compilar una imagen personalizada de Docker que demuestre contenedores personalizados para el entrenamiento con Vertex AI.

Si bien aquí estamos usando TensorFlow para el código del modelo, puedes reemplazarlo fácilmente por otro framework.

Qué aprenderá

Aprenderás a hacer lo siguiente:

  • Compilar código de entrenamiento de modelos y alojarlo en contenedores con Cloud Shell
  • Enviar un trabajo de entrenamiento de modelo personalizado a Vertex AI
  • Implementar el modelo entrenado en un extremo y usar ese extremo para obtener predicciones

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

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. Para enviarnos comentarios, visita la página de asistencia.

Vertex incluye muchas herramientas diferentes para ayudarte con cada etapa del flujo de trabajo del AA, como puedes ver en el siguiente diagrama. Nos enfocaremos en el uso de Entrenamiento y Predicción de Vertex, que se destacan a continuación.

Servicios de Vertex

3. Cómo configurar tu entorno

Configuración del entorno de autoaprendizaje

Accede a la consola de Cloud y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.

Recuerde el ID de proyecto, un nombre único en todos los proyectos de Google Cloud (el nombre anterior ya se encuentra en uso y no lo podrá usar).

A continuación, deberás habilitar la facturación en la consola de Cloud para usar los recursos de Google Cloud recursos.

Ejecutar este codelab no debería costar mucho, tal vez nada. Asegúrate de seguir las instrucciones de la sección “Realiza una limpieza” en la que se aconseja cómo cerrar recursos para no incurrir en facturación más allá de este instructivo. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de$300.

Paso 1: Inicia Cloud Shell

En este lab, trabajarás con una sesión de Cloud Shell, que es un intérprete de comandos alojado en una máquina virtual que se ejecuta en la nube de Google. Podrías ejecutar fácilmente esta sección de forma local, en tu computadora, pero Cloud Shell brinda una experiencia reproducible en un entorno coherente para todo el mundo. Después de este lab, puedes volver a probar esta sección en tu computadora.

Autoriza Cloud Shell

Activar Cloud Shell

En la parte superior derecha de la consola de Cloud, haz clic en el siguiente botón para activar Cloud Shell:

Activar Cloud Shell

Si nunca iniciaste Cloud Shell, aparecerá una pantalla intermedia (mitad inferior de la página) que describe en qué consiste. Si ese es el caso, haz clic en Continuar (y no volverás a verlo). Así es como se ve la pantalla única:

Configuración de Cloud Shell

El aprovisionamiento y la conexión a Cloud Shell solo tomará unos minutos.

Inicial de Cloud Shell

Esta máquina virtual está cargada con todas las herramientas de desarrollo que necesitas. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que permite mejorar considerablemente el rendimiento de la red y la autenticación. Gran parte de tu trabajo en este codelab, si no todo, se puede hacer simplemente con un navegador o tu Chromebook.

Una vez conectado a Cloud Shell, debería ver que ya se autenticó y que el proyecto ya se configuró con tu ID del proyecto.

En Cloud Shell, ejecuta el siguiente comando para confirmar que está autenticado:

gcloud auth list

Resultado del comando

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`

Ejecuta el siguiente comando en Cloud Shell para confirmar que el comando de gcloud conoce tu proyecto:

gcloud config list project

Resultado del comando

[core]
project = <PROJECT_ID>

De lo contrario, puedes configurarlo con el siguiente comando:

gcloud config set project <PROJECT_ID>

Resultado del comando

Updated property [core/project].

Cloud Shell cuenta con algunas variables de entorno, incluida GOOGLE_CLOUD_PROJECT, que contiene el nombre de nuestro proyecto de Cloud actual. Lo usaremos en varios lugares a lo largo de este lab. Puede ejecutar el siguiente código para verla:

echo $GOOGLE_CLOUD_PROJECT

Paso 2: Habilitar las API

Más adelante, verás en qué momento se necesitan estos servicios y por qué. Por ahora, ejecuta este comando para que tu proyecto pueda acceder a los servicios de Compute Engine, Container Registry y Vertex AI:

gcloud services enable compute.googleapis.com         \
                       containerregistry.googleapis.com  \
                       aiplatform.googleapis.com

Si se realizó correctamente, se mostrará un mensaje similar a este:

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

Paso 3: Crea un bucket de Cloud Storage

Para ejecutar un trabajo de entrenamiento en Vertex AI, necesitaremos un bucket de almacenamiento para almacenar los elementos del modelo guardados. Ejecuta los siguientes comandos en la terminal de Cloud Shell para crear un bucket:

BUCKET_NAME=gs://$GOOGLE_CLOUD_PROJECT-bucket
gsutil mb -l us-central1 $BUCKET_NAME

Paso 4: Alias de Python 3

En el código de este lab, se usa Python 3. Para asegurarte de usar Python 3 cuando ejecutes las secuencias de comandos que crearás en este lab, ejecuta el siguiente comando en Cloud Shell para crear un alias:

alias python=python3

El modelo que entrenaremos y entregaremos en este lab se basa en este instructivo de la documentación de TensorFlow. En este instructivo, se usa el conjunto de datos Auto MPG de Kaggle para predecir el ahorro de combustible de un vehículo.

4. Aloja el código de entrenamiento en contenedores

Para enviar este trabajo de entrenamiento a Vertex, pondremos el código de entrenamiento en un contenedor de Docker y lo enviaremos a Google Container Registry. Con este enfoque, podemos entrenar un modelo compilado con cualquier framework.

Paso 1: Configura los archivos

Para comenzar, en la terminal de Cloud Shell, ejecuta los siguientes comandos para crear los archivos que necesitaremos para nuestro contenedor de Docker:

mkdir mpg
cd mpg
touch Dockerfile
mkdir trainer
touch trainer/train.py

Ahora, deberías tener un directorio mpg/ similar al siguiente:

+ Dockerfile
+ trainer/
    + train.py

Para ver y editar estos archivos, usaremos el editor de código integrado de Cloud Shell. Puedes alternar entre el editor y la terminal haciendo clic en el botón de la barra de menú superior derecha en Cloud Shell:

Cambiar al editor en Cloud Shell

Paso 2: Crea un Dockerfile

Para alojar el código en contenedores, primero, crearemos un Dockerfile. En nuestro Dockerfile, incluiremos todos los comandos necesarios para ejecutar la imagen. Así, se instalarán todas las bibliotecas que utilicemos y se configurará el punto de entrada para el código de entrenamiento.

Desde el editor de archivos de Cloud Shell, abre tu directorio mpg/ y haz doble clic para abrir el Dockerfile:

Abre Dockerfile

Luego, copia lo siguiente en este archivo:

FROM gcr.io/deeplearning-platform-release/tf2-cpu.2-3
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.train"]

Este Dockerfile usa la imagen de Docker con TensorFlow Enterprise 2.3 para contenedores de aprendizaje profundo. Los contenedores de aprendizaje profundo en Google Cloud tienen preinstalados muchos frameworks comunes de AA y ciencia de datos. El que estamos usando incluye TF Enterprise 2.3, Pandas, scikit-learn y más. Después de descargar esa imagen, este Dockerfile configura el punto de entrada para el código de entrenamiento, que agregaremos en el siguiente paso.

Paso 3: Agrega el código de entrenamiento de modelos

En el editor de Cloud Shell, abre el archivo train.py y copia el código que aparece a continuación (se trata de una adaptación del instructivo en la documentación de TensorFlow).

# This will be replaced with your bucket name after running the `sed` command in the tutorial
BUCKET = "BUCKET_NAME"

import numpy as np
import pandas as pd
import pathlib
import tensorflow as tf

from tensorflow import keras
from tensorflow.keras import layers

print(tf.__version__)

"""## The Auto MPG dataset

The dataset is available from the [UCI Machine Learning Repository](https://archive.ics.uci.edu/ml/).

### Get the data
First download the dataset.
"""

"""Import it using pandas"""

dataset_path = "https://storage.googleapis.com/io-vertex-codelab/auto-mpg.csv"
dataset = pd.read_csv(dataset_path, na_values = "?")

dataset.tail()

"""### Clean the data

The dataset contains a few unknown values.
"""

dataset.isna().sum()

"""To keep this initial tutorial simple drop those rows."""

dataset = dataset.dropna()

"""The `"origin"` column is really categorical, not numeric. So convert that to a one-hot:"""

dataset['origin'] = dataset['origin'].map({1: 'USA', 2: 'Europe', 3: 'Japan'})

dataset = pd.get_dummies(dataset, prefix='', prefix_sep='')
dataset.tail()

"""### Split the data into train and test

Now split the dataset into a training set and a test set.

We will use the test set in the final evaluation of our model.
"""

train_dataset = dataset.sample(frac=0.8,random_state=0)
test_dataset = dataset.drop(train_dataset.index)

"""### Inspect the data

Have a quick look at the joint distribution of a few pairs of columns from the training set.

Also look at the overall statistics:
"""

train_stats = train_dataset.describe()
train_stats.pop("mpg")
train_stats = train_stats.transpose()
train_stats

"""### Split features from labels

Separate the target value, or "label", from the features. This label is the value that you will train the model to predict.
"""

train_labels = train_dataset.pop('mpg')
test_labels = test_dataset.pop('mpg')

"""### Normalize the data

Look again at the `train_stats` block above and note how different the ranges of each feature are.

It is good practice to normalize features that use different scales and ranges. Although the model *might* converge without feature normalization, it makes training more difficult, and it makes the resulting model dependent on the choice of units used in the input.

Note: Although we intentionally generate these statistics from only the training dataset, these statistics will also be used to normalize the test dataset. We need to do that to project the test dataset into the same distribution that the model has been trained on.
"""

def norm(x):
  return (x - train_stats['mean']) / train_stats['std']
normed_train_data = norm(train_dataset)
normed_test_data = norm(test_dataset)

"""This normalized data is what we will use to train the model.

Caution: The statistics used to normalize the inputs here (mean and standard deviation) need to be applied to any other data that is fed to the model, along with the one-hot encoding that we did earlier.  That includes the test set as well as live data when the model is used in production.

## The model

### Build the model

Let's build our model. Here, we'll use a `Sequential` model with two densely connected hidden layers, and an output layer that returns a single, continuous value. The model building steps are wrapped in a function, `build_model`, since we'll create a second model, later on.
"""

def build_model():
  model = keras.Sequential([
    layers.Dense(64, activation='relu', input_shape=[len(train_dataset.keys())]),
    layers.Dense(64, activation='relu'),
    layers.Dense(1)
  ])

  optimizer = tf.keras.optimizers.RMSprop(0.001)

  model.compile(loss='mse',
                optimizer=optimizer,
                metrics=['mae', 'mse'])
  return model

model = build_model()

"""### Inspect the model

Use the `.summary` method to print a simple description of the model
"""

model.summary()

"""Now try out the model. Take a batch of `10` examples from the training data and call `model.predict` on it.

It seems to be working, and it produces a result of the expected shape and type.

### Train the model

Train the model for 1000 epochs, and record the training and validation accuracy in the `history` object.

Visualize the model's training progress using the stats stored in the `history` object.

This graph shows little improvement, or even degradation in the validation error after about 100 epochs. Let's update the `model.fit` call to automatically stop training when the validation score doesn't improve. We'll use an *EarlyStopping callback* that tests a training condition for  every epoch. If a set amount of epochs elapses without showing improvement, then automatically stop the training.

You can learn more about this callback [here](https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/EarlyStopping).
"""

model = build_model()

EPOCHS = 1000

# The patience parameter is the amount of epochs to check for improvement
early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)

early_history = model.fit(normed_train_data, train_labels, 
                    epochs=EPOCHS, validation_split = 0.2, 
                    callbacks=[early_stop])


# Export model and save to GCS
model.save(BUCKET + '/mpg/model')

Una vez que hayas copiado el código anterior en el archivo mpg/trainer/train.py, regresa a la terminal en Cloud Shell y ejecuta el siguiente comando para agregar tu propio nombre de bucket al archivo:

sed -i "s|BUCKET_NAME|$BUCKET_NAME|g" trainer/train.py

Paso 4: Compila y prueba el contenedor de forma local

En la terminal, ejecuta el siguiente comando para definir una variable con el URI de la imagen de contenedor en Google Container Registry:

IMAGE_URI="gcr.io/$GOOGLE_CLOUD_PROJECT/mpg:v1"

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

docker build ./ -t $IMAGE_URI

Una vez que hayas compilado el contenedor, envíalo a Google Container Registry:

docker push $IMAGE_URI

Para verificar que la imagen se envió a Container Registry, deberías ver algo como esto cuando navegues a la sección de Container Registry de tu consola:

Vista previa de Container Registry

Ahora que ya enviamos el contenedor a Container Registry, podemos iniciar el trabajo de entrenamiento de un modelo personalizado.

5. Ejecuta un trabajo de entrenamiento en Vertex AI

Vertex te ofrece dos opciones para entrenar modelos:

  • AutoML: Entrena modelos de alta calidad con poco esfuerzo y experiencia en AA.
  • Entrenamiento personalizado: Ejecuta aplicaciones de entrenamiento personalizado en la nube con uno de los contenedores compilados previamente de Google Cloud o usa uno propio.

En este lab, usaremos un entrenamiento personalizado a través de nuestro propio contenedor personalizado en Google Container Registry. Para comenzar, ve a Entrenamiento (Training) de la sección de Vertex de la consola de Cloud.

Menú de la barra lateral de Vertex: Entrenamiento

Paso 1: Inicia el trabajo de entrenamiento

Haz clic en Crear para ingresar los parámetros del trabajo de entrenamiento y el modelo implementado:

  • 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.
  • Ingresa mpg (o el nombre que quieras asignarle a tu modelo) en Nombre del modelo.
  • Haga clic en Continue.

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

Opción de contenedor personalizado

En la primera casilla (Imagen de contenedor), haz clic en Explorar y busca el contenedor que acabas de enviar a Container Registry. Debería verse algo similar a esto:

Buscar contenedor

Deja el resto de los campos en blanco y haz clic en Continuar.

No usaremos el ajuste de hiperparámetros en este instructivo, así que deja sin marcar la casilla Habilitar el ajuste de hiperparámetros y haz clic en Continuar.

En Procesamiento y precios, no cambies la región seleccionada y selecciona n1-standard-4 como tu tipo de máquina:

Tipo de máquina

Debido a que el modelo que usamos en esta demostración se entrena rápidamente, usaremos un tipo de máquina más pequeño.

En el paso Contenedor de predicción, selecciona Sin contenedor de predicción:

No hay un contenedor de predicciones

6. Implementa un extremo del modelo

En este paso, crearemos un extremo para nuestro modelo entrenado. Podemos usarlo para obtener predicciones en nuestro modelo mediante la API de Vertex AI. Para ello, creamos una versión de los recursos del modelo entrenado que se exportó a disposición en un bucket público de GCS.

En una organización, es común tener un equipo o persona a cargo de crear el modelo y otro equipo a cargo de implementarlo. En los pasos que abordaremos, se te mostrará cómo tomar un modelo que ya fue entrenado e implementarlo para la predicción.

Aquí usaremos el SDK de Vertex AI para crear un modelo, implementarlo en un extremo y obtener una predicción.

Paso 1: Instala el SDK de Vertex

En la terminal de Cloud Shell, ejecuta lo siguiente para instalar el SDK de Vertex AI:

pip3 install google-cloud-aiplatform --upgrade --user

Podemos usar este SDK para interactuar con muchas partes diferentes de Vertex.

Paso 2: Crea el modelo y, luego, implementa el extremo

A continuación, crearemos un archivo de Python y usaremos el SDK para crear un recurso del modelo y, luego, implementarlo en un extremo. En el editor de archivos de Cloud Shell, selecciona File y, luego, New File:

Archivo nuevo en Cloud Shell

Asígnale el nombre deploy.py al archivo. Abre este archivo en el editor y copia el siguiente código:

from google.cloud import aiplatform

# Create a model resource from public model assets
model = aiplatform.Model.upload(
    display_name="mpg-imported",
    artifact_uri="gs://io-vertex-codelab/mpg-model/",
    serving_container_image_uri="gcr.io/cloud-aiplatform/prediction/tf2-cpu.2-3:latest"
)

# Deploy the above model to an endpoint
endpoint = model.deploy(
    machine_type="n1-standard-4"
)

A continuación, vuelve a la terminal en Cloud Shell, cd vuelve a tu directorio raíz y ejecuta esta secuencia de comandos de Python que acabas de crear:

cd ..
python3 deploy.py | tee deploy-output.txt

Verás actualizaciones registradas en tu terminal a medida que se crean los recursos. Este proceso tardará entre 10 y 15 minutos en ejecutarse. Para asegurarte de que funcione correctamente, navega a la sección Modelos de la consola en Vertex AI:

Modelo en la consola de Vertex

Haz clic en mgp-imported para ver el extremo para la creación de ese modelo:

Extremo pendiente

En la terminal de Cloud Shell, verás algo como el siguiente registro cuando se complete la implementación de tu extremo:

Endpoint model deployed. Resource name: projects/your-project-id/locations/us-central1/endpoints/your-endpoint-id

La usarás en el siguiente paso para obtener una predicción del extremo implementado.

Paso 3: Obtén predicciones en el extremo implementado

En el editor de Cloud Shell, crea un archivo nuevo llamado predict.py:

Crear archivo de predicción

Abre predict.py y pega en él el siguiente código:

from google.cloud import aiplatform

endpoint = aiplatform.Endpoint(
    endpoint_name="ENDPOINT_STRING"
)

# A test example we'll send to our model for prediction
test_mpg = [1.4838871833555929,
 1.8659883497083019,
 2.234620276849616,
 1.0187816540094903,
 -2.530890710602246,
 -1.6046416850441676,
 -0.4651483719733302,
 -0.4952254087173721,
 0.7746763768735953]

response = endpoint.predict([test_mpg])

print('API response: ', response)

print('Predicted MPG: ', response.predictions[0][0])

Luego, regresa a tu terminal y escribe lo siguiente para reemplazar ENDPOINT_STRING en el archivo de predicción por tu propio extremo:

ENDPOINT=$(cat deploy-output.txt | sed -nre 's:.*Resource name\: (.*):\1:p' | tail -1)
sed -i "s|ENDPOINT_STRING|$ENDPOINT|g" predict.py

Ahora, es momento de ejecutar el archivo predict.py para obtener una predicción desde el extremo del modelo implementado:

python3 predict.py

Deberías ver registrada la respuesta de la API, junto con la predicción del ahorro de combustible para nuestra predicción de prueba.

🎉 ¡Felicitaciones! 🎉

Aprendiste a usar Vertex AI para hacer lo siguiente:

  • Entrenar un modelo suministrando el código de entrenamiento en un contenedor personalizado (en este ejemplo, usaste un modelo de TensorFlow, pero puedes entrenar un modelo creado con cualquier framework a través de contenedores personalizados)
  • Implementar un modelo de TensorFlow con un contenedor previamente compilado como parte del mismo flujo de trabajo que usaste para el entrenamiento
  • Crear un extremo del modelo y generar una predicción

Si quieres obtener más información sobre los diferentes componentes de Vertex AI, consulta la documentación. Si deseas ver los resultados del trabajo de entrenamiento que iniciaste en el paso 5, navega a la sección de entrenamiento de la consola de Vertex.

7. Limpieza

Para borrar el extremo que implementaste, navega a la sección Extremos de la consola de Vertex y haz clic en el ícono de borrar:

Borrar extremo

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