text-embeddings-inference documentation

Развёртывание TEI на Google Cloud Run

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Развёртывание TEI на Google Cloud Run

Развёртывание Text Embeddings Inference (TEI) на Google Cloud Platform (GCP) позволяет использовать преимущества базовой технологии Kubernetes, которая обеспечивает автоматическое масштабирование TEI вверх или вниз в зависимости от нагрузки.

В Google Cloud существует три основных варианта развертывания TEI (или любого другого Docker-контейнера):

  • Cloud Run
  • Эндпоинты Vertex AI
  • GKE (Google Kubernetes Engine).

В этом руководстве объясняется, как развернуть TEI на Cloud Run — полностью управляемом сервисе от Google. Cloud Run представляет собой так называемое serverless-решение. Это означает, что серверная инфраструктура обслуживается Google, а вам достаточно предоставить Docker-контейнер. Преимущество этого подхода в том, что вы платите за вычислительные ресурсы только при наличии нагрузки на ваше приложение. Cloud Run автоматически запускает серверы при появлении нагрузки и масштабирует их до нуля, когда нагрузка отсутствует.

Мы покажем, как развернуть любую модель текстовых эмбеддингов с использованием GPU или без него.

На момент написания документации поддержка GPU в Cloud Run доступна в 4 регионах. Если вы хотите её использовать, запросите увеличение квоты для Total Nvidia L4 GPU allocation, per project per region. На данный момент единственными доступными GPU в Cloud Run являются NVIDIA L4 (24GiB VRAM); по умолчанию включено автоматическое масштабирование до 7 экземпляров (больше доступно через квоту), а также масштабирование до нуля экземпляров при отсутствии запросов.

Настройка / Конфигурация

В этом руководстве предполагается, что вы уже создали проект в Google Cloud и включили биллинг. Это можно сделать на https://console.cloud.google.com/.

Сначала необходимо установить gcloud CLI на локальную машину. Это позволяет программно взаимодействовать с вашим проектом Google Cloud.

Необязательно, но для упрощения использования команд в этом учебнике вам нужно установить следующие переменные окружения для GCP:

export PROJECT_ID=your-project-id
export LOCATION=europe-west1  # or any location you prefer: https://cloud.google.com/run/docs/locations
export CONTAINER_URI="gcr.io/deeplearning-platform-release/huggingface-text-embeddings-inference-cpu.1-6"
export SERVICE_NAME="text-embedding-server" # choose a name for your service
export MODEL_ID="ibm-granite/granite-embedding-278m-multilingual" # choose any embedding model

Некоторые уточнения:

  • Мы предоставляем URI последней официальной Docker-образной версии на основе README.
  • Мы выбрали модель эмбеддингов IBM granite благодаря её сильным многоязычным возможностям. Разумеется, можно выбрать любую другую модель эмбеддингов из хаба. Рекомендуется искать модели с тегами feature-extraction, sentence-similarity или text-ranking.

Затем вам нужно войти в свой аккаунт Google Cloud и указать идентификатор проекта, который вы хотите использовать для развертывания Cloud Run.

gcloud auth login
gcloud auth application-default login  # For local development
gcloud config set project $PROJECT_ID

После входа в систему необходимо включить Cloud Run API, так как он требуется для развертывания Hugging Face DLC for TEI на Cloud Run.

gcloud services enable run.googleapis.com

Развёртывание TEI на Cloud Run

Когда всё готово, вы можете выполнить команду gcloud run deploy, чтобы развернуть Docker-образ.

Для выполнения команды необходимо указать следующие параметры:

  • --image: URI контейнерного образа для развертывания.
  • --args: Аргументы, передаваемые в точку входа контейнера, а именно text-embeddings-inference для Hugging Face DLC для TEI. Подробнее о поддерживаемых аргументах — здесь.
    • --model-id: идентификатор модели, в данном случае ibm-granite/granite-embedding-278m-multilingual.
    • --max-concurrent-requests: максимальное количество одновременных запросов для данного развёртывания. Низкое ограничение приводит к отказу в обслуживании клиентов вместо того, чтобы заставлять их ждать слишком долго, что обычно позволяет корректно обрабатывать обратное давление. Значение установлено в 64, но по умолчанию равно 512.
  • --port: порт, на котором контейнер принимает соединения.
  • --cpu и --memory: количество ЦП и объём памяти, выделяемые контейнеру. Значения должны быть установлены в 4 и 16Gi (16 ГиБ) соответственно, так как это минимальные требования для использования GPU.
  • --no-cpu-throttling: Отключает троттлинг CPU, что необходимо для использования GPU.
  • --gpu и --gpu-type: количество и тип используемых GPU. Значения должны быть равны 1 и nvidia-l4 соответственно, так как на момент написания этого туториала это единственные доступные варианты для Cloud Run on GPUs.
  • --max-instances: максимальное количество запускаемых инстансов, установлено в 3, но значение по умолчанию — 7. Также можно установить значение 1, однако это может привести к простоям во время миграций инфраструктуры, поэтому рекомендуется использовать значение больше 1.
  • --concurrency: максимальное количество одновременных запросов на инстанс, установлено в 64. Обратите внимание, что это значение также согласовано с аргументом --max-concurrent-requests в TEI.
  • --region: регион для развертывания сервиса Cloud Run.
  • --no-allow-unauthenticated: Отключает доступ к сервису без аутентификации, что является хорошей практикой, поскольку добавляет слой аутентификации, управляемый Google Cloud IAM.

При необходимости вы можете указать аргументы --vpc-egress=all-traffic и --subnet=default, так как в публичный интернет отправляется внешний трафик, и для ускорения сети необходимо направить весь трафик через сеть VPC, установив эти флаги. Обратите внимание, что помимо установки флагов, для доступа в публичный интернет необходимо настроить Google Cloud NAT, что является платным продуктом. Подробнее см. в документации Cloud Run — Лучшие практики по сетям.

gcloud compute routers create nat-router --network=default --region=$LOCATION
gcloud compute routers nats create vm-nat --router=nat-router --region=$LOCATION --auto-allocate-nat-external-ips --nat-all-subnet-ip-ranges

Наконец, вы можете выполнить команду gcloud run deploy, чтобы развернуть TEI в Cloud Run:

gcloud run deploy $SERVICE_NAME \
    --image=$CONTAINER_URI \
    --args="--model-id=$MODEL_ID,--max-concurrent-requests=64" \
    --set-env-vars=HF_HUB_ENABLE_HF_TRANSFER=1 \
    --port=8080 \
    --cpu=8 \
    --memory=32Gi \
    --region=$LOCATION \
    --no-allow-unauthenticated

Если вы хотите развернуть с использованием GPU, выполните следующую команду:

gcloud run deploy $SERVICE_NAME \
    --image=$CONTAINER_URI \
    --args="--model-id=$MODEL_ID,--max-concurrent-requests=64" \
    --set-env-vars=HF_HUB_ENABLE_HF_TRANSFER=1 \
    --port=8080 \
    --cpu=8 \
    --memory=32Gi \
    --no-cpu-throttling \
    --gpu=1 \
    --gpu-type=nvidia-l4 \
    --max-instances=3 \
    --concurrency=64 \
    --region=$LOCATION \
    --no-allow-unauthenticated

Или, как следует, если вы создали Cloud NAT:

gcloud beta run deploy $SERVICE_NAME \
    --image=$CONTAINER_URI \
    --args="--model-id=$MODEL_ID,--max-concurrent-requests=64" \
    --set-env-vars=HF_HUB_ENABLE_HF_TRANSFER=1 \
    --port=8080 \
    --cpu=8 \
    --memory=32Gi \
    --no-cpu-throttling \
    --gpu=1 \
    --gpu-type=nvidia-l4 \
    --max-instances=3 \
    --concurrency=64 \
    --region=$LOCATION \
    --no-allow-unauthenticated \
    --vpc-egress=all-traffic \
    --subnet=default

При первом развертывании нового контейнера на Cloud Run процесс займет около 5 минут, так как образ необходимо импортировать из Google Cloud Artifact Registry. Однако при последующих развертываниях время будет меньше, поскольку образ уже был импортирован ранее.

Вывод

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

Все сервисы Cloud Run по умолчанию развертываются в приватном режиме, что означает, что к ним невозможно получить доступ без предоставления данных аутентификации в заголовках запроса. Эти сервисы защищены с помощью IAM и могут вызываться только Project Owners, Project Editors, а также Cloud Run Admins и Cloud Run Invokers.

В этом случае будут рассмотрены несколько альтернатив для предоставления доступа разработчикам; другие сценарии использования выходят за рамки данного примера, поскольку они либо небезопасны из-за отключенной аутентификации (для сценариев публичного доступа), либо требуют дополнительной настройки для сценариев, готовых к работе в продакшене (аутентификация между сервисами, доступ конечных пользователей).

Альтернативы, упомянутые ниже, предназначены для сценариев разработки и не должны использоваться в готовых к работе в продакшене сценариях без изменений. Описанный ниже подход следует руководству, определённому в Cloud Run Documentation - Authenticate Developers; однако все остальные руководства, упомянутые выше, можно найти в Cloud Run Documentation - Authentication overview.

Через Cloud Run Proxy

Cloud Run Proxy запускает сервер на localhost, который проксирует запросы к указанному Cloud Run Service с прикреплёнными учётными данными; это полезно для тестирования и экспериментов.

gcloud run services proxy $SERVICE_NAME --region $LOCATION

Затем вы можете отправлять запросы к развернутому сервису на Cloud Run, используя URL http://localhost:8080, без аутентификации, который предоставляется прокси, как показано в примерах ниже. Вы можете просмотреть документацию API по адресу http://localhost:8080/docs в вашем браузере.

cURL

Чтобы отправить запрос POST в сервис TEI с помощью cURL, выполните следующую команду:

curl http://localhost:8080/embed \
    -X POST \
    -H 'Content-Type: application/json' \
    -d '{
        "model": "tei",
        "text": "What is deep learning?"
    }'

В качестве альтернативы можно отправлять запросы на совместимый с OpenAI эндпоинт:

curl http://localhost:8080/v1/embeddings \
    -X POST \
    -H 'Content-Type: application/json' \
    -d '{
        "model": "tei",
        "text": "What is deep learning?"
    }'

Python

Для выполнения инференсинга с помощью Python можно использовать Python SDK huggingface_hub (рекомендуется) или Python SDK openai.

huggingface_hub

Вы можете установить его через pip с помощью команды pip install --upgrade --quiet huggingface_hub, а затем выполнить:

from huggingface_hub import InferenceClient

client = InferenceClient()
embedding = client.feature_extraction("What is deep learning?",
                                      model="http://localhost:8080/embed")
print(len(embedding[0]))

OpenAI

Вы можете установить его через pip с помощью команды pip install --upgrade openai, а затем выполнить:

from openai import OpenAI

client = OpenAI(base_url="http://localhost:8080/v1/embeddings", api_key="")

response = client.embeddings.create(
  model="tei",
  input="What is deep learning?"
)

print(response)

(рекомендуется) Через URL сервиса Cloud Run

У Cloud Run Service есть уникальный URL, который можно использовать для отправки запросов из любой точки, применяя Google Cloud Credentials с доступом Cloud Run Invoke к сервису; это рекомендуемый подход, так как он более безопасен и последователен по сравнению с использованием Cloud Run Proxy.

URL сервиса Cloud Run можно получить с помощью следующей команды (для удобства он присваивается переменной SERVICE_URL):

SERVICE_URL=$(gcloud run services describe $SERVICE_NAME --region $LOCATION --format 'value(status.url)')

Затем вы можете отправлять запросы к развернутому сервису в Cloud Run, используя SERVICE_URL и любые Google Cloud Credentials с доступом Cloud Run Invoke. Для настройки учетных данных существует несколько подходов, некоторые из них перечислены ниже:

Использование токена по умолчанию из Google Cloud SDK:

  • С помощью gcloud:
gcloud auth print-identity-token
  • Через Python:
import google.auth
from google.auth.transport.requests import Request as GoogleAuthRequest

auth_req = GoogleAuthRequest()
creds, _ = google.auth.default()
creds.refresh(auth_req)

id_token = creds.id_token
  • Использование учётной записи службы (Service Account) с доступом Cloud Run Invoke, что можно сделать любым из следующих способов:

Создайте Service Account до создания Cloud Run Service, а затем при создании Cloud Run Service установите флаг service-account на адрес электронной почты Service Account. Используйте Access Token для этого Service Account только с помощью gcloud auth print-access-token --impersonate-service-account=SERVICE_ACCOUNT_EMAIL. Создайте Service Account после создания Cloud Run Service, а затем обновите Cloud Run Service, чтобы он использовал этот Service Account. Используйте Access Token для этого Service Account только с помощью gcloud auth print-access-token --impersonate-service-account=SERVICE_ACCOUNT_EMAIL.

Рекомендуемый подход — использовать Service Account (SA), поскольку доступ можно контролировать эффективнее, а права назначаются более детально. Так как Cloud Run Service не был создан с использованием SA (что было бы ещё одним удобным вариантом), вам теперь необходимо создать SA, предоставить ему необходимые разрешения, обновить Cloud Run Service для использования этого SA, а затем сгенерировать токен доступа, который будет установлен в качестве токена аутентификации в запросах; после завершения работы с ним этот токен можно отозвать.

  • Для удобства задайте переменную окружения SERVICE_ACCOUNT_NAME:
export SERVICE_ACCOUNT_NAME=tei-invoker
  • Создайте учётную запись службы:
gcloud iam service-accounts create $SERVICE_ACCOUNT_NAME
  • Назначьте роли Cloud Run Invoker для учётной записи службы:
gcloud run services add-iam-policy-binding $SERVICE_NAME \
    --member="serviceAccount:$SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
    --role="roles/run.invoker" \
    --region=$LOCATION

Сгенерируйте токен доступа для учётной записи службы:

export ACCESS_TOKEN=$(gcloud auth print-access-token --impersonate-service-account=$SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com)

Ток доступа имеет ограниченный срок действия и по умолчанию истекает через 1 час. Если вы хотите увеличить срок действия токена сверх значения по умолчанию, вам необходимо создать политику организации и использовать аргумент —lifetime при создании токена. Подробнее см. в разделе Access token lifetime. В противном случае вы можете сгенерировать новый токен, повторно выполнив ту же команду.

Теперь вы можете приступить к изучению различных вариантов отправки запросов к развернутому Cloud Run Service, используя SERVICE_URL и ACCESS_TOKEN, как описано выше.

cURL

Чтобы отправить запрос POST в сервис TEI с помощью cURL, выполните следующую команду:

curl $SERVICE_URL/v1/embeddigs \
    -X POST \
    -H "Authorization: Bearer $ACCESS_TOKEN" \
    -H 'Content-Type: application/json' \
    -d '{
        "model": "tei",
        "text": "What is deep learning?"
    }'

Python

Для выполнения инференсинга с помощью Python можно использовать Python SDK huggingface_hub (рекомендуется) или Python SDK openai.

huggingface_hub

Вы можете установить его через pip с помощью команды pip install --upgrade --quiet huggingface_hub, а затем выполнить:

import os
from huggingface_hub import InferenceClient

client = InferenceClient(
    base_url=os.getenv("SERVICE_URL"),
    api_key=os.getenv("ACCESS_TOKEN"),
)

embedding = client.feature_extraction("What is deep learning?",
                                      model="http://localhost:8080/embed")
print(len(embedding[0]))

OpenAI

Вы можете установить его через pip с помощью команды pip install --upgrade openai, а затем выполнить:

import os
from openai import OpenAI

client = OpenAI(
    base_url=os.getenv("SERVICE_URL"),
    api_key=os.getenv("ACCESS_TOKEN"),
)

response = client.embeddings.create(
  model="tei",
  input="What is deep learning?"
)

print(response)

Освобождение ресурсов

Наконец, когда вы закончите работу с TEI на Cloud Run Service, вы можете безопасно удалить его, чтобы избежать ненужных расходов, например, если сервисы Cloud Run будут вызваны случайно больше раз, чем разрешено вашим месячным лимитом вызовов Cloud Run в бесплатном тарифе.

Чтобы удалить Cloud Run Service, вы можете перейти в Google Cloud Console по адресу https://console.cloud.google.com/run и удалить его вручную; либо использовать Google Cloud SDK через gcloud следующим образом:

gcloud run services delete $SERVICE_NAME --region $LOCATION

Кроме того, если вы выполнили шаги из раздела через URL службы Cloud Run и создали учётную запись службы (Service Account) и токен доступа, вы можете либо удалить учётную запись службы, либо просто отозвать токен доступа, если он всё ещё действителен.

  • (рекомендуется) Отозвать токен доступа как:
gcloud auth revoke --impersonate-service-account=$SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com
  • (необязательно) Удалите Service Account следующим образом:
gcloud iam service-accounts delete $SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com

Наконец, если вы решили включить сеть VPC с помощью Cloud NAT, вы также можете удалить Cloud NAT (это платный продукт), так как:

gcloud compute routers nats delete vm-nat --router=nat-router --region=$LOCATION
gcloud compute routers delete nat-router --region=$LOCATION

Ссылки

Update on GitHub