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

1. Обзор

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

Чему вы научитесь

Вы научитесь:

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

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

2. Введение в Vertex AI

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

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

Обзор продукции Vertex

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

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

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

deployment_pool

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

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

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

Перейдите в раздел Compute Engine и выберите «Включить», если эта функция еще не включена.

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

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

Панель мониторинга Vertex AI

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

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

Меню Vertex AI

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

Notebook_api

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

Notebooks_UI

Затем выберите «Создать новый блокнот» .

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

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

создать_блокнот

Выберите «Расширенные настройки» .

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

enable_terminal

Все остальные расширенные настройки можно оставить без изменений.

Далее нажмите «Создать» . Создание экземпляра займет несколько минут.

После создания экземпляра выберите «ОТКРЫТЬ JUPYTERLAB» .

open_jupyterlab

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

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

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

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

launcher_terminal

В терминале выполните следующую команду, чтобы определить переменную окружения для вашего проекта, заменив 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 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)

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

execute_nb

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

execution_config

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

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

6. Модель развертывания

Шаг 1: Загрузка модели

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

tf_nb

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

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 теперь должны отображаться обе модели. Статус развертывания пуст, поскольку модели еще не развернуты.

модель_регистрация

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

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

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

После создания конечной точки вы увидите её в консоли.

console_endpoint

Шаг 3: Создайте пул ресурсов развертывания (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 , указав в ней ID для model_2 . Этот ID можно получить, выполнив команду model_2.name

MODEL_2_ID="{MODEL_2_ID}"

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

Для обновления распределения трафика необходимо определить идентификатор развернутой модели (DeployedModel ID) для model_1 . Обратите внимание, что он отличается от идентификатора модели (model ID).

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 в консоли. Если вы хотите полностью удалить блокнот, нажмите кнопку «Удалить».

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

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

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