Vertex AI: trenowanie i udostępnianie modelu niestandardowego

1. Omówienie

W tym module wykorzystasz Vertex AI do wytrenowania i obsługi modelu TensorFlow za pomocą kodu w niestandardowym kontenerze.

W tym przykładzie do kodu modelu używamy TensorFlow, ale możesz go łatwo zastąpić inną platformą.

Czego się nauczysz

Poznasz takie zagadnienia jak:

  • Tworzenie i konteneryzacja kodu trenowania modelu w Vertex Workbench
  • Przesyłanie niestandardowego zadania trenowania do Vertex AI
  • Wdróż wytrenowany model w punkcie końcowym i używaj tego punktu końcowego do uzyskiwania prognoz

Łączny koszt przeprowadzenia tego laboratorium w Google Cloud wynosi około 1 USD.

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. Jeśli masz jakieś uwagi, odwiedź stronę pomocy.

Vertex AI zawiera wiele różnych usług, które obsługują kompleksowe przepływy pracy związane z systemami uczącymi się. Ten moduł będzie dotyczył wymienionych poniżej usług: Training, Prediction i Workbench.

Omówienie usługi Vertex

3. Konfigurowanie środowiska

Aby uruchomić to ćwiczenie, musisz mieć projekt Google Cloud Platform z włączonym rozliczeniem. Aby utworzyć projekt, postępuj zgodnie z tymi instrukcjami.

Krok 1. Włącz Compute Engine API

Przejdź do Compute Engine i wybierz Włącz, jeśli usługa nie jest jeszcze włączona. Potrzebujesz go do utworzenia instancji notatnika.

Krok 2. Włącz interfejs Vertex AI API

Przejdź do sekcji Vertex AI w konsoli Cloud i kliknij Włącz interfejs Vertex AI API.

Panel Vertex AI

Krok 3. Włącz interfejs Container Registry API

Otwórz rejestr kontenerów i wybierz Włącz, jeśli nie jest jeszcze włączony. Użyjesz go do utworzenia kontenera na potrzeby niestandardowego zadania trenowania.

Krok 4. Utwórz instancję Vertex AI Workbench

W konsoli Cloud w sekcji Vertex AI kliknij Workbench:

Menu Vertex AI

Następnie na karcie Notatniki zarządzane przez użytkownika kliknij Nowy notatnik:

Tworzenie nowego notatnika

Następnie wybierz najnowszą wersję typu instancji TensorFlow Enterprise (z LTS) bez GPU:

Instancja TFE

Użyj opcji domyślnych i kliknij Utwórz.

Model, który będziemy trenować i umieszczać w tym module, został utworzony na podstawie tego samouczka z dokumentacji TensorFlow. W tym samouczku do przewidywania zużycia paliwa przez pojazd użyto danych Auto MPG z Kaggle.

4. Konteneryzacja kodu trenowania

Prześlemy to zadanie trenowania do Vertex, umieszczając kod trenowania w kontenerze Dockera i przesyłając ten kontener do Google Container Registry. Dzięki temu możemy wytrenować model utworzony za pomocą dowolnego frameworku.

Aby rozpocząć, w menu Menu z aplikacjami otwórz okno terminala w instancji notatnika:

Otwórz terminal w notatniku

Utwórz nowy katalog o nazwie mpg i znajdź do niego dysk CD:

mkdir mpg
cd mpg

Krok 1. Utwórz plik Dockerfile

Pierwszym krokiem w konteneryzacji kodu jest utworzenie pliku Dockerfile. W pliku Dockerfile uwzględnimy wszystkie polecenia potrzebne do uruchomienia obrazu. Spowoduje to zainstalowanie wszystkich bibliotek, których używamy, i ustawienie punktu wejścia dla kodu treningowego. W terminalu utwórz pusty plik Dockerfile:

touch Dockerfile

Otwórz plik Dockerfile i wklej do niego ten kod:

FROM gcr.io/deeplearning-platform-release/tf2-cpu.2-6
WORKDIR /

# Copies the trainer code to the docker image.
COPY trainer /trainer

# Sets up the entry point to invoke the trainer.
ENTRYPOINT ["python", "-m", "trainer.train"]

Ten plik Dockerfile używa obrazu Dockera TensorFlow Enterprise 2.3 dla Deep Learning Container. Kontenery do głębokiego uczenia się w Google Cloud są dostarczane z wstępnie zainstalowanymi popularnymi platformami do tworzenia systemów uczących się i narzędzi do analizy danych. Używamy między innymi TF Enterprise 2.3, Pandas i Scikit-learn. Po pobraniu tego obrazu plik Dockerfile konfiguruje punkt początkowy dla kodu trenowania. Te pliki nie zostały jeszcze utworzone. W następnym kroku dodamy kod do trenowania i eksportowania modelu.

Krok 2. Utwórz zasobnik Cloud Storage

W zadaniu treningowym wyeksportujemy wytrenowany model TensorFlow do zasobnika Cloud Storage. Vertex będzie używać tego pliku do odczytywania zasobów wyeksportowanego modelu i jego wdrażania. 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. Flaga -l (lokalizacja) jest ważna, ponieważ musi być w tym samym regionie, w którym wdrożysz punkt końcowy modelu w dalszej części samouczka:

BUCKET_NAME="gs://${PROJECT_ID}-bucket"
gsutil mb -l us-central1 $BUCKET_NAME

Krok 3. Dodaj kod do trenowania modelu

W terminalu uruchom te polecenia, aby utworzyć katalog z kodem szkoleniowym i plik Pythona, do którego dodasz kod:

mkdir trainer
touch trainer/train.py

W katalogu mpg/ powinny teraz znajdować się te pliki:

+ Dockerfile
+ trainer/
    + train.py

Następnie otwórz utworzony właśnie plik train.py i skopiuj kod poniżej (jest to wersja samouczka w dokumentacji TensorFlow).

Na początku pliku zaktualizuj zmienną BUCKET, podając nazwę zasobnika na dane utworzonego w poprzednim kroku:

import numpy as np
import pandas as pd
import pathlib
import tensorflow as tf

from tensorflow import keras
from tensorflow.keras import layers

print(tf.__version__)

"""## The Auto MPG dataset

The dataset is available from the [UCI Machine Learning Repository](https://archive.ics.uci.edu/ml/).

### Get the data
First download the dataset.
"""

dataset_path = keras.utils.get_file("auto-mpg.data", "http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data")
dataset_path

"""Import it using pandas"""

column_names = ['MPG','Cylinders','Displacement','Horsepower','Weight',
                'Acceleration', 'Model Year', 'Origin']
dataset = pd.read_csv(dataset_path, names=column_names,
                      na_values = "?", comment='\t',
                      sep=" ", skipinitialspace=True)

dataset.tail()

# TODO: replace `your-gcs-bucket` with the name of the Storage bucket you created earlier
BUCKET = 'gs://your-gcs-bucket'

"""### Clean the data

The dataset contains a few unknown values.
"""

dataset.isna().sum()

"""To keep this initial tutorial simple drop those rows."""

dataset = dataset.dropna()

"""The `"Origin"` column is really categorical, not numeric. So convert that to a one-hot:"""

dataset['Origin'] = dataset['Origin'].map({1: 'USA', 2: 'Europe', 3: 'Japan'})

dataset = pd.get_dummies(dataset, prefix='', prefix_sep='')
dataset.tail()

"""### Split the data into train and test

Now split the dataset into a training set and a test set.

We will use the test set in the final evaluation of our model.
"""

train_dataset = dataset.sample(frac=0.8,random_state=0)
test_dataset = dataset.drop(train_dataset.index)

"""### Inspect the data

Have a quick look at the joint distribution of a few pairs of columns from the training set.

Also look at the overall statistics:
"""

train_stats = train_dataset.describe()
train_stats.pop("MPG")
train_stats = train_stats.transpose()
train_stats

"""### Split features from labels

Separate the target value, or "label", from the features. This label is the value that you will train the model to predict.
"""

train_labels = train_dataset.pop('MPG')
test_labels = test_dataset.pop('MPG')

"""### Normalize the data

Look again at the `train_stats` block above and note how different the ranges of each feature are.

It is good practice to normalize features that use different scales and ranges. Although the model *might* converge without feature normalization, it makes training more difficult, and it makes the resulting model dependent on the choice of units used in the input.

Note: Although we intentionally generate these statistics from only the training dataset, these statistics will also be used to normalize the test dataset. We need to do that to project the test dataset into the same distribution that the model has been trained on.
"""

def norm(x):
  return (x - train_stats['mean']) / train_stats['std']
normed_train_data = norm(train_dataset)
normed_test_data = norm(test_dataset)

"""This normalized data is what we will use to train the model.

Caution: The statistics used to normalize the inputs here (mean and standard deviation) need to be applied to any other data that is fed to the model, along with the one-hot encoding that we did earlier.  That includes the test set as well as live data when the model is used in production.

## The model

### Build the model

Let's build our model. Here, we'll use a `Sequential` model with two densely connected hidden layers, and an output layer that returns a single, continuous value. The model building steps are wrapped in a function, `build_model`, since we'll create a second model, later on.
"""

def build_model():
  model = keras.Sequential([
    layers.Dense(64, activation='relu', input_shape=[len(train_dataset.keys())]),
    layers.Dense(64, activation='relu'),
    layers.Dense(1)
  ])

  optimizer = tf.keras.optimizers.RMSprop(0.001)

  model.compile(loss='mse',
                optimizer=optimizer,
                metrics=['mae', 'mse'])
  return model

model = build_model()

"""### Inspect the model

Use the `.summary` method to print a simple description of the model
"""

model.summary()

"""Now try out the model. Take a batch of `10` examples from the training data and call `model.predict` on it.

It seems to be working, and it produces a result of the expected shape and type.

### Train the model

Train the model for 1000 epochs, and record the training and validation accuracy in the `history` object.

Visualize the model's training progress using the stats stored in the `history` object.

This graph shows little improvement, or even degradation in the validation error after about 100 epochs. Let's update the `model.fit` call to automatically stop training when the validation score doesn't improve. We'll use an *EarlyStopping callback* that tests a training condition for  every epoch. If a set amount of epochs elapses without showing improvement, then automatically stop the training.

You can learn more about this callback [here](https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/EarlyStopping).
"""

model = build_model()

EPOCHS = 1000

# The patience parameter is the amount of epochs to check for improvement
early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)

early_history = model.fit(normed_train_data, train_labels, 
                    epochs=EPOCHS, validation_split = 0.2, 
                    callbacks=[early_stop])


# Export model and save to GCS
model.save(BUCKET + '/mpg/model')

Krok 4. Utwórz i przetestuj kontener lokalnie

W terminalu zdefiniuj zmienną z identyfikatorem URI obrazu kontenera w Google Container Registry:

IMAGE_URI="gcr.io/$PROJECT_ID/mpg:v1"

Następnie utwórz kontener, uruchamiając to polecenie w katalogu głównym mpg:

docker build ./ -t $IMAGE_URI

Uruchom kontener w ramach instancji notatnika, aby sprawdzić, czy działa on prawidłowo:

docker run $IMAGE_URI

Trenowanie modelu powinno zakończyć się po 1–2 minutach, a dokładność weryfikacji wyniesie około 72% (dokładna dokładność może się różnić). Po uruchomieniu kontenera lokalnie przenieś go do Google Container Registry:

docker push $IMAGE_URI

Po przekazaniu kontenera do Container Registry możemy teraz rozpocząć zadanie trenowania modelu niestandardowego.

5. Uruchamianie zadania treningowego w Vertex AI

Vertex AI oferuje 2 opcje trenowania modeli:

  • AutoML trenowanie wysokiej jakości modeli systemów uczących się przy minimalnym nakładzie pracy i bez specjalistycznej wiedzy z tej dziedziny.
  • Trenowanie niestandardowe: uruchamiaj niestandardowe aplikacje treningowe w chmurze, korzystając z jednego z gotowych kontenerów Google Cloud lub własnego.

W tym laboratorium korzystamy z niestandardowego treningu za pomocą własnego kontenera niestandardowego w Google Container Registry. Na początek otwórz sekcję Modele w sekcji Vertex w konsoli Cloud:

Menu Vertex

Krok 1. Uruchom zadanie trenowania

Kliknij Utwórz, aby podać parametry zadania trenowania i wdrożonego modelu:

  • W sekcji Zbiór danych wybierz Brak zarządzanego zbioru danych.
  • Następnie jako metodę trenowania wybierz Trenowanie niestandardowe (zaawansowane) i kliknij Dalej.
  • Kliknij Dalej.

W następnym kroku w polu Nazwa modelu wpisz mpg (lub dowolną nazwę modelu). Następnie wybierz Kontener niestandardowy:

Opcja kontenera niestandardowego

W polu tekstowym Obraz kontenera kliknij Przeglądaj i znajdź obraz Dockera, który został właśnie przesłany do Container Registry. Pozostałe pola pozostaw puste i kliknij Dalej.

W tym samouczku nie będziemy używać dostrajania hiperparametrów, więc nie zaznaczaj pola Włącz dostrajanie hiperparametrów i kliknij Dalej.

W sekcji Obliczenia i ceny pozostaw wybrany region bez zmian i jako typ maszyny wybierz n1-standard-4:

Typ maszyny

Pozostaw pola akceleratora puste i kliknij Dalej. Ponieważ model w tym pokazie trenuje szybko, używamy mniejszego typu maszyny.

W kroku Kontener prognozy wybierz Gotowy kontener, a następnie TensorFlow 2.6.

Pozostaw domyślne ustawienia gotowego kontenera bez zmian. W sekcji Katalog modeli wpisz zasobnik GCS z podkatalogiem mpg. To jest ścieżka w skrypcie trenowania modelu, w której wyeksportujesz wytrenowany model:

Ustawienia prognozowania

Vertex będzie szukać w tej lokalizacji podczas wdrażania modelu. Możesz już rozpocząć trening. Aby rozpocząć zadanie trenowania, kliknij Rozpocznij trenowanie. W sekcji Trening w konsoli zobaczysz coś takiego:

Zadania trenowania

6. Wdrażanie punktu końcowego modelu

Podczas konfigurowania zadania trenowania określiliśmy, gdzie Vertex AI ma szukać wyeksportowanych komponentów modelu. W ramach potoku trenowania Vertex utworzy zasób modelu na podstawie ścieżki zasobu. Sam zasób modelu nie jest wdrożonym modelem, ale gdy już go masz, możesz go wdrożyć w punkcie końcowym. Aby dowiedzieć się więcej o modelach i punktach końcowych w Vertex AI, zapoznaj się z tą dokumentacją.

Na tym etapie utworzymy punkt końcowy dla wytrenowanego modelu. Możemy go użyć do uzyskania prognoz na podstawie naszego modelu za pomocą interfejsu Vertex AI API.

Krok 1. Wdróż punkt końcowy

Po zakończeniu zadania trenowania w sekcji Modele w konsoli powinien pojawić się model o nazwie mpg (lub innej jej nazwie):

Ukończone zadania

Gdy zadanie trenowania zostało uruchomione, Vertex utworzył dla Ciebie zasób modelu. Aby korzystać z tego modelu, musisz wdrożyć punkt końcowy. Na jeden model możesz mieć wiele punktów końcowych. Kliknij model, a potem Wdróż w punkcie końcowym.

Wybierz Utwórz nowy punkt końcowy i nadaj mu nazwę, np. v1. Pozostaw jako wybraną opcję Standardowy w sekcji Dostęp i kliknij Dalej.

Pozostaw ustawienie Podział ruchu na 100, a w polu Minimalna liczba węzłów obliczeniowych wpisz 1. W sekcji Typ maszyny wybierz n1-standard-2 (lub dowolny typ maszyny). Pozostaw inne domyślne wartości, a potem kliknij Dalej. Nie będziemy monitorować tego modelu, więc teraz kliknij Wdróż, aby rozpocząć wdrożenie punktu końcowego.

Wdrożenie punktu końcowego zajmie 10–15 minut. Po jego zakończeniu otrzymasz e-maila. Po zakończeniu wdrażania punktu końcowego zobaczysz widok, który pokazuje 1 punkt końcowy wdrożony w zasobie modelu:

Wdróż w punkcie końcowym

Krok 2. Uzyskaj prognozy dla wdrożonego modelu

Na podstawie wytrenowanego modelu będziemy otrzymywać prognozy z notatnika w języku Python przy użyciu interfejsu Vertex Python API. Wróć do instancji notatnika i za pomocą programu uruchamiającego utwórz notatnik w języku Python 3:

Otwórz notatnik

Aby zainstalować pakiet Vertex AI SDK, w notatniku wykonaj w komórce ten kod:

!pip3 install google-cloud-aiplatform --upgrade --user

Następnie dodaj komórkę w notatniku, aby zaimportować pakiet SDK i utworzyć odwołanie do właśnie wdrożonego punktu końcowego:

from google.cloud import aiplatform

endpoint = aiplatform.Endpoint(
    endpoint_name="projects/YOUR-PROJECT-NUMBER/locations/us-central1/endpoints/YOUR-ENDPOINT-ID"
)

W powyższym ciągu znaków endpoint_name musisz zastąpić 2 wartości numerem projektu i adresem punktu końcowego. Numer projektu znajdziesz w panelu projektu, w polu Numer projektu.

Identyfikator punktu końcowego znajdziesz w sekcji punktów końcowych w konsoli:

Znajdowanie identyfikatora punktu końcowego

Na koniec utwórz prognozę dla punktu końcowego, kopiując i uruchamiając poniższy kod w nowej komórce:

test_mpg = [1.4838871833555929,
 1.8659883497083019,
 2.234620276849616,
 1.0187816540094903,
 -2.530890710602246,
 -1.6046416850441676,
 -0.4651483719733302,
 -0.4952254087173721,
 0.7746763768735953]

response = endpoint.predict([test_mpg])

print('API response: ', response)

print('Predicted MPG: ', response.predictions[0][0])

W tym przykładzie wartości są już znormalizowane, czyli w takim formacie, którego oczekuje model.

Po uruchomieniu tej komórki powinieneś zobaczyć prognozę około 16 mil na galon.

🎉 Gratulacje! 🎉

Poznałeś/poznałaś już te sposoby korzystania z Vertex AI:

  • Wytrenuj model, przesyłając kod trenowania w kontenerze niestandardowym. W tym przykładzie użyto modelu TensorFlow, ale możesz wytrenować model utworzony za pomocą dowolnego frameworku, korzystając z niestandardowych kontenerów.
  • Wdrożyć model TensorFlow za pomocą gotowego kontenera w ramach tego samego przepływu pracy, który został użyty do trenowania.
  • Utwórz punkt końcowy modelu i wygeneruj prognozę.

Więcej informacji o różnych elementach Vertex znajdziesz w dokumentacji.

7. Czyszczenie

Jeśli chcesz nadal korzystać z notatnika utworzonego w tym laboratorium, zalecamy jego wyłączenie, gdy go nie używasz. W interfejsie Workbench w konsoli Cloud wybierz notebook, a następnie Zatrzymaj.

Jeśli chcesz całkowicie usunąć zeszyt, w prawym górnym rogu kliknij przycisk Usuń.

Aby usunąć wdrożony punkt końcowy, otwórz sekcję Punkty końcowe w konsoli Vertex AI, kliknij utworzony punkt końcowy, a następnie wybierz Odmów wdrażania modelu w punkcie końcowym:

Usuń punkt końcowy

Aby usunąć zasobnik Cloud Storage, w menu nawigacyjnym konsoli Cloud przejdź do usługi Storage, wybierz zasobnik i kliknij Usuń:

Usuń miejsce na dane