1. Wprowadzenie
W tym module dowiesz się, jak używać niestandardowych procedur prognozowania w Vertex AI, aby tworzyć niestandardowe logikę wstępnego i potwierdzenia. W tym przykładzie wykorzystano Scikit-learn, ale niestandardowe procedury prognozowania mogą działać z innymi platformami ML w języku Python, takimi jak XGBoost, PyTorch czy TensorFlow.
Czego się nauczysz
- Zapisz niestandardową logikę prognozowania za pomocą niestandardowych procedur prognozowania
- Testowanie niestandardowego kontenera i modelu lokalnie
- Testowanie niestandardowego kontenera obsługującego w Vertex AI Predictions
2. Wprowadzenie do Vertex AI
W tym module wykorzystano najnowszą ofertę usług AI dostępną w Google Cloud. Vertex AI integruje ofertę systemów uczących się z całego Google Cloud, tworząc bezproblemowe środowisko programistyczne. Wcześniej modele wytrenowane z użyciem AutoML i modele niestandardowe były dostępne w oddzielnych usługach. Nowa oferta jest łączona w 1 interfejs API wraz z innymi nowymi usługami. 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. W tym module skupimy się na prognozach i usłudze Workbench.
3. Omówienie przypadku użycia
W tym module utworzysz losowy model regresji lasu, który pozwoli przewidzieć cenę diamentu na podstawie takich atrybutów jak krój, czytelność i rozmiar.
Napiszesz własną logikę wstępnego przetwarzania, aby sprawdzić, czy dane w momencie wyświetlania są w formacie oczekiwanym przez model. Napisać także niestandardową logikę przetwarzania końcowego w celu zaokrąglenia prognoz i przekształcenia ich w ciągi znaków. Do utworzenia tej logiki użyjesz niestandardowych procedur prognozowania.
Wprowadzenie do niestandardowych rutyn prognozowania
Gotowe kontenery Vertex AI obsługują żądania prognoz, wykonując operację prognozowania na platformie systemów uczących się. Jeśli przed wykonaniem niestandardowych procedur prognozowania trzeba było wstępnie przetworzyć dane wejściowe przed wykonaniem prognozy lub przetworzyć prognozę modelu przed zwróceniem wyniku, trzeba było utworzyć kontener niestandardowy.
Aby utworzyć niestandardowy kontener obsługujący, musisz napisać serwer HTTP, który opakowuje wytrenowany model, tłumaczy żądania HTTP na dane wejściowe modelu i przekształca dane wyjściowe modelu w odpowiedzi.
Dzięki niestandardowym procedurom prognozowania Vertex AI udostępnia komponenty związane z obsługą, dzięki czemu możesz się skupić na przekształceniach modelu i danych.
Co utworzysz
Skonfigurujesz sieć VPC o nazwie cell-vpc, która składa się z podsieci obszaru roboczego używanej do wdrażania notatnika zarządzanego przez użytkownika oraz do punktu końcowego prognozy online i punktu końcowego modelu wdrożonego w us-central1, jak pokazano na ilustracji 1 poniżej.
Figure1
4. Włącz interfejsy API samouczka
Krok 1. Włącz Compute Engine API
Przejdź do Compute Engine i wybierz opcję Włącz, jeśli nie jest jeszcze włączona. Będzie Ci to potrzebne do utworzenia instancji notatnika.
Krok 2. Włącz Artifact Registry API
Otwórz Artifact Registry i wybierz Włącz, jeśli nie jest jeszcze włączone. W ten sposób utworzysz niestandardowy kontener wyświetlania.
Krok 3. Włącz interfejs Vertex AI API
Przejdź do sekcji Vertex AI w konsoli Cloud i kliknij Włącz interfejs Vertex AI API.
Krok 4. Utwórz instancję Vertex AI Workbench
Włącz Notebooks API, jeśli nie jest jeszcze włączona.
5. Tworzenie celu LPC
W tym samouczku używamy zmiennych $variables, które ułatwiają 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
Tworzenie pliku cell-vpc
W Cloud Shell wykonaj te czynności:
gcloud compute networks create aiml-vpc --project=$projectid --subnet-mode=custom
Tworzenie podsieci notatnika zarządzanej przez użytkownika
Utwórz podsieć obszaru roboczego w Cloud Shell.
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 NAT
W tym samouczku usługa Cloud NAT jest używana do pobierania pakietów oprogramowania, ponieważ notatnik zarządzany przez użytkownika nie ma zewnętrznego adresu IP. Cloud NAT zapewnia funkcje NAT dla ruchu 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 – 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 o nazwie 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
Tworzenie konta usługi zarządzanego przez użytkownika (notatnik)
W tej sekcji utworzysz konto usługi zarządzane przez użytkownika, które zostanie powiązane z Vertex Workbench (Notatnik) używanym w samouczku.
W samouczku na koncie usługi zostaną zastosowane te reguły:
Utwórz konto usługi w Cloud Shell.
gcloud iam service-accounts create user-managed-notebook-sa \
--display-name="user-managed-notebook-sa"
W Cloud Shell zaktualizuj konto usługi, przypisując do niego rolę Administrator 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, dodając do niego 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, dodając do niego rolę Administrator 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 wymień konto 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
Tworzenie notatnika zarządzanego przez użytkownika
W następnej sekcji utwórz notatnik zarządzany przez użytkownika zawierający utworzone wcześniej konto usługi – user-managed-notebook-sa.
Utwórz w Cloud Shell instancję klienta prywatnego.
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
W zasobniku Cloud Storage będziesz przechowywać model i artefakty wstępnego przetwarzania. Jeśli w projekcie masz już zasobnik, którego chcesz użyć, możesz pominąć ten krok.
W Menu z aplikacjami otwórz nową sesję terminala.
Uruchom w terminalu to polecenie, aby zdefiniować zmienną env dla swojego projektu. Zastąp „your-cloud-project” identyfikatorem swojego projektu:
PROJECT_ID='your-cloud-project'
Następnie uruchom to polecenie w terminalu, aby utworzyć nowy zasobnik w projekcie.
BUCKET="gs://${PROJECT_ID}-cpr-bucket"
gsutil mb -l us-central1 $BUCKET
Krok 2. Wytrenuj model
W terminalu utwórz nowy katalog o nazwie cpr-codelab i umieść w nim dysk cd.
mkdir cpr-codelab
cd cpr-codelab
W przeglądarce plików przejdź do nowego katalogu cpr-codelab, a następnie w programie uruchamiającym utwórz nowy notatnik w Pythonie 3 o nazwie Tasks.ipynb.
Katalog cpr-codelab powinien teraz wyglądać tak:
+ cpr-codelab/
+ task.ipynb
W notatniku wklej ten kod.
Najpierw utwórz 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ł wstępnie zainstalowany inny zestaw zależności niż środowisko notatnika. Z tego powodu warto wyświetlić listę wszystkich zależności modelu w pliku requirements.txt, a następnie użyć narzędzia pip, aby zainstalować w notatniku dokładnie te same zależności. Później przetestujesz model lokalnie, zanim wdrożysz go w Vertex AI, aby dokładnie 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ć artefakty modelu i artefaktów wstępnego przetwarzania.
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
Katalog cpr-codelab powinien teraz wyglądać tak:
+ cpr-codelab/
+ model_artifacts/
+ scr_dir/
+ requirements.txt
+ task.ipynb
+ requirements.txt
Po skonfigurowaniu struktury katalogów nadszedł czas na wytrenowanie modelu.
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 poniższe zmienne. Pamiętaj, aby zastąpić PROJECT_ID identyfikatorem projektu, a wartość 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 morskiej, a następnie utwórz 2 ramki danych: jedną z funkcjami i 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'])
Spójrzmy na dane treningowe. Jak widać, każdy wiersz przedstawia diament.
x_train.head()
I etykiety, czyli odpowiadające im ceny.
y_train.head()
Teraz zdefiniuj sklearn przekształcenie kolumny, aby zakodować cechy kategorialne i przeskalować je na jeden ciąg, aby przeskalować wartości liczbowe.
column_transform = make_column_transformer(
(preprocessing.OneHotEncoder(sparse=False), [1,2,3]),
(preprocessing.StandardScaler(), [0,4,5,6,7,8]))
Zdefiniuj losowy model lasu
regr = RandomForestRegressor(max_depth=10, random_state=0)
Następnie utwórz potok sklearn. Oznacza to, że dane przesyłane do tego potoku zostaną najpierw zakodowane/skalowane, a następnie przekazane do modelu.
my_pipeline = make_pipeline(column_transform, regr)
Dopasowanie potoku do danych treningowych
my_pipeline.fit(x_train, y_train)
Wypróbujmy model, aby się upewnić, że działa zgodnie z oczekiwaniami. Wywołaj metodę prognozowania 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ż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 utwórz artefakt wstępnego przetwarzania. Ten artefakt zostanie wczytany do kontenera niestandardowego po uruchomieniu serwera modelu. Artefakt wstępnego przetwarzania może mieć niemal dowolną postać (np. plik z piklem), ale w takim przypadku musisz zapisać słownik do pliku JSON.
clarity_dict={"Flawless": "FL",
"Internally Flawless": "IF",
"Very Very Slightly Included": "VVS1",
"Very Slightly Included": "VS2",
"Slightly Included": "S12",
"Included": "I3"}
W naszych danych szkoleniowych zawsze podawane były skróty w postaci skróconej (np. „FL” zamiast „Flawless”). Podczas wyświetlania chcemy sprawdzić, czy dane dotyczące tej funkcji również zostały skrócone. Dzieje się tak, ponieważ nasz model wie, jak zakodować jeden „FL” z gorącą ale nie „bez łat”. Później napiszesz ten niestandardowy mechanizm wstępnego przetwarzania danych. Na razie zapisz tabelę wyszukiwania w pliku JSON, a potem zapisz go 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}/
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. Utwórz niestandardowy kontener obsługujący za pomocą serwera modelu CPR
Po wytrenowaniu modelu i zapisaniu artefaktu przetwarzania wstępnego możesz więc utworzyć niestandardowy kontener do wyświetlania. Zwykle utworzenie kontenera obsługującego wymaga napisania kodu serwera modelu. Jednak w przypadku niestandardowych procedur prognozowania Vertex AI Predictions generuje serwer modeli i tworzy dla Ciebie niestandardowy obraz kontenera.
Niestandardowy kontener wyświetlania zawiera 3 fragmenty kodu:
- Serwer modelu (zostanie wygenerowany automatycznie przez pakiet SDK i zapisany w scr_dir/)
- Serwer HTTP hostujący model
- Odpowiada za konfigurację tras, portów itp.
- Odpowiada za różne aspekty obsługi żądań przez serwer WWW, takie jak deserializacja treści żądania, 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 w pakiecie SDK.
- Odpowiada za logikę ML za przetwarzanie żądania prognozy.
Każdy z tych komponentów można dostosowywać do swoich potrzeb. W tym przykładzie wdrożysz tylko prognozowanie.
Predyktor odpowiada za logikę ML za przetwarzanie żądania prognozy, na przykład za niestandardowe wstępne przetwarzanie i po przetwarzaniu. Aby napisać niestandardową logikę prognozowania, musisz podklasować interfejs Vertex AI Predictor.
Ta wersja niestandardowych procedur prognozowania zawiera predykatory wielokrotnego użytku XGBoost i Sklearn, ale jeśli chcesz użyć innej platformy, możesz utworzyć własną, podklasyfikując podstawowe prognozy.
Poniżej znajdziesz przykład prognozatora Sklearn. To jest cały kod, który trzeba napisać, aby zbudować serwer z modelem niestandardowym.
W notatniku wklej poniższy kod, aby podklasyfikować SklearnPredictor i zapisać go w pliku Pythona w katalogu src_dir/. Pamiętaj, że w tym przykładzie dostosowujemy tylko metody wczytywania, wstępnego przetwarzania i po zakończeniu przetwarzania, a nie metodę prognozowania.
%%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 wczytywania wczytuje się do artefaktu przetwarzania wstępnego, którym jest w tym przypadku słownik, który mapuje wartości przejrzystości diamentów na ich skróty.
- Metoda wstępnego przetwarzania korzysta z tego artefaktu, aby mieć pewność, że w momencie wyświetlenia funkcja przejrzystości ma format skrócony. W przeciwnym razie przekształca cały ciąg na jego skrót.
- Metoda postprocess zwraca prognozowaną wartość w postaci ciągu znaków ze znakiem $ i zaokrągla wartość.
Następnie utwórz obraz za pomocą pakietu SDK Vertex AI Python. Przy użyciu niestandardowych procedur prognozowania zostanie wygenerowany plik Dockerfile i stworzony dla Ciebie 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"),
)
Napisz plik testowy z 2 przykładami do wykorzystania w prognozie. Jeden z nich ma skróconą nazwę przejrzystości, ale drugi musi zostać najpierw przekonwertowany.
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ć w tych celach:
predict_response.content
9. Wdrażanie modelu w Vertex AI
Po lokalnym przetestowaniu kontenera musisz 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 wypchnij 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}",)
Gdy model zostanie przesłany, powinien być widoczny w konsoli:
Następnie wdróż model, aby móc go używać do prognoz online. Niestandardowe procedury prognozowania współpracują również z prognozami zbiorczymi, więc jeśli Twój przypadek użycia nie wymaga prognoz online, nie musisz wdrażać modelu.
Następnie wypchnij obraz.
endpoint = model.deploy(machine_type="n1-standard-2")
Na koniec przetestuj wdrożony model, pobierając prognozę.
endpoint.predict(instances=[[0.23, 'Ideal', 'E', 'VS2', 61.5, 55.0, 3.95, 3.98, 2.43]])
🎉 Gratulacje! 🎉
Wiesz już, jak używać Vertex AI do:
- Napisz niestandardową logikę wstępnego i potwierdzenia za pomocą niestandardowych procedur prognozowania
Cosmopup uważa, że ćwiczenia z programowania są świetne!
Co dalej?
Więcej informacji 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 odpowiedzi na pytania przy użyciu Vertex AI