1. Panoramica
In questo lab imparerai a utilizzare le routine di previsione personalizzate su Vertex AI per scrivere una logica di pre-elaborazione e post-elaborazione personalizzata. Sebbene questo esempio utilizzi Scikit-learn, le routine di previsione personalizzate possono funzionare con altri framework ML Python come XGBoost, PyTorch e TensorFlow.
Cosa imparerai
Al termine del corso sarai in grado di:
- Scrivere una logica di previsione personalizzata con routine di previsione personalizzate
- Testare il container e il modello di pubblicazione personalizzati in locale
- Testare il container di pubblicazione personalizzato su Vertex AI Predictions
Il costo totale per eseguire questo lab su Google Cloud è di circa 1 $.
2. Introduzione a Vertex AI
Questo lab utilizza la più recente offerta di prodotti AI disponibile su Google Cloud. Vertex AI integra le offerte ML di Google Cloud in un'esperienza di sviluppo fluida. In precedenza, i modelli addestrati con AutoML e i modelli personalizzati erano accessibili tramite servizi separati. La nuova offerta combina entrambi in un'unica API, insieme ad altri nuovi prodotti. Puoi anche migrare progetti esistenti su Vertex AI.
Vertex AI include molti prodotti diversi per supportare i flussi di lavoro ML end-to-end. Questo lab si concentrerà su Predictions e Workbench.

3. Panoramica del caso d'uso
Caso d'uso
In questo lab creerai un modello di regressione della foresta casuale per prevedere il prezzo di un diamante in base ad attributi come taglio, purezza e dimensioni.
Scriverai una logica di pre-elaborazione personalizzata per verificare che i dati al momento della pubblicazione siano nel formato previsto dal modello. Scriverai anche una logica di post-elaborazione personalizzata per arrotondare le previsioni e convertirle in stringhe. Per scrivere questa logica, utilizzerai routine di previsione personalizzate.
Introduzione alle routine di previsione personalizzate
I container predefiniti di Vertex AI gestiscono le richieste di previsione eseguendo l'operazione di previsione del framework di machine learning. Prima delle routine di previsione personalizzate, se volevi pre-elaborare l'input prima dell'esecuzione della previsione o post-elaborare la previsione del modello prima di restituire il risultato, dovevi creare un container personalizzato.
La creazione di un container di pubblicazione personalizzato richiede la scrittura di un server HTTP che esegue il wrapping del modello addestrato, traduce le richieste HTTP in input del modello e traduce gli output del modello in risposte.
Con le routine di previsione personalizzate, Vertex AI fornisce i componenti correlati alla pubblicazione, in modo che tu possa concentrarti sul modello e sulle trasformazioni dei dati.
4. Configura l'ambiente
Per eseguire questo codelab, devi avere un progetto della piattaforma Google Cloud con la fatturazione abilitata. Per creare un progetto, segui le istruzioni riportate qui.
Passaggio 1: abilita l'API Compute Engine
Vai a Compute Engine e seleziona Abilita se non è già abilitato. Ne avrai bisogno per creare la tua istanza di notebook.
Passaggio 2: abilita l'API Artifact Registry
Vai a Artifact Registry e seleziona Abilita se non è già abilitato. Lo utilizzerai per creare un container di pubblicazione personalizzato.
Passaggio 3: abilita l'API Vertex AI
Accedi alla sezione Vertex AI della tua console Cloud e fai clic su Abilita API Vertex AI.

Passaggio 4: crea un'istanza di Vertex AI Workbench
Nella sezione Vertex AI della console Cloud, fai clic su Workbench:

Abilita l'API Notebooks se non è già abilitata.

Una volta abilitata, fai clic su ISTANZE, quindi seleziona CREA NUOVA.
Accetta le opzioni predefinite e fai clic su Crea.
Quando l'istanza è pronta, fai clic su APRI JUPYTERLAB per aprirla.
5. Scrivi il codice di addestramento
Passaggio 1: crea un bucket Cloud Storage
Memorizzerai il modello e gli artefatti di pre-elaborazione in un bucket Cloud Storage. Se hai già un bucket nel progetto che vuoi utilizzare, puoi saltare questo passaggio.
Dal launcher, apri una nuova sessione di terminale.

Dal tuo terminale, esegui quanto segue per definire una variabile env per il tuo progetto, assicurandoti di sostituire your-cloud-project con l'ID del tuo progetto:
PROJECT_ID='your-cloud-project'
Poi, esegui quanto segue nel terminale per creare un nuovo bucket nel progetto.
BUCKET="gs://${PROJECT_ID}-cpr-bucket"
gsutil mb -l us-central1 $BUCKET
Passaggio 2: addestra il modello
Dal terminale, crea una nuova directory chiamata cpr-codelab e passa a questa directory.
mkdir cpr-codelab
cd cpr-codelab
Nel browser dei file, vai alla nuova directory cpr-codelab, quindi utilizza il launcher per creare un nuovo blocco note Python 3 chiamato task.ipynb.

La directory cpr-codelab dovrebbe ora avere il seguente aspetto:
+ cpr-codelab/
+ task.ipynb
Nel blocco note, incolla il seguente codice.
Innanzitutto, scrivi un file 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
Il modello di cui esegui il deployment avrà un insieme di dipendenze preinstallate diverso da quello dell'ambiente del blocco note. Per questo motivo, ti consigliamo di elencare tutte le dipendenze del modello in requirements.txt e poi utilizzare pip per installare esattamente le stesse dipendenze nel notebook. In un secondo momento, testerai il modello in locale prima di eseguire il deployment su Vertex AI per verificare che gli ambienti corrispondano.
Installa le dipendenze nel blocco note utilizzando pip.
!pip install -U --user -r requirements.txt
Tieni presente che dovrai riavviare il kernel al termine dell'installazione di pip.

Poi, crea le directory in cui memorizzerai il modello e gli artefatti di pre-elaborazione.
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
La directory cpr-codelab dovrebbe ora avere il seguente aspetto:
+ cpr-codelab/
+ model_artifacts/
+ scr_dir/
+ requirements.txt
+ task.ipynb
+ requirements.txt
Ora che la struttura delle directory è configurata, è il momento di addestrare un modello.
Innanzitutto, importa le librerie.
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)
Poi, definisci le seguenti variabili. Assicurati di sostituire PROJECT_ID con l'ID progetto e BUCKET_NAME con il bucket che hai creato nel passaggio precedente.
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}"
Carica i dati dalla libreria seaborn, quindi crea due dataframe, uno con le caratteristiche e l'altro con l'etichetta.
data = sns.load_dataset('diamonds', cache=True, data_home=None)
label = 'price'
y_train = data['price']
x_train = data.drop(columns=['price'])
Diamo un'occhiata ai dati di addestramento. Puoi vedere che ogni riga rappresenta un diamante.
x_train.head()
E le etichette, che sono i prezzi corrispondenti.
y_train.head()
Ora, definisci una trasformazione delle colonne sklearn per codificare le caratteristiche categoriche e scalare le caratteristiche numeriche.
column_transform = make_column_transformer(
(preprocessing.OneHotEncoder(), [1,2,3]),
(preprocessing.StandardScaler(), [0,4,5,6,7,8]))
Definisci il modello di foresta casuale.
regr = RandomForestRegressor(max_depth=10, random_state=0)
Poi, crea una pipeline sklearn. Ciò significa che i dati inseriti in questa pipeline verranno prima codificati/scalati e poi passati al modello.
my_pipeline = make_pipeline(column_transform, regr)
Adatta la pipeline ai dati di addestramento.
my_pipeline.fit(x_train, y_train)
Proviamo il modello per assicurarci che funzioni come previsto. Chiama il metodo predict sul modello, passando un campione di test.
my_pipeline.predict([[0.23, 'Ideal', 'E', 'SI2', 61.5, 55.0, 3.95, 3.98, 2.43]])
Ora possiamo salvare la pipeline nella directory model_artifacts e copiarla nel bucket Cloud Storage.
joblib.dump(my_pipeline, 'model_artifacts/model.joblib')
!gsutil cp model_artifacts/model.joblib {BUCKET_NAME}/{MODEL_ARTIFACT_DIR}/
Passaggio 3: salva un artefatto di pre-elaborazione
Poi, creerai un artefatto di pre-elaborazione. Questo artefatto verrà caricato nel container personalizzato all'avvio del server del modello. L'artefatto di pre-elaborazione può avere quasi qualsiasi forma (ad esempio un file pickle), ma in questo caso scriverai un dizionario in un file JSON.
clarity_dict={"Flawless": "FL",
"Internally Flawless": "IF",
"Very Very Slightly Included": "VVS1",
"Very Slightly Included": "VS2",
"Slightly Included": "S12",
"Included": "I3"}
La caratteristica clarity nei nostri dati di addestramento era sempre in forma abbreviata (ad es. "FL" anziché "Flawless"). Al momento della pubblicazione, vogliamo verificare che anche i dati di questa caratteristica siano abbreviati. Questo perché il nostro modello sa come codificare "FL", ma non "Flawless". Scriverai questa logica di pre-elaborazione personalizzata in un secondo momento. Per il momento, salva questa tabella di ricerca in un file JSON e poi scrivila nel 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}/
La directory cpr-codelab locale dovrebbe ora avere il seguente aspetto:
+ cpr-codelab/
+ model_artifacts/
+ model.joblib
+ preprocessor.json
+ scr_dir/
+ requirements.txt
+ task.ipynb
+ requirements.txt
6. Crea un container di pubblicazione personalizzato utilizzando il server del modello CPR
Ora che il modello è stato addestrato e l'artefatto di pre-elaborazione è stato salvato, è il momento di creare il container di pubblicazione personalizzato. In genere, la creazione di un container di pubblicazione richiede la scrittura di codice del server del modello. Tuttavia, con le routine di previsione personalizzate, Vertex AI Predictions genera un server del modello e crea un'immagine container personalizzata.
Un container di pubblicazione personalizzato contiene i seguenti tre elementi di codice:
- Server del modello (verrà generato automaticamente dall'SDK e memorizzato in
scr_dir/)- Server HTTP che ospita il modello
- Responsabile della configurazione di route/porte/ecc.
- Gestore delle richieste
- Responsabile degli aspetti del server web della gestione di una richiesta, come la deserializzazione del corpo della richiesta, la serializzazione della risposta, l'impostazione delle intestazioni della risposta e così via.
- In questo esempio, utilizzerai il gestore predefinito,
google.cloud.aiplatform.prediction.handler.PredictionHandler, fornito nell'SDK.
- Predittore
- Responsabile della logica ML per l'elaborazione di una richiesta di previsione.
Ciascuno di questi componenti può essere personalizzato in base ai requisiti del tuo caso d'uso. In questo esempio, implementerai solo il predittore.
Il predittore è responsabile della logica ML per l'elaborazione di una richiesta di previsione, come la pre-elaborazione e la post-elaborazione personalizzate. Per scrivere una logica di previsione personalizzata, devi creare una sottoclasse dell'interfaccia del predittore di Vertex AI.
Questa release delle routine di previsione personalizzate include predittori XGBoost e Sklearn riutilizzabili, ma se devi utilizzare un framework diverso puoi crearne uno tuo creando una sottoclasse del predittore di base.
Di seguito è riportato un esempio del predittore Sklearn. Questo è tutto il codice che dovresti scrivere per creare questo server del modello personalizzato.

Nel blocco note, incolla il seguente codice per creare una sottoclasse di SklearnPredictor e scriverlo in un file Python in src_dir/. Tieni presente che in questo esempio personalizziamo solo i metodi load, preprocess e postprocess, non il metodo 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)]}
Diamo un'occhiata più da vicino a ciascuno di questi metodi.
- Il metodo
loadcarica l'artefatto di pre-elaborazione, che in questo caso è un dizionario che mappa i valori di purezza del diamante alle relative abbreviazioni. - Il metodo
preprocessutilizza questo artefatto per garantire che al momento della pubblicazione la caratteristica di purezza sia nel formato abbreviato. In caso contrario, converte la stringa completa nella relativa abbreviazione. - Il metodo
postprocessrestituisce il valore previsto come stringa con un segno $ e arrotonda il valore.
Poi, utilizza l'SDK Vertex AI Python per creare l'immagine. Utilizzando le routine di previsione personalizzate, il Dockerfile verrà generato e l'immagine verrà creata automaticamente.
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"),
)
Scrivi un file di test con due campioni per la previsione. Una delle istanze ha il nome di purezza abbreviato, ma l'altra deve essere convertita prima.
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)
Testa il container in locale eseguendo il deployment di un modello locale.
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()
Puoi visualizzare i risultati della previsione con:
predict_response.content
7. Esegui il deployment del modello su Vertex AI
Ora che hai testato il container in locale, è il momento di eseguire il push dell'immagine in Artifact Registry e caricare il modello in Vertex AI Model Registry.
Innanzitutto, configura Docker per accedere ad 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
Poi, esegui il push dell'immagine.
local_model.push_image()
E carica il modello.
model = aiplatform.Model.upload(local_model = local_model,
display_name=MODEL_DISPLAY_NAME,
artifact_uri=f"{BUCKET_NAME}/{MODEL_ARTIFACT_DIR}",)
Una volta caricato il modello, dovresti vederlo nella console:

Poi, esegui il deployment del modello in modo da poterlo utilizzare per le previsioni online. Le routine di previsione personalizzate funzionano anche con la previsione in batch, quindi se il tuo caso d'uso non richiede previsioni online, non devi eseguire il deployment del modello.
endpoint = model.deploy(machine_type="n1-standard-2")
Infine, testa il modello di cui hai eseguito il deployment ottenendo una previsione.
endpoint.predict(instances=[[0.23, 'Ideal', 'E', 'VS2', 61.5, 55.0, 3.95, 3.98, 2.43]])
🎉 Congratulazioni! 🎉
Hai imparato come utilizzare Vertex AI per:
- Scrivere una logica di pre-elaborazione e post-elaborazione personalizzata con routine di previsione personalizzate
Per saperne di più sulle diverse parti di Vertex AI, consulta la documentazione.
8. Esegui la pulizia
Se vuoi continuare a utilizzare il notebook creato in questo lab, ti consigliamo di disattivarlo quando non lo usi. Dall'interfaccia utente di Workbench nella console Google Cloud, seleziona il blocco note, quindi seleziona Interrompi.
Se vuoi eliminare completamente il blocco note, fai clic sul pulsante Elimina in alto a destra.

Per eliminare l'endpoint di cui hai eseguito il deployment, vai alla sezione Endpoint della console, fai clic sull'endpoint che hai creato, quindi seleziona Annulla il deployment del modello nell'endpoint:

Per eliminare l'immagine container, vai ad Artifact Registry, seleziona il repository che hai creato e seleziona Elimina.

Per eliminare il bucket di archiviazione, utilizza il menu di navigazione nella console Cloud, vai a Storage, seleziona il bucket e fai clic su Elimina:
