Vertex AI: совместное размещение моделей на одной виртуальной машине для прогнозирования

1. Обзор

В ходе этой лабораторной работы вы будете использовать функцию совместного размещения моделей в Vertex AI для размещения нескольких моделей на одной виртуальной машине для онлайн-прогнозирования.

Что ты учишь

Вы узнаете, как:

  • Создайте пул DeploymentResourcePool
  • Развертывание моделей в DeploymentResourcePool

Общая стоимость запуска этой лаборатории в Google Cloud составляет около 2 долларов США .

2. Знакомство с Vertex AI

В этой лаборатории используются новейшие продукты искусственного интеллекта, доступные в Google Cloud. Vertex AI интегрирует предложения машинного обучения в Google Cloud в единый процесс разработки. Раньше модели, обученные с помощью AutoML, и пользовательские модели были доступны через отдельные сервисы. Новое предложение объединяет оба API в одном API, а также другие новые продукты. Вы также можете перенести существующие проекты на Vertex AI. Если у вас есть какие-либо отзывы, пожалуйста, посетите страницу поддержки .

Vertex AI включает в себя множество различных продуктов для поддержки комплексных рабочих процессов машинного обучения. Эта лабораторная работа будет сосредоточена на продуктах, перечисленных ниже: Прогнозы и Workbench.

Обзор продукта Vertex

3. Обзор вариантов использования

При развертывании моделей в сервисе прогнозирования Vertex AI каждая модель по умолчанию развертывается на собственной виртуальной машине. Чтобы сделать хостинг более экономичным, вы можете разместить несколько моделей на одной виртуальной машине, что приведет к более эффективному использованию памяти и вычислительных ресурсов. Количество моделей, которые вы решите развернуть на одной виртуальной машине, будет зависеть от размеров моделей и структуры трафика, но эта функция особенно полезна для сценариев, когда у вас много развернутых моделей с редким трафиком.

Поддержка модели совместного размещения представляет концепцию пула ресурсов развертывания, который группирует модели для совместного использования ресурсов внутри виртуальной машины. Модели могут совместно использовать виртуальную машину, если они используют общую конечную точку, а также если они развернуты на разных конечных точках. В настоящее время модели в одном пуле ресурсов должны иметь один и тот же образ контейнера, включая версию платформы предварительно созданных контейнеров Vertex Prediction. Кроме того, в этом выпуске поддерживаются только предварительно созданные контейнеры Vertex Prediction с платформой модели Tensorflow, другие платформы моделей и пользовательские контейнеры пока не поддерживаются.

развертывание_пул

4. Настройте свою среду

Для запуска этой лаборатории кода вам понадобится проект Google Cloud Platform с включенной оплатой. Чтобы создать проект, следуйте инструкциям здесь .

Шаг 1. Включите API Compute Engine.

Перейдите к Compute Engine и выберите «Включить» , если он еще не включен.

Шаг 2. Включите API Vertex AI.

Перейдите в раздел Vertex AI в облачной консоли и нажмите «Включить Vertex AI API» .

Панель управления Vertex AI

Шаг 3. Создайте экземпляр Vertex AI Workbench.

В разделе Vertex AI облачной консоли нажмите Workbench:

Меню вершинного AI

Включите API ноутбуков, если это еще не сделано.

Notebook_api

После включения нажмите «УПРАВЛЯЕМЫЕ НОУТБУКЫ» :

Ноутбуки_UI

Затем выберите НОВЫЙ НОУТБУК .

новый_ноутбук

Дайте своему блокноту имя и в разделе «Разрешения» выберите «Учетная запись службы».

create_notebook

Выберите Дополнительные настройки .

В разделе «Безопасность» выберите «Включить терминал», если он еще не включен.

Enable_terminal

Все остальные дополнительные настройки вы можете оставить как есть.

Далее нажмите Создать . Подготовка экземпляра займет пару минут.

После создания экземпляра выберите OPEN JUPYTERLAB .

open_jupyterlab

5. Модель поезда

Прежде чем мы сможем опробовать функцию совместного хостинга, нам сначала необходимо обучить модель и сохранить сохраненные артефакты модели в корзине облачного хранилища. Мы воспользуемся исполнителем блокнота Workbench для запуска обучающего задания.

Шаг 1. Создайте сегмент облачного хранилища.

Если в вашем проекте уже есть сегмент, который вы хотите использовать, вы можете пропустить этот шаг. В противном случае из панели запуска откройте новый сеанс терминала.

launcher_terminal

В терминале выполните следующую команду, чтобы определить переменную env для вашего проекта, обязательно заменяя your-cloud-project идентификатором вашего проекта:

PROJECT_ID='your-cloud-project'

Затем выполните следующую команду, чтобы создать новый сегмент в вашем проекте.

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

Шаг 2. Запустите выполнение блокнота

В панели запуска вашего экземпляра Workbench откройте новый блокнот TensorFlow 2.

launcher_tf2

Код ниже обучает бинарный классификатор настроений (положительный или отрицательный) на наборе данных обзора фильмов IMDB . Вставьте код в свой блокнот.

Обязательно замените {YOUR_BUCKET} сегментом, созданным на предыдущем шаге (или другим сегментом в вашем проекте). Здесь мы будем хранить сохраненные артефакты модели, которые нам понадобятся позже, когда мы загрузим модель в реестр моделей 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)

Далее нажмите кнопку «Выполнить» .

выполнить_nb

Затем настройте выполнение следующим образом и нажмите ОТПРАВИТЬ.

исполнение_конфигурации

На вкладке «Выполнения» в консоли вы можете отслеживать статус вашего учебного задания.

статус_выполнения

6. Развертывание модели

Шаг 1. Загрузите модель.

Когда выполнение завершится, вернитесь в записную книжку Workbench, чтобы загрузить модель. Создайте новый блокнот TensorFlow.

tf_nb

Сначала импортируйте Vertex AI Python SDK.

from google.cloud import aiplatform

Затем загрузите модель, заменив {YOUR_BUCKET} сегментом, указанным в обучающем коде.

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

В демонстрационных целях мы загрузим эту модель дважды, создав два разных ресурса модели в Vertex AI. Это сделано для того, чтобы мы могли протестировать развертывание нескольких моделей на одной конечной точке в пуле ресурсов развертывания. В реальном сценарии у вас будет две разные модели вместо создания моделей из одних и тех же сохраненных артефактов, но это ярлык, поэтому нам не нужно запускать еще одно обучение. Кроме того, вы также можете выбрать развертывание двух моделей на разных конечных точках в одном пуле ресурсов развертывания.

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

В реестре моделей Vertex AI теперь вы должны увидеть обе модели. Статус развертывания пуст, поскольку мы еще не развернули модели.

model_registry

Шаг 2. Создайте конечную точку

Создайте конечную точку. Обратите внимание, что это отличается от развертывания модели в конечной точке.

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

Когда конечная точка будет создана, вы увидите ее в консоли.

console_endpoint

Шаг 3. Создайте пул DeploymentResourcePool.

Вы можете создать DeploymentResourcePool с помощью следующей команды. Обязательно замените {YOUR_PROJECT} идентификатором своего проекта.

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

Вы можете увидеть бассейн, запустив

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

Шаг 4. Разверните модели в конечной точке.

Теперь, когда пул ресурсов создан, мы можем развернуть модели в пуле ресурсов.

Сначала мы развернем model_1 . Обязательно замените MODEL_1_ID и ENDPOINT_ID соответствующими идентификаторами.

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

Следующая команда развернет model_1 в конечной точке в пуле ресурсов.

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

Это займет несколько минут, но когда это будет сделано, вы увидите модель, развернутую в конечной точке в консоли.

model_1_endpoint

Далее мы можем развернуть model_2 в том же пуле развертывания. Мы развернем его в той же конечной точке, что и model_1 . Однако вы также можете выбрать развертывание model_2 в другой конечной точке в том же пуле ресурсов.

Обновите MODEL_ID , указав идентификатор model_2 . Опять же, вы можете получить этот идентификатор, запустив model_2.name

MODEL_2_ID="{MODEL_2_ID}"

Затем разверните model_2 . Поскольку у нас уже развернута model_1 в конечной точке, нам нужно обновить trafficSplit , чтобы трафик был разделен между двумя моделями. Нам не придется обновлять trafficSplit если мы решим развернуть model_2 на другой конечной точке в том же пуле ресурсов.

Чтобы обновить разделение трафика, вам необходимо определить идентификатор DeployedModel для model_1 . Обратите внимание, что это отличается от идентификатора модели.

DEPLOYED_MODEL_1_ID = {DEPLOYED_MODEL_1_ID}

Затем выполните следующее, чтобы развернуть вторую модель.

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

Опять же, в этом примере две модели были развернуты в одной конечной точке, но вы также можете совместно разместить модели в одном пуле ресурсов, которые развернуты в разных конечных точках. В этом случае вам не придется беспокоиться о разделении трафика.

После развертывания второй модели вы увидите их обе в консоли.

развернутые_модели

Шаг 5. Получите прогнозы

Последний шаг — проверить конечную точку и получить прогнозы.

Сначала определите наше тестовое предложение.

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

Затем вызовите Predict в конечной точке, который вернет прогноз одной из моделей, развернутых в конечной точке.

endpoint.predict(instances=x_test)

🎉Поздравляем! 🎉

Вы узнали, как использовать Vertex AI, чтобы:

  • Совместное размещение моделей на одной виртуальной машине для онлайн-прогнозирования

Чтобы узнать больше о различных частях Vertex, ознакомьтесь с документацией .

7. Очистка

Вам потребуется отменить развертывание моделей с конечной точки, если вы не планируете их использовать. Вы также можете полностью удалить конечную точку. При необходимости вы всегда можете повторно развернуть модель в конечной точке.

undeploy_model

Блокноты, управляемые Workbench, автоматически отключаются после 180 минут простоя, поэтому вам не нужно беспокоиться об отключении экземпляра. Если вы хотите вручную завершить работу экземпляра, нажмите кнопку «Стоп» в разделе консоли Vertex AI Workbench. Если вы хотите полностью удалить блокнот, нажмите кнопку «Удалить».

Остановить экземпляр

Чтобы удалить сегмент хранилища, в меню навигации облачной консоли перейдите к разделу «Хранилище», выберите сегмент и нажмите «Удалить»:

Удалить хранилище