文本嵌入推理文档
在 Google Cloud Run 上部署 TEI
并获得增强的文档体验
开始使用
在 Google Cloud Run 上部署 TEI
在 Google Cloud Platform (GCP) 上部署文本嵌入推理 (TEI) 可以利用底层 Kubernetes 技术,该技术可确保 TEI 根据需求自动扩展或缩减。
在 Google Cloud 上,有 3 个主要选项可用于部署 TEI(或任何其他 Docker 容器)
- Cloud Run
- Vertex AI 端点
- GKE(Google Kubernetes Engine)。
本指南将介绍如何在 Cloud Run 上部署 TEI,Cloud Run 是 Google 提供的一项完全托管的服务。Cloud Run 是一种所谓的无服务器产品。这意味着服务器基础设施由 Google 处理,您只需提供一个 Docker 容器。这样做的好处是,您只在应用程序有需求时才为计算付费。当有需求时,Cloud Run 会自动启动服务器;当没有需求时,它会缩减到零实例。
我们将展示如何部署任何带或不带 GPU 的文本嵌入模型。
[!NOTE] 截至撰写本文时,Cloud Run 上的 GPU 支持在 4 个区域已普遍可用。如果您有兴趣使用它,请申请增加配额,用于`每个项目每个区域的总 Nvidia L4 GPU 分配`。目前,NVIDIA L4 GPU(24GiB 显存)是 Cloud Run 上唯一可用的 GPU;默认情况下,它支持自动扩展到最多 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
一些澄清
- 我们根据 README 提供最新的官方 Docker 镜像 URI。
- 我们选择部署 IBM granite 嵌入模型,因为它具有强大的多语言能力。当然,您可以从 Hub 中选择任何其他嵌入模型。建议查找标记为 `feature-extraction`、`sentence-similarity` 或 `text-ranking` 的模型。
然后您需要登录您的 Google Cloud 账户并设置您要用于部署 Cloud Run 的项目 ID。
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
在 Cloud Run 上部署 TEI
一切就绪后,您可以调用 `gcloud run deploy` 命令来部署 Docker 镜像。
该命令需要您指定以下参数
--image
:要部署的容器镜像 URI。--args
:传递给容器入口点的参数,对于 Hugging Face DLC for TEI,该参数为 `text-embeddings-inference`。更多关于支持的参数,请此处阅读。--model-id
:要使用的模型 ID,在此例中为ibm-granite/granite-embedding-278m-multilingual
。--quantize
:要使用的量化方法。如果未指定,它将从 `config.json` 文件中的 `quantization_config->quant_method` 中检索。--max-concurrent-requests
:此特定部署的最大并发请求数。设置较低的限制将拒绝客户端请求,而不是让它们等待太长时间,这通常有利于正确处理反压。设置为 64,但默认值为 128。
--port
:容器监听的端口。--cpu
和--memory
:分配给容器的 CPU 数量和内存量。需要分别设置为 4 和 16Gi (16 GiB);因为这是使用 GPU 的最低要求。--no-cpu-throttling
:禁用 CPU 节流,这是使用 GPU 所必需的。--gpu
和--gpu-type
:要使用的 GPU 数量和 GPU 类型。必须分别设置为 1 和 `nvidia-l4`;因为在撰写本教程时,这些是 Cloud Run on GPUs 上唯一可用的选项。--max-instances
:要运行的最大实例数,设置为 3,但默认最大值为 7。另外,也可以设置为 1,但这最终可能导致基础设施迁移期间停机,因此建议设置为 1 以上。--concurrency
:每个实例的最大并发请求数,设置为 64。请注意,此值也与 TEI 中的--max-concurrent-requests
参数一致。--region
:部署 Cloud Run 服务的区域。--no-allow-unauthenticated
:禁用对服务的未经身份验证的访问,这是一个很好的做法,因为它添加了由 Google Cloud IAM 管理的身份验证层。
[!NOTE] 可选地,您可以包含参数 `—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` 命令来部署 Cloud Run 上的 TEI,如下所示:
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
[!NOTE] 首次在 Cloud Run 上部署新容器大约需要 5 分钟,因为它需要从 Google Cloud Artifact Registry 导入,但在后续部署中,由于镜像已提前导入,因此所需时间会更短。
推理
部署后,您可以通过任何受支持的 TEI 端点向服务发送请求,请查看 TEI 的 OpenAPI 规范以查看所有可用的端点及其各自的参数。
所有 Cloud Run 服务默认情况下都是私有部署的,这意味着未经请求头中提供身份验证凭据,无法访问它们。这些服务受 IAM 保护,并且只能由项目所有者、项目编辑者、Cloud Run 管理员和 Cloud Run 调用者调用。
在这种情况下,将展示几种启用开发人员访问的替代方案;而其他用例超出了本示例的范围,因为它们要么由于身份验证被禁用而不安全(对于公共访问场景),要么需要额外的设置才能用于生产就绪场景(服务到服务身份验证、最终用户访问)。
[!NOTE] 下面提到的替代方案适用于开发场景,不应直接用于生产就绪场景。以下方法遵循Cloud Run 文档 - 身份验证开发人员中定义的指南;但您可以在Cloud Run 文档 - 身份验证概述中找到所有其他指南,如上所述。
通过 Cloud Run 代理
Cloud Run 代理在本地主机上运行一个服务器,该服务器将请求代理到指定的 Cloud Run 服务并附加凭据;这对于测试和实验很有用。
gcloud run services proxy $SERVICE_NAME --region $LOCATION
然后,您可以使用 https://:8080 URL 向 Cloud Run 上部署的服务发送请求,无需身份验证,如以下示例所示,由代理公开。您可以在浏览器中查看 API 文档:https://:8080/docs。
cURL
要使用 cURL 向 TEI 服务发送 POST 请求,您可以运行以下命令
curl https://:8080/embed \
-X POST \
-H 'Content-Type: application/json' \
-d '{
"model": "tei",
"text": "What is deep learning?"
}'
或者,也可以向兼容 OpenAI 的端点发送请求
curl https://:8080/v1/embeddings \
-X POST \
-H 'Content-Type: application/json' \
-d '{
"model": "tei",
"text": "What is deep learning?"
}'
Python
要使用 Python 运行推理,您可以使用 huggingface_hub Python SDK(推荐)或 openai Python SDK。
huggingface_hub
您可以通过 `pip install --upgrade --quiet huggingface_hub` 安装,然后运行
from huggingface_hub import InferenceClient
client = InferenceClient()
embedding = client.feature_extraction("What is deep learning?",
model="https://:8080/embed")
print(len(embedding[0]))
OpenAI
您可以通过 `pip install --upgrade openai` 安装,然后运行
from openai import OpenAI
client = OpenAI(base_url="https://:8080/v1/embeddings", api_key="")
response = client.embeddings.create(
model="tei",
input="What is deep learning?"
)
print(response)
(推荐)通过 Cloud Run 服务 URL
Cloud Run 服务有一个唯一的 URL,可以用于从任何地方发送请求,使用具有 Cloud Run 调用访问权限的 Google Cloud 凭据;这是推荐的方法,因为它比使用 Cloud Run 代理更安全、更一致。
Cloud Run 服务的 URL 可以通过以下命令获取(为方便起见,分配给 SERVICE_URL 变量)
SERVICE_URL=$(gcloud run services describe $SERVICE_NAME --region $LOCATION --format 'value(status.url)')
然后,您可以使用 `SERVICE_URL` 和任何具有 Cloud Run Invoke 访问权限的 Google Cloud 凭据向 Cloud Run 上部署的服务发送请求。设置凭据有多种方法,其中一些列在下面
使用 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
- 使用具有 Cloud Run Invoke 访问权限的服务帐户,可以通过以下任何一种方法完成
在创建 Cloud Run 服务之前创建服务帐户,然后在创建 Cloud Run 服务时将 service-account 标志设置为服务帐户电子邮件。并且仅使用 `gcloud auth print-access-token --impersonate-service-account=SERVICE_ACCOUNT_EMAIL` 为该服务帐户使用访问令牌。 在创建 Cloud Run 服务之后创建服务帐户,然后更新 Cloud Run 服务以使用该服务帐户。并且仅使用 `gcloud auth print-access-token --impersonate-service-account=SERVICE_ACCOUNT_EMAIL` 为该服务帐户使用访问令牌。
推荐的方法是使用服务帐户 (SA),因为访问可以得到更好的控制,并且权限更精细;由于 Cloud Run 服务不是使用 SA 创建的(这是另一个不错的选择),您现在需要创建 SA,授予其必要的权限,更新 Cloud Run 服务以使用 SA,然后生成访问令牌以设置为请求中的身份验证令牌,该令牌可以在使用完毕后撤销。
- 为了方便起见,设置 SERVICE_ACCOUNT_NAME 环境变量
export SERVICE_ACCOUNT_NAME=tei-invoker
- 创建服务帐户
gcloud iam service-accounts create $SERVICE_ACCOUNT_NAME
- 授予服务帐户 Cloud Run 调用者角色
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 参数。请参阅访问令牌生命周期以了解更多信息。否则,您也可以通过再次运行相同的命令来生成新令牌。
现在,您已经可以深入研究向已部署的 Cloud Run 服务发送请求的不同替代方案,使用如上所述的 `SERVICE_URL` 和 `ACCESS_TOKEN`。
cURL
要使用 cURL 向 TEI 服务发送 POST 请求,您可以运行以下命令
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 运行推理,您可以使用 huggingface_hub Python SDK(推荐)或 openai Python SDK。
huggingface_hub
您可以通过 `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="https://:8080/embed")
print(len(embedding[0]))
OpenAI
您可以通过 `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)
资源清理
最后,一旦您在 Cloud Run 服务上使用完 TEI,就可以安全地删除它,以避免产生不必要的费用,例如,如果 Cloud Run 服务在免费套餐中意外调用次数超过您的每月 Cloud Run 调用分配。
要删除 Cloud Run 服务,您可以前往 Google Cloud 控制台 https://console.cloud.google.com/run 手动删除;或者通过 gcloud 使用 Google Cloud SDK,如下所示
gcloud run services delete $SERVICE_NAME --region $LOCATION
此外,如果您按照“通过 Cloud Run 服务 URL”中的步骤操作并生成了服务帐户和访问令牌,您可以删除服务帐户,或者如果它仍然有效,只需撤销访问令牌。
- (推荐)撤销访问令牌,如下所示:
gcloud auth revoke --impersonate-service-account=$SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com
- (可选)删除服务帐户,如下所示:
gcloud iam service-accounts delete $SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com
最后,如果您决定通过 Cloud NAT 启用 VPC 网络,您还可以删除 Cloud NAT(这是一个付费产品),如下所示
gcloud compute routers nats delete vm-nat --router=nat-router --region=$LOCATION
gcloud compute routers delete nat-router --region=$LOCATION