通过 Ray 使用 GKE 中的多主机 TPU 应用 Gemma 开放模型

本教程将引导您使用 Ray Serve LLM 部署多主机 TPU 推理服务。通过利用 Ray 的原生 TPU 支持,以原子方式在复杂的加速器拓扑中共同调度分布式引擎工作器,您可以跨多主机 TPU 切片部署大型模型以进行推理。

本教程适用于机器学习 (ML) 工程师、平台管理员和运维人员,以及对使用 Kubernetes 容器编排功能在分布式多主机 TPU 切片上处理 AI/机器学习工作负载感兴趣的数据和 AI 专家。如需详细了解我们在 Google Cloud 内容中提及的常见角色和示例任务,请参阅常见的 GKE 用户角色和任务

在阅读本页面之前,请确保您熟悉以下内容:

背景

本部分介绍本指南中使用的关键技术。

TPU

利用张量处理单元 (TPU),您可以加速在节点上运行的特定工作负载,例如机器学习和数据处理。TPU 的主要优势在于大规模性能。本教程使用第六代 Cloud TPU TPU Trillium。多主机 TPU 切片由多个物理节点组成,这些节点使用高速芯片间互连 (ICI) 进行通信,非常适合高吞吐量和低延迟服务。

Ray 上的 vLLM

vLLM 是一种高吞吐量、高内存效率的 LLM 服务引擎。通过与 Ray Serve 集成,vLLM 可以跨多个主机进行扩缩,并以原生方式访问物理硬件拓扑。本教程演示了如何使用 Ray Serve 的 LLMConfigLLMServer 部署在多主机切片上编排 vLLM 推理,让框架自动处理拓扑分布和展示位置组扩展。

目标

本教程为您提供了一个基础,让您能够了解和探索在托管式 Kubernetes 环境中部署实际 LLM 以进行推理,该环境使用多主机 TPU。

  1. 使用处于 Autopilot 或 Standard 模式的 GKE 集群准备环境。
  2. 构建具有内置依赖项的自定义容器映像。
  3. 将 Ray LLM Python 脚本部署到集群,以编排通过 TPU 切片进行的 vLLM 推理。
  4. 通过 curl 和可选的网页聊天界面,使用 Ray LLM 提供 Gemma 4 模型。

准备工作

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。如果您之前安装了 gcloud CLI,请通过运行 gcloud components update 命令来获取最新版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。
  • 确保您的项目在所选区域中有足够的 TPU Trillium (v6e) 容量配额。如需了解详情,请参阅 Cloud TPU 配额
  • 确保您的 GKE 集群使用 GKE Dataplane V2,并且满足 DRANET 的版本要求:对于 Standard 和 Autopilot,版本均为 1.35.2-gke.1842000 或更高版本
  • 确保您拥有以下 IAM 角色
    • roles/container.admin
    • roles/iam.serviceAccountAdmin

准备环境

在本教程中,您将使用 Cloud Shell 来管理 Google Cloud上托管的资源。Cloud Shell 中预安装了本教程所需的软件,包括 kubectlgcloud CLI。

如需使用 Cloud Shell 设置您的环境,请按照以下步骤操作:

  1. 在 Google Cloud 控制台中,点击激活 Cloud Shell 激活 Shell 按钮 以启动 Cloud Shell 会话。此操作会在 Google Cloud 控制台的底部窗格中启动会话。

  2. 创建并激活 Python 虚拟环境:

    python3 -m venv ray-env
    source ray-env/bin/activate
    
  3. 安装 Ray CLI:

    pip install "ray"
    
  4. 设置默认环境变量:

    export PROJECT_ID=$(gcloud config get project)
    export CLUSTER_NAME=ray-llm-cluster
    export REGION=REGION
    export ZONE=ZONE
    export NAMESPACE=default
    export KSA_NAME=ray-ksa
    export GSA_NAME=tpu-reader-sa
    export NETWORK_NAME=${CLUSTER_NAME}-net
    export GS_BUCKET=BUCKET_NAME
    export REPO_NAME=ray-repo
    export CUSTOM_IMAGE_URI=REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/vllm-tpu-ray:vllm-tpu
    

    替换以下内容:

    • PROJECT_ID:您的 Google Cloud 项目 ID。
    • CLUSTER_NAME:您的集群的名称。
    • REGION:TPU Trillium 容量可用的区域。
    • ZONE:您的 TPU Trillium 容量可用的可用区。如需了解详情,请参阅 GKE 中的 TPU 可用性
    • REPOSITORY:您的 Artifact Registry 代码库的名称。
    • BUCKET_NAME:存储桶的名称。

创建和配置 Google Cloud 资源

请按照以下说明创建所需的资源。

创建 GKE 集群和节点池

您可以在 GKE Autopilot 或 Standard 集群中的 TPU 上应用 Gemma。GKE 托管的 DRANET 可为分布式 Pod 动态请求和管理高性能网络资源,从而使 GKE 能够自动为加速器间通信预配辅助高速网络,而无需手动设置 VPC。

Autopilot

  1. 在 Cloud Shell 中,创建 Autopilot 集群:

    gcloud container clusters create-auto ${CLUSTER_NAME} \
        --project=${PROJECT_ID} \
        --enable-ray-operator \
        --location=${REGION}
    
  2. 配置 kubectl 以与您的集群通信:

    gcloud container clusters get-credentials ${CLUSTER_NAME} \
        --location=${REGION}
    
  3. 如需在 Autopilot 模式下使用 GKE 管理的 DRANET,请部署代码库中提供的自定义 ComputeClass 资源,以选择启用动态网络:

    apiVersion: cloud.google.com/v1
    kind: ComputeClass
    metadata:
      name: dranet-compute-class
    spec:
      nodePoolAutoCreation:
        enabled: true
      nodePoolConfig:
        dra:
          networking:
            enabled: true
      priorities:
      - machineType: ct6e-standard-4t
        acceleratorNetworkProfile: auto
  4. 将清单应用到您的集群:

    kubectl apply -f ai-ml/gke-ray/rayserve/llm/tpu/networking/dranet-compute-class.yaml
    

标准

  1. 在 Cloud Shell 中,创建一个启用 Ray 运算符并使用 GKE Dataplane V2 的 Standard 集群:

    gcloud container clusters create ${CLUSTER_NAME} \
        --project=${PROJECT_ID} \
        --addons=RayOperator,GcsFuseCsiDriver \
        --machine-type=n2-standard-8 \
        --enable-dataplane-v2 \
        --workload-pool=${PROJECT_ID}.svc.id.goog \
        --location=${ZONE}
    
  2. 创建启用了 DRANET 驱动程序的多主机 TPU 切片节点池:

    gcloud container node-pools create v6e-16 \
        --location=${ZONE} \
        --cluster=${CLUSTER_NAME} \
        --machine-type=ct6e-standard-4t \
        --tpu-topology=4x4 \
        --num-nodes=4 \
        --enable-gvnic \
        --scopes=https://www.googleapis.com/auth/cloud-platform \
        --accelerator-network-profile=auto \
        --node-labels=cloud.google.com/gke-networking-dra-driver=true
    

配置存储空间和身份验证

创建 Cloud Storage 存储桶并初始化 Rapid Cache 实例以加快模型加载速度,然后为 Hugging Face 配置身份验证:

  1. 在 TPU 可用区中,创建存储桶并初始化 Rapid Cache 实例:

    gcloud storage buckets create gs://${GS_BUCKET} --project=${PROJECT_ID} --default-storage-class=STANDARD --location=${REGION}
    
    gcloud storage buckets anywhere-caches create gs://${GS_BUCKET} ${ZONE} \
        --ttl=1d \
        --admission-policy=ADMIT_ON_FIRST_MISS
    
  2. 配置身份链接,以帮助安全地将权重存储桶装载到 GKE Pod 中。首先,创建一个专用 IAM 服务账号,并向其授予存储桶读取权限:

    gcloud iam service-accounts create ${GSA_NAME}
    
    gcloud storage buckets add-iam-policy-binding gs://${GS_BUCKET} \
        --member="serviceAccount:${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
        --role="roles/storage.objectAdmin"
    
  3. 创建 Workload Identity Federation for GKE 绑定并为 Kubernetes ServiceAccount 对象添加注解:

    gcloud iam service-accounts add-iam-policy-binding ${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com \
        --role="roles/iam.workloadIdentityUser" \
        --member="serviceAccount:${PROJECT_ID}.svc.id.goog[${NAMESPACE}/${KSA_NAME}]"
    
    kubectl create serviceaccount ${KSA_NAME} --namespace ${NAMESPACE}
    kubectl annotate serviceaccount ${KSA_NAME} --namespace ${NAMESPACE} iam.gke.io/gcp-service-account=${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com
    
  4. 如需下载 Gemma 4 模型权重,您必须在 Hugging Face 上确认 Google 的许可协议。前往 Hugging Face 上的 Gemma 4 模型页面

  5. 登录并点击同意并访问代码库,以接受许可条款。

  6. 前往 Hugging Face 账号设置,然后生成具有 Read 角色的访问令牌

  7. 导出您的 Hugging Face 令牌并创建一个 Kubernetes Secret,以便 Ray 可以拉取模型权重:

    export HF_TOKEN=YOUR_HUGGING_FACE_TOKEN
    
    kubectl create secret generic hf-secret \
      --from-literal=hf_api_token=${HF_TOKEN}
    

构建自定义容器映像

为确保多主机环境具备所有必需的依赖项,请基于 vLLM 的 TPU 映像构建自定义映像,并将部署脚本复制到其中。

  1. 创建 Artifact Registry 代码库:

    gcloud artifacts repositories create ${REPO_NAME} \
        --repository-format=docker \
        --location=${REGION}
    
  2. 向您的项目验证 Docker 的身份:

    gcloud auth configure-docker ${REGION}-docker.pkg.dev
    
  3. 检查示例代码库中的 Dockerfile

    FROM vllm/vllm-tpu:v0.21.0
    
    ENV VLLM_TARGET_DEVICE=tpu
    ENV VLLM_XLA_CACHE_PATH=/data
    
    USER root
    
    RUN pip install --no-cache-dir -U \
        "https://s3-us-west-2.amazonaws.com/ray-wheels/master/75b85027a859439fae5634e49aa6443f6fbecfeb/ray-3.0.0.dev0-cp312-cp312-manylinux2014_x86_64.whl" && \
        pip install --no-cache-dir --no-deps "ray[llm]"
    
    COPY serve_tpu_multihost.py /home/ray/serve_tpu_multihost.py
  4. 构建映像并将其推送到 Artifact Registry:

    docker build -t ${CUSTOM_IMAGE_URI} .
    docker push ${CUSTOM_IMAGE_URI}
    

将模型权重预先暂存到 Cloud Storage

在部署 RayCluster 之前,请使用独立的 Kubernetes 作业将模型权重直接预暂存到 Cloud Storage 存储桶中,以优化模型加载性能并帮助确保分布式 TPU 切片的高可用性。这种解耦方法可实现协调的并行流式传输,从而缩短集群启动时间。

  1. 下载器作业的清单可在代码库中找到。检查清单配置:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: model-downloader
    spec:
      ttlSecondsAfterFinished: 60
      template:
        metadata:
          annotations:
            gke-gcsfuse/volumes: "true"
            gke-gcsfuse/memory-limit: "0"
        spec:
          serviceAccountName: ${KSA_NAME}
          restartPolicy: OnFailure
          containers:
          - name: downloader
            image: python:3.10-slim
            command: ["/bin/sh", "-c"]
            args:
            - |
              pip install -U huggingface_hub filelock
    
              python -c '
              import filelock
    
              class DummyLock:
                  def __init__(self, *args, **kwargs): pass
                  def __enter__(self): return self
                  def __exit__(self, *args): pass
                  def acquire(self, *args, **kwargs): pass
                  def release(self, *args, **kwargs): pass
    
              filelock.FileLock = DummyLock
    
              from huggingface_hub import snapshot_download
              snapshot_download(
                  repo_id="google/gemma-4-31B-it", 
                  local_dir="/data/google/gemma-4-31B-it"
              )
              '
            env:
            - name: HF_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
            volumeMounts:
            - name: gcs-fuse-csi-ephemeral
              mountPath: /data
          volumes:
          - name: gcs-fuse-csi-ephemeral
            csi:
              driver: gcsfuse.csi.storage.gke.io
              volumeAttributes:
                bucketName: ${GS_BUCKET}
                mountOptions: "implicit-dirs"
  2. 通过应用代码库中的文件来创建下载器作业:

    envsubst < ai-ml/gke-ray/rayserve/llm/tpu/components/model-downloader-job.yaml | kubectl apply -f -
    
  3. 监控作业,直到下载流报告成功:

    kubectl logs -f job/model-downloader
    

创建推理脚本

以下 Python 脚本定义了一个由 Ray Serve 的高级 LLMConfig 封装容器提供支持的 Ray Serve 应用。

  1. 检查示例代码库中的 serve_tpu_multihost.py 脚本:

    import os
    import ray
    from ray import serve
    from ray.serve.llm import LLMConfig, ModelLoadingConfig, LLMServingArgs, build_openai_app
    
    # Read configurations from environment variables
    MODEL_ID = os.environ.get("MODEL_ID", "google/gemma-4-31B-it")
    MODEL_SOURCE = os.environ.get("MODEL_SOURCE", "/data/google/gemma-4-31B-it")
    
    # TPU hardware options (i.e. TPU-V6E, TPU-V7X etc.)
    ACCELERATOR_TYPE = os.environ.get("ACCELERATOR_TYPE", "TPU-V6E")
    TPU_TOPOLOGY = os.environ.get("TPU_TOPOLOGY", "4x4")
    
    # vLLM engine parameters
    TENSOR_PARALLEL_SIZE = int(os.environ.get("TENSOR_PARALLEL_SIZE", "16"))
    MAX_MODEL_LEN = int(os.environ.get("MAX_MODEL_LEN", "8192"))
    MAX_NUM_BATCHED_TOKENS = int(os.environ.get("MAX_NUM_BATCHED_TOKENS", "4096"))
    
    # Define the multi-host TPU LLM config
    llm_config = LLMConfig(
        model_loading_config=dict(
            model_id=MODEL_ID,
            model_source=MODEL_SOURCE
        ),
        accelerator_type=ACCELERATOR_TYPE,
        accelerator_config={"kind": "tpu", "topology": TPU_TOPOLOGY},
        engine_kwargs={
            "tensor_parallel_size": TENSOR_PARALLEL_SIZE,
            "max_model_len": MAX_MODEL_LEN,
            "max_num_batched_tokens": MAX_NUM_BATCHED_TOKENS,
            "distributed_executor_backend": "ray",
        }
    )
    
    deployment = build_openai_app(
        LLMServingArgs(
            llm_configs=[llm_config]
        )
    )

了解 Ray LLM API

该脚本利用 Ray Serve 的原生 ray.serve.llm 库来抽象化多主机 TPU 编排的复杂性。通过封装 vLLM 引擎,Ray Serve LLM 提供了一个高性能、可伸缩的框架,专门用于生产环境中高度分布式的推理工作负载。

使用 Ray LLM API 可带来以下几项关键优势:

  • 多节点部署:Ray Serve LLM 使用户能够以原生方式自动放置、协调和分配拓扑,从而部署跨多个分布式主机(例如 TPU 多主机切片)的大型模型。
  • vLLM 兼容性:Ray Serve LLM 提供与 vLLM 服务器一致的 OpenAI 兼容 API。您还可以在 Kubernetes 集群中伸缩工作负载的同时,访问 vLLM 的高级功能集(例如结构化输出、多模态功能和推理模型)。
  • 可用于生产环境的功能:Ray Serve LLM 包含企业级功能,例如内置的自动扩缩、可最大限度提高缓存命中率的自定义请求路由,以及用于指标和可观测性的内置集成。

在提供的推理脚本中,部署由两个主要组件定义:

  • LLMConfig:此对象定义了投放配置。它指定了模型来源、vLLM 的引擎参数和 accelerator_config。通过设置 {"kind": "tpu", "topology": "4x4"},Ray Serve LLM 会自动配置一个分布式展示位置组,该群组与您的 16 芯片 TPU v6e 切片完全匹配。
  • build_openai_app:此 API 会自动将配置的 vLLM 引擎封装在与 OpenAI 兼容的 FastAPI 服务器中,让您无需编写任何自定义服务器代码,即可获得行业标准的 REST API(例如 /v1/chat/completions)。

部署 RayService

部署动态资源分配 (DRA) 网络配置和 RayService 服务清单:

  1. 通过部署代码库中提供的 ResourceClaimTemplate,请求每个节点上的所有可用 NetDevice 接口:

    apiVersion: resource.k8s.io/v1
    kind: ResourceClaimTemplate
    metadata:
      name: all-netdev
    spec:
      spec:
        devices:
          requests:
          - name: req-netdev
            exactly:
              deviceClassName: netdev.google.com
              allocationMode: All
  2. 将模板清单应用到您的集群:

    kubectl apply -f ai-ml/gke-ray/rayserve/llm/tpu/networking/all-netdev-template.yaml
    
  3. 代码库中提供了 RayService 服务清单。检查清单配置:

    apiVersion: ray.io/v1
    kind: RayService
    metadata:
      name: vllm-tpu-multihost
      labels:
        ai.gke.io/model: "gemma-4-31B-it"
        ai.gke.io/inference-server: "vllm"
    spec:
      serveConfigV2: |
        http_options:
          host: 0.0.0.0
          port: 8000
        applications:
          - name: llm
            import_path: ai-ml.gke-ray.rayserve.llm.tpu.serve_tpu_multihost:deployment
            runtime_env:
              working_dir: "https://github.com/GoogleCloudPlatform/kubernetes-engine-samples/archive/main.zip"
              env_vars:
                # Use local disk to prevent multi-host GCSFuse race conditions
                VLLM_XLA_CACHE_PATH: "/tmp/vllm_xla_cache"
      rayClusterConfig:
        headGroupSpec:
          rayStartParams: {}
          template:
            metadata:
              annotations:
                gke-gcsfuse/volumes: "true"
                gke-gcsfuse/cpu-limit: "0"
                gke-gcsfuse/memory-limit: "0"
                gke-gcsfuse/ephemeral-storage-limit: "0"
            spec:
              serviceAccountName: $KSA_NAME
              containers:
              - name: ray-head
                image: $CUSTOM_IMAGE_URI
                imagePullPolicy: Always
                ports:
                - containerPort: 6379
                  name: gcs
                - containerPort: 8265
                  name: dashboard
                - containerPort: 10001
                  name: client
                - containerPort: 8000
                  name: serve
                resources:
                  limits:
                    cpu: "2"
                    memory: 16Gi
                  requests:
                    cpu: "2"
                    memory: 16Gi
                volumeMounts:
                - name: dshm
                  mountPath: /dev/shm
                - name: gcs-fuse-csi-ephemeral
                  mountPath: /data
              volumes:
              - name: dshm
                emptyDir:
                  medium: Memory
              - name: gke-gcsfuse-cache
                emptyDir:
                  medium: Memory
              - name: gcs-fuse-csi-ephemeral
                csi:
                  driver: gcsfuse.csi.storage.gke.io
                  volumeAttributes:
                    bucketName: $GS_BUCKET
                    mountOptions: "implicit-dirs"
        workerGroupSpecs:
        - groupName: tpu-group
          replicas: 1
          minReplicas: 1
          maxReplicas: 1
          numOfHosts: 4
          rayStartParams: {}
          template:
            metadata:
              annotations:
                gke-gcsfuse/volumes: "true"
                gke-gcsfuse/cpu-limit: "0"
                gke-gcsfuse/memory-limit: "0"
                gke-gcsfuse/ephemeral-storage-limit: "0"
            spec:
              serviceAccountName: $KSA_NAME
              containers:
                - name: ray-worker
                  image: $CUSTOM_IMAGE_URI
                  imagePullPolicy: Always
                  resources:
                    limits:
                      cpu: "20"
                      google.com/tpu: "4"
                      memory: 200Gi
                    requests:
                      cpu: "20"
                      google.com/tpu: "4"
                      memory: 200Gi
                    claims:
                    - name: netdev
                  env:
                    - name: HF_HOME
                      value: "/data/huggingface"
                    - name: HF_TOKEN
                      valueFrom:
                        secretKeyRef:
                          name: hf-secret
                          key: hf_api_token
                    - name: JAX_PLATFORMS
                      value: "tpu,cpu"
                    - name: NODE_IP
                      valueFrom:
                        fieldRef:
                          fieldPath: status.hostIP
                    - name: VBAR_CONTROL_SERVICE_URL
                      value: $(NODE_IP):8353
                    - name: TPU_MULTIHOST_BACKEND
                      value: "ray"
                    - name: TPU_BACKEND_TYPE
                      value: "jax"
                    - name: ENABLE_PJRT_COMPATIBILITY
                      value: "true"
                  volumeMounts:
                  - name: dshm
                    mountPath: /dev/shm
                  - name: gcs-fuse-csi-ephemeral
                    mountPath: /data
              volumes:
              - name: dshm
                emptyDir:
                  medium: Memory
              - name: gke-gcsfuse-cache
                emptyDir:
                  medium: Memory
              - name: gcs-fuse-csi-ephemeral
                csi:
                  driver: gcsfuse.csi.storage.gke.io
                  volumeAttributes:
                    bucketName: $GS_BUCKET
                    mountOptions: "implicit-dirs"
              resourceClaims:
                - name: netdev
                  resourceClaimTemplateName: all-netdev
              nodeSelector:
                cloud.google.com/gke-tpu-accelerator: tpu-v6e-slice
                cloud.google.com/gke-tpu-topology: 4x4
  4. 使用清单部署服务:

    Autopilot

    1. 如需在 Autopilot 集群中部署服务,您必须先下载清单并在本地对其进行修改,以添加选择启用 ComputeClass nodeSelector,这是在 Autopilot 上进行 DRANET 网络连接所必需的:

      curl -O https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/main/ai-ml/gke-ray/rayserve/llm/tpu/ray-service.tpu-v6e-multihost.yaml
      
    2. nodeSelector 字段下添加标签,使其如下所示:

      nodeSelector:
        cloud.google.com/gke-tpu-accelerator: tpu-v6e-slice
        cloud.google.com/gke-tpu-topology: 4x4
        cloud.google.com/compute-class: dranet-compute-class
      
    3. 然后,使用修改后的本地清单部署服务:

      envsubst < ray-service.tpu-v6e-multihost.yaml | kubectl apply -f -
      

    标准

    如需在标准集群中部署服务,请直接从代码库部署清单:

    envsubst < ai-ml/gke-ray/rayserve/llm/tpu/ray-service.tpu-v6e-multihost.yaml | kubectl apply -f -
    

验证

  1. 等待 RayService 可用:

    kubectl wait --for=condition=Ready --timeout=1800s rayservice/vllm-tpu-multihost
    
  2. 如需确认模型已成功加载,请查看 Ray head Pod 中的日志:

    kubectl logs -f -l ray.io/node-type=head -c ray-head
    

应用模型

在本部分中,您将与模型互动。确保模型已完全下载,然后再继续。

设置端口转发

运行以下命令,设置到模型的端口转发:

kubectl port-forward svc/vllm-tpu-multihost-head-svc 8000:8000 2>&1 >/dev/null &

使用 curl 与模型互动

本部分介绍如何执行基本的冒烟测试来验证所部署的 Gemma 4 模型。

在新的终端会话中,使用 curl 与模型聊天:

curl -X POST http://127.0.0.1:8000/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d '{
        "model": "google/gemma-4-31B-it",
        "messages": [
            {
              "role": "user",
              "content": "Why is GKE managed DRANET preferred for multi-host TPU networking?"
            }
        ],
        "max_tokens": 256
    }'

输出类似于以下内容:

{
  "id": "chatcmpl-392692d3-5325-4832-a3a3-0b084c1045b0",
  "object": "chat.completion",
  "created": 1779883255,
  "model": "google/gemma-4-31B-it",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "To understand why GKE-managed **DRANET** (Distributed RANET) is preferred for multi-host TPU networking, it is first necessary to understand the fundamental challenge of TPU pods: **the need for massive, low-latency, all-to-all communication.**\n\nWhen you scale a model across multiple TPU hosts (multi-host), the hosts must synchronize gradients and weights constantly. Standard TCP/IP networking introduces too much overhead (latency and CPU jitter) for these operations.\n\nHere is the detailed breakdown of why GKE-managed DRANET is the preferred architecture:\n\n### 1. Bypassing the Kernel (Zero-Copy Networking)\nStandard networking requires the operating system kernel to handle packets, moving data from the network card to kernel space and then to user space.\n*   **The DRANET Advantage:** DRANET implements a specialized networking stack that allows for **Kernel Bypass**. It enables the TPU hardware/drivers to write data directly into the memory of the destination host. This reduces latency and eliminates the CPU overhead associated with processing network interrupts.\n\n### 2. High-Bandwidth, Low-Latency Interconnect\nMulti-host TPU training relies on a specialized topology (like a 2D or 3D"
      },
      "finish_reason": "length"
    }
  ]
}

(可选)通过 Gradio 聊天界面与模型互动

在本部分中,您将构建一个网页聊天应用,可让您与指令调优模型互动。

Gradio 是一个 Python 库,它有一个可为聊天机器人创建界面的 ChatInterface 封装容器。

部署聊天界面

聊天界面的清单可在代码库中找到。检查清单配置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gradio
  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.7
        resources:
          requests:
            cpu: "250m"
            memory: "512Mi"
          limits:
            cpu: "500m"
            memory: "512Mi"
        env:
        - name: CONTEXT_PATH
          value: "/v1/chat/completions"
        - name: HOST
          value: "http://vllm-tpu-multihost-serve-svc:8000"
        - name: LLM_ENGINE
          value: "openai-chat"
        - name: MODEL_ID
          value: "google/gemma-4-31B-it"
        - name: DISABLE_SYSTEM_MESSAGE
          value: "true"
        ports:
        - containerPort: 7860
---
apiVersion: v1
kind: Service
metadata:
  name: gradio
spec:
  selector:
    app: gradio
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 7860
  type: ClusterIP

应用清单:

kubectl apply -f ai-ml/gke-ray/rayserve/llm/tpu/components/gradio.yaml

等待部署成为可用状态:

kubectl wait --for=condition=Available --timeout=900s deployment/gradio

使用聊天界面

在 Cloud Shell 中,运行以下命令:

kubectl port-forward service/gradio 8080:8080

这会创建从 Cloud Shell 到 Gradio 服务的端口转发。

点击 Cloud Shell 任务栏右上角的网页预览图标 “网页预览”按钮。点击在端口 8080 上预览。浏览器中会打开一个新的标签页。

使用 Gradio 聊天界面与 Gemma 互动。添加提示,然后点击提交

观察模型性能

如需查看在 KubeRay 上运行的模型的观测性指标信息中心,您可以使用专门的 Ray on GKE 信息中心。

如需有关配置集群和访问可观测性信息中心的详细说明,请参阅收集和查看 Google Kubernetes Engine (GKE) 上的 Ray 集群的日志和指标

访问 Ray 信息中心

如需检查 Ray actor 的状态、查看详细的应用日志,以及在 Ray 中原生监控节点级利用率,您可以访问 Ray 信息中心。

  1. 将 Ray 头节点服务通过端口转发到您的本地机器:

    kubectl port-forward svc/vllm-tpu-multihost-head-svc 8265:8265
    
  2. 打开浏览器,然后前往 http://localhost:8265。 如果您使用的是 Cloud Shell,请点击网页预览按钮,然后选择在端口 8265 上预览

  3. 如需查看 vLLM 部署、模型副本健康状况和查询延迟时间,请点击服务标签页。

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除这些资源:

  1. 删除 RayService:

    kubectl delete rayservice vllm-tpu-multihost
    
  2. 删除 GKE 集群:

    gcloud container clusters delete ${CLUSTER_NAME} --zone=${ZONE}
    

后续步骤