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

1. Omówienie

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

Czego się nauczysz

Poznasz takie zagadnienia jak:

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

Całkowity koszt uruchomienia tego modułu w Google Cloud wynosi około 2 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 z użyciem AutoML i modele niestandardowe były dostępne w oddzielnych usługach. Nowa oferta jest łączona w 1 interfejs API wraz 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: Prognozy i Workbench.

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 we własnej maszynie wirtualnej. Aby hostowanie było tańsze, możesz hostować wiele modeli w tej samej maszynie wirtualnej, co pozwala lepiej wykorzystywać pamięć i zasoby obliczeniowe. Liczba modeli, które zdecydujesz się wdrożyć w tej samej maszynie wirtualnej, zależy od rozmiarów modeli i wzorców ruchu, ale ta funkcja jest szczególnie przydatna w sytuacjach, gdy masz wiele wdrożonych modeli o niewielkim ruchu.

Obsługa modeli współhostowania wprowadza koncepcję puli zasobów wdrożenia, która grupuje modele służące do współdzielenia zasobów w maszynie wirtualnej. Modele mogą współdzielić maszynę wirtualną, jeśli współużytkują jeden 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ą modelu Tensorflow. Inne platformy modeli i kontenery niestandardowe nie są jeszcze obsługiwane.

deployment_pool

4. Konfigurowanie środowiska

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.

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

W sekcji Vertex AI w konsoli Cloud kliknij Workbench:

Menu Vertex AI

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

Notebook_api

Po włączeniu kliknij ZARZĄDZANE NOTATKI:

Notebooks_UI

Następnie wybierz NOWY NOTATNIK.

new_notebook

Nadaj notatnikowi nazwę i w sekcji Permission (Uprawnienia) wybierz Service account (Konto usługi).

create_notebook

Wybierz Ustawienia zaawansowane.

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

enable_terminal

Inne ustawienia zaawansowane możesz pozostawić bez zmian.

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

Po utworzeniu instancji wybierz OTWÓRZ JUPYTERLAB.

open_jupyterlab

5. Trenuj model

Zanim wypróbujemy funkcję współhostowania, musimy wytrenować model i zapisać zapisane artefakty 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 zasobnik, którego chcesz użyć, możesz pominąć ten krok. Jeśli nie, w programie uruchamiającym otwórz nową sesję terminala.

launcher_terminal

Uruchom w terminalu 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 podane niżej polecenie, aby utworzyć w projekcie nowy zasobnik.

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

Krok 2. Uruchom wykonywanie notatnika

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

launcher_tf2

Poniższy kod trenuje klasyfikator nastawienia binarnego (pozytywnego lub negatywnego) w zbiorze danych recenzji filmów w IMDB. Wklej kod do notatnika.

Pamiętaj, aby zastąpić {YOUR_BUCKET} zasobnikiem utworzonym w poprzednim kroku (lub innym zasobnikiem w projekcie). To tutaj będziemy przechowywać zapisane artefakty modelu, które będą potrzebne później, gdy prześlesz 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 następujący sposób i kliknij PRZEŚLIJ.

execution_config

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

execution_status

6. Wdrażanie modelu

Krok 1. Prześlij model

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

tf_nb

Najpierw zaimportuj pakiet SDK Vertex AI Python

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

Dla celów demonstracyjnych prześlemy ten model dwukrotnie, tworząc 2 różne zasoby modelu w Vertex AI. Dzięki temu możemy testować wdrażanie wielu modeli w jednym punkcie końcowym w ramach puli zasobów wdrożenia. W rzeczywistości dostępne byłyby 2 różne modele zamiast tworzenia modeli z tych samych zapisanych artefaktów. Jest to jednak skrót, który eliminuje konieczność uruchamiania 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. Różni się to od wdrażania modelu w punkcie końcowym.

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

Utworzony punkt końcowy zobaczysz w konsoli.

console_endpoint

Krok 3. Utwórz pulę zasobów wdrożeń

Możesz utworzyć pulę zasobów wdrożeń 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}'

Aby wyświetlić pulę, uruchom polecenie

!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. Pamiętaj, aby zastąpić MODEL_1_ID i ENDPOINT_ID odpowiednimi identyfikatorami.

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

Za pomocą poniższego polecenia wdrożysz 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}'

Może to potrwać kilka minut, a po jego zakończeniu model wdrożony w punkcie końcowym w konsoli.

model_1_endpoint

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

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

MODEL_2_ID="{MODEL_2_ID}"

Następnie wdróż pakiet model_2. Ponieważ w punkcie końcowym wdrożono już model_1, musimy zaktualizować trafficSplit, aby ruch był rozdzielany między te 2 modele. Nie musielibyśmy aktualizować zasobu 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 wykonaj 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 2 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ą wdrożone w różnych punktach końcowych. W takim przypadku nie trzeba się martwić o podział ruchu.

Po wdrożeniu drugiego modelu zobaczysz je w konsoli.

deployed_models

Krok 5. Uzyskaj prognozy

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

Najpierw zdefiniuj 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! 🎉

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

  • Współgospodarz modele w tej samej maszynie wirtualnej do prognozowania online

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

7. Czyszczenie

Jeśli nie zamierzasz ich używać, warto wycofać wdrożenie modeli 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

Limit czasu zarządzanych notatników Workbench automatycznie wygasa 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 na dane, w menu nawigacyjnym w konsoli Google Cloud otwórz Cloud Storage, wybierz swój zasobnik i kliknij Usuń:

Usuń miejsce na dane