1. Przegląd
W tym laboratorium dowiesz się, jak używać niestandardowych procedur prognozowania w Vertex AI do pisania niestandardowej logiki przetwarzania wstępnego i końcowego. W tym przykładzie używamy Scikit-learn, ale niestandardowe procedury prognozowania mogą działać z innymi platformami ML w Pythonie, takimi jak XGBoost, PyTorch i TensorFlow.
Czego się dowiesz
Poznasz takie zagadnienia jak:
- Pisanie niestandardowej logiki prognozowania za pomocą niestandardowych procedur prognozowania
- Testowanie niestandardowego kontenera udostępniania i modelu lokalnie
- Testowanie niestandardowego kontenera obsługującego w usłudze prognozowania Vertex AI
Całkowity koszt ukończenia tego laboratorium w Google Cloud wynosi około 1 USD.
2. Wprowadzenie do Vertex AI
W tym module wykorzystujemy najnowszą ofertę produktów AI dostępną w Google Cloud. Vertex AI integruje oferty ML w Google Cloud, zapewniając płynne środowisko programistyczne. Wcześniej modele wytrenowane za pomocą AutoML i modele niestandardowe były dostępne w ramach osobnych usług. Nowa oferta łączy je w jeden interfejs API wraz z innymi nowymi usługami. Możesz też przeprowadzić migrację istniejących projektów do Vertex AI.
Vertex AI obejmuje wiele różnych usług, które obsługują kompleksowe przepływy pracy związane z uczeniem maszynowym. Ten moduł skupia się na Prognozowaniu i Workbench.

3. Omówienie przypadku użycia
Przypadek użycia
W tym laboratorium utworzysz model regresji lasu losowego, aby przewidywać cenę diamentu na podstawie takich atrybutów jak szlif, czystość i rozmiar.
Napiszesz niestandardową logikę wstępnego przetwarzania, aby sprawdzić, czy dane w momencie wyświetlania są w formacie oczekiwanym przez model. Napiszesz też niestandardową logikę przetwarzania końcowego, aby zaokrąglić prognozy i przekształcić je w ciągi znaków. Aby napisać tę logikę, użyjesz niestandardowych procedur prognozowania.
Wprowadzenie do niestandardowych procedur prognozowania
Gotowe kontenery Vertex AI obsługują żądania prognozowania, wykonując operację prognozowania w ramach uczenia maszynowego. Przed wprowadzeniem niestandardowych procedur prognozowania, jeśli przed wykonaniem prognozy lub po niej chciałeś przetworzyć wstępnie dane wejściowe, musiałeś utworzyć kontener niestandardowy.
Tworzenie niestandardowego kontenera do obsługi wymaga napisania serwera HTTP, który opakowuje wytrenowany model, tłumaczy żądania HTTP na dane wejściowe modelu i tłumaczy dane wyjściowe modelu na odpowiedzi.
W przypadku niestandardowych procedur prognozowania Vertex AI udostępnia komponenty związane z udostępnianiem, dzięki czemu możesz skupić się na modelu i przekształceniach danych.
4. Konfigurowanie środowiska
Aby wykonać to ćwiczenie, musisz mieć projekt w Google Cloud Platform z włączonymi płatnościami. Aby utworzyć projekt, postępuj zgodnie z instrukcjami.
Krok 1. Włącz interfejs Compute Engine API
Przejdź do Compute Engine i kliknij Włącz, jeśli nie jest jeszcze włączona. Będzie Ci potrzebny do utworzenia instancji notatnika.
Krok 2. Włącz interfejs Artifact Registry API
Otwórz Artifact Registry i kliknij Włącz, jeśli nie jest jeszcze włączona. Użyjesz go do utworzenia niestandardowego kontenera do obsługi.
Krok 3. Włącz interfejs Vertex AI API
Otwórz sekcję Vertex AI w konsoli Cloud i kliknij Włącz interfejs Vertex AI API.

Krok 4. Tworzenie instancji Vertex AI Workbench
W sekcji Vertex AI w konsoli Cloud kliknij Workbench:

Włącz interfejs Notebooks API, jeśli nie jest jeszcze włączony.

Po włączeniu tej opcji kliknij INSTANCJE, a potem UTWÓRZ NOWĄ.
Zaakceptuj opcje domyślne i kliknij Utwórz.
Gdy instancja będzie gotowa, kliknij OTWÓRZ JUPYTERLAB, aby ją otworzyć.
5. Pisanie kodu szkoleniowego
Krok 1. Utwórz zasobnik w Cloud Storage
Model i artefakty wstępnego przetwarzania zapiszesz w zasobniku Cloud Storage. Jeśli masz już w projekcie zasobnik, którego chcesz użyć, możesz pominąć ten krok.
W programie uruchamiającym otwórz nową sesję terminala.

W terminalu uruchom to polecenie, aby zdefiniować zmienną środowiskową dla projektu. Pamiętaj, aby zastąpić your-cloud-project identyfikatorem projektu:
PROJECT_ID='your-cloud-project'
Następnie uruchom w terminalu to polecenie, aby utworzyć nowy zasobnik w projekcie.
BUCKET="gs://${PROJECT_ID}-cpr-bucket"
gsutil mb -l us-central1 $BUCKET
Krok 2. Trenowanie modelu
W terminalu utwórz nowy katalog o nazwie cpr-codelab i przejdź do niego.
mkdir cpr-codelab
cd cpr-codelab
W przeglądarce plików przejdź do nowego katalogu cpr-codelab, a następnie za pomocą programu uruchamiającego utwórz nowy notatnik w Pythonie 3 o nazwie task.ipynb.

Twój katalog cpr-codelab powinien teraz wyglądać tak:
+ cpr-codelab/
+ task.ipynb
Wklej do notatnika ten kod.
Najpierw utwórz plik 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
Wdrożony model będzie miał wstępnie zainstalowany inny zestaw zależności niż środowisko notatnika. Dlatego w pliku requirements.txt musisz podać wszystkie zależności modelu, a następnie użyć narzędzia pip, aby zainstalować te same zależności w notatniku. Później przetestujesz model lokalnie, a następnie wdrożysz go w Vertex AI, aby sprawdzić, czy środowiska są zgodne.
Zainstaluj zależności w notatniku za pomocą narzędzia pip.
!pip install -U --user -r requirements.txt
Pamiętaj, że po zakończeniu instalacji za pomocą pip musisz ponownie uruchomić jądro.

Następnie utwórz katalogi, w których będziesz przechowywać model i artefakty przetwarzania wstępnego.
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
Twój katalog cpr-codelab powinien teraz wyglądać tak:
+ cpr-codelab/
+ model_artifacts/
+ scr_dir/
+ requirements.txt
+ task.ipynb
+ requirements.txt
Struktura katalogów jest już skonfigurowana, więc możesz wytrenować model.
Najpierw zaimportuj biblioteki.
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)
Następnie zdefiniuj te zmienne. Pamiętaj, aby zastąpić PROJECT_ID identyfikatorem projektu, a BUCKET_NAME – zasobnikiem utworzonym w poprzednim kroku.
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}"
Wczytaj dane z biblioteki seaborn, a następnie utwórz 2 ramki danych: jedną z cechami, a drugą z etykietą.
data = sns.load_dataset('diamonds', cache=True, data_home=None)
label = 'price'
y_train = data['price']
x_train = data.drop(columns=['price'])
Przyjrzyjmy się danym treningowym. Każdy wiersz reprezentuje diament.
x_train.head()
i etykiety, czyli odpowiadające im ceny.
y_train.head()
Teraz zdefiniuj transformację kolumn sklearn, aby zakodować metodą one-hot cechy kategorialne i skalować cechy liczbowe.
column_transform = make_column_transformer(
(preprocessing.OneHotEncoder(), [1,2,3]),
(preprocessing.StandardScaler(), [0,4,5,6,7,8]))
Definiowanie modelu lasu losowego
regr = RandomForestRegressor(max_depth=10, random_state=0)
Następnie utwórz potok sklearn. Oznacza to, że dane przekazywane do tego potoku będą najpierw kodowane lub skalowane, a potem przekazywane do modelu.
my_pipeline = make_pipeline(column_transform, regr)
Dopasowywanie potoku do danych treningowych
my_pipeline.fit(x_train, y_train)
Wypróbujmy model, aby sprawdzić, czy działa zgodnie z oczekiwaniami. Wywołaj w modelu metodę predict, przekazując próbkę testową.
my_pipeline.predict([[0.23, 'Ideal', 'E', 'SI2', 61.5, 55.0, 3.95, 3.98, 2.43]])
Teraz możemy zapisać potok w katalogu model_artifacts i skopiować go do zasobnika Cloud Storage.
joblib.dump(my_pipeline, 'model_artifacts/model.joblib')
!gsutil cp model_artifacts/model.joblib {BUCKET_NAME}/{MODEL_ARTIFACT_DIR}/
Krok 3. Zapisz artefakt przetwarzania wstępnego
Następnie utworzysz artefakt wstępnego przetwarzania. Ten artefakt zostanie załadowany do kontenera niestandardowego po uruchomieniu serwera modelu. Artefakt przetwarzania wstępnego może mieć niemal dowolną formę (np. plik pickle), ale w tym przypadku zapiszesz słownik w pliku JSON.
clarity_dict={"Flawless": "FL",
"Internally Flawless": "IF",
"Very Very Slightly Included": "VVS1",
"Very Slightly Included": "VS2",
"Slightly Included": "S12",
"Included": "I3"}
Funkcja clarity w naszych danych treningowych zawsze występowała w skróconej formie (np. „FL” zamiast „Flawless”). W momencie wyświetlania reklamy chcemy sprawdzić, czy dane tej funkcji są również skrócone. Dzieje się tak, ponieważ nasz model wie, jak zakodować metodą one-hot „FL”, ale nie wie, jak zakodować „Flawless”. Własną logikę wstępnego przetwarzania napiszesz później. Na razie zapisz tę tabelę wyszukiwania w pliku JSON, a następnie zapisz ją w zasobniku 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}/
Twój lokalny katalog cpr-codelab powinien teraz wyglądać tak:
+ cpr-codelab/
+ model_artifacts/
+ model.joblib
+ preprocessor.json
+ scr_dir/
+ requirements.txt
+ task.ipynb
+ requirements.txt
6. Tworzenie niestandardowego kontenera udostępniania za pomocą serwera modelu CPR
Model został już wytrenowany, a artefakt przetwarzania wstępnego został zapisany. Teraz możesz utworzyć niestandardowy kontener do obsługi. Zwykle tworzenie kontenera obsługi wymaga napisania kodu serwera modelu. W przypadku niestandardowych procedur prognozowania usługa Vertex AI Predictions generuje serwer modelu i tworzy niestandardowy obraz kontenera.
Niestandardowy kontener do obsługi zawiera te 3 elementy kodu:
- Serwer modelu (zostanie wygenerowany automatycznie przez pakiet SDK i przechowywany w
scr_dir/)- serwer HTTP, który hostuje model;
- Odpowiada za konfigurowanie tras, portów itp.
- Request Handler
- Odpowiada za aspekty obsługi żądania związane z serwerem internetowym, takie jak deserializacja treści żądania i serializacja odpowiedzi, ustawianie nagłówków odpowiedzi itp.
- W tym przykładzie użyjesz domyślnego modułu obsługi
google.cloud.aiplatform.prediction.handler.PredictionHandlerdostarczonego w SDK.
- Predictor
- Odpowiada za logikę ML przetwarzania żądania prognozy.
Każdy z tych komponentów można dostosować do wymagań konkretnego przypadku użycia. W tym przykładzie zaimplementujesz tylko predyktor.
Predyktor jest odpowiedzialny za logikę uczenia maszynowego do przetwarzania żądania prognozy, np. za niestandardowe przetwarzanie wstępne i końcowe. Aby napisać niestandardową logikę prognozowania, utwórz klasę podrzędną interfejsu Vertex AI Predictor.
Ta wersja niestandardowych procedur prognozowania zawiera wielokrotnego użytku predyktory XGBoost i Sklearn, ale jeśli chcesz użyć innej platformy, możesz utworzyć własną, tworząc klasę podrzędną predyktora bazowego.
Poniżej znajdziesz przykład predyktora Sklearn. To cały kod, który musisz napisać, aby utworzyć ten niestandardowy serwer modelu.

Wklej do notatnika ten kod, aby utworzyć klasę podrzędną SklearnPredictor i zapisać ją w pliku Pythona w src_dir/. Pamiętaj, że w tym przykładzie dostosowujemy tylko metody load, preprocess i postprocess, a nie metodę 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)]}
Przyjrzyjmy się dokładniej każdej z tych metod.
- Metoda
loadwczytuje artefakt przetwarzania wstępnego, którym w tym przypadku jest słownik mapujący wartości czystości diamentu na ich skróty. - Metoda
preprocessużywa tego artefaktu, aby zapewnić, że w momencie wyświetlania funkcja przejrzystości będzie w skróconym formacie. W przeciwnym razie przekształci cały ciąg znaków w skrót. - Metoda
postprocesszwraca prognozowaną wartość jako ciąg znaków ze znakiem dolara i zaokrągla wartość.
Następnie użyj pakietu Vertex AI Python SDK, aby utworzyć obraz. Korzystając z niestandardowych procedur prognozowania, wygenerujesz plik Dockerfile i utworzysz obraz.
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"),
)
Utwórz plik testowy z 2 próbkami do prognozowania. Jedna z instancji ma skróconą nazwę Clarity, ale drugą trzeba najpierw przekonwertować.
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)
Przetestuj kontener lokalnie, wdrażając model lokalny.
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()
Wyniki prognozy możesz wyświetlić za pomocą tych narzędzi:
predict_response.content
7. Wdrażanie modelu w Vertex AI
Po przetestowaniu kontenera lokalnie możesz przenieść obraz do Artifact Registry i przesłać model do Vertex AI Model Registry.
Najpierw skonfiguruj Dockera, aby miał dostęp do 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
Następnie przesuń obraz.
local_model.push_image()
Następnie prześlij model.
model = aiplatform.Model.upload(local_model = local_model,
display_name=MODEL_DISPLAY_NAME,
artifact_uri=f"{BUCKET_NAME}/{MODEL_ARTIFACT_DIR}",)
Po przesłaniu modelu powinien on być widoczny w konsoli:

Następnie wdróż model, aby można było go używać do prognozowania online. Niestandardowe procedury prognozowania działają też w przypadku prognozowania zbiorczego, więc jeśli Twój przypadek użycia nie wymaga prognoz online, nie musisz wdrażać modelu.
endpoint = model.deploy(machine_type="n1-standard-2")
Na koniec przetestuj wdrożony model, uzyskując prognozę.
endpoint.predict(instances=[[0.23, 'Ideal', 'E', 'VS2', 61.5, 55.0, 3.95, 3.98, 2.43]])
🎉 Gratulacje! 🎉
Dowiedziałeś się, jak używać Vertex AI do:
- Pisanie niestandardowej logiki przetwarzania wstępnego i końcowego za pomocą niestandardowych procedur prognozowania
Więcej informacji o poszczególnych częściach Vertex AI znajdziesz w dokumentacji.
8. Czyszczenie
Jeśli chcesz nadal korzystać z notatnika utworzonego w tym module, zalecamy wyłączanie go, gdy nie jest używany. W interfejsie Workbench w konsoli Google Cloud wybierz notatnik, a następnie kliknij Zatrzymaj.
Jeśli chcesz całkowicie usunąć notatnik, w prawym górnym rogu kliknij przycisk Usuń.

Aby usunąć wdrożony punkt końcowy, otwórz sekcję Punkty końcowe w konsoli, kliknij utworzony punkt końcowy, a następnie wybierz Wycofaj wdrożenie modelu z punktu końcowego:

Aby usunąć obraz kontenera, otwórz Artifact Registry, wybierz utworzone repozytorium i kliknij Usuń.

Aby usunąć zasobnik Storage, w menu nawigacyjnym konsoli Cloud otwórz Przechowywanie, wybierz zasobnik i kliknij Usuń:
