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 sur 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 se traduit par une meilleure utilisation de la mémoire et des ressources de calcul. Le nombre de modèles que vous choisissez de déployer sur la même VM dépend de leur taille et des modèles de trafic, mais cette fonctionnalité est particulièrement utile dans les cas où vous disposez de nombreux modèles déployés avec un trafic creux.
La prise en charge des modèles de co-hébergement introduit le concept de pool de ressources de déploiement, qui regroupe des 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, et également s'ils sont déployés sur différents points de terminaison. Actuellement, les modèles d'un même pool de ressources doivent avoir la même image de conteneur, y compris la version du framework des conteneurs prédéfinis de 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 conteneurs personnalisés ne sont pas encore compatibles.
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 d'essayer 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 à partir du lanceur d'applications.
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: Lancez 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 sentiments binaire (positif ou négatif) sur l'ensemble de données de revue de films IMDB. Collez le code dans votre notebook.
Veillez à remplacer {YOUR_BUCKET}
par le bucket que vous avez créé à l'étape précédente (ou un autre bucket de votre projet). C'est dans cet emplacement que nous stockerons les artefacts de modèle enregistrés, dont nous aurons besoin ultérieurement pour importer 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.
L'onglet "Exécutions" de la console vous permet de suivre l'état de votre job d'entraînement.
6. Déployer un modèle
Étape 1: Importez le modèle
Une fois l'exécution terminée, revenez au notebook Workbench pour importer le modèle. Créer un notebook TensorFlow
Tout d'abord, importez le SDK Vertex AI pour Python
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 importerons ce modèle deux fois, ce qui créera 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 disposez de deux modèles différents au lieu de créer des modèles à partir des mêmes artefacts enregistrés. Toutefois, comme il s'agit d'un raccourci, vous n'avez pas besoin de lancer une autre exécution d'entraînement. De plus, vous pouvez choisir de déployer les deux modèles sur différents points de terminaison 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')
Vous devriez maintenant voir les deux modèles dans le registre de modèles Vertex AI. L'état du 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. Notez que cela 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 pool de ressources de déploiement à 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 voir 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éployer 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.
Commençons par déployer model_1
. Veillez à remplacer MODEL_1_ID
et ENDPOINT_ID
par leurs 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, vous verrez le modèle déployé sur le point de terminaison dans la console.
Nous pouvons maintenant déployer model_2
dans le même pool de déploiement. Nous allons la déployer sur le même point de terminaison que model_1
. Cependant, vous pouvez également choisir de déployer model_2
sur un autre point de terminaison au sein du même pool de ressources.
Mettez à jour MODEL_ID
avec l'ID de model_2
. Là encore, 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'aurons pas à mettre à jour le trafficSplit
si nous choisissons de déployer model_2
sur un autre point de terminaison au sein du même pool de ressources.
Pour mettre à jour la répartition du trafic, vous devez définir l'ID de la classe "DeployedModel" pour model_1
. Notez qu'il est différent de l'ID du modèle.
DEPLOYED_MODEL_1_ID = {DEPLOYED_MODEL_1_ID}
Ensuite, exécutez 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'auriez 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 la fonction predict sur le point de terminaison, qui renverra une prédiction à partir 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 :
- Cohé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" :