Vertex AI: Co-Hosten von Modellen auf derselben VM für Vorhersagen

1. Übersicht

In diesem Lab verwenden Sie die Funktion für das gemeinsame Hosting von Modellen in Vertex AI, um mehrere Modelle auf derselben VM für Onlinevorhersagen zu hosten.

Lerninhalte

Die folgenden Themen werden behandelt:

  • DeploymentResourcePool erstellen
  • Modelle in einem DeploymentResourcePool bereitstellen

Die Gesamtkosten für die Ausführung dieses Labs in Google Cloud betragen etwa 2$.

2. Einführung in Vertex AI

In diesem Lab wird das neueste KI-Angebot von Google Cloud verwendet. Vertex AI integriert die ML-Angebote in Google Cloud für eine nahtlose Entwicklung. Bisher konnten auf mit AutoML trainierte Modelle und benutzerdefinierte Modelle über separate Dienste zugegriffen werden. Das neue Angebot kombiniert beide zusammen mit anderen neuen Produkten in einer einzigen API. Sie können auch vorhandene Projekte zu Vertex AI migrieren. Wenn Sie uns Feedback geben möchten, besuchen Sie die Supportseite.

Vertex AI umfasst viele verschiedene Produkte zur Unterstützung von End-to-End-ML-Workflows. In diesem Lab liegt der Schwerpunkt auf den unten aufgeführten Produkten: Vorhersagen und Workbench.

Vertex-Produktübersicht

3. Anwendungsfall – Übersicht

Beim Bereitstellen von Modellen für den Vertex AI-Vorhersagedienst wird jedes Modell standardmäßig auf seiner eigenen VM bereitgestellt. Um das Hosting kostengünstiger zu gestalten, können Sie mehrere Modelle auf derselben VM hosten. Dies führt zu einer besseren Auslastung von Arbeitsspeicher und Rechenressourcen. Die Anzahl der Modelle, die Sie auf derselben VM bereitstellen, hängt von den Modellgrößen und den Trafficmustern ab. Diese Funktion ist jedoch besonders nützlich für Szenarien, in denen viele bereitgestellte Modelle mit wenig Traffic vorhanden sind.

Mit der Unterstützung des Co-Hosting-Modells wird das Konzept eines Ressourcenpools für die Bereitstellung eingeführt, mit dem Modelle gruppiert werden, um Ressourcen innerhalb einer VM zu teilen. Modelle können eine VM gemeinsam nutzen, wenn sie einen Endpunkt teilen oder wenn sie auf verschiedenen Endpunkten bereitgestellt werden. Derzeit müssen Modelle im selben Ressourcenpool dasselbe Container-Image mit derselben Framework-Version der vordefinierten Vertex Prediction-Container haben. Außerdem werden in dieser Version nur vordefinierte Vertex Prediction-Container mit dem TensorFlow-Modell-Framework unterstützt. Andere Modell-Frameworks und benutzerdefinierte Container werden noch nicht unterstützt.

deployment_pool

4. Umgebung einrichten

Sie benötigen ein Google Cloud Platform-Projekt mit aktivierter Abrechnung, um dieses Codelab auszuführen. Eine Anleitung zum Erstellen eines Projekts finden Sie hier.

Schritt 1: Compute Engine API aktivieren

Rufen Sie Compute Engine auf und wählen Sie Aktivieren aus, falls die Option noch nicht aktiviert ist.

Schritt 2: Vertex AI API aktivieren

Rufen Sie den Bereich „Vertex AI“ der Cloud Console auf und klicken Sie auf Vertex AI API aktivieren.

Vertex AI-Dashboard

Schritt 3: Vertex AI Workbench-Instanz erstellen

Klicken Sie in der Cloud Console im Bereich „Vertex AI“ auf „Workbench“:

Vertex AI-Menü

Aktivieren Sie die Notebooks API, falls sie noch nicht aktiviert ist.

Notebook_api

Klicken Sie nach der Aktivierung auf VERWALTETE NOTEBOOKS:

Notebooks_UI

Wählen Sie dann NEUES NOTEBOOK aus.

new_notebook

Geben Sie Ihrem Notebook einen Namen und wählen Sie unter Berechtigung die Option Dienstkonto aus.

create_notebook

Wähle Erweiterte Einstellungen aus.

Wählen Sie unter Sicherheit die Option „Terminal aktivieren“ aus, falls sie noch nicht aktiviert ist.

enable_terminal

Alle anderen erweiterten Einstellungen können Sie unverändert lassen.

Klicken Sie dann auf Erstellen. Die Bereitstellung der Instanz dauert einige Minuten.

Wählen Sie nach dem Erstellen der Instanz JUPYTERLAB ÖFFNEN aus.

open_jupyterlab

5. Modell trainieren

Bevor wir die Co-Hosting-Funktion ausprobieren können, müssen wir zuerst ein Modell trainieren und die gespeicherten Modellartefakte in einem Cloud Storage-Bucket ablegen. Wir verwenden den Workbench Notebook Executor, um den Trainingsjob zu starten.

Schritt 1: Cloud Storage-Bucket erstellen

Wenn Sie bereits einen Bucket in Ihrem Projekt haben, den Sie verwenden möchten, können Sie diesen Schritt überspringen. Andernfalls öffnen Sie im Launcher eine neue Terminalsitzung.

launcher_terminal

Führen Sie im Terminal den folgenden Befehl aus, um eine Umgebungsvariable für Ihr Projekt zu definieren. Ersetzen Sie dabei your-cloud-project durch die ID Ihres Projekts:

PROJECT_ID='your-cloud-project'

Führen Sie als Nächstes den folgenden Befehl aus, um einen neuen Bucket in Ihrem Projekt zu erstellen.

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

Schritt 2: Notebookausführung starten

Öffnen Sie im Launcher der Workbench-Instanz ein neues TensorFlow 2-Notebook.

launcher_tf2

Mit dem folgenden Code wird ein binärer Sentimentklassifikator (positiv oder negativ) mit dem Dataset für IMDB-Filmrezensionen trainiert. Fügen Sie den Code in Ihr Notebook ein.

Ersetzen Sie {YOUR_BUCKET} durch den Bucket, den Sie im vorherigen Schritt erstellt haben (oder einen anderen Bucket in Ihrem Projekt). Hier speichern wir die gespeicherten Modellartefakte, die wir später benötigen, wenn wir das Modell in Vertex AI Model Registry hochladen.

import numpy as np

import tensorflow_datasets as tfds
import tensorflow as tf

# REPLACE WITH YOUR BUCKET!
OUTPUT_PATH='gs://{YOUR_BUCKET}/model_output'

BUFFER_SIZE = 10000
BATCH_SIZE = 64
VOCAB_SIZE = 1000

# Load data
dataset, info = tfds.load('imdb_reviews', with_info=True,
                          as_supervised=True)
train_dataset, test_dataset = dataset['train'], dataset['test']

train_dataset = train_dataset.shuffle(BUFFER_SIZE).batch(BATCH_SIZE).prefetch(tf.data.AUTOTUNE)
test_dataset = test_dataset.batch(BATCH_SIZE).prefetch(tf.data.AUTOTUNE)

# Create text encoder
encoder = tf.keras.layers.TextVectorization(
    max_tokens=VOCAB_SIZE)
encoder.adapt(train_dataset.map(lambda text, label: text))

# Create model
model = tf.keras.Sequential([
    encoder,
    tf.keras.layers.Embedding(
        input_dim=len(encoder.get_vocabulary()),
        output_dim=64,
        # Use masking to handle the variable sequence lengths
        mask_zero=True),
    tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dense(1)
])

# Compile model
model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              optimizer=tf.keras.optimizers.Adam(1e-4),
              metrics=['accuracy'])

# Fit model
history = model.fit(train_dataset, epochs=10,
                    validation_data=test_dataset,
                    validation_steps=30)

# Save model
model.save(OUTPUT_PATH)

Klicken Sie dann auf die Schaltfläche Execute (Ausführen).

execute_nb

Konfigurieren Sie dann die Ausführung wie unten beschrieben und klicken Sie auf SENDEN.

execution_config

Auf dem Tab „Ausführungen“ in der Console können Sie den Status Ihres Trainingsjobs verfolgen.

execution_status

6. Modell bereitstellen

Schritt 1: Modell hochladen

Kehren Sie nach Abschluss der Ausführung zum Workbench-Notebook zurück, um das Modell hochzuladen. Erstellen Sie ein neues TensorFlow-Notebook.

tf_nb

Importieren Sie zuerst das Vertex AI Python SDK

from google.cloud import aiplatform

Laden Sie dann das Modell hoch und ersetzen Sie {YOUR_BUCKET} durch den Bucket, den Sie im Trainingscode angegeben haben.

# replace {YOUR_BUCKET}
model_1 = aiplatform.Model.upload(display_name='text-model-1',
                                  artifact_uri='gs://{YOUR_BUCKET}/model_output',
                                  serving_container_image_uri='us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-8:latest')

Zu Demonstrationszwecken laden wir dieses Modell zweimal hoch und erstellen so zwei verschiedene Modellressourcen in Vertex AI. So können wir die Bereitstellung mehrerer Modelle auf einem einzelnen Endpunkt innerhalb eines Ressourcenpools für die Bereitstellung testen. In einem realen Szenario würden Sie zwei verschiedene Modelle haben, anstatt Modelle aus denselben gespeicherten Artefakten zu erstellen. Dies ist jedoch eine Verknüpfung, damit wir kein weiteres Training starten müssen. Außerdem können Sie die beiden Modelle auch an verschiedenen Endpunkten innerhalb desselben Ressourcenpools für die Bereitstellung bereitstellen.

# replace {YOUR_BUCKET}
model_2 = aiplatform.Model.upload(display_name='text-model-2',
                                  artifact_uri='gs://{YOUR_BUCKET}/model_output',
                                  serving_container_image_uri='us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-8:latest')

In der Vertex AI Model Registry sollten jetzt beide Modelle angezeigt werden. Der Bereitstellungsstatus ist leer, da die Modelle noch nicht bereitgestellt wurden.

model_registry

Schritt 2: Endpunkt erstellen

Erstellen Sie einen Endpunkt. Das unterscheidet sich vom Bereitstellen eines Modells auf einem Endpunkt.

endpoint = aiplatform.Endpoint.create('cohost-endpoint')

Sobald der Endpunkt erstellt wurde, wird er in der Console angezeigt.

console_endpoint

Schritt 3: DeploymentResourcePool erstellen

Sie können den DeploymentResourcePool mit dem folgenden Befehl erstellen: Ersetzen Sie dabei {YOUR_PROJECT} durch Ihre Projekt-ID.

# replace {YOUR_PROJECT}
PROJECT_ID={YOUR_PROJECT}
REGION="us-central1"
VERTEX_API_URL=REGION + "-aiplatform.googleapis.com"
VERTEX_PREDICTION_API_URL=REGION + "-prediction-aiplatform.googleapis.com"
MULTI_MODEL_API_VERSION="v1beta1"

# Give the pool a name
DEPLOYMENT_RESOURCE_POOL_ID="my-resource-pool"

import json
import pprint
pp = pprint.PrettyPrinter(indent=4)

CREATE_RP_PAYLOAD = {
  "deployment_resource_pool":{
    "dedicated_resources":{
      "machine_spec":{
        "machine_type":"n1-standard-4"
      },
      "min_replica_count":1,
      "max_replica_count":2
    }
  },
  "deployment_resource_pool_id":DEPLOYMENT_RESOURCE_POOL_ID
}
CREATE_RP_REQUEST=json.dumps(CREATE_RP_PAYLOAD)
pp.pprint("CREATE_RP_REQUEST: " + CREATE_RP_REQUEST)

!curl \
-X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://{VERTEX_API_URL}/{MULTI_MODEL_API_VERSION}/projects/{PROJECT_ID}/locations/{REGION}/deploymentResourcePools \
-d '{CREATE_RP_REQUEST}'

Sie können den Pool mit dem Befehl

!curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://{VERTEX_API_URL}/{MULTI_MODEL_API_VERSION}/projects/{PROJECT_ID}/locations/{REGION}/deploymentResourcePools/{DEPLOYMENT_RESOURCE_POOL_ID}

Schritt 4: Modelle auf dem Endpunkt bereitstellen

Nachdem der Ressourcenpool erstellt wurde, können Sie die Modelle im Ressourcenpool bereitstellen.

Zuerst stellen wir model_1 bereit. Ersetzen Sie MODEL_1_ID und ENDPOINT_ID durch die entsprechenden IDs.

MODEL_1_ID="{MODEL_1_ID}"
ENDPOINT_ID="{ENDPOINT_ID}"

Mit dem folgenden Befehl wird model_1 auf dem Endpunkt im Ressourcenpool bereitgestellt.

MODEL_NAME = "projects/{project_id}/locations/{region}/models/{model_id}".format(project_id=PROJECT_ID, region=REGION, model_id=MODEL_1_ID)
SHARED_RESOURCE = "projects/{project_id}/locations/{region}/deploymentResourcePools/{deployment_resource_pool_id}".format(project_id=PROJECT_ID, region=REGION, deployment_resource_pool_id=DEPLOYMENT_RESOURCE_POOL_ID)

DEPLOY_MODEL_PAYLOAD = {
  "deployedModel": {
    "model": MODEL_NAME,
    "shared_resources": SHARED_RESOURCE
  },
  "trafficSplit": {
    "0": 100
  }
}
DEPLOY_MODEL_REQUEST=json.dumps(DEPLOY_MODEL_PAYLOAD)
pp.pprint("DEPLOY_MODEL_REQUEST: " + DEPLOY_MODEL_REQUEST)

!curl -X POST \
 -H "Authorization: Bearer $(gcloud auth print-access-token)" \
 -H "Content-Type: application/json" \
https://{VERTEX_API_URL}/{MULTI_MODEL_API_VERSION}/projects/{PROJECT_ID}/locations/{REGION}/endpoints/{ENDPOINT_ID}:deployModel \
-d '{DEPLOY_MODEL_REQUEST}'

Das dauert einige Minuten. Anschließend wird das Modell in der Console auf dem Endpunkt bereitgestellt.

model_1_endpoint

Als Nächstes können wir model_2 im selben Bereitstellungspool bereitstellen. Wir stellen sie unter demselben Endpunkt wie model_1 bereit. Sie können model_2 aber auch an einem anderen Endpunkt innerhalb desselben Ressourcenpools bereitstellen.

Aktualisieren Sie MODEL_ID mit der ID für model_2. Sie können diese ID auch mit dem Befehl model_2.name abrufen.

MODEL_2_ID="{MODEL_2_ID}"

Stellen Sie dann model_2 bereit. Da model_1 bereits auf dem Endpunkt bereitgestellt wurde, müssen wir trafficSplit aktualisieren, damit der Traffic zwischen den beiden Modellen aufgeteilt wird. Wir müssten die trafficSplit nicht aktualisieren, wenn wir model_2 an einem anderen Endpunkt innerhalb desselben Ressourcenpools bereitstellen.

Wenn Sie die Trafficaufteilung aktualisieren möchten, müssen Sie die DeployedModel-ID für model_1 definieren. Beachten Sie, dass sich diese von der Modell-ID unterscheidet.

DEPLOYED_MODEL_1_ID = {DEPLOYED_MODEL_1_ID}

Führen Sie dann Folgendes aus, um das zweite Modell bereitzustellen.

MODEL_NAME = "projects/{project_id}/locations/{region}/models/{model_id}".format(project_id=PROJECT_ID, region=REGION, model_id=MODEL_2_ID)
SHARED_RESOURCE = "projects/{project_id}/locations/{region}/deploymentResourcePools/{deployment_resource_pool_id}".format(project_id=PROJECT_ID, region=REGION, deployment_resource_pool_id=DEPLOYMENT_RESOURCE_POOL_ID)

#`trafficSplit` is a map from a DeployedModel's ID to the percentage of this Endpoint's traffic that should be forwarded to that DeployedModel.
# The traffic percentage values for an endpoint must add up to 100.
# The key for the model being deployed is "0".

DEPLOY_MODEL_PAYLOAD = {
  "deployedModel": {
    "model": MODEL_NAME,
    "shared_resources": SHARED_RESOURCE
  },
  "trafficSplit": {
    "0": 50,
    DEPLOYED_MODEL_1_ID: 50
  }
}
DEPLOY_MODEL_REQUEST=json.dumps(DEPLOY_MODEL_PAYLOAD)
pp.pprint("DEPLOY_MODEL_REQUEST: " + DEPLOY_MODEL_REQUEST)

!curl -X POST \
 -H "Authorization: Bearer $(gcloud auth print-access-token)" \
 -H "Content-Type: application/json" \
https://{VERTEX_API_URL}/{MULTI_MODEL_API_VERSION}/projects/{PROJECT_ID}/locations/{REGION}/endpoints/{ENDPOINT_ID}:deployModel \
-d '{DEPLOY_MODEL_REQUEST}'

Auch in diesem Beispiel wurden die beiden Modelle am selben Endpunkt bereitgestellt. Sie können aber auch Modelle gemeinsam im selben Ressourcenpool hosten, die an unterschiedlichen Endpunkten bereitgestellt werden. In diesem Fall müssen Sie sich nicht um die Aufteilung des Traffics kümmern.

Nachdem das zweite Modell bereitgestellt wurde, werden beide in der Console angezeigt.

deployed_models

Schritt 5: Vorhersagen abrufen

Im letzten Schritt testen Sie den Endpunkt und erhalten Vorhersagen.

Definieren Sie zunächst den Testsatz.

x_test=['The movie was cool. The animation and the graphics were out of this world. I would recommend this movie.']

Rufen Sie dann „Predict“ auf dem Endpunkt auf, der eine Vorhersage von einem der auf dem Endpunkt bereitgestellten Modelle zurückgibt.

endpoint.predict(instances=x_test)

🎉 Glückwunsch! 🎉

Sie haben gelernt, wie Sie Vertex AI für Folgendes verwenden:

  • Modelle gemeinsam auf derselben VM für Onlinevorhersagen hosten

Weitere Informationen zu den verschiedenen Bereichen von Vertex finden Sie in der Dokumentation.

7. Bereinigen

Heben Sie die Bereitstellung der Modelle am Endpunkt auf, wenn Sie sie nicht verwenden möchten. Sie können den Endpunkt auch vollständig löschen. Sie können ein Modell bei Bedarf jederzeit wieder auf einem Endpunkt bereitstellen.

undeploy_model

Von Workbench verwaltete Notebooks werden nach 180 Minuten Inaktivität automatisch beendet. Sie müssen sich also nicht um das Herunterfahren der Instanz kümmern. Wenn Sie die Instanz manuell herunterfahren möchten, klicken Sie in der Console im Bereich „Vertex AI Workbench“ auf die Schaltfläche „Beenden“. Wenn Sie das Notizbuch vollständig löschen möchten, klicken Sie auf die Schaltfläche „Löschen“.

Instanz beenden

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

Speicher löschen