1. Présentation
Dans cet atelier, vous allez apprendre à utiliser des routines de prédiction personnalisées sur Vertex AI pour écrire une logique de prétraitement et de post-traitement personnalisée. Bien que cet exemple utilise Scikit-learn, les routines de prédiction personnalisées peuvent fonctionner avec d'autres frameworks de ML Python tels que XGBoost, PyTorch et TensorFlow.
Objectifs
Vous allez apprendre à effectuer les opérations suivantes :
- Écrire une logique de prédiction personnalisée avec des routines de prédiction personnalisées
- Tester le modèle et le conteneur de diffusion personnalisé en local
- Tester le conteneur de diffusion personnalisé dans Vertex AI Prediction
Le coût total d'exécution de cet atelier sur Google Cloud est d'environ 1$.
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.
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 Predictions et Workbench.
3. Présentation du cas d'utilisation
Cas d'utilisation
Dans cet atelier, vous allez créer un modèle de régression par forêt aléatoire pour prédire le prix d'un diamant en fonction d'attributs tels que la taille, la clarté et la taille.
Vous allez écrire une logique de prétraitement personnalisée pour vérifier que les données au moment de la diffusion sont au format attendu par le modèle. Vous allez également écrire une logique de post-traitement personnalisée pour arrondir les prédictions et les convertir en chaînes. Pour écrire cette logique, vous utiliserez des routines de prédiction personnalisées.
Présentation des routines de prédiction personnalisées
Les conteneurs prédéfinis Vertex AI gèrent les requêtes de prédiction en effectuant l'opération de prédiction du framework de machine learning. Avant les routines de prédiction personnalisées, si vous souhaitiez prétraiter l'entrée avant l'exécution de la prédiction ou post-traiter la prédiction du modèle avant de renvoyer le résultat, vous deviez créer un conteneur personnalisé.
Pour créer un conteneur de diffusion personnalisé, vous devez écrire un serveur HTTP qui encapsule le modèle entraîné, traduit les requêtes HTTP en entrées du modèle et traduit les sorties du modèle en réponses.
Avec les routines de prédiction personnalisées, Vertex AI vous fournit les composants liés à l'inférence pour que vous puissiez vous concentrer sur votre modèle et les transformations de données.
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. Vous en aurez besoin pour créer votre instance de notebook.
Étape 2 : Activez l'API Artifact Registry
Accédez à Artifact Registry et cliquez sur Activer si ce n'est pas déjà fait. Vous l'utiliserez pour créer un conteneur de diffusion personnalisé.
Étape 3 : Activez l'API Vertex AI
Accédez à la section Vertex AI de Cloud Console, puis cliquez sur Activer l'API Vertex AI.
Étape 4 : 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 INSTANCES (INSTANCES), puis sélectionnez CREATE NEW (CRÉER).
Acceptez les options par défaut et cliquez sur Créer.
Lorsque l'instance est prête, cliquez sur OPEN JUPYTERLAB (OUVRIR JUPYTERLAB) pour l'ouvrir.
5. Rédiger le code d'entraînement
Étape 1: Créez un bucket Cloud Storage
Vous allez stocker le modèle et les artefacts de prétraitement dans un bucket Cloud Storage. Si vous souhaitez utiliser un bucket déjà présent dans votre projet, vous pouvez ignorer cette étape.
Depuis le lanceur, ouvrez une nouvelle session de terminal.
Depuis votre 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 dans votre terminal pour créer un bucket dans votre projet.
BUCKET="gs://${PROJECT_ID}-cpr-bucket"
gsutil mb -l us-central1 $BUCKET
Étape 2: Entraîner le modèle
Dans le terminal, créez un répertoire appelé cpr-codelab
et utilisez la commande cd pour y accéder.
mkdir cpr-codelab
cd cpr-codelab
Dans l'explorateur de fichiers, accédez au nouveau répertoire cpr-codelab
, puis utilisez le lanceur pour créer un notebook Python 3 nommé task.ipynb
.
Votre répertoire cpr-codelab
devrait se présenter comme suit:
+ cpr-codelab/
+ task.ipynb
Dans le notebook, collez le code suivant.
Commencez par écrire un fichier requirements.txt
.
%%writefile requirements.txt
fastapi
uvicorn==0.17.6
joblib~=1.0
numpy~=1.20
scikit-learn>=1.2.2
pandas
google-cloud-storage>=1.26.0,<2.0.0dev
google-cloud-aiplatform[prediction]>=1.16.0
Le modèle que vous déployez aura un ensemble de dépendances préinstallées différent de celui de votre environnement Notebook. Pour cette raison, vous devez lister toutes les dépendances du modèle dans requirements.txt
, puis utiliser pip pour installer exactement les mêmes dépendances dans le notebook. Plus tard, vous testerez le modèle localement avant de le déployer sur Vertex AI pour vérifier que les environnements correspondent.
Pip installe les dépendances dans le notebook.
!pip install -U --user -r requirements.txt
Notez que vous devrez redémarrer le noyau une fois l'installation de pip terminée.
Ensuite, créez les répertoires dans lesquels vous allez stocker le modèle et les artefacts de prétraitement.
USER_SRC_DIR = "src_dir"
!mkdir $USER_SRC_DIR
!mkdir model_artifacts
# copy the requirements to the source dir
!cp requirements.txt $USER_SRC_DIR/requirements.txt
Votre répertoire cpr-codelab
devrait se présenter comme suit:
+ cpr-codelab/
+ model_artifacts/
+ scr_dir/
+ requirements.txt
+ task.ipynb
+ requirements.txt
Maintenant que la structure de répertoires est configurée, il est temps d'entraîner un modèle.
Commencez par importer les bibliothèques.
import seaborn as sns
import numpy as np
import pandas as pd
from sklearn import preprocessing
from sklearn.ensemble import RandomForestRegressor
from sklearn.pipeline import make_pipeline
from sklearn.compose import make_column_transformer
import joblib
import logging
# set logging to see the docker container logs
logging.basicConfig(level=logging.INFO)
Définissez ensuite les variables suivantes. Veillez à remplacer PROJECT_ID
par l'ID de votre projet et BUCKET_NAME
par le bucket que vous avez créé à l'étape précédente.
REGION = "us-central1"
MODEL_ARTIFACT_DIR = "sklearn-model-artifacts"
REPOSITORY = "diamonds"
IMAGE = "sklearn-image"
MODEL_DISPLAY_NAME = "diamonds-cpr"
# Replace with your project
PROJECT_ID = "{PROJECT_ID}"
# Replace with your bucket
BUCKET_NAME = "gs://{BUCKET_NAME}"
Chargez les données de la bibliothèque Seaborn, puis créez deux DataFrames, l'un avec les caractéristiques et l'autre avec l'étiquette.
data = sns.load_dataset('diamonds', cache=True, data_home=None)
label = 'price'
y_train = data['price']
x_train = data.drop(columns=['price'])
Examinons les données d'entraînement. Vous pouvez voir que chaque ligne représente un losange.
x_train.head()
Et les étiquettes, qui sont les prix correspondants.
y_train.head()
Définissez maintenant une transformation de colonne sklearn pour effectuer un encodage one-hot des caractéristiques catégorielles et ajuster les caractéristiques numériques.
column_transform = make_column_transformer(
(preprocessing.OneHotEncoder(), [1,2,3]),
(preprocessing.StandardScaler(), [0,4,5,6,7,8]))
Définir le modèle de forêt aléatoire
regr = RandomForestRegressor(max_depth=10, random_state=0)
Créez ensuite un pipeline sklearn. Cela signifie que les données transmises à ce pipeline seront d'abord encodées/mises à l'échelle, puis transmises au modèle.
my_pipeline = make_pipeline(column_transform, regr)
Adapter le pipeline aux données d'entraînement
my_pipeline.fit(x_train, y_train)
Essayons le modèle pour nous assurer qu'il fonctionne comme prévu. Appelez la méthode predict
sur le modèle en transmettant un échantillon de test.
my_pipeline.predict([[0.23, 'Ideal', 'E', 'SI2', 61.5, 55.0, 3.95, 3.98, 2.43]])
Nous pouvons maintenant enregistrer le pipeline dans le répertoire model_artifacts
et le copier dans le bucket Cloud Storage.
joblib.dump(my_pipeline, 'model_artifacts/model.joblib')
!gsutil cp model_artifacts/model.joblib {BUCKET_NAME}/{MODEL_ARTIFACT_DIR}/
Étape 3: Enregistrer un artefact de prétraitement
Vous allez ensuite créer un artefact de prétraitement. Cet artefact sera chargé dans le conteneur personnalisé au démarrage du serveur de modèles. Votre artefact de prétraitement peut se présenter sous n'importe quel format, par exemple un fichier pickle, mais dans ce cas, vous allez écrire un dictionnaire dans un fichier JSON.
clarity_dict={"Flawless": "FL",
"Internally Flawless": "IF",
"Very Very Slightly Included": "VVS1",
"Very Slightly Included": "VS2",
"Slightly Included": "S12",
"Included": "I3"}
La caractéristique clarity
de nos données d'entraînement était toujours au format abrégé (par exemple, "FL" au lieu de "Flawless"). Lors de l'inférence, nous voulons vérifier que les données de cette caractéristique sont également abrégées. En effet, notre modèle sait comment encoder "FL" à chaud, mais pas "Flawless". Vous écrirez cette logique de prétraitement personnalisée ultérieurement. Pour le moment, il vous suffit d'enregistrer cette table de conversion dans un fichier JSON, puis de l'écrire dans le bucket Cloud Storage.
import json
with open("model_artifacts/preprocessor.json", "w") as f:
json.dump(clarity_dict, f)
!gsutil cp model_artifacts/preprocessor.json {BUCKET_NAME}/{MODEL_ARTIFACT_DIR}/
Votre répertoire cpr-codelab
local devrait maintenant se présenter comme suit:
+ cpr-codelab/
+ model_artifacts/
+ model.joblib
+ preprocessor.json
+ scr_dir/
+ requirements.txt
+ task.ipynb
+ requirements.txt
6. Créer un conteneur de diffusion personnalisé à l'aide du serveur de modèles CPR
Maintenant que le modèle a été entraîné et que l'artefact de prétraitement a été enregistré, il est temps de créer le conteneur de diffusion personnalisé. En règle générale, la création d'un conteneur de diffusion nécessite d'écrire du code de serveur de modèle. Toutefois, avec les routines de prédiction personnalisées, Vertex AI Predictions génère un serveur de modèle et crée une image de conteneur personnalisée pour vous.
Un conteneur de diffusion personnalisé contient les trois éléments de code suivants:
- Serveur de modèle (il sera généré automatiquement par le SDK et stocké dans
scr_dir/
)- Serveur HTTP qui héberge le modèle
- Chargé de la configuration des routes, des ports, etc.
- Gestionnaire de requêtes
- Il est responsable des aspects du serveur Web liés au traitement d'une requête, tels que la désérialisation du corps de la requête, la sérialisation de la réponse, la définition des en-têtes de réponse, etc.
- Dans cet exemple, vous utiliserez le gestionnaire par défaut,
google.cloud.aiplatform.prediction.handler.PredictionHandler
, fourni dans le SDK.
- Prédicteur
- Responsable de la logique de ML pour le traitement d'une requête de prédiction.
Chacun de ces composants peut être personnalisé en fonction des exigences de votre cas d'utilisation. Dans cet exemple, vous n'implémenterez que le prédicteur.
Le prédicteur est responsable de la logique de ML pour traiter une requête de prédiction, comme le prétraitement et le posttraitement personnalisés. Pour écrire une logique de prédiction personnalisée, vous sous-classez l'interface du prédicteur Vertex AI.
Cette version des routines de prédiction personnalisées est fournie avec des prédicteurs XGBoost et Sklearn réutilisables. Toutefois, si vous devez utiliser un autre framework, vous pouvez créer le vôtre en sous-classant le prédicteur de base.
Vous trouverez ci-dessous un exemple du prédicteur Sklearn. Voici tout le code que vous devez écrire pour créer ce serveur de modèle personnalisé.
Dans votre notebook, collez le code suivant pour sous-classer SklearnPredictor
et écrivez-le dans un fichier Python dans src_dir/
. Notez que dans cet exemple, nous ne personnalisons que les méthodes load
, preprocess
et postprocess
, et non la méthode predict
.
%%writefile $USER_SRC_DIR/predictor.py
import joblib
import numpy as np
import json
from google.cloud import storage
from google.cloud.aiplatform.prediction.sklearn.predictor import SklearnPredictor
class CprPredictor(SklearnPredictor):
def __init__(self):
return
def load(self, artifacts_uri: str) -> None:
"""Loads the sklearn pipeline and preprocessing artifact."""
super().load(artifacts_uri)
# open preprocessing artifact
with open("preprocessor.json", "rb") as f:
self._preprocessor = json.load(f)
def preprocess(self, prediction_input: np.ndarray) -> np.ndarray:
"""Performs preprocessing by checking if clarity feature is in abbreviated form."""
inputs = super().preprocess(prediction_input)
for sample in inputs:
if sample[3] not in self._preprocessor.values():
sample[3] = self._preprocessor[sample[3]]
return inputs
def postprocess(self, prediction_results: np.ndarray) -> dict:
"""Performs postprocessing by rounding predictions and converting to str."""
return {"predictions": [f"${value}" for value in np.round(prediction_results)]}
Examinons chacune de ces méthodes plus en détail.
- La méthode
load
se charge dans l'artefact de prétraitement, qui est dans ce cas un dictionnaire mappant les valeurs de clarté des diamants à leurs abréviations. - La méthode
preprocess
utilise cet artefact pour s'assurer qu'au moment de la diffusion, la fonctionnalité de clarté est au format abrégé. Sinon, il convertit la chaîne complète en abréviation. - La méthode
postprocess
renvoie la valeur prédite sous forme de chaîne avec un signe $ et arrondit la valeur.
Ensuite, utilisez le SDK Vertex AI pour Python pour créer l'image. À l'aide de routines de prédiction personnalisées, le fichier Dockerfile sera généré et l'image sera créée automatiquement.
from google.cloud import aiplatform
aiplatform.init(project=PROJECT_ID, location=REGION)
import os
from google.cloud.aiplatform.prediction import LocalModel
from src_dir.predictor import CprPredictor # Should be path of variable $USER_SRC_DIR
local_model = LocalModel.build_cpr_model(
USER_SRC_DIR,
f"{REGION}-docker.pkg.dev/{PROJECT_ID}/{REPOSITORY}/{IMAGE}",
predictor=CprPredictor,
requirements_path=os.path.join(USER_SRC_DIR, "requirements.txt"),
)
Écrivez un fichier de test avec deux exemples de prédiction. L'une des instances porte le nom abrégé, mais l'autre doit d'abord être convertie.
import json
sample = {"instances": [
[0.23, 'Ideal', 'E', 'VS2', 61.5, 55.0, 3.95, 3.98, 2.43],
[0.29, 'Premium', 'J', 'Internally Flawless', 52.5, 49.0, 4.00, 2.13, 3.11]]}
with open('instances.json', 'w') as fp:
json.dump(sample, fp)
Testez le conteneur localement en déployant un modèle local.
with local_model.deploy_to_local_endpoint(
artifact_uri = 'model_artifacts/', # local path to artifacts
) as local_endpoint:
predict_response = local_endpoint.predict(
request_file='instances.json',
headers={"Content-Type": "application/json"},
)
health_check_response = local_endpoint.run_health_check()
Vous pouvez afficher les résultats de la prédiction avec :
predict_response.content
7. Déployer le modèle dans Vertex AI
Maintenant que vous avez testé le conteneur localement, il est temps de transférer l'image vers Artifact Registry et d'importer le modèle dans Vertex AI Model Registry.
Commencez par configurer Docker pour qu'il accède à Artifact Registry.
!gcloud artifacts repositories create {REPOSITORY} --repository-format=docker \
--location=us-central1 --description="Docker repository"
!gcloud auth configure-docker {REGION}-docker.pkg.dev --quiet
Transférez ensuite l'image.
local_model.push_image()
Importez le modèle.
model = aiplatform.Model.upload(local_model = local_model,
display_name=MODEL_DISPLAY_NAME,
artifact_uri=f"{BUCKET_NAME}/{MODEL_ARTIFACT_DIR}",)
Une fois le modèle importé, il doit s'afficher dans la console:
Déployez ensuite le modèle pour pouvoir l'utiliser pour les prédictions en ligne. Les routines de prédiction personnalisées fonctionnent également avec la prédiction par lot. Par conséquent, si votre cas d'utilisation ne nécessite pas de prédictions en ligne, vous n'avez pas besoin de déployer le modèle.
endpoint = model.deploy(machine_type="n1-standard-2")
Enfin, testez le modèle déployé en obtenant une prédiction.
endpoint.predict(instances=[[0.23, 'Ideal', 'E', 'VS2', 61.5, 55.0, 3.95, 3.98, 2.43]])
🎉 Félicitations ! 🎉
Vous savez désormais utiliser Vertex AI pour :
- Écrire une logique de prétraitement et de post-traitement personnalisée avec des routines de prédiction personnalisées
Pour en savoir plus sur les différentes parties de Vertex AI, consultez la documentation.
8. Nettoyage
Si vous souhaitez continuer à utiliser le notebook que vous avez créé dans cet atelier, nous vous recommandons de le désactiver quand vous ne vous en servez pas. Dans l'interface utilisateur de Workbench dans la console Google Cloud, sélectionnez le notebook, puis Arrêter.
Si vous souhaitez supprimer le notebook définitivement, cliquez sur le bouton Supprimer situé en haut à droite.
Pour supprimer le point de terminaison que vous avez déployé, accédez à la section "Points de terminaison" de la console, cliquez sur le point de terminaison que vous avez créé, puis sélectionnez Annuler le déploiement du modèle sur le point de terminaison:
Pour supprimer l'image du conteneur, accédez à Artifact Registry, sélectionnez le dépôt que vous avez créé, puis 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: