本教程介绍了如何通过 Ray Operator 插件和 vLLM 服务框架,使用 Google Kubernetes Engine (GKE) 中的张量处理单元 (TPU) 来应用大语言模型 (LLM)。
在本教程中,您可以在 TPU v5e 或 TPU Trillium (v6e) 上提供 LLM 模型,具体方法如下:
- 单主机 TPU v5e 上的 Llama 3 8B 指令。
- 单主机 TPU v5e 上的 Mistral 7B instruct v0.3。
- 单主机 TPU Trillium (v6e) 上的 Llama 3.1 70B。
本指南适用于对通过 Kubernetes 容器编排功能在 TPU 上使用 Ray 应用模型感兴趣的生成式 AI 客户、GKE 的新用户和现有用户、机器学习工程师、MLOps (DevOps) 工程师或平台管理员。
背景
本部分介绍本指南中使用的关键技术。
GKE 代管式 Kubernetes 服务
Google Cloud 提供各种服务,包括 GKE,非常适合部署和管理 AI/机器学习工作负载。GKE 是一种托管式 Kubernetes 服务,可简化容器化应用的部署、扩缩和管理。GKE 提供必要的基础架构,包括可扩缩的资源、分布式计算和高效的网络,以处理 LLM 的计算需求。
如需详细了解关键 Kubernetes 概念,请参阅开始了解 Kubernetes。 如需详细了解 GKE 以及它如何帮助您扩缩、自动执行和管理 Kubernetes,请参阅 GKE 概览。
Ray Operator
GKE 上的 Ray Operator 插件提供了端到端 AI/机器学习平台,用于部署、训练和微调机器学习工作负载。在本教程中,您将使用 Ray Serve(Ray 中的框架)通过 Hugging Face 为热门 LLM 供给数据。
TPU
TPU 是 Google 定制开发的应用专用集成电路 (ASIC),用于加速机器学习和使用 TensorFlow、PyTorch 和 JAX 等框架构建的 AI 模型。
本教程介绍了如何在 TPU v5e 或 TPU Trillium (v6e) 节点上提供 LLM 模型,并根据每个模型的要求配置 TPU 拓扑,以低延迟响应提示。
vLLM
vLLM 是一个经过高度优化的开源 LLM 服务框架,可提高 TPU 上的服务吞吐量,具有如下功能:
- 具有 PagedAttention 且经过优化的 Transformer(转换器)实现
- 连续批处理,可提高整体服务吞吐量
- 多个 GPU 上的张量并行处理和分布式服务
如需了解详情,请参阅 vLLM 文档。
目标
本教程介绍以下步骤:
- 创建具有 TPU 节点池的 GKE 集群。
- 部署包含单主机 TPU 切片的 RayCluster 自定义资源。GKE 会将 RayCluster 自定义资源部署为 Kubernetes Pod。
- 提供 LLM。
- 与模型互动。
您可以选择性地配置 Ray Serve 框架支持的以下模型部署资源和方法:
- 部署 RayService 自定义资源。
- 通过模型组合实现多个模型的组合。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行
gcloud components update
以获取最新版本。
- 如果您还没有 Hugging Face 账号,请创建一个。
- 确保您拥有 Hugging Face 令牌。
- 确保您有权访问要使用的 Hugging Face 模型。通常需要在 Hugging Face 模型页面上签署相关协议并向模型所有者申请使用权,来获得此类访问权限。
准备环境
确保您的 Google Cloud 项目中有足够的配额来提供给单主机 TPU v5e 或单主机 TPU Trillium (v6e)。如需管理配额,请参阅 TPU 配额。
在 Google Cloud 控制台中,启动 Cloud Shell 实例:
打开 Cloud Shell克隆示例代码库:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git cd kubernetes-engine-samples
导航到工作目录:
cd ai-ml/gke-ray/rayserve/llm
为 GKE 集群创建设置默认环境变量:
export PROJECT_ID=$(gcloud config get project) export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)") export CLUSTER_NAME=vllm-tpu export COMPUTE_REGION=
REGION export COMPUTE_ZONE=ZONE export HF_TOKEN=HUGGING_FACE_TOKEN export GSBUCKET=vllm-tpu-bucket export KSA_NAME=vllm-sa export NAMESPACE=default export MODEL_ID="meta-llama/Meta-Llama-3-8B-Instruct" export VLLM_IMAGE=docker.io/vllm/vllm-tpu:866fa4550d572f4ff3521ccf503e0df2e76591a1 export SERVICE_NAME=vllm-tpu-head-svc替换以下内容:
HUGGING_FACE_TOKEN
:您的 Hugging Face 访问令牌。REGION
:您拥有 TPU 配额的区域。确保您要使用的 TPU 版本在此区域中可用。如需了解详情,请参阅 GKE 中的 TPU 可用性。ZONE
:具有可用 TPU 配额的可用区。VLLM_IMAGE
:vLLM TPU 映像。 您可以使用公共docker.io/vllm/vllm-tpu:866fa4550d572f4ff3521ccf503e0df2e76591a1
映像,也可以构建自己的 TPU 映像。
export PROJECT_ID=$(gcloud config get project) export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)") export CLUSTER_NAME=vllm-tpu export COMPUTE_REGION=
REGION export COMPUTE_ZONE=ZONE export HF_TOKEN=HUGGING_FACE_TOKEN export GSBUCKET=vllm-tpu-bucket export KSA_NAME=vllm-sa export NAMESPACE=default export MODEL_ID="mistralai/Mistral-7B-Instruct-v0.3" export TOKENIZER_MODE=mistral export VLLM_IMAGE=docker.io/vllm/vllm-tpu:866fa4550d572f4ff3521ccf503e0df2e76591a1 export SERVICE_NAME=vllm-tpu-head-svc替换以下内容:
HUGGING_FACE_TOKEN
:您的 Hugging Face 访问令牌。REGION
:您拥有 TPU 配额的区域。确保您要使用的 TPU 版本在此区域提供。如需了解详情,请参阅 GKE 中的 TPU 可用性。ZONE
:具有可用 TPU 配额的可用区。VLLM_IMAGE
:vLLM TPU 映像。 您可以使用公共docker.io/vllm/vllm-tpu:866fa4550d572f4ff3521ccf503e0df2e76591a1
映像,也可以构建自己的 TPU 映像。
export PROJECT_ID=$(gcloud config get project) export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)") export CLUSTER_NAME=vllm-tpu export COMPUTE_REGION=
REGION export COMPUTE_ZONE=ZONE export HF_TOKEN=HUGGING_FACE_TOKEN export GSBUCKET=vllm-tpu-bucket export KSA_NAME=vllm-sa export NAMESPACE=default export MODEL_ID="meta-llama/Llama-3.1-70B" export MAX_MODEL_LEN=8192 export VLLM_IMAGE=docker.io/vllm/vllm-tpu:866fa4550d572f4ff3521ccf503e0df2e76591a1 export SERVICE_NAME=vllm-tpu-head-svc替换以下内容:
HUGGING_FACE_TOKEN
:您的 Hugging Face 访问令牌。REGION
:您拥有 TPU 配额的区域。确保您要使用的 TPU 版本在此区域提供。如需了解详情,请参阅 GKE 中的 TPU 可用性。ZONE
:具有可用 TPU 配额的可用区。VLLM_IMAGE
:vLLM TPU 映像。 您可以使用公共docker.io/vllm/vllm-tpu:866fa4550d572f4ff3521ccf503e0df2e76591a1
映像,也可以构建自己的 TPU 映像。
拉取 vLLM 容器映像:
docker pull ${VLLM_IMAGE}
创建集群
您可以使用 Ray Operator 插件,在 GKE Autopilot 或 Standard 集群中通过 Ray 在 TPU 上为 LLM 供给数据。
使用 Autopilot 集群可获得全托管式 Kubernetes 体验。如需选择最适合您的工作负载的 GKE 操作模式,请参阅选择 GKE 操作模式。
使用 Cloud Shell 创建 Autopilot 或 Standard 集群:
创建启用了 Ray Operator 插件的 GKE Autopilot 集群:
gcloud container clusters create-auto ${CLUSTER_NAME} \ --enable-ray-operator \ --release-channel=rapid \ --location=${COMPUTE_REGION}
创建启用了 Ray Operator 插件的 Standard 集群:
gcloud container clusters create ${CLUSTER_NAME} \ --release-channel=rapid \ --location=${COMPUTE_ZONE} \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --machine-type="n1-standard-4" \ --addons=RayOperator,GcsFuseCsiDriver
创建单主机 TPU 切片节点池:
gcloud container node-pools create tpu-1 \ --location=${COMPUTE_ZONE} \ --cluster=${CLUSTER_NAME} \ --machine-type=ct5lp-hightpu-8t \ --num-nodes=1
GKE 会创建一个具有
ct5lp-hightpu-8t
机器类型的 TPU v5e 节点池。gcloud container node-pools create tpu-1 \ --location=${COMPUTE_ZONE} \ --cluster=${CLUSTER_NAME} \ --machine-type=ct5lp-hightpu-8t \ --num-nodes=1
GKE 会创建一个具有
ct5lp-hightpu-8t
机器类型的 TPU v5e 节点池。gcloud container node-pools create tpu-1 \ --location=${COMPUTE_ZONE} \ --cluster=${CLUSTER_NAME} \ --machine-type=ct6e-standard-8t \ --num-nodes=1
GKE 会创建一个具有
ct6e-standard-8t
机器类型的 TPU v6e 节点池。
配置 kubectl 以与您的集群通信
如需配置 kubectl 以与您的集群通信,请运行以下命令:
gcloud container clusters get-credentials ${CLUSTER_NAME} \
--location=${COMPUTE_REGION}
gcloud container clusters get-credentials ${CLUSTER_NAME} \
--location=${COMPUTE_ZONE}
为 Hugging Face 凭据创建 Kubernetes Secret
如需创建包含 Hugging Face 令牌的 Kubernetes Secret,请运行以下命令:
kubectl create secret generic hf-secret \
--from-literal=hf_api_token=${HF_TOKEN} \
--dry-run=client -o yaml | kubectl --namespace ${NAMESPACE} apply -f -
创建 Cloud Storage 存储桶
为了加快 vLLM 部署的启动时间并最大限度地减少每个节点所需的磁盘空间,请使用 Cloud Storage FUSE CSI 驱动程序将下载的模型和编译缓存挂载到 Ray 节点。
在 Cloud Shell 中,运行以下命令:
gcloud storage buckets create gs://${GSBUCKET} \
--uniform-bucket-level-access
此命令会创建一个 Cloud Storage 存储分区来存储您从 Hugging Face 下载的模型文件。
设置 Kubernetes ServiceAccount 以访问存储分区
创建 Kubernetes ServiceAccount:
kubectl create serviceaccount ${KSA_NAME} \ --namespace ${NAMESPACE}
向 Kubernetes ServiceAccount 授予对 Cloud Storage 存储分区的读写权限:
gcloud storage buckets add-iam-policy-binding gs://${GSBUCKET} \ --member "principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/${NAMESPACE}/sa/${KSA_NAME}" \ --role "roles/storage.objectUser"
GKE 会为 LLM 创建以下资源:
- 用于存储下载的模型和编译缓存的 Cloud Storage 存储分区。Cloud Storage FUSE CSI 驱动程序会读取存储分区中的内容。
- 启用了文件缓存的卷以及 Cloud Storage FUSE 的并行下载功能。
最佳实践: 根据模型内容(例如权重文件)的预期大小,使用由
tmpfs
或Hyperdisk / Persistent Disk
支持的文件缓存。在本教程中,您将使用由 RAM 支持的 Cloud Storage FUSE 文件缓存。
部署 RayCluster 自定义资源
部署 RayCluster 自定义资源,该资源通常由一个系统 Pod 和多个工作器 Pod 组成。
请完成以下步骤,创建 RayCluster 自定义资源以部署经过 Llama 3 8B 指令调优的模型:
检查
ray-cluster.tpu-v5e-singlehost.yaml
清单:应用清单:
envsubst < tpu/ray-cluster.tpu-v5e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
envsubst
命令会替换清单中的环境变量。
GKE 会创建一个 RayCluster 自定义资源,其中包含一个 workergroup
,该 workergroup
在 2x4
拓扑中包含 TPU v5e 单主机。
创建 RayCluster 自定义资源以部署 Mistral-7B 模型,具体步骤如下:
检查
ray-cluster.tpu-v5e-singlehost.yaml
清单:应用清单:
envsubst < tpu/ray-cluster.tpu-v5e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
envsubst
命令会替换清单中的环境变量。
GKE 会创建一个 RayCluster 自定义资源,其中包含一个 workergroup
,该 workergroup
在 2x4
拓扑中包含 TPU v5e 单主机。
请完成以下步骤,创建 RayCluster 自定义资源以部署 Llama 3.1 70B 模型:
检查
ray-cluster.tpu-v6e-singlehost.yaml
清单:应用清单:
envsubst < tpu/ray-cluster.tpu-v6e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
envsubst
命令会替换清单中的环境变量。
GKE 会创建一个 RayCluster 自定义资源,其中包含 2x4
拓扑中的 TPU v6e 单主机的 workergroup
。
连接到 RayCluster 自定义资源
创建 RayCluster 自定义资源后,您可以连接到 RayCluster 资源并开始部署模型。
验证 GKE 是否已创建 RayCluster 服务:
kubectl --namespace ${NAMESPACE} get raycluster/vllm-tpu \ --output wide
输出类似于以下内容:
NAME DESIRED WORKERS AVAILABLE WORKERS CPUS MEMORY GPUS TPUS STATUS AGE HEAD POD IP HEAD SERVICE IP vllm-tpu 1 1 ### ###G 0 8 ready ### ###.###.###.### ###.###.###.###
等待
STATUS
变为ready
,并且HEAD POD IP
和HEAD SERVICE IP
列中显示 IP 地址。建立到 Ray 头节点的
port-forwarding
会话:pkill -f "kubectl .* port-forward .* 8265:8265" pkill -f "kubectl .* port-forward .* 10001:10001" kubectl --namespace ${NAMESPACE} port-forward service/${SERVICE_NAME} 8265:8265 2>&1 >/dev/null & kubectl --namespace ${NAMESPACE} port-forward service/${SERVICE_NAME} 10001:10001 2>&1 >/dev/null &
验证 Ray 客户端是否可以连接到远程 RayCluster 自定义资源:
docker run --net=host -it ${VLLM_IMAGE} \ ray list nodes --address http://localhost:8265
输出类似于以下内容:
======== List: YYYY-MM-DD HH:MM:SS.NNNNNN ======== Stats: ------------------------------ Total: 2 Table: ------------------------------ NODE_ID NODE_IP IS_HEAD_NODE STATE STATE_MESSAGE NODE_NAME RESOURCES_TOTAL LABELS 0 XXXXXXXXXX ###.###.###.### True ALIVE ###.###.###.### CPU: 2.0 ray.io/node_id: XXXXXXXXXX memory: #.### GiB node:###.###.###.###: 1.0 node:__internal_head__: 1.0 object_store_memory: #.### GiB 1 XXXXXXXXXX ###.###.###.### False ALIVE ###.###.###.### CPU: 100.0 ray.io/node_id: XXXXXXXXXX TPU: 8.0 TPU-v#e-8-head: 1.0 accelerator_type:TPU-V#E: 1.0 memory: ###.### GiB node:###.###.###.###: 1.0 object_store_memory: ##.### GiB tpu-group-0: 1.0
使用 vLLM 部署模型
使用 vLLM 部署模型:
docker run \
--env MODEL_ID=${MODEL_ID} \
--net=host \
--volume=./tpu:/workspace/vllm/tpu \
-it \
${VLLM_IMAGE} \
serve run serve_tpu:model \
--address=ray://localhost:10001 \
--app-dir=./tpu \
--runtime-env-json='{"env_vars": {"MODEL_ID": "meta-llama/Meta-Llama-3-8B-Instruct"}}'
docker run \
--env MODEL_ID=${MODEL_ID} \
--env TOKENIZER_MODE=${TOKENIZER_MODE} \
--net=host \
--volume=./tpu:/workspace/vllm/tpu \
-it \
${VLLM_IMAGE} \
serve run serve_tpu:model \
--address=ray://localhost:10001 \
--app-dir=./tpu \
--runtime-env-json='{"env_vars": {"MODEL_ID": "mistralai/Mistral-7B-Instruct-v0.3", "TOKENIZER_MODE": "mistral"}}'
docker run \
--env MAX_MODEL_LEN=${MAX_MODEL_LEN} \
--env MODEL_ID=${MODEL_ID} \
--net=host \
--volume=./tpu:/workspace/vllm/tpu \
-it \
${VLLM_IMAGE} \
serve run serve_tpu:model \
--address=ray://localhost:10001 \
--app-dir=./tpu \
--runtime-env-json='{"env_vars": {"MAX_MODEL_LEN": "8192", "MODEL_ID": "meta-llama/Meta-Llama-3.1-70B"}}'
查看 Ray 信息中心
您可以通过 Ray 信息中心查看 Ray Serve 部署和相关日志。
- 点击 Cloud Shell 任务栏右上角的
Web Preview 按钮。
- 点击更改端口,然后将端口号设置为
8265
。 - 点击更改并预览。
- 在 Ray 信息中心内,点击服务标签页。
服务部署的状态变为 HEALTHY
后,模型便可以开始处理输入了。
应用模型
本指南重点介绍了支持文本生成的模型。这种技术可让您根据提示创作文本内容。
设置到服务器的端口转发:
pkill -f "kubectl .* port-forward .* 8000:8000" kubectl --namespace ${NAMESPACE} port-forward service/${SERVICE_NAME} 8000:8000 2>&1 >/dev/null &
向 Serve 端点发送提示:
curl -X POST http://localhost:8000/v1/generate -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'
展开即可下部分可查看输出示例。
{"prompt": "What
are the top 5 most popular programming languages? Be brief.", "text": " (Note:
This answer may change over time.)\n\nAccording to the TIOBE Index, a widely
followed measure of programming language popularity, the top 5 languages
are:\n\n1. JavaScript\n2. Python\n3. Java\n4. C++\n5. C#\n\nThese rankings are
based on a combination of search engine queries, web traffic, and online
courses. Keep in mind that other sources may have slightly different rankings.
(Source: TIOBE Index, August 2022)", "token_ids": [320, 9290, 25, 1115, 4320,
1253, 2349, 927, 892, 9456, 11439, 311, 279, 350, 3895, 11855, 8167, 11, 264,
13882, 8272, 6767, 315, 15840, 4221, 23354, 11, 279, 1948, 220, 20, 15823,
527, 1473, 16, 13, 13210, 198, 17, 13, 13325, 198, 18, 13, 8102, 198, 19, 13,
356, 23792, 20, 13, 356, 27585, 9673, 33407, 527, 3196, 389, 264, 10824, 315,
2778, 4817, 20126, 11, 3566, 9629, 11, 323, 2930, 14307, 13, 13969, 304, 4059,
430, 1023, 8336, 1253, 617, 10284, 2204, 33407, 13, 320, 3692, 25, 350, 3895,
11855, 8167, 11, 6287, 220, 2366, 17, 8, 128009]}
设置到服务器的端口转发:
pkill -f "kubectl .* port-forward .* 8000:8000" kubectl --namespace ${NAMESPACE} port-forward service/${SERVICE_NAME} 8000:8000 2>&1 >/dev/null &
向 Serve 端点发送提示:
curl -X POST http://localhost:8000/v1/generate -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'
展开即可下部分可查看输出示例。
{"prompt": "What are the top 5 most popular programming languages? Be brief.",
"text": "\n\n1. JavaScript: Widely used for web development, particularly for
client-side scripting and building dynamic web page content.\n\n2. Python:
Known for its simplicity and readability, it's widely used for web
development, machine learning, data analysis, and scientific computing.\n\n3.
Java: A general-purpose programming language used in a wide range of
applications, including Android app development, web services, and
enterprise-level applications.\n\n4. C#: Developed by Microsoft, it's often
used for Windows desktop apps, game development (Unity), and web development
(ASP.NET).\n\n5. TypeScript: A superset of JavaScript that adds optional
static typing and other features for large-scale, maintainable JavaScript
applications.", "token_ids": [781, 781, 29508, 29491, 27049, 29515, 1162,
1081, 1491, 2075, 1122, 5454, 4867, 29493, 7079, 1122, 4466, 29501, 2973,
7535, 1056, 1072, 4435, 11384, 5454, 3652, 3804, 29491, 781, 781, 29518,
29491, 22134, 29515, 1292, 4444, 1122, 1639, 26001, 1072, 1988, 3205, 29493,
1146, 29510, 29481, 13343, 2075, 1122, 5454, 4867, 29493, 6367, 5936, 29493,
1946, 6411, 29493, 1072, 11237, 22031, 29491, 781, 781, 29538, 29491, 12407,
29515, 1098, 3720, 29501, 15460, 4664, 17060, 4610, 2075, 1065, 1032, 6103,
3587, 1070, 9197, 29493, 3258, 13422, 1722, 4867, 29493, 5454, 4113, 29493,
1072, 19123, 29501, 5172, 9197, 29491, 781, 781, 29549, 29491, 1102, 29539,
29515, 9355, 1054, 1254, 8670, 29493, 1146, 29510, 29481, 3376, 2075, 1122,
9723, 25470, 14189, 29493, 2807, 4867, 1093, 2501, 1240, 1325, 1072, 5454,
4867, 1093, 2877, 29521, 29491, 12466, 1377, 781, 781, 29550, 29491, 6475,
7554, 29515, 1098, 26434, 1067, 1070, 27049, 1137, 14401, 12052, 1830, 25460,
1072, 1567, 4958, 1122, 3243, 29501, 6473, 29493, 9855, 1290, 27049, 9197,
29491, 2]}
设置到服务器的端口转发:
pkill -f "kubectl .* port-forward .* 8000:8000" kubectl --namespace ${NAMESPACE} port-forward service/${SERVICE_NAME} 8000:8000 2>&1 >/dev/null &
向 Serve 端点发送提示:
curl -X POST http://localhost:8000/v1/generate -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'
展开即可下部分可查看输出示例。
{"prompt": "What are
the top 5 most popular programming languages? Be brief.", "text": " This is a
very subjective question, but there are some general guidelines to follow when
selecting a language. For example, if you\u2019re looking for a language
that\u2019s easy to learn, you might want to consider Python. It\u2019s one of
the most popular languages in the world, and it\u2019s also relatively easy to
learn. If you\u2019re looking for a language that\u2019s more powerful, you
might want to consider Java. It\u2019s a more complex language, but it\u2019s
also very popular. Whichever language you choose, make sure you do your
research and pick one that\u2019s right for you.\nThe most popular programming
languages are:\nWhy is C++ so popular?\nC++ is a powerful and versatile
language that is used in many different types of software. It is also one of
the most popular programming languages, with a large community of developers
who are always creating new and innovative ways to use it. One of the reasons
why C++ is so popular is because it is a very efficient language. It allows
developers to write code that is both fast and reliable, which is essential
for many types of software. Additionally, C++ is very flexible, meaning that
it can be used for a wide range of different purposes. Finally, C++ is also
very popular because it is easy to learn. There are many resources available
online and in books that can help anyone get started with learning the
language.\nJava is a versatile language that can be used for a variety of
purposes. It is one of the most popular programming languages in the world and
is used by millions of people around the globe. Java is used for everything
from developing desktop applications to creating mobile apps and games. It is
also a popular choice for web development. One of the reasons why Java is so
popular is because it is a platform-independent language. This means that it
can be used on any type of computer or device, regardless of the operating
system. Java is also very versatile and can be used for a variety of different
purposes.", "token_ids": [1115, 374, 264, 1633, 44122, 3488, 11, 719, 1070,
527, 1063, 4689, 17959, 311, 1833, 994, 27397, 264, 4221, 13, 1789, 3187, 11,
422, 499, 3207, 3411, 369, 264, 4221, 430, 753, 4228, 311, 4048, 11, 499,
2643, 1390, 311, 2980, 13325, 13, 1102, 753, 832, 315, 279, 1455, 5526, 15823,
304, 279, 1917, 11, 323, 433, 753, 1101, 12309, 4228, 311, 4048, 13, 1442,
499, 3207, 3411, 369, 264, 4221, 430, 753, 810, 8147, 11, 499, 2643, 1390,
311, 2980, 8102, 13, 1102, 753, 264, 810, 6485, 4221, 11, 719, 433, 753, 1101,
1633, 5526, 13, 1254, 46669, 4221, 499, 5268, 11, 1304, 2771, 499, 656, 701,
3495, 323, 3820, 832, 430, 753, 1314, 369, 499, 627, 791, 1455, 5526, 15840,
15823, 527, 512, 10445, 374, 356, 1044, 779, 5526, 5380, 34, 1044, 374, 264,
8147, 323, 33045, 4221, 430, 374, 1511, 304, 1690, 2204, 4595, 315, 3241, 13,
1102, 374, 1101, 832, 315, 279, 1455, 5526, 15840, 15823, 11, 449, 264, 3544,
4029, 315, 13707, 889, 527, 2744, 6968, 502, 323, 18699, 5627, 311, 1005, 433,
13, 3861, 315, 279, 8125, 3249, 356, 1044, 374, 779, 5526, 374, 1606, 433,
374, 264, 1633, 11297, 4221, 13, 1102, 6276, 13707, 311, 3350, 2082, 430, 374,
2225, 5043, 323, 15062, 11, 902, 374, 7718, 369, 1690, 4595, 315, 3241, 13,
23212, 11, 356, 1044, 374, 1633, 19303, 11, 7438, 430, 433, 649, 387, 1511,
369, 264, 7029, 2134, 315, 2204, 10096, 13, 17830, 11, 356, 1044, 374, 1101,
1633, 5526, 1606, 433, 374, 4228, 311, 4048, 13, 2684, 527, 1690, 5070, 2561,
2930, 323, 304, 6603, 430, 649, 1520, 5606, 636, 3940, 449, 6975, 279, 4221,
627, 15391, 3S74, 264, 33045, 4221, 430, 649, 387, 1511, 369, 264, 8205, 315,
10096, 13, 1102, 374, 832, 315, 279, 1455, 5526, 15840, 15823, 304, 279, 1917,
323, 374, 1511, 555, 11990, 315, 1274, 2212, 279, 24867, 13, 8102, 374, 1511,
369, 4395, 505, 11469, 17963, 8522, 311, 6968, 6505, 10721, 323, 3953, 13,
1102, 374, 1101, 264, 5526, 5873, 369, 3566, 4500, 13, 3861, 315, 279, 8125,
3249, 8102, 374, 779, 5526, 374, 1606, 433, 374, 264, 5452, 98885, 4221, 13,
1115, 3445, 430, 433, 649, 387, 1511, 389, 904, 955, 315, 6500, 477, 3756, 11,
15851, 315, 279, 10565, 1887, 13, 8102, 374, 1101, 1633, 33045, 323, 649, 387,
1511, 369, 264, 8205, 315, 2204, 10096, 13, 128001]}
其他配置
您可以选择性地配置 Ray Serve 框架支持的以下模型部署资源和方法:
- 部署 RayService 自定义资源。在本教程的前面步骤中,您使用的是 RayCluster,而不是 RayService。我们建议在生产环境中使用 RayService。
- 通过模型组合实现多个模型的组合。配置 Ray Serve 框架支持的模型多路复用和模型组合。借助模型组合,您可以将多个 LLM 的输入和输出链接在一起,并将这些模型整合到单个应用中。
- 构建和部署您自己的 TPU 映像。如果您需要对 Docker 映像的内容进行更精细的控制,我们建议您使用此选项。
部署 RayService
您可以使用 RayService 自定义资源部署本教程中的相同模型。
删除您在本教程中创建的 RayCluster 自定义资源:
kubectl --namespace ${NAMESPACE} delete raycluster/vllm-tpu
创建 RayService 自定义资源以部署模型:
检查
ray-service.tpu-v5e-singlehost.yaml
清单:应用清单:
envsubst < tpu/ray-service.tpu-v5e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
envsubst
命令会替换清单中的环境变量。GKE 会创建一个 RayService,其中包含一个
workergroup
,该workergroup
在2x4
拓扑中包含一个 TPU v5e 单主机。
检查
ray-service.tpu-v5e-singlehost.yaml
清单:应用清单:
envsubst < tpu/ray-service.tpu-v5e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
envsubst
命令会替换清单中的环境变量。GKE 会创建一个 RayService,其中
workergroup
包含2x4
拓扑中的 TPU v5e 单主机。
检查
ray-service.tpu-v6e-singlehost.yaml
清单:应用清单:
envsubst < tpu/ray-service.tpu-v6e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
envsubst
命令会替换清单中的环境变量。
GKE 会创建一个 RayCluster 自定义资源,其中部署了 Ray Serve 应用并创建了后续的 RayService 自定义资源。
验证 RayService 资源的状态:
kubectl --namespace ${NAMESPACE} get rayservices/vllm-tpu
等待服务状态变为
Running
:NAME SERVICE STATUS NUM SERVE ENDPOINTS vllm-tpu Running 1
检索 RayCluster 主服务的名称:
SERVICE_NAME=$(kubectl --namespace=${NAMESPACE} get rayservices/vllm-tpu \ --template={{.status.activeServiceStatus.rayClusterStatus.head.serviceName}})
建立到 Ray 头节点的
port-forwarding
会话以查看 Ray 信息中心:pkill -f "kubectl .* port-forward .* 8265:8265" kubectl --namespace ${NAMESPACE} port-forward service/${SERVICE_NAME} 8265:8265 2>&1 >/dev/null &
部署模型。
清理 RayService 资源:
kubectl --namespace ${NAMESPACE} delete rayservice/vllm-tpu
通过模型组合实现多个模型的组合
模型组合是一种将多个模型组合到单个应用中的方法。
在本部分中,您将使用 GKE 集群将 Llama 3 8B IT 和 Gemma 7B IT 这两个模型组合到单个应用中:
- 第一个模型是负责回答提示中提出的问题的助理型模型。
- 第二个模型是摘要器模型。助理型模型的输出会链接到摘要器模型的输入中。最终结果是助理型模型所提供回答的摘要版本。
设置环境:
export ASSIST_MODEL_ID=meta-llama/Meta-Llama-3-8B-Instruct export SUMMARIZER_MODEL_ID=google/gemma-7b-it
对于 Standard 集群,请创建一个额外的单主机 TPU 切片节点池:
gcloud container node-pools create tpu-2 \ --location=${COMPUTE_ZONE} \ --cluster=${CLUSTER_NAME} \ --machine-type=
MACHINE_TYPE \ --num-nodes=1将
MACHINE_TYPE
替换为以下任意机器类型:ct5lp-hightpu-8t
来预配 TPU v5e。ct6e-standard-8t
用于预配 TPU v6e。
Autopilot 集群会自动预配所需的节点。
根据您要使用的 TPU 版本部署 RayService 资源:
检查
ray-service.tpu-v5e-singlehost.yaml
清单:应用清单:
envsubst < model-composition/ray-service.tpu-v5e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
检查
ray-service.tpu-v6e-singlehost.yaml
清单:应用清单:
envsubst < model-composition/ray-service.tpu-v6e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
等待 RayService 资源的状态变为
Running
:kubectl --namespace ${NAMESPACE} get rayservice/vllm-tpu
输出类似于以下内容:
NAME SERVICE STATUS NUM SERVE ENDPOINTS vllm-tpu Running 2
在此输出中,
RUNNING
状态表示 RayService 资源已准备就绪。确认 GKE 为 Ray Serve 应用创建了该 Service:
kubectl --namespace ${NAMESPACE} get service/vllm-tpu-serve-svc
输出类似于以下内容:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE vllm-tpu-serve-svc ClusterIP ###.###.###.### <none> 8000/TCP ###
建立到 Ray 头节点的
port-forwarding
会话:pkill -f "kubectl .* port-forward .* 8000:8000" kubectl --namespace ${NAMESPACE} port-forward service/vllm-tpu-serve-svc 8000:8000 2>&1 >/dev/null &
向模型发送请求:
curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What is the most popular programming language for machine learning and why?", "max_tokens": 1000}'
输出类似于以下内容:
{"text": [" used in various data science projects, including building machine learning models, preprocessing data, and visualizing results.\n\nSure, here is a single sentence summarizing the text:\n\nPython is the most popular programming language for machine learning and is widely used in data science projects, encompassing model building, data preprocessing, and visualization."]}
构建和部署 TPU 映像
本教程使用 vLLM 中的托管 TPU 映像。vLLM 提供了一个 Dockerfile.tpu
映像,该映像会在包含 TPU 依赖项的必需 PyTorch XLA 映像上构建 vLLM。不过,您也可以构建和部署自己的 TPU 映像,以便更精细地控制 Docker 映像的内容。
创建一个 Docker 仓库以存储本指南中的容器映像:
gcloud artifacts repositories create vllm-tpu --repository-format=docker --location=${COMPUTE_REGION} && \ gcloud auth configure-docker ${COMPUTE_REGION}-docker.pkg.dev
克隆 vLLM 代码库:
git clone https://github.com/vllm-project/vllm.git cd vllm
构建映像:
docker build -f Dockerfile.tpu . -t vllm-tpu
使用 Artifact Registry 名称标记 TPU 映像:
export VLLM_IMAGE=${COMPUTE_REGION}-docker.pkg.dev/${PROJECT_ID}/vllm-tpu/vllm-tpu:
TAG docker tag vllm-tpu ${VLLM_IMAGE}将
TAG
替换为您要定义的代码的名称。如果您未指定标记,Docker 将应用默认的最新标记。将该映像推送到 Artifact Registry。
docker push ${VLLM_IMAGE}
逐个删除资源
如果您使用的是现有项目,并且不想将其删除,则可逐个删除不再需要的资源。
删除 RayCluster 自定义资源:
kubectl --namespace ${NAMESPACE} delete rayclusters vllm-tpu
删除 Cloud Storage 存储桶:
gcloud storage rm -r gs://${GSBUCKET}
删除 Artifact Registry 代码库:
gcloud artifacts repositories delete vllm-tpu \ --location=${COMPUTE_REGION}
删除集群:
gcloud container clusters delete ${CLUSTER_NAME} \ --location=
LOCATION 将
LOCATION
替换为以下任意环境变量:- 对于 Autopilot 集群,请使用
COMPUTE_REGION
。 - 对于 Standard 集群,请使用
COMPUTE_ZONE
。
- 对于 Autopilot 集群,请使用
删除项目
如果您在新 Google Cloud 项目中部署了本教程,但不再需要该项目,请完成以下步骤来将其删除:
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
后续步骤
- 了解如何使用 GKE 平台编排功能运行经过优化的 AI/机器学习工作负载。
- 查看 GitHub 中的示例代码,了解如何在 GKE 上使用 Ray Serve。
- 如需了解如何收集和查看 GKE 上运行的 Ray 集群的指标,请完成收集和查看 GKE 上的 Ray 集群的日志和指标中的步骤。