Vertex AI: współhostowane modele w tej samej maszynie wirtualnej do prognozowania

1. Przegląd

W tym module użyjesz funkcji modelu współhostinguVertex AI, aby hostować wiele modeli na tej samej maszynie wirtualnej na potrzeby prognoz online.

Czego się dowiesz

Poznasz takie zagadnienia jak:

  • Utwórz DeploymentResourcePool
  • Wdrażanie modeli w DeploymentResourcePool

Całkowity koszt ukończenia tego modułu w Google Cloud wynosi około 2 USD.

2. Wprowadzenie do Vertex AI

W tym module wykorzystujemy najnowszą ofertę produktów AI dostępną w Google Cloud. Vertex AI integruje usługi 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. Ten moduł skupia się na produktach wyróżnionych poniżej: PrognozyWorkbench.

Omówienie usługi Vertex

3. Omówienie przypadku użycia

Podczas wdrażania modeli w usłudze prognozowania Vertex AI każdy model jest domyślnie wdrażany na własnej maszynie wirtualnej. Aby obniżyć koszty hostingu, możesz hostować wiele modeli na tej samej maszynie wirtualnej, co pozwala lepiej wykorzystać pamięć i zasoby obliczeniowe. Liczba modeli, które zdecydujesz się wdrożyć na tej samej maszynie wirtualnej, będzie zależeć od rozmiarów modeli i wzorców ruchu, ale ta funkcja jest szczególnie przydatna w przypadku wielu wdrożonych modeli o rzadkim ruchu.

Obsługa modelu współhostingu wprowadza pojęcie puli zasobów wdrożenia, która grupuje modele w celu współdzielenia zasobów w obrębie maszyny wirtualnej. Modele mogą współdzielić maszynę wirtualną, jeśli współdzielą punkt końcowy, a także jeśli są wdrożone w różnych punktach końcowych. Obecnie modele w tej samej puli zasobów muszą mieć ten sam obraz kontenera, w tym wersję platformy gotowych kontenerów Vertex Prediction. Dodatkowo w tej wersji obsługiwane są tylko gotowe kontenery Vertex Prediction z platformą modeli TensorFlow. Inne platformy modeli i kontenery niestandardowe nie są jeszcze obsługiwane.

deployment_pool

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

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. Utwórz instancję Vertex AI Workbench

W sekcji Vertex AI w konsoli Cloud kliknij Workbench:

Menu Vertex AI

Włącz interfejs Notebooks API, jeśli nie jest jeszcze włączony.

Notebook_api

Po włączeniu kliknij ZARZĄDZANE NOTATNIKI:

Notebooks_UI

Następnie wybierz NOWY NOTEBOOK.

new_notebook

Nadaj nazwę notatnikowi, a w sekcji Uprawnienia wybierz Konto usługi.

create_notebook

Kliknij Ustawienia zaawansowane.

W sekcji Zabezpieczenia wybierz „Włącz terminal”, jeśli nie jest jeszcze włączony.

enable_terminal

Wszystkie pozostałe ustawienia zaawansowane możesz pozostawić bez zmian.

Następnie kliknij Utwórz. Udostępnienie instancji zajmie kilka minut.

Po utworzeniu instancji kliknij OTWÓRZ JUPYTERLAB.

open_jupyterlab

5. Trenuj model

Zanim wypróbujemy funkcję współhostingowania, musimy wytrenować model i zapisać artefakty zapisanego modelu w zasobniku Cloud Storage. Do uruchomienia zadania trenowania użyjemy wykonawcy notatnika Workbench.

Krok 1. Utwórz zasobnik Cloud Storage

Jeśli w projekcie masz już zasobnik, którego chcesz użyć, możesz pominąć ten krok. W przeciwnym razie otwórz nową sesję terminala z poziomu programu uruchamiającego.

launcher_terminal

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 to polecenie, aby utworzyć nowy zasobnik w projekcie.

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

Krok 2. Uruchom wykonanie notatnika

W programie uruchamiającym instancji Workbench otwórz nowy notatnik TensorFlow 2.

launcher_tf2

Poniższy kod trenuje binarny klasyfikator nastawienia (pozytywne lub negatywne) na zbiorze danych recenzji filmów IMDB. Wklej kod do notatnika.

Zastąp {YOUR_BUCKET} zasobnikiem utworzonym w poprzednim kroku (lub innym zasobnikiem w projekcie). W tym miejscu będziemy przechowywać zapisane artefakty modelu, które będą nam potrzebne później, gdy prześlemy model do Vertex AI Model Registry.

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)

Następnie kliknij przycisk Wykonaj.

execute_nb

Następnie skonfiguruj wykonanie w ten sposób i kliknij PRZEŚLIJ.

execution_config

Na karcie Wykonania w konsoli możesz śledzić stan zadania trenowania.

execution_status

6. Wdrażanie modelu

Krok 1. Prześlij model

Po zakończeniu wykonania wróć do notatnika Workbench, aby przesłać model. Utwórz nowy notatnik TensorFlow.

tf_nb

Najpierw zaimportuj pakiet Vertex AI Python SDK.

from google.cloud import aiplatform

Następnie prześlij model, zastępując {YOUR_BUCKET} zasobnikiem określonym w kodzie trenowania.

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

Na potrzeby demonstracji prześlemy ten model 2 razy, tworząc w Vertex AI 2 różne zasoby modelu. Dzięki temu możemy przetestować wdrażanie wielu modeli w jednym punkcie końcowym w puli zasobów wdrożenia. W rzeczywistym scenariuszu zamiast tworzyć modele z tych samych zapisanych artefaktów, użyjesz 2 różnych modeli. Jest to jednak skrót, dzięki któremu nie musimy uruchamiać kolejnego trenowania. Możesz też wdrożyć te 2 modele w różnych punktach końcowych w tej samej puli zasobów wdrożenia.

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

W rejestrze modeli Vertex AI powinny być teraz widoczne oba modele. Stan wdrożenia jest pusty, ponieważ nie wdrożyliśmy jeszcze modeli.

model_registry

Krok 2. Utwórz punkt końcowy

Utwórz punkt końcowy. Pamiętaj, że różni się to od wdrażania modelu w punkcie końcowym.

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

Gdy punkt końcowy zostanie utworzony, zobaczysz go w konsoli.

console_endpoint

Krok 3. Utwórz DeploymentResourcePool

Możesz utworzyć DeploymentResourcePool za pomocą tego polecenia. Pamiętaj, aby zastąpić {YOUR_PROJECT} identyfikatorem projektu.

# 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}'

Pulę możesz sprawdzić, uruchamiając

!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}

Krok 4. Wdróż modele w punkcie końcowym

Po utworzeniu puli zasobów możemy wdrożyć w niej modele.

Najpierw wdrożymy model_1. Zastąp MODEL_1_IDENDPOINT_ID odpowiednimi identyfikatorami.

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

To polecenie wdroży model_1 w punkcie końcowym w puli zasobów.

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}'

Zajmie to kilka minut, ale po zakończeniu w konsoli zobaczysz model wdrożony w punkcie końcowym.

model_1_endpoint

Następnie możemy wdrożyć model_2 w tej samej puli wdrożeń. Wdrożymy go w tym samym punkcie końcowym co model_1. Możesz jednak wdrożyćmodel_2 w innym punkcie końcowym w tej samej puli zasobów.

Zaktualizuj MODEL_ID o identyfikator model_2. Ten identyfikator możesz uzyskać, uruchamiając model_2.name

MODEL_2_ID="{MODEL_2_ID}"

Następnie wdróż model_2. Ponieważ w punkcie końcowym mamy już wdrożony model model_1, musimy zaktualizować model trafficSplit, aby ruch był dzielony między te 2 modele. Nie musimy aktualizować trafficSplit, jeśli zdecydujemy się wdrożyć model_2 w innym punkcie końcowym w tej samej puli zasobów.

Aby zaktualizować podział ruchu, musisz zdefiniować identyfikator DeployedModel dla model_1. Pamiętaj, że różni się on od identyfikatora modelu.

DEPLOYED_MODEL_1_ID = {DEPLOYED_MODEL_1_ID}

Następnie uruchom to polecenie, aby wdrożyć drugi model.

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}'

W tym przykładzie oba modele zostały wdrożone w tym samym punkcie końcowym, ale możesz też współhostować modele w tej samej puli zasobów, które są wdrażane w różnych punktach końcowych. W takim przypadku nie musisz się martwić podziałem ruchu.

Po wdrożeniu drugiego modelu oba będą widoczne w konsoli.

deployed_models

Krok 5. Pobieraj prognozy

Ostatnim krokiem jest przetestowanie punktu końcowego i uzyskanie prognoz.

Najpierw zdefiniujmy zdanie testowe.

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

Następnie wywołaj prognozę w punkcie końcowym, która zwróci prognozę z jednego z modeli wdrożonych w punkcie końcowym.

endpoint.predict(instances=x_test)

🎉 Gratulacje! 🎉

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

  • Współhostowanie modeli na tej samej maszynie wirtualnej na potrzeby prognozowania online

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

7. Czyszczenie

Jeśli nie planujesz używać modeli, wycofaj ich wdrożenie z punktu końcowego. Możesz też całkowicie usunąć punkt końcowy. W razie potrzeby zawsze możesz ponownie wdrożyć model w punkcie końcowym.

undeploy_model

Zarządzane notesy Workbench automatycznie wyłączają się po 180 minutach bezczynności, więc nie musisz się martwić o wyłączenie instancji. Jeśli chcesz ręcznie wyłączyć instancję, kliknij przycisk Zatrzymaj w sekcji Vertex AI Workbench w konsoli. Jeśli chcesz całkowicie usunąć notatnik, kliknij przycisk Usuń.

Zatrzymaj instancję

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

Usuń miejsce na dane