Vertex AI: trenowanie i udostępnianie modelu niestandardowego

1. Przegląd

W tym laboratorium wykorzystasz Vertex AI do wytrenowania i udostępnienia modelu TensorFlow za pomocą kodu w kontenerze niestandardowym.

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

Czego się dowiesz

Poznasz takie zagadnienia jak:

  • Tworzenie i konteneryzowanie kodu trenowania modelu w Vertex Workbench
  • Przesyłanie zadania trenowania modelu niestandardowego do Vertex AI
  • Wdrożenie wytrenowanego modelu w punkcie końcowym i używanie tego punktu końcowego do uzyskiwania prognoz.

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

Vertex AI obejmuje wiele różnych usług, które obsługują kompleksowe przepływy pracy związane z uczeniem maszynowym. To laboratorium skupi się na wyróżnionych poniżej produktach: trenowaniu, prognozowaniu i Workbench.

Omówienie usługi Vertex

3. 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 Vertex AI API

Otwórz sekcję 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 Container Registry i kliknij Włącz, jeśli nie jest jeszcze włączona. Użyjesz go do utworzenia kontenera na potrzeby niestandardowego zadania trenowania.

Krok 4. Tworzenie instancji Vertex AI Workbench

W sekcji Vertex AI w konsoli Cloud kliknij Workbench:

Menu Vertex AI

Następnie w sekcji Notatniki zarządzane przez użytkownika kliknij Nowy notatnik:

Utwórz nowy notatnik

Następnie wybierz najnowszą wersję typu instancji TensorFlow Enterprise (z LTS) bez procesorów graficznych:

Instancja TFE

Użyj opcji domyślnych, a potem kliknij Utwórz.

Model, który wytrenujemy i wdrożymy w tym laboratorium, jest oparty na tym samouczku z dokumentacji TensorFlow. W samouczku używany jest zbiór danych Auto MPG z Kaggle do przewidywania spalania pojazdu.

4. Konteneryzacja kodu trenowania

Prześlemy to zadanie trenowania do Vertex AI, 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 w dowolnej platformie.

Aby rozpocząć, w menu Launchera otwórz okno terminala w instancji notatnika:

Otwórz terminal w notatniku

Utwórz nowy katalog o nazwie mpg i przejdź do niego:

mkdir mpg
cd mpg

Krok 1. Utwórz plik Dockerfile

Pierwszym krokiem w procesie kontenerowania kodu jest utworzenie pliku Dockerfile. W pliku Dockerfile umieścimy wszystkie polecenia potrzebne do uruchomienia obrazu. Zainstaluje wszystkie używane przez nas biblioteki i skonfiguruje punkt wejścia dla naszego kodu szkoleniowego. W terminalu utwórz pusty plik Dockerfile:

touch Dockerfile

Otwórz plik Dockerfile i skopiuj 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 Deep Learning Container TensorFlow Enterprise 2.3. Kontenery do deep learningu w Google Cloud mają fabrycznie zainstalowanych wiele popularnych platform ML i narzędzi do nauki o danych. Używana przez nas platforma obejmuje m.in. TF Enterprise 2.3, Pandas i Scikit-learn. Po pobraniu tego obrazu ten plik Dockerfile konfiguruje punkt wejścia dla naszego kodu szkoleniowego. Nie utworzyliśmy jeszcze tych plików. W następnym kroku dodamy kod do trenowania i eksportowania modelu.

Krok 2. Utwórz zasobnik Cloud Storage

W ramach zadania trenowania wyeksportujemy wytrenowany model TensorFlow do zasobnika Cloud Storage. Vertex użyje tego do odczytania wyeksportowanych zasobów modelu i wdrożenia modelu. 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 znajdować się w tym samym regionie, w którym w dalszej części samouczka wdrożysz punkt końcowy modelu:

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

Krok 3. Dodaj kod trenowania modelu

W terminalu uruchom to polecenie, aby utworzyć katalog na kod trenowania i plik Pythona, do którego dodamy kod:

mkdir trainer
touch trainer/train.py

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

+ Dockerfile
+ trainer/
    + train.py

Następnie otwórz utworzony plik train.py i skopiuj poniższy kod (pochodzi on z samouczka w dokumentacji TensorFlow).

Na początku pliku zaktualizuj zmienną BUCKET, wpisują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. Tworzenie i testowanie kontenera 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 instancji notatnika, aby sprawdzić, czy działa prawidłowo:

docker run $IMAGE_URI

Trenowanie modelu powinno zakończyć się w ciągu 1–2 minut, a dokładność weryfikacji powinna wynosić około 72% (dokładna wartość może się różnić). Gdy skończysz uruchamiać kontener lokalnie, przenieś go do Google Container Registry:

docker push $IMAGE_URI

Po przeniesieniu kontenera do Container Registry możemy rozpocząć niestandardowe zadanie trenowania modelu.

5. Uruchamianie zadania trenowania w Vertex AI

Vertex AI oferuje 2 opcje trenowania modeli:

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

W tym module używamy trenowania niestandardowego 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. Rozpocznij zadanie trenowania

Kliknij Utwórz, aby wprowadzić 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 inną nazwę, którą chcesz nadać modelowi). Następnie wybierz Kontener niestandardowy:

Opcja niestandardowego kontenera

W polu tekstowym Obraz kontenera kliknij Przeglądaj i znajdź obraz Dockera przesłany przed chwilą do Container Registry. Pozostałe pola pozostaw puste i kliknij Dalej.

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

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

Typ maszyny

Pozostaw pola akceleratora puste i kliknij Dalej. Ponieważ model w tej wersji demonstracyjnej trenuje się szybko, używamy mniejszego typu maszyny.

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

Pozostaw domyślne ustawienia gotowego kontenera. W sekcji Katalog modelu wpisz zasobnik GCS z podkatalogiem mpg. Jest to ścieżka w skrypcie trenowania modelu, w której eksportujesz wytrenowany model:

Ustawienia prognozowania

Vertex będzie szukać w tej lokalizacji podczas wdrażania modelu. Możesz rozpocząć trenowanie. Aby rozpocząć zadanie trenowania, kliknij Rozpocznij trenowanie. W sekcji Trenowanie 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 zasobów modelu. W ramach potoku trenowania Vertex utworzy zasób modelu na podstawie tej ścieżki do zasobu. Sam zasób modelu nie jest wdrożonym modelem, ale gdy masz już model, możesz go wdrożyć w punkcie końcowym. Więcej informacji o modelach i punktach końcowych w Vertex AI znajdziesz w dokumentacji.

W tym kroku utworzymy punkt końcowy dla wytrenowanego modelu. Możemy go użyć do uzyskiwania prognoz dotyczących 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 być widoczny model o nazwie mpg (lub innej, jeśli taką nazwę mu nadano):

Zakończone zadania

Po uruchomieniu zadania trenowania Vertex utworzył zasób modelu. Aby używać tego modelu, musisz wdrożyć punkt końcowy. Każdy model może mieć wiele punktów końcowych. Kliknij model, a następnie kliknij Wdróż w punkcie końcowym.

Wybierz Utwórz nowy punkt końcowy i nadaj mu nazwę, np. v1. W sekcji Dostęp pozostaw wybraną opcję Standardowy, a następnie kliknij Dalej.

Pozostaw wartość 100 w polu Podział ruchu i wpisz 1 w polu Minimalna liczba węzłów obliczeniowych. W sekcji Typ maszyny wybierz n1-standard-2 (lub dowolny inny typ maszyny). Pozostaw wybrane domyślne wartości pozostałych ustawień i kliknij Dalej. Nie włączymy monitorowania tego modelu, więc kliknij Wdróż, aby rozpocząć wdrażanie punktu końcowego.

Wdrożenie punktu końcowego zajmie 10–15 minut. Gdy się zakończy, otrzymasz e-maila. Gdy punkt końcowy zostanie wdrożony, zobaczysz ten komunikat, który pokazuje 1 wdrożony punkt końcowy w zasobie Model:

Wdróż w punkcie końcowym

Krok 2. Uzyskiwanie prognoz na podstawie wdrożonego modelu

Prognozy dotyczące wytrenowanego modelu uzyskamy z notatnika w Pythonie za pomocą interfejsu Vertex Python API. Wróć do instancji notatnika i utwórz notatnik w Pythonie 3 w Menu z aplikacjami:

Otwórz notatnik

Aby zainstalować pakiet Vertex AI SDK, w komórce notatnika wykonaj to polecenie:

!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 endpoint_name musisz zastąpić 2 wartości numerem projektu i punktem końcowym. Numer projektu znajdziesz w panelu informacyjnym 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 w nowej komórce poniższy kod:

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])

Ten przykład zawiera już znormalizowane wartości, czyli format, którego oczekuje nasz model.

Uruchom tę komórkę. Powinna się wyświetlić prognoza wynosząca około 16 mil na galon.

🎉 Gratulacje! 🎉

Dowiedziałeś się, jak używać Vertex AI do:

  • Wytrenuj model, podając kod trenowania w kontenerze niestandardowym. W tym przykładzie użyto modelu TensorFlow, ale za pomocą kontenerów niestandardowych możesz wytrenować model utworzony w dowolnej platformie.
  • Wdróż model TensorFlow za pomocą gotowego kontenera w ramach tego samego przepływu pracy, którego używasz do trenowania.
  • Utwórz punkt końcowy modelu i wygeneruj prognozę.

Więcej informacji o różnych częściach Vertex znajdziesz w dokumentacji.

7. 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 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 Vertex AI, kliknij utworzony punkt końcowy, a następnie wybierz Cofnij wdrożenie modelu z punktu końcowego:

Usuń punkt końcowy

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

Usuń miejsce na dane