本教程介绍如何使用多个 GPU 来借助 Google Kubernetes Engine (GKE) 中的 GPU 应用大语言模型 (LLM),以实现高效且可伸缩的推理。本教程会创建一个使用多个 L4 GPU 的 GKE 集群,并准备 GKE 基础架构以提供以下任何模型:
根据模型的数据格式,GPU 数量也会有所不同。在本教程中,每个模型都使用两个 L4 GPU。如需了解详情,请参阅计算 GPU 的数量。
在 GKE 中完成本教程之前,我们建议您学习 GKE 中的 GPU 简介。
目标
本教程适用于希望使用 GKE 编排功能提供 LLM 的 MLOps 或 DevOps 工程师或是平台管理员。
本教程介绍以下步骤:
- 创建集群和节点池。
- 准备工作负载。
- 部署工作负载。
- 与 LLM 界面交互。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行
gcloud components update
以获取最新版本。
某些模型有额外要求。确保您满足以下要求:
- 如需通过 Hugging Face 访问模型,请使用 HuggingFace 令牌。
- 对于 Mixtral 8x7b 模型,请接受 Mistral Mixtral 模型的条件。
- 对于 Llama 3 70b 模型,请确保您拥有 Meta Llama 模型的有效许可。
准备环境
在 Google Cloud 控制台中,启动 Cloud Shell 实例:
打开 Cloud Shell设置默认环境变量:
gcloud config set project PROJECT_ID export PROJECT_ID=$(gcloud config get project) export REGION=us-central1
将 PROJECT_ID 替换为您的 Google Cloud 项目 ID。
创建 GKE 集群和节点池
您可以在 GKE Autopilot 或 Standard 集群中的 GPU 上应用 LLM。我们建议您使用 Autopilot 集群获得全托管式 Kubernetes 体验。如需选择最适合您的工作负载的 GKE 操作模式,请参阅选择 GKE 操作模式。
Autopilot
在 Cloud Shell 中,运行以下命令:
gcloud container clusters create-auto l4-demo \ --project=${PROJECT_ID} \ --region=${REGION} \ --release-channel=rapid
GKE 会根据所部署的工作负载的请求,创建具有所需 CPU 和 GPU 节点的 Autopilot 集群。
配置
kubectl
以与您的集群通信:gcloud container clusters get-credentials l4-demo --region=${REGION}
标准
在 Cloud Shell 中,运行以下命令以创建使用适用于 GKE 的工作负载身份联合的标准集群:
gcloud container clusters create l4-demo --location ${REGION} \ --workload-pool ${PROJECT_ID}.svc.id.goog \ --enable-image-streaming \ --node-locations=$REGION-a \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --machine-type n2d-standard-4 \ --num-nodes 1 --min-nodes 1 --max-nodes 5 \ --release-channel=rapid
集群创建可能需要几分钟的时间。
运行以下命令来为集群创建节点池:
gcloud container node-pools create g2-standard-24 --cluster l4-demo \ --accelerator type=nvidia-l4,count=2,gpu-driver-version=latest \ --machine-type g2-standard-24 \ --enable-autoscaling --enable-image-streaming \ --num-nodes=0 --min-nodes=0 --max-nodes=3 \ --node-locations $REGION-a,$REGION-c --region $REGION --spot
GKE 会为 LLM 创建以下资源:
- 公共 Google Kubernetes Engine (GKE) Standard 版本集群。
- 机器类型为
g2-standard-24
的节点池缩减为 0 个节点。在启动请求 GPU 的 Pod 之前,您无需为任何 GPU 付费。此节点池预配 Spot 虚拟机,其价格低于默认标准 Compute Engine 虚拟机,但不保证可用性。您可以从此命令中移除--spot
标志以及text-generation-inference.yaml
配置中的cloud.google.com/gke-spot
节点选择器,以使用按需虚拟机。
配置
kubectl
以与您的集群通信:gcloud container clusters get-credentials l4-demo --region=${REGION}
准备工作负载
以下部分介绍了如何根据您要使用的模型设置工作负载:
Llama 3 70b
设置默认环境变量:
export HF_TOKEN=HUGGING_FACE_TOKEN
将
HUGGING_FACE_TOKEN
替换为您的 HuggingFace 令牌。为 HuggingFace 令牌创建 Kubernetes Secret:
kubectl create secret generic l4-demo \ --from-literal=HUGGING_FACE_TOKEN=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -
创建以下
text-generation-inference.yaml
清单:在此清单中:
NUM_SHARD
必须为2
,因为模型需要两个 NVIDIA L4 GPU。QUANTIZE
设置为bitsandbytes-nf4
,这意味着模型以 4 位模式加载,而不是 32 位模式。这样,GKE 就可以减少所需的 GPU 内存量,并提高推理速度。不过,模型准确率可能会降低。如需了解如何计算要请求的 GPU,请参阅计算 GPU 的数量。
应用清单:
kubectl apply -f text-generation-inference.yaml
输出类似于以下内容:
deployment.apps/llm created
验证模型的状态:
kubectl get deploy
输出类似于以下内容:
NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 20m
查看正在运行的部署的日志:
kubectl logs -l app=llm
输出类似于以下内容:
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
Mixtral 8x7b
设置默认环境变量:
export HF_TOKEN=HUGGING_FACE_TOKEN
将
HUGGING_FACE_TOKEN
替换为您的 HuggingFace 令牌。为 HuggingFace 令牌创建 Kubernetes Secret:
kubectl create secret generic l4-demo \ --from-literal=HUGGING_FACE_TOKEN=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -
创建以下
text-generation-inference.yaml
清单:在此清单中:
NUM_SHARD
必须为2
,因为模型需要两个 NVIDIA L4 GPU。QUANTIZE
设置为bitsandbytes-nf4
,这意味着模型以 4 位模式加载,而不是 32 位模式。这样,GKE 就可以减少所需的 GPU 内存量,并提高推理速度。但是,这可能会降低模型准确率。如需了解如何计算要请求的 GPU,请参阅计算 GPU 的数量。
应用清单:
kubectl apply -f text-generation-inference.yaml
输出类似于以下内容:
deployment.apps/llm created
验证模型的状态:
watch kubectl get deploy
部署准备就绪后,输出类似于以下内容。如需退出监控,请按
CTRL + C
。NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 10m
查看正在运行的部署的日志:
kubectl logs -l app=llm
输出类似于以下内容:
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
Falcon 40b
创建以下
text-generation-inference.yaml
清单:在此清单中:
NUM_SHARD
必须为2
,因为模型需要两个 NVIDIA L4 GPU。QUANTIZE
设置为bitsandbytes-nf4
,这意味着模型以 4 位模式加载,而不是 32 位模式。这样,GKE 就可以减少所需的 GPU 内存量,并提高推理速度。不过,模型准确率可能会降低。如需了解如何计算要请求的 GPU,请参阅计算 GPU 的数量。
应用清单:
kubectl apply -f text-generation-inference.yaml
输出类似于以下内容:
deployment.apps/llm created
验证模型的状态:
watch kubectl get deploy
部署准备就绪后,输出类似于以下内容。如需退出监控,请按
CTRL + C
。NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 10m
查看正在运行的部署的日志:
kubectl logs -l app=llm
输出类似于以下内容:
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
创建 ClusterIP 类型的 Service
创建以下
llm-service.yaml
清单:apiVersion: v1 kind: Service metadata: name: llm-service spec: selector: app: llm type: ClusterIP ports: - protocol: TCP port: 80 targetPort: 8080
应用清单:
kubectl apply -f llm-service.yaml
部署聊天界面
使用 Gradio 构建一个 Web 应用,使您可以与模型进行互动。Gradio 是一个 Python 库,它具有一个可为聊天机器人创建界面的 ChatInterface 封装容器。
Llama 3 70b
创建一个名为
gradio.yaml
的文件:应用清单:
kubectl apply -f gradio.yaml
找到 Service 的外部 IP 地址:
kubectl get svc
输出类似于以下内容:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125m
从
EXTERNAL-IP
列中复制外部 IP 地址。在您的网络浏览器中使用外部 IP 地址及公开的端口查看模型界面:
http://EXTERNAL_IP
Mixtral 8x7b
创建一个名为
gradio.yaml
的文件:应用清单:
kubectl apply -f gradio.yaml
找到 Service 的外部 IP 地址:
kubectl get svc
输出类似于以下内容:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125m
从
EXTERNAL-IP
列中复制外部 IP 地址。在您的网络浏览器中使用外部 IP 地址及公开的端口查看模型界面:
http://EXTERNAL_IP
Falcon 40b
创建一个名为
gradio.yaml
的文件:应用清单:
kubectl apply -f gradio.yaml
找到 Service 的外部 IP 地址:
kubectl get svc
输出类似于以下内容:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125m
从
EXTERNAL-IP
列中复制外部 IP 地址。在您的网络浏览器中使用外部 IP 地址及公开的端口查看模型界面:
http://EXTERNAL_IP
计算 GPU 的数量
GPU 的数量取决于 QUANTIZE
标志的值。在本教程中,QUANTIZE
设置为 bitsandbytes-nf4
,这意味着模型以 4 位模式加载。
一个 700 亿个参数模型至少需要 40 GB 的 GPU 内存,相当于 700 亿 x 4 位(700 亿 x 4 位= 35 GB),并考虑 5 GB 的开销。在这种情况下,单个 L4 GPU 没有足够的内存。因此,本教程中的示例使用两个 L4 GPU 的内存 (2 x 24 = 48 GB)。此配置足以在 L4 GPU 中运行 Falcon 40b 或 Llama 3 70b。
清理
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
删除集群
为避免系统因您在本指南中创建的资源向您的 Google Cloud 账号收取费用,请删除 GKE 集群:
gcloud container clusters delete l4-demo --region ${REGION}