Menyajikan model terbuka Gemma menggunakan TPU di GKE dengan Ray LLM

Tutorial ini memandu Anda men-deploy layanan inferensi TPU multi-host menggunakan Ray Serve LLM. Dengan memanfaatkan dukungan TPU native Ray untuk secara atomik menjadwalkan bersama worker mesin terdistribusi di seluruh topologi akselerator yang kompleks, Anda dapat men-deploy model besar melalui slice TPU multi-host untuk inferensi.

Tutorial ini ditujukan untuk engineer Machine Learning (ML), admin dan operator Platform, serta spesialis Data dan AI yang tertarik untuk menggunakan kemampuan orkestrasi container Kubernetes untuk menyajikan workload AI/ML pada slice TPU multi-host terdistribusi. Untuk mempelajari lebih lanjut peran umum dan contoh tugas yang dirujuk dalam Google Cloud konten, lihat Peran dan tugas pengguna GKE umum.

Sebelum membaca halaman ini, pastikan Anda memahami hal-hal berikut:

Latar belakang

Bagian ini menjelaskan teknologi utama yang digunakan dalam panduan ini.

TPU

Tensor Processing Unit (TPU) memungkinkan Anda mempercepat workload tertentu yang berjalan di node, seperti machine learning dan pemrosesan data. Keuntungan utama TPU adalah performa dalam skala besar. Tutorial ini menggunakan TPU Trillium, generasi keenam Cloud TPU. Slice TPU multi-host terdiri dari beberapa node fisik yang berkomunikasi menggunakan interkoneksi antar-chip (ICI) berkecepatan tinggi, yang berfungsi baik untuk penayangan dengan throughput tinggi dan latensi rendah.

vLLM di Ray

vLLM adalah mesin penyajian LLM dengan throughput tinggi dan efisien memori. Dengan berintegrasi dengan Ray Serve, vLLM dapat menskalakan di beberapa host dan mengakses topologi hardware fisik secara native. Tutorial ini menunjukkan penggunaan deployment LLMConfig dan LLMServer Ray Serve untuk mengorkestrasi inferensi vLLM di seluruh slice multi-host, sehingga framework dapat menangani distribusi topologi dan penyebaran grup penempatan secara otomatis.

Tujuan

Tutorial ini memberikan dasar untuk memahami dan menjelajahi deployment LLM praktis untuk inferensi di lingkungan Kubernetes terkelola yang menggunakan TPU multi-host.

  1. Siapkan lingkungan Anda dengan cluster GKE dalam mode Autopilot atau Standard.
  2. Bangun image container kustom dengan dependensi bawaan.
  3. Deploy skrip Python Ray LLM ke cluster Anda untuk mengatur inferensi vLLM melalui slice TPU.
  4. Gunakan Ray LLM untuk menyajikan model Gemma 4 melalui curl dan antarmuka chat web opsional.

Sebelum memulai

Sebelum memulai, pastikan Anda telah melakukan tugas berikut:

  • Aktifkan Google Kubernetes Engine API.
  • Aktifkan Google Kubernetes Engine API
  • Jika ingin menggunakan Google Cloud CLI untuk tugas ini, instal lalu lakukan inisialisasi gcloud CLI. Jika sebelumnya Anda telah menginstal gcloud CLI, dapatkan versi terbaru dengan menjalankan perintah gcloud components update. Versi gcloud CLI yang lebih lama mungkin tidak mendukung menjalankan perintah dalam dokumen ini.
  • Pastikan project Anda memiliki kuota yang cukup untuk kapasitas TPU Trillium (v6e) di region yang Anda pilih. Untuk mengetahui informasi selengkapnya, lihat kuota Cloud TPU.
  • Pastikan cluster GKE Anda menggunakan GKE Dataplane V2 dan memenuhi persyaratan versi untuk DRANET: 1.35.2-gke.1842000 atau yang lebih baru untuk Standard dan Autopilot.
  • Pastikan Anda memiliki peran IAM berikut:
    • roles/container.admin
    • roles/iam.serviceAccountAdmin

Menyiapkan lingkungan Anda

Dalam tutorial ini, Anda akan menggunakan Cloud Shell untuk mengelola resource yang dihosting di Google Cloud. Cloud Shell telah diinstal dengan software yang Anda perlukan untuk tutorial ini, termasuk kubectl dan gcloud CLI.

Untuk menyiapkan lingkungan Anda dengan Cloud Shell, ikuti langkah-langkah berikut:

  1. Di konsol Google Cloud , luncurkan sesi Cloud Shell dengan mengklik Activate Cloud Shell Tombol Activate Shell. Tindakan ini akan meluncurkan sesi di panel bawah konsol Google Cloud .

  2. Membuat dan mengaktifkan lingkungan virtual Python:

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

    pip install "ray"
    
  4. Tetapkan variabel lingkungan default:

    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
    

    Ganti kode berikut:

    • PROJECT_ID: Google Cloud Project ID Anda.
    • CLUSTER_NAME: nama cluster Anda.
    • REGION: region tempat kapasitas TPU Trillium Anda tersedia.
    • ZONE: zona tempat kapasitas TPU Trillium Anda tersedia. Untuk mengetahui informasi selengkapnya, lihat Ketersediaan TPU di GKE.
    • REPOSITORY: nama repositori Artifact Registry Anda.
    • BUCKET_NAME: nama bucket penyimpanan Anda.

Membuat dan mengonfigurasi resource Google Cloud

Ikuti petunjuk berikut untuk membuat resource yang diperlukan.

Membuat cluster GKE dan node pool

Anda dapat menayangkan Gemma di TPU dalam cluster GKE Autopilot atau Standard. DRANET yang dikelola GKE secara dinamis meminta dan mengelola resource jaringan berperforma tinggi untuk Pod terdistribusi Anda, sehingga GKE dapat otomatis menyediakan jaringan berkecepatan tinggi sekunder untuk komunikasi antar-akselerator tanpa memerlukan penyiapan VPC manual.

Autopilot

  1. Di Cloud Shell, buat cluster Autopilot:

    gcloud container clusters create-auto ${CLUSTER_NAME} \
        --project=${PROJECT_ID} \
        --enable-ray-operator \
        --location=${REGION}
    
  2. Konfigurasi kubectl untuk berkomunikasi dengan cluster Anda:

    gcloud container clusters get-credentials ${CLUSTER_NAME} \
        --location=${REGION}
    
  3. Untuk menggunakan DRANET yang dikelola GKE dalam mode Autopilot, deploy resource ComputeClass kustom yang disediakan di repositori untuk memilih ikut serta dalam jaringan dinamis:

    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. Terapkan manifes ke cluster Anda:

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

Standar

  1. Di Cloud Shell, buat cluster Standard yang mengaktifkan operator Ray dan menggunakan GKE Dataplane V2:

    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. Buat node pool slice TPU multi-host dengan driver DRANET diaktifkan:

    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
    

Mengonfigurasi penyimpanan dan autentikasi

Buat bucket Cloud Storage dan inisialisasi instance Rapid Cache untuk mempercepat pemuatan model, lalu konfigurasi autentikasi untuk Hugging Face:

  1. Di zona TPU Anda, buat bucket penyimpanan dan lakukan inisialisasi instance 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. Konfigurasi penautan identitas untuk membantu memasang bucket berat ke Pod GKE Anda secara aman. Pertama, buat akun layanan IAM khusus dan berikan izin baca bucket:

    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. Buat binding Workload Identity Federation for GKE dan beri anotasi pada objek ServiceAccount Kubernetes:

    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. Untuk mendownload bobot model Gemma 4, Anda harus menyetujui perjanjian lisensi Google di Hugging Face. Buka halaman model Gemma 4 di Hugging Face.

  5. Login dan setujui persyaratan lisensi dengan mengklik Setuju dan akses repositori.

  6. Buka setelan akun Hugging Face Anda dan buat Token Akses dengan peran Read.

  7. Ekspor token Hugging Face Anda dan buat secret Kubernetes agar Ray dapat menarik bobot model:

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

Membangun image container kustom

Untuk memastikan lingkungan multi-host memiliki semua dependensi yang diperlukan, buat image kustom berdasarkan image TPU vLLM dan salin skrip penayangan Anda ke dalamnya.

  1. Buat repositori Artifact Registry:

    gcloud artifacts repositories create ${REPO_NAME} \
        --repository-format=docker \
        --location=${REGION}
    
  2. Lakukan autentikasi Docker ke project Anda:

    gcloud auth configure-docker ${REGION}-docker.pkg.dev
    
  3. Periksa Dockerfile di repositori contoh:

    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. Bangun dan kirim image ke Artifact Registry:

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

Menyiapkan bobot model ke Cloud Storage

Sebelum men-deploy RayCluster, optimalkan performa pemuatan model dan bantu memastikan ketersediaan tinggi di seluruh slice TPU terdistribusi dengan melakukan pra-penyusunan bobot model langsung di bucket Cloud Storage menggunakan Job Kubernetes mandiri. Pendekatan yang tidak terkait ini memungkinkan streaming paralel yang terkoordinasi, sehingga mempercepat waktu mulai cluster.

  1. Manifes untuk tugas downloader tersedia di repositori. Tinjau konfigurasi manifes:

    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. Buat tugas downloader dengan menerapkan file di repositori:

    envsubst < ai-ml/gke-ray/rayserve/llm/tpu/components/model-downloader-job.yaml | kubectl apply -f -
    
  3. Pantau tugas hingga aliran download melaporkan keberhasilan:

    kubectl logs -f job/model-downloader
    

Buat skrip inferensi

Skrip Python berikut menentukan aplikasi Ray Serve yang didukung oleh wrapper LLMConfig tingkat tinggi Ray Serve.

  1. Periksa skrip serve_tpu_multihost.py di repositori contoh:

    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]
        )
    )

Memahami Ray LLM API

Skrip ini memanfaatkan library ray.serve.llm bawaan Ray Serve untuk menghilangkan kerumitan orkestrasi TPU multi-host. Dengan membungkus mesin vLLM, Ray Serve LLM menyediakan framework berperforma tinggi dan skalabel yang dirancang khusus untuk workload inferensi yang sangat terdistribusi dalam produksi.

Penggunaan Ray LLM API memberikan beberapa manfaat utama:

  • Deployment multi-node: Ray Serve LLM memungkinkan pengguna menyajikan model besar yang mencakup beberapa host terdistribusi (seperti slice multi-host TPU) dengan penempatan, koordinasi, dan distribusi topologi otomatis secara native.
  • Kompatibilitas vLLM: Ray Serve LLM menyediakan API yang kompatibel dengan OpenAI yang selaras dengan server vLLM. Anda juga dapat mengakses serangkaian fitur canggih vLLM (seperti output terstruktur, kemampuan multimodal, dan model penalaran) sambil menskalakan workload di seluruh cluster Kubernetes Anda.
  • Fitur siap produksi: Ray Serve LLM mencakup kemampuan tingkat perusahaan seperti penskalaan otomatis bawaan, perutean permintaan kustom untuk memaksimalkan hit cache, dan integrasi bawaan untuk metrik dan kemampuan observasi.

Dalam skrip inferensi yang disediakan, deployment ditentukan oleh dua komponen utama:

  • LLMConfig: objek ini menentukan konfigurasi penayangan. Objek ini menentukan sumber model, parameter mesin untuk vLLM, dan accelerator_config. Dengan menyetel {"kind": "tpu", "topology": "4x4"}, Ray Serve LLM akan otomatis menyediakan grup penempatan terdistribusi yang dipetakan secara persis ke slice TPU v6e 16 chip fisik Anda.
  • build_openai_app: API ini secara otomatis membungkus mesin vLLM yang dikonfigurasi dalam server FastAPI yang kompatibel dengan OpenAI, sehingga Anda mendapatkan REST API standar industri (seperti /v1/chat/completions) langsung tanpa menulis kode server kustom.

Men-deploy RayService

Deploy konfigurasi jaringan Alokasi Resource Dinamis (DRA) dan manifes penayangan RayService:

  1. Minta semua antarmuka NetDevice yang tersedia di setiap node dengan men-deploy ResourceClaimTemplate yang disediakan di repositori:

    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. Terapkan manifes template ke cluster Anda:

    kubectl apply -f ai-ml/gke-ray/rayserve/llm/tpu/networking/all-netdev-template.yaml
    
  3. Manifes penayangan RayService tersedia di repositori. Tinjau konfigurasi manifes:

    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. Deploy layanan menggunakan manifes:

    Autopilot

    1. Untuk men-deploy layanan di cluster Autopilot, Anda harus mendownload manifes terlebih dahulu dan mengeditnya secara lokal untuk menambahkan ComputeClass nodeSelector yang diperlukan untuk jaringan DRANET di Autopilot:

      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. Tambahkan label di kolom nodeSelector sehingga terlihat seperti ini:

      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. Kemudian, deploy layanan menggunakan manifes lokal yang telah diubah:

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

    Standar

    Untuk men-deploy layanan di cluster Standard, deploy manifes langsung dari repositori:

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

Verifikasi

  1. Tunggu hingga RayService tersedia:

    kubectl wait --for=condition=Ready --timeout=1800s rayservice/vllm-tpu-multihost
    
  2. Untuk mengonfirmasi bahwa model berhasil dimuat, lihat log dari Pod head Ray:

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

Menyajikan model

Di bagian ini, Anda berinteraksi dengan model. Pastikan model didownload sepenuhnya sebelum melanjutkan.

Menyiapkan penerusan port

Siapkan penerusan port ke model dengan menjalankan perintah berikut:

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

Berinteraksi dengan model menggunakan curl

Bagian ini menunjukkan cara melakukan pengujian dasar untuk memverifikasi model Gemma 4 yang di-deploy.

Dalam sesi terminal baru, gunakan curl untuk memulai percakapan dengan model Anda:

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
    }'

Outputnya akan terlihat mirip seperti berikut:

{
  "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"
    }
  ]
}

(Opsional) Berinteraksi dengan model melalui antarmuka chat Gradio

Di bagian ini, Anda akan membuat aplikasi chat web yang memungkinkan Anda berinteraksi dengan model yang dioptimalkan untuk mengikuti perintah.

Gradio adalah library Python yang memiliki wrapper ChatInterface yang membuat antarmuka pengguna untuk chatbot.

Men-deploy antarmuka chat

Manifes untuk antarmuka chat tersedia di repositori. Tinjau konfigurasi manifes:

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

Terapkan manifes:

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

Tunggu hingga deployment tersedia:

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

Menggunakan antarmuka chat

Jalankan perintah berikut di Cloud Shell:

kubectl port-forward service/gradio 8080:8080

Tindakan ini akan membuat penerusan port dari Cloud Shell ke layanan Gradio.

Klik ikon Web Preview Tombol Pratinjau Web yang dapat ditemukan di kanan atas taskbar Cloud Shell. Klik Preview on Port 8080. Tab baru akan terbuka di browser Anda.

Berinteraksi dengan Gemma menggunakan antarmuka chat Gradio. Tambahkan perintah, lalu klik Kirim.

Mengamati performa model

Untuk melihat dasbor metrik kemampuan pengamatan model yang berjalan di KubeRay, Anda dapat menggunakan dasbor khusus Ray di GKE.

Untuk mengetahui petunjuk mendetail tentang cara mengonfigurasi cluster dan mengakses dasbor keamat-amatan, lihat Mengumpulkan dan melihat log dan metrik untuk RayCluster di Google Kubernetes Engine (GKE).

Mengakses Dasbor Ray

Untuk memeriksa status aktor Ray, melihat log aplikasi mendetail, dan memantau penggunaan tingkat node secara native di Ray, Anda dapat mengakses Dasbor Ray.

  1. Teruskan port layanan head node Ray ke mesin lokal Anda:

    kubectl port-forward svc/vllm-tpu-multihost-head-svc 8265:8265
    
  2. Buka browser Anda, lalu buka http://localhost:8265. Jika Anda menggunakan Cloud Shell, klik tombol Web Preview dan pilih Preview on port 8265.

  3. Untuk melihat deployment vLLM, kondisi replika model, dan latensi kueri, klik tab Serve.

Pembersihan

Agar akun Google Cloud Anda tidak dikenai biaya untuk resource yang digunakan dalam tutorial ini, hapus resource tersebut:

  1. Hapus RayService:

    kubectl delete rayservice vllm-tpu-multihost
    
  2. Hapus cluster GKE:

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

Langkah berikutnya