1. Présentation
Dans cet atelier, vous allez utiliser la fonctionnalité de modèle de co-hébergement de Vertex AI pour héberger plusieurs modèles sur la même VM afin d'obtenir des prédictions en ligne.
Objectifs
Vous allez apprendre à effectuer les opérations suivantes :
- Créer un élément
DeploymentResourcePool
- Déployer des modèles dans un
DeploymentResourcePool
Le coût total d'exécution de cet atelier sur Google Cloud est d'environ 2 $.
2. Présentation de Vertex AI
Cet atelier utilise la toute dernière offre de produits d'IA de Google Cloud. Vertex AI simplifie l'expérience de développement en intégrant toutes les offres de ML de Google Cloud. Auparavant, les modèles entraînés avec AutoML et les modèles personnalisés étaient accessibles depuis des services distincts. La nouvelle offre regroupe ces deux types de modèles mais aussi d'autres nouveaux produits en une seule API. Vous pouvez également migrer des projets existants vers Vertex AI. Pour envoyer un commentaire, consultez la page d'assistance.
Vertex AI comprend de nombreux produits différents qui permettent de gérer les workflows de ML de bout en bout. Cet atelier se concentre sur les produits mis en évidence ci-dessous : Predictions et Workbench.
3. Présentation du cas d'utilisation
Lorsque vous déployez des modèles dans le service de prédiction Vertex AI, chaque modèle est déployé par défaut sur sa propre VM. Pour rendre l'hébergement plus rentable, vous pouvez héberger plusieurs modèles sur la même VM, ce qui permet d'utiliser plus efficacement la mémoire et les ressources de calcul. Le nombre de modèles que vous choisissez de déployer sur la même VM dépend de la taille des modèles et des modèles de trafic, mais cette fonctionnalité est particulièrement utile dans les scénarios où vous avez de nombreux modèles déployés avec un trafic clairsemé.
La gestion du co-hébergement de modèles introduit le concept de pool de ressources de déploiement, qui regroupe les modèles pour partager des ressources au sein d'une VM. Les modèles peuvent partager une VM s'ils partagent un point de terminaison, mais aussi s'ils sont déployés sur différents points de terminaison. Actuellement, les modèles du même pool de ressources doivent avoir la même image de conteneur, y compris la version de framework des conteneurs prédéfinis Vertex Prediction. De plus, seuls les conteneurs prédéfinis Vertex Prediction avec le framework de modèle TensorFlow sont compatibles avec cette version. Les autres frameworks de modèles et les conteneurs personnalisés ne sont pas encore acceptés.
4. Configurer votre environnement
Pour suivre cet atelier de programmation, vous aurez besoin d'un projet Google Cloud Platform dans lequel la facturation est activée. Pour créer un projet, suivez ces instructions.
Étape 1 : Activez l'API Compute Engine
Accédez à Compute Engine et cliquez sur Activer si ce n'est pas déjà fait.
Étape 2: Activez l'API Vertex AI
Accédez à la section Vertex AI de Cloud Console, puis cliquez sur Activer l'API Vertex AI.
Étape 3: Créez une instance Vertex AI Workbench
Dans la section Vertex AI de Cloud Console, cliquez sur Workbench :
Activez l'API Notebooks si ce n'est pas déjà fait.
Une fois l'API activée, cliquez sur NOTEBOOKS GÉRÉS :
Sélectionnez ensuite NOUVEAU NOTEBOOK.
Attribuez un nom à votre notebook, puis sous Autorisation, sélectionnez Compte de service.
Sélectionnez Paramètres avancés.
Dans la section Sécurité, sélectionnez "Activer le terminal" si ce n'est pas déjà fait.
Vous pouvez conserver tous les autres paramètres avancés tels quels.
Cliquez ensuite sur Créer. Le provisionnement de l'instance prend quelques minutes.
Une fois l'instance créée, sélectionnez OUVRIR JUPYTERLAB :
5. Entraîner le modèle
Avant de pouvoir tester la fonctionnalité de co-hébergement, nous devons d'abord entraîner un modèle et stocker les artefacts de modèle enregistrés dans un bucket Cloud Storage. Nous allons utiliser l'exécuteur de notebooks Workbench pour lancer le job d'entraînement.
Étape 1 : Créez un bucket Cloud Storage
Si vous souhaitez utiliser un bucket existant dans votre projet, vous pouvez ignorer cette étape. Sinon, ouvrez une nouvelle session de terminal depuis le lanceur.
Depuis le terminal, exécutez la commande suivante afin de définir une variable d'environnement pour votre projet, en veillant à remplacer your-cloud-project
par l'ID de votre projet:
PROJECT_ID='your-cloud-project'
Ensuite, exécutez la commande suivante pour créer un bucket dans votre projet.
BUCKET="gs://${PROJECT_ID}-bucket"
gsutil mb -l us-central1 $BUCKET
Étape 2: Lancer l'exécution du notebook
Dans le lanceur de votre instance Workbench, ouvrez un nouveau notebook TensorFlow 2.
Le code ci-dessous entraîne un classificateur de sentiment binaire (positif ou négatif) sur l'ensemble de données d'avis sur les films IMDB. Collez le code dans votre notebook.
Assurez-vous de remplacer {YOUR_BUCKET}
par le bucket que vous avez créé à l'étape précédente (ou par un autre bucket de votre projet). C'est là que nous allons stocker les artefacts de modèle enregistrés, dont nous aurons besoin plus tard lorsque nous importerons le modèle dans Vertex AI Model Registry.
import numpy as np
import tensorflow_datasets as tfds
import tensorflow as tf
# REPLACE WITH YOUR BUCKET!
OUTPUT_PATH='gs://{YOUR_BUCKET}/model_output'
BUFFER_SIZE = 10000
BATCH_SIZE = 64
VOCAB_SIZE = 1000
# Load data
dataset, info = tfds.load('imdb_reviews', with_info=True,
as_supervised=True)
train_dataset, test_dataset = dataset['train'], dataset['test']
train_dataset = train_dataset.shuffle(BUFFER_SIZE).batch(BATCH_SIZE).prefetch(tf.data.AUTOTUNE)
test_dataset = test_dataset.batch(BATCH_SIZE).prefetch(tf.data.AUTOTUNE)
# Create text encoder
encoder = tf.keras.layers.TextVectorization(
max_tokens=VOCAB_SIZE)
encoder.adapt(train_dataset.map(lambda text, label: text))
# Create model
model = tf.keras.Sequential([
encoder,
tf.keras.layers.Embedding(
input_dim=len(encoder.get_vocabulary()),
output_dim=64,
# Use masking to handle the variable sequence lengths
mask_zero=True),
tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.Dense(1)
])
# Compile model
model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
optimizer=tf.keras.optimizers.Adam(1e-4),
metrics=['accuracy'])
# Fit model
history = model.fit(train_dataset, epochs=10,
validation_data=test_dataset,
validation_steps=30)
# Save model
model.save(OUTPUT_PATH)
Ensuite, sélectionnez le bouton Execute (Exécuter).
Configurez ensuite votre exécution comme suit, puis cliquez sur ENVOYER.
Dans l'onglet "Exécutions" de la console, vous pouvez suivre l'état de votre tâche d'entraînement.
6. Déployer un modèle
Étape 1: Importer le modèle
Une fois l'exécution terminée, revenez au notebook Workbench pour importer le modèle. Créez un notebook TensorFlow.
Commencez par importer le SDK Python Vertex AI.
from google.cloud import aiplatform
Importez ensuite le modèle, en remplaçant {YOUR_BUCKET}
par le bucket que vous avez spécifié dans le code d'entraînement.
# replace {YOUR_BUCKET}
model_1 = aiplatform.Model.upload(display_name='text-model-1',
artifact_uri='gs://{YOUR_BUCKET}/model_output',
serving_container_image_uri='us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-8:latest')
À des fins de démonstration, nous allons importer ce modèle deux fois, créant ainsi deux ressources de modèle différentes dans Vertex AI. Cela nous permet de tester le déploiement de plusieurs modèles sur un seul point de terminaison au sein d'un pool de ressources de déploiement. Dans un scénario réel, vous auriez deux modèles différents au lieu de créer des modèles à partir des mêmes artefacts enregistrés. Toutefois, il s'agit d'un raccourci pour ne pas avoir à lancer une autre exécution d'entraînement. Vous pouvez également choisir de déployer les deux modèles sur des points de terminaison différents au sein du même pool de ressources de déploiement.
# replace {YOUR_BUCKET}
model_2 = aiplatform.Model.upload(display_name='text-model-2',
artifact_uri='gs://{YOUR_BUCKET}/model_output',
serving_container_image_uri='us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-8:latest')
Dans Vertex AI Model Registry, vous devriez maintenant voir les deux modèles. L'état de déploiement est vide, car nous n'avons pas encore déployé les modèles.
Étape 2: Créez un point de terminaison
Créer un point de terminaison. Cette opération diffère du déploiement d'un modèle sur un point de terminaison.
endpoint = aiplatform.Endpoint.create('cohost-endpoint')
Une fois le point de terminaison créé, il s'affiche dans la console.
Étape 3: Créez le pool de ressources de déploiement
Vous pouvez créer le DeploymentResourcePool à l'aide de la commande suivante. Veillez à remplacer {YOUR_PROJECT}
par l'ID de votre projet.
# replace {YOUR_PROJECT}
PROJECT_ID={YOUR_PROJECT}
REGION="us-central1"
VERTEX_API_URL=REGION + "-aiplatform.googleapis.com"
VERTEX_PREDICTION_API_URL=REGION + "-prediction-aiplatform.googleapis.com"
MULTI_MODEL_API_VERSION="v1beta1"
# Give the pool a name
DEPLOYMENT_RESOURCE_POOL_ID="my-resource-pool"
import json
import pprint
pp = pprint.PrettyPrinter(indent=4)
CREATE_RP_PAYLOAD = {
"deployment_resource_pool":{
"dedicated_resources":{
"machine_spec":{
"machine_type":"n1-standard-4"
},
"min_replica_count":1,
"max_replica_count":2
}
},
"deployment_resource_pool_id":DEPLOYMENT_RESOURCE_POOL_ID
}
CREATE_RP_REQUEST=json.dumps(CREATE_RP_PAYLOAD)
pp.pprint("CREATE_RP_REQUEST: " + CREATE_RP_REQUEST)
!curl \
-X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://{VERTEX_API_URL}/{MULTI_MODEL_API_VERSION}/projects/{PROJECT_ID}/locations/{REGION}/deploymentResourcePools \
-d '{CREATE_RP_REQUEST}'
Vous pouvez afficher le pool en exécutant
!curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://{VERTEX_API_URL}/{MULTI_MODEL_API_VERSION}/projects/{PROJECT_ID}/locations/{REGION}/deploymentResourcePools/{DEPLOYMENT_RESOURCE_POOL_ID}
Étape 4: Déployez les modèles sur le point de terminaison
Maintenant que le pool de ressources a été créé, nous pouvons déployer les modèles dans le pool de ressources.
Tout d'abord, nous allons déployer model_1
. Veillez à remplacer MODEL_1_ID
et ENDPOINT_ID
par les ID respectifs.
MODEL_1_ID="{MODEL_1_ID}"
ENDPOINT_ID="{ENDPOINT_ID}"
La commande suivante déploie model_1
sur le point de terminaison au sein du pool de ressources.
MODEL_NAME = "projects/{project_id}/locations/{region}/models/{model_id}".format(project_id=PROJECT_ID, region=REGION, model_id=MODEL_1_ID)
SHARED_RESOURCE = "projects/{project_id}/locations/{region}/deploymentResourcePools/{deployment_resource_pool_id}".format(project_id=PROJECT_ID, region=REGION, deployment_resource_pool_id=DEPLOYMENT_RESOURCE_POOL_ID)
DEPLOY_MODEL_PAYLOAD = {
"deployedModel": {
"model": MODEL_NAME,
"shared_resources": SHARED_RESOURCE
},
"trafficSplit": {
"0": 100
}
}
DEPLOY_MODEL_REQUEST=json.dumps(DEPLOY_MODEL_PAYLOAD)
pp.pprint("DEPLOY_MODEL_REQUEST: " + DEPLOY_MODEL_REQUEST)
!curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://{VERTEX_API_URL}/{MULTI_MODEL_API_VERSION}/projects/{PROJECT_ID}/locations/{REGION}/endpoints/{ENDPOINT_ID}:deployModel \
-d '{DEPLOY_MODEL_REQUEST}'
Cette opération prend quelques minutes. Une fois terminée, le modèle est déployé sur le point de terminaison dans la console.
Nous pouvons ensuite déployer model_2
dans le même pool de déploiement. Nous allons le déployer sur le même point de terminaison que model_1
. Toutefois, vous pouvez également choisir de déployer model_2
sur un autre point de terminaison du même pool de ressources.
Mettez à jour MODEL_ID
avec l'ID de model_2
. Encore une fois, vous pouvez obtenir cet ID en exécutant model_2.name
.
MODEL_2_ID="{MODEL_2_ID}"
Déployez ensuite model_2
. Comme model_1
est déjà déployé sur le point de terminaison, nous devons mettre à jour trafficSplit
pour que le trafic soit réparti entre les deux modèles. Nous n'aurions pas besoin de mettre à jour trafficSplit
si nous choisissons de déployer model_2
sur un autre point de terminaison du même pool de ressources.
Pour mettre à jour la répartition du trafic, vous devez définir l'ID de modèle déployé pour model_1
. Notez que ce numéro diffère de l'ID du modèle.
DEPLOYED_MODEL_1_ID = {DEPLOYED_MODEL_1_ID}
Exécutez ensuite la commande suivante pour déployer le deuxième modèle.
MODEL_NAME = "projects/{project_id}/locations/{region}/models/{model_id}".format(project_id=PROJECT_ID, region=REGION, model_id=MODEL_2_ID)
SHARED_RESOURCE = "projects/{project_id}/locations/{region}/deploymentResourcePools/{deployment_resource_pool_id}".format(project_id=PROJECT_ID, region=REGION, deployment_resource_pool_id=DEPLOYMENT_RESOURCE_POOL_ID)
#`trafficSplit` is a map from a DeployedModel's ID to the percentage of this Endpoint's traffic that should be forwarded to that DeployedModel.
# The traffic percentage values for an endpoint must add up to 100.
# The key for the model being deployed is "0".
DEPLOY_MODEL_PAYLOAD = {
"deployedModel": {
"model": MODEL_NAME,
"shared_resources": SHARED_RESOURCE
},
"trafficSplit": {
"0": 50,
DEPLOYED_MODEL_1_ID: 50
}
}
DEPLOY_MODEL_REQUEST=json.dumps(DEPLOY_MODEL_PAYLOAD)
pp.pprint("DEPLOY_MODEL_REQUEST: " + DEPLOY_MODEL_REQUEST)
!curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://{VERTEX_API_URL}/{MULTI_MODEL_API_VERSION}/projects/{PROJECT_ID}/locations/{REGION}/endpoints/{ENDPOINT_ID}:deployModel \
-d '{DEPLOY_MODEL_REQUEST}'
Là encore, dans cet exemple, les deux modèles ont été déployés sur le même point de terminaison, mais vous pouvez également cohéberger des modèles sur le même pool de ressources qui sont déployés sur des points de terminaison différents. Dans ce cas, vous n'aurez pas à vous soucier de la répartition du trafic.
Une fois le second modèle déployé, les deux modèles s'afficheront dans la console.
Étape 5: Obtenez des prédictions
La dernière étape consiste à tester le point de terminaison et à obtenir des prédictions.
Tout d'abord, définissez la phrase test.
x_test=['The movie was cool. The animation and the graphics were out of this world. I would recommend this movie.']
Appelez ensuite "predict" sur le point de terminaison, qui renverra une prédiction de l'un des modèles déployés sur le point de terminaison.
endpoint.predict(instances=x_test)
🎉 Félicitations ! 🎉
Vous savez désormais utiliser Vertex AI pour :
- Co-héberger des modèles sur la même VM pour les prédictions en ligne
Pour en savoir plus sur les différents composants de Vertex, consultez la documentation.
7. Nettoyage
Nous vous recommandons d'annuler le déploiement des modèles sur le point de terminaison si vous ne prévoyez pas de les utiliser. Vous pouvez également supprimer l'intégralité du point de terminaison. Vous pouvez toujours redéployer un modèle sur un point de terminaison si nécessaire.
Les notebooks gérés par Workbench expirent automatiquement après 180 minutes d'inactivité. Vous n'avez donc pas à vous soucier de l'arrêt de l'instance. Si vous souhaitez arrêter l'instance manuellement, cliquez sur le bouton "Arrêter" dans la section "Vertex AI Workbench" de la console. Si vous souhaitez supprimer le notebook définitivement, cliquez sur le bouton "Supprimer".
Pour supprimer le bucket de stockage, utilisez le menu de navigation de la console Cloud pour accéder à Stockage, sélectionnez votre bucket puis cliquez sur "Supprimer" :