Modell mit Vertex AI erstellen und bereitstellen

1. Übersicht

In diesem Lab lernen Sie, wie Sie mit Vertex AI, der neu angekündigten verwalteten ML-Plattform von Google Cloud, End-to-End-ML-Workflows erstellen. Sie lernen, wie Sie von Rohdaten in ein bereitgestelltes Modell übergehen, und machen diesen Workshop bereit, um Ihre eigenen ML-Projekte mit Vertex AI zu entwickeln und in der Produktion einzusetzen. In diesem Lab erstellen wir mit Cloud Shell ein benutzerdefiniertes Docker-Image, um benutzerdefinierte Container für das Training mit Vertex AI zu demonstrieren.

Wir verwenden TensorFlow für den Modellcode, können es aber problemlos durch ein anderes Framework ersetzen.

Lerninhalte

Die folgenden Themen werden behandelt:

  • Modelltrainingscode mit Cloud Shell erstellen und containerisieren
  • Benutzerdefinierten Modelltrainingsjob an Vertex AI senden
  • Trainiertes Modell auf einem Endpunkt bereitstellen und diesen für Vorhersagen verwenden

Die Gesamtkosten für das Lab in Google Cloud belaufen sich auf 2$.

2. Einführung in Vertex AI

In diesem Lab wird das neueste KI-Produktangebot von Google Cloud verwendet. Vertex AI bindet die ML-Angebote in Google Cloud in eine nahtlose Entwicklungsumgebung ein. Zuvor waren mit AutoML trainierte und benutzerdefinierte Modelle über separate Dienste zugänglich. Das neue Angebot vereint beides in einer einzigen API sowie weitere neue Produkte. Sie können auch vorhandene Projekte zu Vertex AI migrieren. Wenn Sie uns Feedback geben möchten, besuchen Sie die Supportseite.

Vertex bietet viele verschiedene Tools, die Sie in jeder Phase des ML-Workflows unterstützen, wie Sie im folgenden Diagramm sehen können. Wir konzentrieren uns auf die Verwendung von Vertex Training und Prediction (siehe unten).

Vertex-Dienste

3. Richten Sie Ihre Umgebung ein.

Umgebung zum selbstbestimmten Lernen einrichten

Melden Sie sich in der Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes Projekt. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie eines erstellen.

Notieren Sie sich die Projekt-ID, also den projektübergreifend nur einmal vorkommenden Namen eines Google Cloud-Projekts. Der oben angegebene Name ist bereits vergeben und kann leider nicht mehr verwendet werden.

Als Nächstes müssen Sie in der Cloud Console die Abrechnung aktivieren, um Google Cloud-Ressourcen nutzen zu können.

Dieses Codelab sollte möglichst wenig kosten. Folgen Sie der Anleitung im Abschnitt „Bereinigen“, . Hier erfahren Sie, wie Sie Ressourcen herunterfahren, damit Ihnen über dieses Tutorial hinaus keine Kosten entstehen. Neue Google Cloud-Nutzer haben Anspruch auf eine kostenlose Testversion mit 300$Guthaben.

Schritt 1: Cloud Shell starten

In diesem Lab arbeiten Sie in einer Cloud Shell-Sitzung, einem Befehlsinterpreter, der von einer virtuellen Maschine in der Cloud von Google gehostet wird. Sie können diesen Abschnitt genauso einfach lokal auf Ihrem Computer ausführen, aber mit Cloud Shell erhalten alle Zugriff auf eine reproduzierbare Version in einer einheitlichen Umgebung. Sie können diesen Abschnitt nach dem Lab gerne auf Ihrem eigenen Computer wiederholen.

Cloud Shell autorisieren

Cloud Shell aktivieren

Klicken Sie rechts oben in der Cloud Console auf die Schaltfläche unten, um Cloud Shell zu aktivieren:

Cloud Shell aktivieren

Wenn Sie Cloud Shell noch nie gestartet haben, wird ein Zwischenbildschirm (below the fold) angezeigt, in dem beschrieben wird, worum es sich dabei handelt. Klicken Sie in diesem Fall auf Weiter. Der Chat wird nie wieder angezeigt. So sieht dieser einmalige Bildschirm aus:

Cloud Shell-Einrichtung

Die Bereitstellung und Verbindung mit Cloud Shell dauert nur einen Moment.

Cloud Shell-Initialisierung

Diese virtuelle Maschine verfügt über alle Entwicklungstools, die Sie benötigen. Es bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und wird in Google Cloud ausgeführt. Dadurch werden die Netzwerkleistung und die Authentifizierung erheblich verbessert. Viele, wenn nicht sogar alle Arbeiten in diesem Codelab können Sie ganz einfach mit einem Browser oder Ihrem Chromebook erledigen.

Sobald Sie mit Cloud Shell verbunden sind, sollten Sie sehen, dass Sie bereits authentifiziert sind und dass das Projekt bereits auf Ihre Projekt-ID eingestellt ist.

Führen Sie in Cloud Shell den folgenden Befehl aus, um zu prüfen, ob Sie authentifiziert sind:

gcloud auth list

Befehlsausgabe

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`

Führen Sie in Cloud Shell den folgenden Befehl aus, um zu prüfen, ob der gcloud-Befehl Ihr Projekt kennt:

gcloud config list project

Befehlsausgabe

[core]
project = <PROJECT_ID>

Ist dies nicht der Fall, können Sie die Einstellung mit diesem Befehl vornehmen:

gcloud config set project <PROJECT_ID>

Befehlsausgabe

Updated property [core/project].

Cloud Shell hat einige Umgebungsvariablen, darunter GOOGLE_CLOUD_PROJECT, das den Namen des aktuellen Cloud-Projekts enthält. Wir werden sie in diesem Lab an verschiedenen Stellen verwenden. Sie können es sich ansehen, indem Sie folgenden Befehl ausführen:

echo $GOOGLE_CLOUD_PROJECT

Schritt 2: APIs aktivieren

In späteren Schritten werden Sie sehen, wo diese Dienste benötigt werden (und warum). Führen Sie vorerst diesen Befehl aus, um Ihrem Projekt Zugriff auf die Compute Engine-, Container Registry- und Vertex AI-Dienste zu gewähren:

gcloud services enable compute.googleapis.com         \
                       containerregistry.googleapis.com  \
                       aiplatform.googleapis.com

Wenn die Aktivierung erfolgreich war, erhalten Sie eine Meldung, die ungefähr so aussieht:

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

Schritt 3: Cloud Storage-Bucket erstellen

Zum Ausführen eines Trainingsjobs in Vertex AI benötigen Sie einen Storage-Bucket zum Speichern der gespeicherten Modell-Assets. Führen Sie die folgenden Befehle in Ihrem Cloud Shell-Terminal aus, um einen Bucket zu erstellen:

BUCKET_NAME=gs://$GOOGLE_CLOUD_PROJECT-bucket
gsutil mb -l us-central1 $BUCKET_NAME

Schritt 4: Alias Python 3

Für den Code in diesem Lab wird Python 3 verwendet. Damit Sie beim Ausführen der Skripts, die Sie in diesem Lab erstellen, Python 3 verwenden, müssen Sie einen Alias in Cloud Shell erstellen:

alias python=python3

Das Modell, das wir in diesem Lab trainieren und bereitstellen, basiert auf dieser Anleitung in der TensorFlow-Dokumentation. In diesem Tutorial wird das Auto MPG-Dataset von Kaggle verwendet, um die Kraftstoffeffizienz eines Fahrzeugs vorherzusagen.

4. Trainingscode containerisieren

Wir senden diesen Trainingsjob an Vertex, indem wir unseren Trainingscode in einen Docker-Container einfügen und diesen Container per Push in Google Container Registry übertragen. Mit diesem Ansatz können wir ein Modell trainieren, das mit einem beliebigen Framework erstellt wurde.

Schritt 1: Dateien einrichten

Führen Sie zuerst im Terminal in Cloud Shell die folgenden Befehle aus, um die Dateien zu erstellen, die Sie für den Docker-Container benötigen:

mkdir mpg
cd mpg
touch Dockerfile
mkdir trainer
touch trainer/train.py

Sie sollten jetzt ein mpg/-Verzeichnis haben, das so aussieht:

+ Dockerfile
+ trainer/
    + train.py

Zum Ansehen und Bearbeiten dieser Dateien verwenden wir den integrierten Code-Editor von Cloud Shell. Sie können zwischen dem Editor und dem Terminal wechseln, indem Sie in Cloud Shell in der Menüleiste rechts oben auf die Schaltfläche klicken:

Zum Editor in Cloud Shell wechseln

Schritt 2: Dockerfile erstellen

Um unseren Code in Container zu verlagern, erstellen wir zuerst ein Dockerfile. In unser Dockerfile geben wir alle Befehle ein, die zum Ausführen des Images erforderlich sind. Damit werden alle Bibliotheken installiert, die wir verwenden, und der Einstiegspunkt für unseren Trainingscode wird eingerichtet.

Öffnen Sie im Cloud Shell-Dateieditor das Verzeichnis mpg/ und doppelklicken Sie darauf, um das Dockerfile zu öffnen:

Dockerfile öffnen

Kopieren Sie dann Folgendes in diese Datei:

FROM gcr.io/deeplearning-platform-release/tf2-cpu.2-3
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"]

Dieses Dockerfile verwendet das Deep Learning Container TensorFlow Enterprise 2.3-Docker-Image. In den Deep-Learning-Containern in Google Cloud sind viele gängige ML- und Data-Science-Frameworks vorinstalliert. Wir verwenden TF Enterprise 2.3, Pandas, Scikit-learn und andere. Nach dem Herunterladen des Images richtet dieses Dockerfile den Einstiegspunkt für unseren Trainingscode ein, den wir im nächsten Schritt hinzufügen.

Schritt 3: Trainingscode für das Modell hinzufügen

Öffnen Sie im Cloud Shell-Editor als Nächstes die Datei train.py und kopieren Sie den unten stehenden Code. Dieser Code wurde aus der Anleitung in der TensorFlow-Dokumentation übernommen.

# This will be replaced with your bucket name after running the `sed` command in the tutorial
BUCKET = "BUCKET_NAME"

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.
"""

"""Import it using pandas"""

dataset_path = "https://storage.googleapis.com/io-vertex-codelab/auto-mpg.csv"
dataset = pd.read_csv(dataset_path, na_values = "?")

dataset.tail()

"""### 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')

Nachdem Sie den Code oben in die Datei mpg/trainer/train.py kopiert haben, kehren Sie zum Terminal in Cloud Shell zurück und führen den folgenden Befehl aus, um der Datei Ihren eigenen Bucket-Namen hinzuzufügen:

sed -i "s|BUCKET_NAME|$BUCKET_NAME|g" trainer/train.py

Schritt 4: Container lokal erstellen und testen

Führen Sie im Terminal den folgenden Befehl aus, um eine Variable mit dem URI des Container-Images in Google Container Registry zu definieren:

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

Erstellen Sie dann den Container, indem Sie im Stammverzeichnis Ihres mpg-Verzeichnisses Folgendes ausführen:

docker build ./ -t $IMAGE_URI

Nachdem Sie den Container erstellt haben, übertragen Sie ihn per Push in die Google Container Registry:

docker push $IMAGE_URI

Wenn Sie prüfen möchten, ob Ihr Image an Container Registry übertragen wurde, sollten Sie in der Konsole im Abschnitt Container Registry Folgendes sehen:

Container Registry-Vorschau

Nachdem unser Container in Container Registry übertragen wurde, können Sie einen Trainingsjob für ein benutzerdefiniertes Modell starten.

5. Trainingsjob in Vertex AI ausführen

Vertex bietet zwei Optionen zum Trainieren von Modellen:

  • AutoML Trainieren Sie mit minimalem Aufwand und minimalen ML-Kenntnissen hochwertige Modelle.
  • Benutzerdefiniertes Training: Sie können Ihre benutzerdefinierten Trainingsanwendungen in der Cloud mit einem der vordefinierten Container von Google Cloud ausführen oder Ihren eigenen verwenden.

In diesem Lab nutzen wir das benutzerdefinierte Training über unseren eigenen benutzerdefinierten Container in Google Container Registry. Gehen Sie zuerst im Vertex-Bereich der Cloud Console zum Abschnitt Training:

Vertex-Seitenmenü – Training

Schritt 1: Trainingsjob starten

Klicken Sie auf Erstellen, um die Parameter für den Trainingsjob und das bereitgestellte Modell einzugeben:

  • Wählen Sie unter Dataset die Option Kein verwaltetes Dataset aus.
  • Wählen Sie dann Benutzerdefiniertes Training (erweitert) als Trainingsmethode aus und klicken Sie auf Weiter.
  • Geben Sie mpg (oder einen anderen Namen für Ihr Modell) bei Modellname ein.
  • Klicken Sie auf Weiter.

Wählen Sie im Schritt „Containereinstellungen“ die Option Benutzerdefinierter Container aus:

Benutzerdefinierte Containeroption

Klicken Sie im ersten Feld (Container-Image) auf Durchsuchen und suchen Sie den Container, den Sie gerade in Container Registry übertragen haben. Die Ausgabe sollte ungefähr so aussehen:

Container suchen

Lassen Sie die restlichen Felder leer und klicken Sie auf Weiter.

Da wir in dieser Anleitung keine Hyperparameter-Abstimmung verwenden, lassen Sie das Kästchen "Hyperparameter-Abstimmung aktivieren" nicht angeklickt und klicken Sie auf Weiter.

Lassen Sie die ausgewählte Region unter Computing und Preise unverändert und wählen Sie als Maschinentyp n1-standard-4 aus:

Maschinentyp

Da das Modell in dieser Demo schnell trainiert wird, verwenden wir einen kleineren Maschinentyp.

Wählen Sie im Schritt Vorhersagecontainer die Option Kein Vorhersagecontainer aus:

Kein Vorhersagecontainer

6. Modellendpunkt bereitstellen

In diesem Schritt erstellen wir einen Endpunkt für unser trainiertes Modell. Damit können wir Vorhersagen für unser Modell über die Vertex AI API abrufen. Dazu stellen wir eine Version der exportierten trainierten Modell-Assets in einem öffentlichen GCS-Bucket zur Verfügung.

In einer Organisation ist es üblich, dass ein Team oder eine Person für die Erstellung des Modells und ein anderes Team für die Bereitstellung des Modells verantwortlich ist. Die Schritte, die wir hier ausführen, zeigen Ihnen, wie Sie ein bereits trainiertes Modell für die Vorhersage bereitstellen.

Hier verwenden wir das Vertex AI SDK, um ein Modell zu erstellen, es auf einem Endpunkt bereitzustellen und eine Vorhersage zu erhalten.

Schritt 1: Vertex SDK installieren

Führen Sie im Cloud Shell-Terminal den folgenden Befehl aus, um das Vertex AI SDK zu installieren:

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

Mit diesem SDK können wir mit vielen verschiedenen Teilen von Vertex interagieren.

Schritt 2: Modell erstellen und Endpunkt bereitstellen

Als Nächstes erstellen wir eine Python-Datei und verwenden das SDK, um eine Modellressource zu erstellen und auf einem Endpunkt bereitzustellen. Wählen Sie im Dateieditor von Cloud Shell Datei und dann Neue Datei aus:

Neue Datei in Cloud Shell

Benennen Sie die Datei deploy.py. Öffnen Sie diese Datei in Ihrem Editor und kopieren Sie den folgenden Code:

from google.cloud import aiplatform

# Create a model resource from public model assets
model = aiplatform.Model.upload(
    display_name="mpg-imported",
    artifact_uri="gs://io-vertex-codelab/mpg-model/",
    serving_container_image_uri="gcr.io/cloud-aiplatform/prediction/tf2-cpu.2-3:latest"
)

# Deploy the above model to an endpoint
endpoint = model.deploy(
    machine_type="n1-standard-4"
)

Gehen Sie dann zurück zum Terminal in Cloud Shell, cd gehen Sie zurück in Ihr Stammverzeichnis und führen Sie das soeben erstellte Python-Skript aus:

cd ..
python3 deploy.py | tee deploy-output.txt

Updates werden in Ihrem Terminal protokolliert, während Ressourcen erstellt werden. Das dauert 10 bis 15 Minuten. Prüfen Sie, ob alles richtig funktioniert, indem Sie in Vertex AI den Abschnitt Models (Modelle) Ihrer Konsole aufrufen:

Modell in der Vertex-Konsole

Klicken Sie auf mgp-imported. Der Endpunkt für das Modell, das gerade erstellt wird, sollte angezeigt werden:

Ausstehender Endpunkt

Wenn die Endpunktbereitstellung abgeschlossen ist, sehen Sie im Cloud Shell-Terminal in etwa das folgende Log:

Endpoint model deployed. Resource name: projects/your-project-id/locations/us-central1/endpoints/your-endpoint-id

Sie benötigen diese im nächsten Schritt, um eine Vorhersage für Ihre bereitgestellte Endopint zu erhalten.

Schritt 3: Vorhersagen auf dem bereitgestellten Endpunkt abrufen

Erstellen Sie in Ihrem Cloud Shell-Editor eine neue Datei mit dem Namen predict.py:

Vorhersagedatei erstellen

Öffnen Sie predict.py und fügen Sie den folgenden Code ein:

from google.cloud import aiplatform

endpoint = aiplatform.Endpoint(
    endpoint_name="ENDPOINT_STRING"
)

# A test example we'll send to our model for prediction
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])

Gehen Sie dann zurück zum Terminal und geben Sie Folgendes ein, um ENDPOINT_STRING in der Vorhersagedatei durch Ihren eigenen Endpunkt zu ersetzen:

ENDPOINT=$(cat deploy-output.txt | sed -nre 's:.*Resource name\: (.*):\1:p' | tail -1)
sed -i "s|ENDPOINT_STRING|$ENDPOINT|g" predict.py

Führen Sie jetzt die Datei predict.py aus, um eine Vorhersage von unserem bereitgestellten Modellendpunkt zu erhalten:

python3 predict.py

Sie sollten die Antwort der API zusammen mit der vorhergesagten Kraftstoffeffizienz für unsere Testvorhersage sehen.

🎉 Glückwunsch! 🎉

Sie haben gelernt, wie Sie mit Vertex AI Folgendes tun können:

  • Trainieren Sie ein Modell, indem Sie den Trainingscode in einem benutzerdefinierten Container bereitstellen. In diesem Beispiel haben Sie ein TensorFlow-Modell verwendet. Sie können aber ein Modell trainieren, das mit einem beliebigen Framework erstellt wurde. Dazu verwenden Sie benutzerdefinierte Container.
  • Stellen Sie ein TensorFlow-Modell mithilfe eines vordefinierten Containers als Teil des Workflows bereit, den Sie für das Training verwendet haben.
  • Erstellen Sie einen Modellendpunkt und generieren Sie eine Vorhersage.

Weitere Informationen zu den verschiedenen Teilen von Vertex AI finden Sie in der Dokumentation. Wenn Sie die Ergebnisse des in Schritt 5 gestarteten Trainingsjobs sehen möchten, gehen Sie zum Trainingsbereich der Vertex-Konsole.

7. Bereinigen

Wenn Sie den von Ihnen bereitgestellten Endpunkt löschen möchten, gehen Sie zum Abschnitt Endpunkte der Vertex-Konsole und klicken Sie auf das Symbol zum Löschen:

Endpunkt löschen

Wenn Sie den Storage-Bucket löschen möchten, gehen Sie im Navigationsmenü der Cloud Console zu „Storage“, wählen Sie den Bucket aus und klicken Sie auf „Löschen“:

Speicher löschen