Vertex AI: trenowanie i udostępnianie modelu niestandardowego

1. Omówienie

W tym module za pomocą Vertex AI wytrenujesz i udostępnisz model 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 konteneryzowanie kodu trenowania modelu w Vertex Workbench
  • Przesyłanie zadania trenowania modelu niestandardowego do Vertex AI
  • Wdróż w punkcie końcowym wytrenowany model i użyj tego punktu końcowego do otrzymywania prognoz

Całkowity koszt uruchomienia tego modułu 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 za pomocą AutoML i modele niestandardowe były dostępne za pomocą oddzielnych usług. Nowa oferta łączy oba te interfejsy API 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 obejmuje wiele różnych usług, które obsługują kompleksowe przepływy pracy ML. W tym module skupimy się na wyróżnionych poniżej usługach: Training, Prognozowanie i Workbench.

Omówienie usługi Vertex

3. Skonfiguruj środowisko

Aby uruchomić to ćwiczenia z programowania, musisz mieć projekt Google Cloud Platform z włączonymi płatnościami. Aby utworzyć projekt, postępuj zgodnie z tymi instrukcjami.

Krok 1. Włącz Compute Engine API

Przejdź do Compute Engine i wybierz opcję Włącz, jeśli 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 Container Registry API

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

Krok 4. Utwórz instancję Vertex AI Workbench

W sekcji Vertex AI w konsoli Cloud kliknij Workbench:

Menu Vertex AI

Następnie na karcie 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 GPU:

Instancja TFE

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

Model, który będziemy trenować i udostępniać w tym module, powstał na podstawie tego samouczka z Dokumentów TensorFlow. Samouczek wykorzystuje zbiór danych Auto SpG firmy Kaggle do przewidywania spalania pojazdu.

4. Konteneryzowanie kodu trenowania

Prześlemy to zadanie treningowe do Vertex, umieszczając kod trenowania w kontenerze Dockera i wypchają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 znajdą się wszystkie polecenia potrzebne do uruchomienia obrazu. Zainstaluje wszystkie używane biblioteki i skonfiguruje punkt wejścia dla kodu trenowania. W terminalu utwórz pusty plik Dockerfile:

touch Dockerfile

Otwórz plik Dockerfile i skopiuj do niego poniższy plik:

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 wykorzystuje obraz Dockera TensorFlow Enterprise 2.3. Kontenery do deep learningu w Google Cloud mają wstępnie zainstalowane wiele popularnych platform do uczenia maszynowego i platformy do badania 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. Nie utworzyliśmy jeszcze tych plików – w następnym kroku dodamy kod do trenowania i eksportowania naszego modelu.

Krok 2. Utwórz zasobnik Cloud Storage

W zadaniu treningowym wyeksportujemy wytrenowany model TensorFlow do zasobnika Cloud Storage. Vertex użyje ich do odczytywania wyeksportowanych zasobów modelu i wdrożenia modelu. W terminalu uruchom to polecenie, aby zdefiniować zmienną env dla swojego projektu, pamiętając o zastąpieniu your-cloud-project identyfikatorem projektu:

PROJECT_ID='your-cloud-project'

Następnie uruchom to polecenie w terminalu, 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 trenowania modelu

W terminalu uruchom to polecenie, aby utworzyć katalog dla kodu trenowania oraz plik Pythona, w którym dodamy ten kod:

mkdir trainer
touch trainer/train.py

W katalogu mpg/ powinny znajdować się następujące elementy:

+ Dockerfile
+ trainer/
    + train.py

Następnie otwórz utworzony plik train.py i skopiuj poniższy kod (został on zaadaptowany z 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 z poziomu głównego katalogu 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ę w ciągu 1–2 minut z dokładnością walidacji na poziomie około 72% (dokładna dokładność może być różna). Gdy zakończysz uruchamianie kontenera lokalnie, wypchnij go do Google Container Registry:

docker push $IMAGE_URI

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

5. Uruchamianie zadania trenowania w Vertex AI

Vertex AI udostępnia 2 opcje dotyczące modeli trenowania:

  • AutoML: trenuj wysokiej jakości modele przy minimalnym nakładzie pracy i bez specjalistycznej wiedzy z zakresu systemów uczących się.
  • Trenowanie niestandardowe: uruchamiaj niestandardowe aplikacje treningowe w chmurze za pomocą jednego z gotowych kontenerów Google Cloud lub użyj własnego.

W tym module używamy trenowania niestandardowego z wykorzystaniem własnego niestandardowego kontenera w Google Container Registry. Aby rozpocząć, przejdź do sekcji Modele w sekcji Vertex w konsoli Cloud:

Menu Vertex

Krok 1. Rozpoczynanie pracy

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

  • W sekcji Zbiór danych wybierz Brak zarządzanego zbioru danych.
  • Następnie wybierz Trenowanie niestandardowe (zaawansowane) jako metodę trenowania 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 stosować dostrajania hiperparametrów, więc pole Włącz dostrajanie hiperparametrów pozostaw odznaczone 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. Model w tej wersji demonstracyjnej szybko trenuje, więc korzystamy z maszyny mniejszego typu.

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

Nie zmieniaj domyślnych ustawień gotowego kontenera. W sekcji Katalog modelu wpisz zasobnik GCS z podkatalogiem mpg. Oto ścieżka w skrypcie trenowania modelu, do której eksportujesz wytrenowany model:

Ustawienia prognozowania

Podczas wdrażania modelu Vertex wyszuka tę lokalizację. Teraz możesz rozpocząć trening. Kliknij Rozpocznij trenowanie, aby rozpocząć zadanie trenowania. W sekcji Training (Szkolenia) w konsoli zobaczysz coś takiego:

Zadania trenowania

6. Wdróż punkt końcowy 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 tej ścieżki zasobu. Sam zasób modelu nie jest modelem wdrożonym, 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 użyć tych informacji, aby uzyskać prognozy w naszym 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

Po uruchomieniu zadania trenowania Vertex utworzył dla Ciebie 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ę, na przykład v1. Pozostaw wybraną opcję dostępu Standardowy, a następnie kliknij Dalej.

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

Wdrożenie punktu końcowego zajmie 10–15 minut. Po zakończeniu wdrażania otrzymasz e-maila. Gdy punkt końcowy zostanie wdrożony, zobaczysz to, co pokazuje jeden 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 utwórz notatnik Python 3 z poziomu menu uruchamiania:

Otwórz notatnik

Aby zainstalować pakiet Vertex AI SDK, w notatniku uruchom w komórce 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 wdrożonego właśnie 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. Aby znaleźć numer projektu, otwórz panel projektu i pobierz wartość „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])

Ten przykład ma już znormalizowane wartości, czyli taki format, jakiego oczekuje nasz model.

Uruchom tę komórkę, a powinna wyświetlić się prognoza z wynikiem około 40 kilometrów na galon.

🎉 Gratulacje! 🎉

Wiesz już, jak używać Vertex AI do:

  • 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ą dowolnej platformy, korzystając z niestandardowych kontenerów.
  • Wdróż model TensorFlow przy użyciu gotowego kontenera w ramach tego samego przepływu pracy co podczas 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łączenie go, gdy nie jest używany. W interfejsie Workbench w konsoli Cloud wybierz notatnik, a następnie kliknij Zatrzymaj.

Aby całkowicie usunąć notatnik, kliknij przycisk Usuń znajdujący się w prawym górnym rogu.

Aby usunąć wdrożony punkt końcowy, przejdź do sekcji Punkty końcowe w konsoli Vertex AI, kliknij utworzony punkt końcowy i wybierz Wycofaj wdrożenie modelu z punktu końcowego:

Usuń punkt końcowy

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

Usuń miejsce na dane