概览
本文档是解决方案参考实现 (SRI) 指南,介绍了部署、提供和验证分布式云纯软件开放模型服务解决方案所需的具体步骤。
本指南介绍了如何部署优化的 vLLM 服务引擎,以在 Distributed Cloud(纯软件)单节点集群配置(面向边缘部署)上运行 Gemma 4 (google/gemma-4-31B-it),并利用物理 NVIDIA GPU 资源(例如 RTX PRO 6000)。
此演练旨在通过 CLI 终端客户端执行,该客户端具有对 Distributed Cloud 纯软件集群的 kubectl 访问权限。
目标
完成此解决方案参考实现后,您将能够:
- 通过本地
.env文件配置服务环境参数。 - 使用
local-shared存储类别部署永久性卷声明 (PVC) 以持久保存模型权重。 - 部署优化的 vLLM 服务引擎,利用 Vertex AI 合格的容器,映射物理
nvidia.com/gpu资源。 - 部署 Gradio Web 界面以提供互动式聊天界面。
- 建立本地端口转发隧道,以通过 API 和 Web 界面验证服务响应速度。
- 通过确认日志和指标(包括 GPU 遥测数据)已提取到 Cloud Logging 和 Cloud Monitoring 中,验证可观测性集成。
准备工作
前提条件(集群设置)
本指南假设您已配置一个正在运行的 Distributed Cloud 纯软件集群,且该集群支持 GPU。如需安装集群,请参阅官方适用于裸金属的 Distributed Cloud(纯软件)文档。GPU 配置必须符合设置和使用 NVIDIA GPU 的官方 Google Cloud文档。
客户端工作站前提条件
确保您的本地终端环境已安装并配置以下工具:
- gcloud CLI:用于项目配置和查询日志。必须经过身份验证 (
gcloud auth login),并且配置为 Distributed Cloud 纯软件集群注册的有效Google Cloud 项目。 - kubectl:管理集群资源所必需的工具。必须配置适当的上下文,才能访问目标 Distributed Cloud 软件专用集群(例如,通过连接网关或直接本地网络访问)。
- curl:必需,用于向服务端点发送测试请求。
- jq:用于解析来自服务端点的 JSON 输出。
Hugging Face 模型访问权限
如需下载和部署 Gemma 4 模型,您必须有权访问 Hugging Face 代码库:
- Hugging Face 账号:确保您在 Hugging Face 上注册了账号。
- 接受模型许可:前往 Gemma 4 31B IT 模型页面,同意许可条款,即可获取门控模型权重。
- 生成访问令牌:从您的 Hugging Face 账号设置(设置 -> 访问令牌)中生成具有读取权限的用户访问令牌。此令牌将用作配置中的
HF_TOKEN。
中央参考配置
所有部署参数均通过位于 <local-config-dir>/.env 的中央 .env 文件进行管理。确保此文件存在,并且包含您的特定参数(Hugging Face 令牌、命名空间、模型名称等)。
.env 结构示例:
# GDCso Cluster Namespace
NAMESPACE_NAME="your-custom-namespace"
# Hugging Face Token (Required to download gated Gemma models)
HF_TOKEN="your-hf-token-here"
# Model Sizing Parameters
MODEL_NAME="google/gemma-4-31B-it"
SAFE_MODEL_NAME="google-gemma-4-31B-it"
# Hyperparameters
MAX_MODEL_LEN=8192
GPU_MEMORY_UTILIZATION=0.95
MAX_NUM_SEQS=512
MAX_NUM_BATCHED_TOKENS=4096
DTYPE="bfloat16"
# Pod Sizing Requests
CPU_REQUEST="4"
MEMORY_REQUEST="80"
设置环境和凭据
创建命名空间和 Hugging Face Secret
在部署之前,您必须创建命名空间和 Hugging Face 令牌 Secret:
# Navigate to your project root
cd <local-working-dir>
# Sourced from your local .env file
source <local-config-dir>/.env
# Create namespace
kubectl create namespace ${NAMESPACE_NAME} --dry-run=client -o yaml | kubectl apply -f -
# Create Hugging Face token secret
kubectl create secret generic hf-token-secret \
--from-literal=token="${HF_TOKEN}" \
-n "${NAMESPACE_NAME}" --dry-run=client -o yaml | kubectl apply -f -
在 Kubernetes 上部署 vLLM
部署包含三个主要清单:PVC、Service 和 Deployment。 这些模板使用在部署时替换的环境变量。
永久性卷声明 (PVC)
PVC 可确保模型权重在 Pod 重启后持久保存,它使用 Distributed Cloud 纯软件 local-shared 存储类别。
创建一个名为 vllm-pvc.yaml 的文件,其中包含以下内容:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: model-cache-pvc
namespace: ${NAMESPACE_NAME}
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-shared
resources:
requests:
storage: 100Gi
服务
在内部通过端口 8000 公开 vLLM API 服务器。
创建一个名为 vllm-service.yaml 的文件,其中包含以下内容:
apiVersion: v1
kind: Service
metadata:
name: vllm-service
namespace: ${NAMESPACE_NAME}
labels:
app: vllm
annotations:
prometheus.io/scrape: "true"
prometheus.io/path: "/metrics"
prometheus.io/port: "8000"
spec:
ports:
- name: http
port: 8000
targetPort: 8000
selector:
app: vllm
type: ClusterIP
部署
运行 vLLM 容器,装载模型缓存卷,并请求物理 GPU 资源。虽然 96 GB 的 VRAM 可以容纳未量化的 BF16 权重(约 62 GB),但此参考实现支持 Blackwell FP8 量化(--quantization=fp8,约 31 GB 权重),从而将 KV 缓存扩展到 56.53 GiB(61,728 个令牌),以实现更高的并发吞吐量。
创建一个名为 vllm-deployment.yaml 的文件,其中包含以下内容:
apiVersion: apps/v1
kind: Deployment
metadata:
name: vllm-deployment
namespace: ${NAMESPACE_NAME}
labels:
app: vllm
ai.gke.io/inference-server: vllm
ai.gke.io/model: ${SAFE_MODEL_NAME}
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: vllm
template:
metadata:
labels:
app: vllm
examples.ai.gke.io/source: user-guide
ai.gke.io/inference-server: vllm
ai.gke.io/model: ${SAFE_MODEL_NAME}
spec:
runtimeClassName: nvidia
containers:
- name: vllm-container
image: us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:gemma4
imagePullPolicy: IfNotPresent
command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
args:
- --model=$(MODEL_ID)
- --host=0.0.0.0
- --port=8000
- --tensor-parallel-size=1
- --enable-log-requests
- --max-model-len=${MAX_MODEL_LEN}
- --gpu-memory-utilization=${GPU_MEMORY_UTILIZATION}
- --max-num-seqs=${MAX_NUM_SEQS}
- --max-num-batched-tokens=${MAX_NUM_BATCHED_TOKENS}
- --dtype=${DTYPE}
- --trust-remote-code
- --enable-prefix-caching
- --enable-chunked-prefill
- --quantization=fp8
env:
- name: MODEL_ID
value: ${MODEL_NAME}
- name: HUGGING_FACE_HUB_TOKEN
valueFrom:
secretKeyRef:
name: hf-token-secret
key: token
- name: LD_LIBRARY_PATH
value: "/usr/local/nvidia/lib64"
ports:
- name: http
containerPort: 8000
resources:
requests:
cpu: ${CPU_REQUEST}
memory: "${MEMORY_REQUEST}Gi"
nvidia.com/gpu: "1"
limits:
cpu: ${CPU_REQUEST}
memory: "${MEMORY_REQUEST}Gi"
nvidia.com/gpu: "1"
volumeMounts:
- mountPath: /root/.cache/huggingface
name: cache-volume
- mountPath: /dev/shm
name: dshm
volumes:
- name: cache-volume
persistentVolumeClaim:
claimName: model-cache-pvc
- name: dshm
emptyDir:
medium: Memory
sizeLimit: 16Gi
Gradio 界面部署
Gradio 界面提供了一个交互式网页界面,用于与模型对话。它部署在集群内,并通过内部 Kubernetes 网络连接到 vLLM 服务。
Gradio 部署
创建一个名为 gradio-deployment.yaml 的文件,其中包含以下内容:
apiVersion: apps/v1
kind: Deployment
metadata:
name: gradio-deployment
namespace: ${NAMESPACE_NAME}
labels:
app: gradio
spec:
replicas: 1
selector:
matchLabels:
app: gradio
template:
metadata:
labels:
app: gradio
spec:
containers:
- name: gradio
image: us-docker.pkg.dev/google-samples/containers/gke/gradio-app:v1.0.4
resources:
requests:
cpu: "250m"
memory: "512Mi"
limits:
cpu: "500m"
memory: "512Mi"
env:
- name: CONTEXT_PATH
value: "/v1/chat/completions"
- name: HOST
value: "http://vllm-service:8000"
- name: MODEL_ID
value: "${MODEL_NAME}"
ports:
- containerPort: 7860
Gradio 服务
创建一个名为 gradio-service.yaml 的文件,其中包含以下内容:
apiVersion: v1
kind: Service
metadata:
name: gradio-service
namespace: ${NAMESPACE_NAME}
spec:
selector:
app: gradio
ports:
- protocol: TCP
port: 8080
targetPort: 7860
type: ClusterIP
可观测性配置
如需详细了解如何配置应用日志记录和监控,请参阅官方应用日志记录和监控指南。
vLLM 监控
为了让 Google Cloud Managed Service for Prometheus (GMP) 能够抓取 vLLM 指标,我们部署了一个以 vLLM pod 为目标的 PodMonitoring 资源。
创建一个名为 vllm-pod-monitoring.yaml 的文件,其中包含以下内容:
apiVersion: monitoring.googleapis.com/v1
kind: PodMonitoring
metadata:
name: vllm-pod-monitoring
namespace: ${NAMESPACE_NAME}
spec:
selector:
matchLabels:
app: vllm
endpoints:
- port: http
interval: 30s
GPU 监控
为了让 Google Cloud Managed Service for Prometheus (GMP) 能够从 NVIDIA DCGM Exporter 抓取 GPU 指标,我们在 gpu-operator 命名空间中部署 PodMonitoring 资源。如需了解详情,请参阅将 GPU 指标发送到 Cloud Monitoring。
创建一个名为 gpu-pod-monitoring.yaml 的文件,其中包含以下内容:
apiVersion: monitoring.googleapis.com/v1
kind: PodMonitoring
metadata:
name: dcgm-gmp
namespace: gpu-operator
spec:
selector:
matchLabels:
app: nvidia-dcgm-exporter
endpoints:
- port: metrics
interval: 30s
执行步数
部署清单
将清单应用到集群。由于 YAML 文件包含环境变量占位符,因此请先使用 envsubst 替换 .env 文件中的变量,然后再应用这些变量。
前往包含 YAML 文件的工作目录:
cd <local-working-dir>加载环境变量:
source <local-config-dir>/.env按顺序应用清单:
# Apply core serving manifests envsubst < vllm-pvc.yaml | kubectl apply -f - envsubst < vllm-service.yaml | kubectl apply -f - envsubst < vllm-deployment.yaml | kubectl apply -f - # Apply observability manifests envsubst < vllm-pod-monitoring.yaml | kubectl apply -f - kubectl apply -f gpu-pod-monitoring.yaml # Apply Gradio UI manifests envsubst < gradio-deployment.yaml | kubectl apply -f - envsubst < gradio-service.yaml | kubectl apply -f -
验证
监控 pod 启动序列
流式传输容器日志以跟踪启动顺序:
# 1. Check pod status (wait until it is Running)
kubectl get pods -n ${NAMESPACE_NAME} -l app=vllm
# 2. Stream logs to verify model loading
kubectl logs -f -l app=vllm -n ${NAMESPACE_NAME}
等待,直到您在日志中看到“active serving ready”信号:
INFO: Application startup complete.
建立端口转发隧道
如需在本地测试端点,请转发服务端口 8000:
kubectl port-forward service/vllm-service 8000:8000 -n ${NAMESPACE_NAME}
保持此终端处于打开状态,或在后台运行此终端。
查询服务端点
在另一个终端中,测试 API 响应速度:
1. 查询模型列表
curl -s http://localhost:8000/v1/models | jq
2. 查询对话补全
curl -s http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "'"${MODEL_NAME}"'",
"messages": [
{"role": "user", "content": "What is AGI in 100 words"}
],
"max_tokens": 150
}' | jq
验证 GPU 和 VRAM 分配
为确保模型高效利用硬件且内存占用空间正确,您可以运行 GPU 审核。
通过 pod 内的 nvidia-smi 审核 GPU
检索活跃 vLLM pod 的名称,并在容器内执行 nvidia-smi:
# Dynamically get the pod name
export VLLM_POD_NAME=$(kubectl get pods -n ${NAMESPACE_NAME} -l app=vllm -o jsonpath='{.items[0].metadata.name}')
# Run nvidia-smi inside the container
kubectl exec ${VLLM_POD_NAME} -n ${NAMESPACE_NAME} -- nvidia-smi
预期输出:输出应报告与 GPU_MEMORY_UTILIZATION 参数匹配的物理 VRAM 利用率。例如,在配备 NVIDIA RTX PRO 6000(约 96 GB VRAM)的工作站上运行 google/gemma-4-31B-it 并使用 GPU_MEMORY_UTILIZATION=0.95 时,您应该会看到分配给 VLLM::EngineCore 的内存约为 95,800 MiB:
+-----------------------------------------------------------------------------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA RTX PRO 6000 Blac... On | 00000000:05:00.0 Off | 0 |
| N/A 36C P0 85W / 600W | 95805MiB / 97887MiB | 0% Default |
+-----------------------------------------+------------------------+----------------------+
验证日志中的 KV 缓存分配
您还可以检查 vLLM 内部分配日志,以验证 KV 缓存大小和令牌并发性:
kubectl logs ${VLLM_POD_NAME} -n ${NAMESPACE_NAME} | grep -E "Available KV cache|GPU KV cache size"
预期输出:
(EngineCore pid=362) INFO 06-18 15:03:43 [gpu_worker.py:456] Available KV cache memory: 56.53 GiB
(EngineCore pid=362) INFO 06-18 15:03:43 [kv_cache_utils.py:1316] GPU KV cache size: 61,728 tokens
这确认了 56.53 GiB 的 VRAM 已预留给上下文 KV 缓存,从而支持大量并发令牌。
验证 Gradio 界面部署
Gradio pod 运行后,您可以通过建立端口转发隧道来访问界面。
监控 Gradio pod 状态
确保 Gradio pod 正在运行:
kubectl get pods -n ${NAMESPACE_NAME} -l app=gradio
预期输出:
NAME READY STATUS RESTARTS AGE
gradio-deployment-yyyyyyyy-yyyyy 1/1 Running 0 1m
建立到 Gradio 的端口转发隧道
将 Gradio 服务端口 8080 转发到本地端口 7860:
kubectl port-forward service/gradio-service 7860:8080 -n ${NAMESPACE_NAME}
保持此终端处于打开状态,或在后台运行此终端:
kubectl port-forward service/gradio-service 7860:8080 -n ${NAMESPACE_NAME} > pf_gradio.log 2>&1 & sleep 3
访问网页界面
- 如果是在本地工作站上运行:打开浏览器并直接前往:
http://localhost:7860 - 如果是在 Cloud Shell 中运行:使用网页预览按钮,选择更改端口,输入
7860,然后点击更改并预览。
您应该会看到 Gradio 聊天机器人界面。您可以输入消息与 Gemma 模型互动。Gradio pod 会在内部将请求路由到 vllm-service 端点。
清理隧道
如需停止端口转发隧道,请执行以下操作:
pkill -f "port-forward service/gradio-service"
监控验证
部署 vLLM 并应用 PodMonitoring 资源后,您可以验证指标是否正在被提取到 Cloud Monitoring 中。
验证 PodMonitoring 状态
确保 PodMonitoring 资源已创建且处于活跃状态:
kubectl get podmonitoring -n ${NAMESPACE_NAME}
使用 Google Cloud 控制台验证指标提取
您可以使用 Google Cloud 控制台(Metrics Explorer)验证指标是否正在被提取:
- 在 Google Cloud 控制台中打开 Metrics Explorer:
- 前往
https://console.cloud.google.com/monitoring/metrics-explorer(确保您已选择项目${GCP_PROJECT_ID})。
- 前往
- 在选择指标下拉菜单中,搜索并选择:
prometheus.googleapis.com/vllm:num_requests_running/gauge以验证 vLLM 指标。prometheus.googleapis.com/DCGM_FI_DEV_GPU_UTIL/gauge以验证 GPU 利用率指标。
- 观察图表,确认数据点是否正在积极绘制。
日志记录验证
工作负载运行后,您可以验证日志是否已导出到 Cloud Logging。
验证 vLLM 日志注入
验证 vLLM 容器日志是否已导出到 Cloud Logging:
project_id=$(gcloud config get-value project)
gcloud logging read "resource.type=\"k8s_container\" AND resource.labels.namespace_name=\"${NAMESPACE_NAME}\" AND resource.labels.container_name=\"vllm-container\"" --limit=10 --project=${project_id}
验证 GPU 指标导出器日志提取
验证 GPU 指标导出器容器日志是否已导出到 Cloud Logging:
project_id=$(gcloud config get-value project)
gcloud logging read "resource.type=\"k8s_container\" AND resource.labels.namespace_name=\"gpu-operator\" AND resource.labels.container_name=\"nvidia-dcgm-exporter\"" --limit=10 --project=${project_id}
使用 Google Cloud 控制台(Logs Explorer)验证日志
您还可以使用 Google Cloud 控制台验证日志提取:
- 在 Google Cloud 控制台中打开 Logs Explorer:
- 前往
https://console.cloud.google.com/logs/query(确保您已选择项目${GCP_PROJECT_ID})。
- 前往
在查询框中,输入以下查询以查看 vLLM 日志:
resource.type="k8s_container" resource.labels.namespace_name="<NAMESPACE_NAME>" resource.labels.container_name="vllm-container"(将
<NAMESPACE_NAME>替换为您的实际命名空间,例如your-custom-namespace)。点击运行查询。您应该会看到来自 vLLM 容器的日志条目。
如需验证 GPU 指标导出器日志,请运行以下查询:
resource.type="k8s_container" resource.labels.namespace_name="gpu-operator" resource.labels.container_name="nvidia-dcgm-exporter"