1. Panoramica
In questo lab imparerai a utilizzare le routine di previsione personalizzate su Vertex AI per scrivere una logica di preelaborazione e postelaborazione personalizzata. Sebbene questo esempio utilizzi Scikit-learn, le routine di previsione personalizzate possono funzionare con altri framework ML di 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
- Testa il contenitore e il modello di pubblicazione personalizzati in locale
- Testa 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 è incentrato su Predizioni e Workbench.
3. Panoramica del caso d'uso
Caso d'uso
In questo lab creerai un modello di regressione con foresta casuale per prevedere il prezzo di un diamante in base ad attributi come taglio, chiarezza e dimensioni.
Scriverai una logica di preelaborazione 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 le 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 di eseguire la previsione o post-elaborare la previsione del modello prima di restituire il risultato, dovevi creare un contenitore personalizzato.
La creazione di un contenitore di pubblicazione personalizzato richiede la scrittura di un server HTTP che ingloba il modello addestrato, traduce le richieste HTTP in input del modello e le uscite del modello in risposte.
Con le routine di previsione personalizzate, Vertex AI fornisce i componenti relativi 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 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 Attiva se non è già abilitato. Ne avrai bisogno per creare la tua istanza di blocco note.
Passaggio 2: abilita l'API Artifact Registry
Passa ad Artifact Registry e seleziona Abilita, se non è già selezionato. Lo utilizzerai per creare un container di pubblicazione personalizzato.
Passaggio 3: abilita l'API Vertex AI
Vai alla sezione Vertex AI della 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 lo è già.
Una volta attivata, fai clic su ISTANZE e poi seleziona CREA NUOVA.
Accetta le opzioni predefinite e fai clic su Crea.
Quando l'istanza è pronta, fai clic su APRI JUPYTERLAB per aprirla.
5. Scrivere codice di addestramento
Passaggio 1: crea un bucket Cloud Storage
Memorizzerai il modello e gli artefatti di preelaborazione in un bucket Cloud Storage. Se nel tuo progetto hai già un bucket che vuoi utilizzare, puoi saltare questo passaggio.
Dal programma di avvio, apri una nuova sessione di terminale.
Dal terminale, esegui quanto segue per definire una variabile env per il tuo progetto, assicurandoti di sostituire your-cloud-project
con l'ID del progetto:
PROJECT_ID='your-cloud-project'
Successivamente, esegui il seguente comando nel terminale per creare un nuovo bucket nel progetto.
BUCKET="gs://${PROJECT_ID}-cpr-bucket"
gsutil mb -l us-central1 $BUCKET
Passaggio 2: addestrare il modello
Dal terminale, crea una nuova directory chiamata cpr-codelab
e accedi con cd.
mkdir cpr-codelab
cd cpr-codelab
Nel browser di file, vai alla nuova directory cpr-codelab
e utilizza il programma di avvio per creare un nuovo blocco note Python 3 denominato task.ipynb
.
La directory cpr-codelab
ora dovrebbe avere il seguente aspetto:
+ cpr-codelab/
+ task.ipynb
Incolla il codice seguente nel blocco note.
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 set di dipendenze diverso preinstallato rispetto all'ambiente del tuo blocco note. Per questo motivo, ti consigliamo di elencare tutte le dipendenze del modello in requirements.txt
e di utilizzare pip per installare le stesse dipendenze nel notebook. Successivamente, testerai il modello localmente prima di eseguirne il deployment in Vertex AI per verificare la corrispondenza degli ambienti.
Pip installa le dipendenze nel blocco note.
!pip install -U --user -r requirements.txt
Tieni presente che dovrai riavviare il kernel al termine dell'installazione di pip.
Quindi, crea le directory in cui archivierai 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 della 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 il tuo 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 e poi crea due dataframe, uno con le funzionalità 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, ovvero i prezzi corrispondenti.
y_train.head()
Ora definisci una trasformazione della colonna sklearn per eseguire la codifica one-hot delle caratteristiche categoriche e la scalatura delle 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)
A questo punto, crea una pipeline sklearn. Ciò significa che i dati inviati a questa pipeline verranno prima codificati/riscalati e poi trasmessi 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 esempio 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
Ora crea un artefatto di preelaborazione. Questo artefatto verrà caricato nel contenitore personalizzato all'avvio del server di modelli. L'elemento pre-elaborazione può essere di 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 funzionalità clarity
nei nostri dati di addestramento era sempre in forma abbreviata (ovvero "FL" invece di "Flawless"). Al momento della pubblicazione, vogliamo verificare che i dati per questa funzionalità siano anche abbreviati. Questo perché il nostro modello sa come codificare in one hot "FL", ma non "Flawless". Scriverai questa logica di pre-elaborazione personalizzata in un secondo momento. Per il momento, però, salva questa tabella di ricerca in un file json e poi scrivilo 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 ora dovrebbe avere il seguente aspetto:
+ cpr-codelab/
+ model_artifacts/
+ model.joblib
+ preprocessor.json
+ scr_dir/
+ requirements.txt
+ task.ipynb
+ requirements.txt
6. Crea un contenitore di pubblicazione personalizzato utilizzando il server del modello CPR
Ora che il modello è stato addestrato e l'elemento di preelaborazione è stato salvato, è il momento di creare il contenitore di pubblicazione personalizzato. In genere, la creazione di un contenitore di pubblicazione richiede la scrittura di codice del server del modello. Tuttavia, con le routine di previsione personalizzate, Vertex AI Predictions genera un server di modelli e crea un'immagine container personalizzata per te.
Un contenitore di pubblicazione personalizzato contiene i seguenti tre frammenti di codice:
- Server modello (viene generato automaticamente dall'SDK e archiviato in
scr_dir/
)- Server HTTP che ospita il modello
- Responsabile della configurazione di route/porte ecc.
- Gestore delle richieste
- Responsabile degli aspetti del web server per la gestione di una richiesta, come la deserializzazione del corpo della richiesta e la serializzazione della risposta, l'impostazione delle intestazioni di risposta e così via.
- In questo esempio utilizzerai l'Handler predefinito
google.cloud.aiplatform.prediction.handler.PredictionHandler
fornito nell'SDK.
- Predizione
- Responsabile della logica ML per l'elaborazione di una richiesta di previsione.
Ognuno 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, ad esempio la pre-elaborazione e la post-elaborazione personalizzate. Per scrivere una logica di previsione personalizzata, dovrai creare una sottoclasse dell'interfaccia di Vertex AI Predictor.
Questa release delle routine di previsione personalizzate include predittori XGBoost e Sklearn riutilizzabili, ma se devi utilizzare un framework diverso, puoi crearne uno tuo sottoclassificando il predittore di base.
Di seguito è riportato un esempio di predittore Sklearn. Questo è tutto il codice da scrivere per creare il server del modello personalizzato.
Nel notebook, incolla il seguente codice per creare una sottoclasse di SklearnPredictor
e scrivilo 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)]}
Esaminiamo più da vicino ciascuno di questi metodi.
- Il metodo
load
viene caricato nell'elemento artefatto di preelaborazione, che in questo caso è un dizionario che mappa i valori di purezza del diamante alle relative abbreviazioni. - il metodo
preprocess
utilizza questo artefatto per garantire che al momento della pubblicazione la funzionalità di chiarezza sia nel formato abbreviato. In caso contrario, la stringa completa viene convertita nella relativa abbreviazione. - Il metodo
postprocess
restituisce il valore previsto come stringa con un segno $ e lo arrotondamento.
Successivamente, 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 per te.
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 esempi per la previsione. Una delle istanze ha il nome chiaro abbreviato, ma l'altra deve essere prima convertita.
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 contenitore localmente 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 in Vertex AI
Ora che hai testato il container in locale, è il momento di eseguire il push dell'immagine ad Artifact Registry e di 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
Quindi, invia l'immagine.
local_model.push_image()
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 dovrebbe essere visualizzato 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 le previsioni batch, quindi se il tuo caso d'uso non richiede previsioni online, non è necessario eseguire il deployment del modello.
endpoint = model.deploy(machine_type="n1-standard-2")
Infine, testa il modello di cui è stato eseguito il deployment ottenendo una previsione.
endpoint.predict(instances=[[0.23, 'Ideal', 'E', 'VS2', 61.5, 55.0, 3.95, 3.98, 2.43]])
🎉 Complimenti! 🎉
Hai imparato come utilizzare Vertex AI per:
- Scrivi una logica di preelaborazione e postelaborazione 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 blocco note 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 e poi 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 e 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 Archiviazione, seleziona il bucket e fai clic su Elimina: