1. Wprowadzenie
W tym laboratorium dowiesz się, jak używać niestandardowych procedur prognozowania w Vertex AI do pisania niestandardowej logiki przetwarzania wstępnego i końcowego. Ten przykład korzysta z biblioteki Scikit-learn, ale niestandardowe procedury prognozowania mogą współpracować z innymi platformami ML w Pythonie, takimi jak XGBoost, PyTorch i TensorFlow.
Czego się nauczysz
- Pisanie niestandardowej logiki prognozowania za pomocą niestandardowych procedur prognozowania
- Lokalne testowanie niestandardowego kontenera udostępniania i modelu
- Testowanie niestandardowego kontenera udostępniania w prognozach Vertex AI
2. Wprowadzenie do Vertex AI
To laboratorium korzysta z najnowszej oferty produktów AI dostępnej w Google Cloud. Vertex AI integruje oferty ML w Google Cloud w ramach bezproblemowego środowiska programistycznego. Wcześniej modele trenowane za pomocą AutoML i modele niestandardowe były dostępne za pomocą oddzielnych usług. Nowa oferta łączy obie te usługi w jeden interfejs API wraz z innymi nowymi produktami. Możesz też przenieść istniejące projekty do Vertex AI.
Vertex AI obejmuje wiele różnych usług, które obsługują kompleksowe przepływy pracy ML. Ten moduł skupi się na prognozach i Workbench.
3. Omówienie przypadku użycia
W tym module utworzysz model regresji lasu losowego, który będzie przewidywać cenę diamentu na podstawie atrybutów takich jak szlif, czystość i rozmiar.
Napiszesz niestandardową logikę przetwarzania wstępnego, aby sprawdzić, czy dane w czasie udostępniania są w formacie oczekiwanym przez model. Napiszesz też niestandardową logikę przetwarzania końcowego, aby zaokrąglić prognozy i przekonwertować je na ciągi znaków. Do napisania tej logiki użyjesz niestandardowych procedur prognozowania.
Wprowadzenie do niestandardowych procedur prognozowania
Gotowe kontenery Vertex AI obsługują żądania prognozowania, wykonując operację prognozowania platformy uczenia maszynowego. Przed wprowadzeniem niestandardowych procedur prognozowania, jeśli chcesz przetworzyć dane wejściowe przed wykonaniem prognozy lub przetworzyć prognozę modelu przed zwróceniem wyniku, musisz utworzyć kontener niestandardowy.
Utworzenie niestandardowego kontenera udostępniania 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.
Dzięki niestandardowym procedurom prognozowania Vertex AI udostępnia komponenty związane z udostępnianiem, dzięki czemu możesz skupić się na modelu i transformacjach danych.
Co utworzysz
Skonfigurujesz sieć VPC o nazwie aiml-vpc, która będzie się składać z podsieci workbench używanej do wdrażania notatnika zarządzanego przez użytkownika oraz uzyskiwania dostępu do prognozowania online i punktu końcowego modelu wdrożonego w regionie us-central1, jak pokazano na rysunku 1 poniżej.
Figure1

4. Włączanie interfejsów API samouczka
Krok 1. Włącz interfejs Compute Engine API
Otwórz Compute Engine i kliknij Włącz, jeśli nie jest jeszcze włączony. Będzie to potrzebne 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łączony. Użyjesz go do utworzenia niestandardowego kontenera udostępniania.
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. Utwórz instancję Vertex AI Workbench
Włącz interfejs Notebooks API, jeśli nie jest jeszcze włączony.
5. Tworzenie sieci aiml-vpc
Ten samouczek korzysta ze zmiennych $variables, aby ułatwić implementację konfiguracji gcloud w Cloud Shell.
W Cloud Shell wykonaj te czynności:
gcloud config list project
gcloud config set project [YOUR-PROJECT-NAME]
projectid=YOUR-PROJECT-NAME
echo $projectid
Utwórz sieć aiml-vpc
W Cloud Shell wykonaj te czynności:
gcloud compute networks create aiml-vpc --project=$projectid --subnet-mode=custom
Utwórz podsieć notatnika zarządzanego przez użytkownika
W Cloud Shell utwórz podsieć workbench-subnet.
gcloud compute networks subnets create workbench-subnet --project=$projectid --range=172.16.10.0/28 --network=aiml-vpc --region=us-central1 --enable-private-ip-google-access
Konfiguracja Cloud Router i Cloud NAT
W samouczku używamy Cloud NAT do pobierania pakietów oprogramowania, ponieważ notatnik zarządzany przez użytkownika nie ma zewnętrznego adresu IP. Cloud NAT zapewnia możliwości NAT wychodzącego, co oznacza, że hosty internetowe nie mogą inicjować komunikacji z notatnikiem zarządzanym przez użytkownika, co zwiększa jego bezpieczeństwo.
W Cloud Shell utwórz regionalny router Cloud Router w regionie us-central1.
gcloud compute routers create cloud-router-us-central1-aiml-nat --network aiml-vpc --region us-central1
W Cloud Shell utwórz regionalną bramę Cloud NAT w regionie us-central1.
gcloud compute routers nats create cloud-nat-us-central1 --router=cloud-router-us-central1-aiml-nat --auto-allocate-nat-external-ips --nat-all-subnet-ip-ranges --region us-central1
6. Tworzenie notatnika zarządzanego przez użytkownika
Utwórz konto usługi zarządzane przez użytkownika (Notebook)
W tej sekcji utworzysz konto usługi zarządzane przez użytkownika, które będzie powiązane z Vertex Workbench (Notebook) używanym w samouczku.
W samouczku do konta usługi zostaną zastosowane te reguły:
W Cloud Shell utwórz konto usługi.
gcloud iam service-accounts create user-managed-notebook-sa \
--display-name="user-managed-notebook-sa"
W Cloud Shell zaktualizuj konto usługi, przypisując mu rolę administratora miejsca na dane.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:user-managed-notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/storage.admin"
W Cloud Shell zaktualizuj konto usługi, przypisując mu rolę użytkownika Vertex AI.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:user-managed-notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/aiplatform.user"
W Cloud Shell zaktualizuj konto usługi, przypisując mu rolę administratora Artifact Registry.
gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:user-managed-notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/artifactregistry.admin"
W Cloud Shell wyświetl listę kont usługi i zanotuj adres e-mail, który będzie używany podczas tworzenia notatnika zarządzanego przez użytkownika.
gcloud iam service-accounts list
Utwórz notatnik zarządzany przez użytkownika
W tej sekcji utworzysz notatnik zarządzany przez użytkownika, który będzie zawierać utworzone wcześniej konto usługi user-managed-notebook-sa.
W Cloud Shell utwórz instancję private-client.
gcloud notebooks instances create workbench-tutorial \
--vm-image-project=deeplearning-platform-release \
--vm-image-family=common-cpu-notebooks \
--machine-type=n1-standard-4 \
--location=us-central1-a \
--shielded-secure-boot \
--subnet-region=us-central1 \
--subnet=workbench-subnet \
--no-public-ip --service-account=user-managed-notebook-sa@$projectid.iam.gserviceaccount.com
7. Pisanie kodu trenowania
Krok 1. Utwórz zasobnik Cloud Storage
Model i artefakty przetwarzania wstępnego 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. Trenuj model
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 otwórz nowy katalog cpr-codelab, a następnie użyj programu uruchamiającego, aby utworzyć nowy notatnik w Pythonie 3 o nazwie task.ipynb.

Twój katalog cpr-codelab powinien teraz wyglądać tak:
+ cpr-codelab/
+ task.ipynb
Wklej ten kod do notatnika.
Najpierw napisz plik requirements.txt.
%%writefile requirements.txt
fastapi
uvicorn==0.17.6
joblib~=1.1.1
numpy>=1.17.3, <1.24.0
scikit-learn~=1.0.0
pandas
google-cloud-storage>=2.2.1,<3.0.0dev
google-cloud-aiplatform[prediction]>=1.18.2
Wdrożony model będzie miał inny zestaw wstępnie zainstalowanych zależności niż środowisko notatnika. Z tego powodu warto wymienić wszystkie zależności modelu w pliku requirements.txt, a następnie użyć pip do zainstalowania dokładnie tych samych zależności w notatniku. Później przetestujesz model lokalnie przed wdrożeniem w Vertex AI, aby sprawdzić, czy środowiska są zgodne.
Pip instaluje zależności w notatniku.
!pip install -U --user -r requirements.txt
Pamiętaj, że po zakończeniu instalacji 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 funkcjami, 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. Widzisz, że każdy wiersz reprezentuje diament.
x_train.head()
A etykiety to odpowiadające im ceny.
y_train.head()
Teraz zdefiniuj przekształcenie kolumny sklearn, aby zakodować funkcje kategorialne i przeskalować funkcje numeryczne.
column_transform = make_column_transformer(
(preprocessing.OneHotEncoder(sparse=False), [1,2,3]),
(preprocessing.StandardScaler(), [0,4,5,6,7,8]))
Zdefiniuj model 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/skalowane, a następnie przekazywane do modelu.
my_pipeline = make_pipeline(column_transform, regr)
Dopasuj potok do danych treningowych.
my_pipeline.fit(x_train, y_train)
Wypróbuj model, aby sprawdzić, czy działa zgodnie z oczekiwaniami. Wywołaj metodę predict w modelu, 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żesz 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 przetwarzania wstępnego. Ten artefakt zostanie wczytany do kontenera niestandardowego po uruchomieniu serwera modelu. Artefakt przetwarzania wstępnego może mieć niemal dowolną postać (np. pliku 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 czystości w naszych danych treningowych zawsze była w skróconej postaci (np. „FL” zamiast „Flawless”). W czasie udostępniania chcemy sprawdzić, czy dane tej funkcji są również skrócone. Wynika to z faktu, że nasz model wie, jak zakodować „FL”, ale nie „Flawless”. Tę niestandardową logikę przetwarzania wstępnego 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
8. Tworzenie niestandardowego kontenera udostępniania za pomocą serwera modelu CPR
Model został już wytrenowany, a artefakt przetwarzania wstępnego zapisany, więc możesz utworzyć niestandardowy kontener udostępniania. Zazwyczaj utworzenie kontenera udostępniania wymaga napisania kodu serwera modelu. Jednak w przypadku niestandardowych procedur prognozowania prognozy Vertex AI generują serwer modelu i tworzą dla Ciebie niestandardowy obraz kontenera.
Niestandardowy kontener udostępniania zawiera te 3 fragmenty kodu:
- Serwer modelu (zostanie wygenerowany automatycznie przez pakiet SDK i zapisany w katalogu scr_dir/)
- Serwer HTTP, który hostuje model
- Odpowiada za konfigurowanie tras, portów itp.
- Odpowiada za aspekty obsługi żądania przez serwer WWW, 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.PredictionHandler udostępnionego w pakiecie SDK.
- Odpowiada za logikę ML przetwarzania żądania prognozy.
Każdy z tych komponentów można dostosować do wymagań przypadku użycia. W tym przykładzie zaimplementujesz tylko predyktor.
Predyktor odpowiada za logikę ML przetwarzania żądania prognozy, taką jak niestandardowe przetwarzanie wstępne i końcowe. Aby napisać niestandardową logikę prognozowania, musisz utworzyć podklasę interfejsu predyktora Vertex AI.
Ta wersja niestandardowych procedur prognozowania zawiera predyktory XGBoost i Sklearn, których można używać ponownie, ale jeśli musisz użyć innej platformy, możesz utworzyć własną, tworząc podklasę predyktora podstawowego.
Poniżej znajdziesz przykład predyktora Sklearn. To cały kod, który musisz napisać, aby utworzyć ten niestandardowy serwer modelu.

Wklej ten kod do notatnika, aby utworzyć podklasę SklearnPredictor i zapisać ją w pliku Pythona w katalogu 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ę bliżej każdej z tych metod.
- Metoda load wczytuje artefakt przetwarzania wstępnego, który w tym przypadku jest słownikiem mapującym wartości czystości diamentu na ich skróty.
- Metoda preprocess używa tego artefaktu, aby zapewnić, że w czasie udostępniania funkcja czystości jest w skróconej postaci. Jeśli nie, przekształca pełny ciąg znaków na jego skrót.
- Metoda postprocess zwraca przewidywaną wartość jako ciąg znaków ze znakiem $ i zaokrągla wartość.
Następnie użyj pakietu Vertex AI Python SDK, aby utworzyć obraz. W przypadku niestandardowych procedur prognozowania plik Dockerfile zostanie wygenerowany, a obraz zostanie utworzony automatycznie.
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"),
)
Napisz plik testowy z 2 próbkami do prognozowania. Jedna z instancji ma skróconą nazwę czystości, ale druga musi zostać najpierw przekonwertowana.
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 zobaczyć za pomocą tego polecenia:
predict_response.content
9. 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 uzyskać 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 przenieś obraz.
local_model.push_image()
I 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ż z prognozowaniem zbiorczym, więc jeśli Twój przypadek użycia nie wymaga prognozowania online, nie musisz wdrażać modelu.
Następnie przenieś obraz.
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! 🎉
W tym module dowiedziałeś się, jak używać Vertex AI do:
- Pisania niestandardowej logiki przetwarzania wstępnego i końcowego za pomocą niestandardowych procedur prognozowania
Cosmopup uważa, że ćwiczenia są super!!

Co dalej?
Dodatkowe materiały i filmy
- Co to jest Vertex AI?
- Pierwsze kroki z Vertex AI
- Które rozwiązanie AI/ML w Vertex AI jest dla mnie odpowiednie?
- Tworzenie systemu odpowiadania na pytania za pomocą Vertex AI
