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

1. Omówienie

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

Czego się nauczysz

Poznasz takie zagadnienia jak:

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

Łączny koszt wykonania tego ćwiczenia w Google Cloud wynosi około 2 USD.

2. Wprowadzenie do Vertex AI

Ten moduł wykorzystuje 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 zawiera wiele różnych usług, które obsługują kompleksowe przepływy pracy związane z systemami uczącymi się. W tym module skupimy się na usługach wymienionych poniżej: PredictionsWorkbench.

Omówienie usługi Vertex

3. Omówienie przypadku użycia

Podczas wdrażania modeli do usługi prognozowania Vertex AI każdy model jest domyślnie wdrażany do własnej maszyny wirtualnej. Aby hosting był bardziej opłacalny, możesz hostować wiele modeli na tej samej maszynie wirtualnej, co zwiększa wykorzystanie pamięci i zasobów obliczeniowych. Liczba modeli, które wdrażasz na tej samej maszynie wirtualnej, zależy od rozmiarów modeli i wzorców ruchu. Ta funkcja jest szczególnie przydatna w sytuacjach, gdy masz wiele wdrożonych modeli z rzadkim ruchem.

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ą korzystać z tej samej maszyny wirtualnej, jeśli mają ten sam punkt końcowy, a także jeśli są wdrażane w różnych punktach końcowych. Obecnie modele w tym samym zbiorze zasobów muszą mieć ten sam obraz kontenera, który zawiera 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 niestandardowe kontenery nie są jeszcze obsługiwane.

deployment_pool

4. Konfigurowanie środowiska

Aby uruchomić to ćwiczenie, musisz mieć projekt Google Cloud Platform z włączonym rozliczeniem. 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 interfejs Notebooks API, jeśli nie jest jeszcze włączony.

Notebook_api

Po włączeniu kliknij ZARZĄDZANE NOTATKI:

Notebooks_UI

Następnie wybierz NOWY NOTATNIK.

new_notebook

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

create_notebook

Wybierz Ustawienia zaawansowane.

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

enable_terminal

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

Następnie kliknij Utwórz. Przygotowanie instancji może potrwać kilka minut.

Po utworzeniu instancji kliknij OTWÓRZ JUPYTERLAB.

open_jupyterlab

5. Trenuj model

Zanim będziemy mogli wypróbować funkcję współhostowania, musimy najpierw wytrenować model i zapisać zapisane artefakty modelu w zasobniku Cloud Storage. Do uruchomienia zadania trenowania użyjemy wykonawcy notebooka 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

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 notebooka

W wyskakującym menu instancji Workbench otwórz nowy notatnik TensorFlow 2.

launcher_tf2

Podany niżej kod trenuje klasyfikator binarny (pozytywne lub negatywne) na podstawie zbioru danych recenzji filmów IMDB. Wklej kod do notatnika.

Pamiętaj, aby zastąpić {YOUR_BUCKET} zasobnikiem utworzonym w poprzednim kroku (lub innym zasobnikiem w projekcie). Tutaj będziemy przechowywać zapisane artefakty modelu, których będziemy potrzebować później, gdy prześlemy model do rejestru modeli Vertex AI.

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 Wykonywanie w konsoli możesz śledzić stan zadania trenowania.

execution_status

6. Wdrażanie modelu

Krok 1. Prześlij model

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

tf_nb

Najpierw zaimportuj pakiet Vertex AI SDK for 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')

W celu przeprowadzenia demonstracji prześlemy ten model 2 razy, tworząc w Vertex AI 2 różne zasoby modelu. Dzięki temu możemy przetestować wdrożenie wielu modeli w pojedynczym punkcie końcowym w ramach puli zasobów wdrożenia. W rzeczywistości dostępne byłyby 2 różne modele, zamiast tworzyć je na podstawie 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 ramach 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 jest to inne niż wdrażanie modelu w punkcie końcowym.

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

Po utworzeniu punktu końcowego zobaczysz go w konsoli.

console_endpoint

Krok 3. Utwórz DeploymentResourcePool

Za pomocą tego polecenia możesz utworzyć DeploymentResourcePool. 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}'

Możesz wyświetlić pulę, wykonują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. Pamiętaj, aby zastąpić wartości MODEL_1_IDENDPOINT_ID odpowiednimi identyfikatorami.

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

To polecenie wdroży model_1 do punktu końcowego w pulach 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. Gdy się skończy, zobaczysz w konsoli model wdrożony na punkcie końcowym.

model_1_endpoint

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

Zaktualizuj MODEL_ID, podając identyfikator model_2. Ponownie możesz uzyskać ten identyfikator, uruchamiając model_2.name

MODEL_2_ID="{MODEL_2_ID}"

Następnie wdróż model_2. Ponieważ model_1 jest już wdrożone w punkcie końcowym, musimy zaktualizować trafficSplit, aby ruch był rozdzielany między te 2 modele. Jeśli zdecydujemy się wdrożyć usługę model_2 do innego punktu końcowego w tej samej puli zasobów, nie będziemy musieli aktualizować usługi trafficSplit.

Aby zaktualizować podział ruchu, musisz zdefiniować identyfikator DeployedModel dla model_1. Pamiętaj, że jest to inny identyfikator niż identyfikator modelu.

DEPLOYED_MODEL_1_ID = {DEPLOYED_MODEL_1_ID}

Następnie wykonaj te czynności, 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ż hostować modele w tym samym zbiorze zasobów, które są wdrażane w różnych punktach końcowych. W takim przypadku nie musisz się martwić o podział ruchu.

Po wdrożeniu drugiego modelu zobaczysz oba modele w konsoli.

deployed_models

Krok 5. Pobieraj prognozy

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

Najpierw określ 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 predict w punkcie końcowym, który zwróci prognozę z jednego z modeli wdrożonych w punkcie końcowym.

endpoint.predict(instances=x_test)

🎉 Gratulacje! 🎉

Poznałeś/poznałaś już te sposoby korzystania z Vertex AI:

  • 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 zamierzasz ich używać, musisz wycofać modele z punktu końcowego. Możesz też całkowicie usunąć punkt końcowy. W razie potrzeby możesz w każdej chwili ponownie wdrożyć model w punkcie końcowym.

undeploy_model

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

Zatrzymaj instancję

Aby usunąć zasobnik na dane, w menu nawigacyjnym w konsoli Cloud przejdź do Cloud Storage, wybierz swój zasobnik i kliknij Usuń:

Usuwanie miejsca na dane