Menggunakan vLLM di GKE untuk menjalankan inferensi dengan Qwen3

Tutorial ini menunjukkan cara men-deploy dan menyajikan model bahasa besar (LLM) Qwen3 dengan framework penyajian vLLM. Anda men-deploy model di satu instance virtual machine (VM) A4 di Google Kubernetes Engine (GKE).

Tutorial ini ditujukan untuk engineer machine learning (ML), administrator dan operator platform, serta spesialis data dan AI yang tertarik menggunakan kemampuan orkestrasi container Kubernetes untuk menangani workload inferensi.

Tujuan

  1. Akses Qwen3 menggunakan Hugging Face.

  2. Siapkan lingkungan Anda.

  3. Buat cluster GKE dalam mode Autopilot.

  4. Membuat bucket Cloud Storage.

  5. Buat secret Kubernetes untuk kredensial Hugging Face.

  6. Konfigurasi Workload Identity Federation untuk Cloud Storage.

  7. Isi bucket Cloud Storage dengan model Qwen3.

  8. Deploy container vLLM ke GKE Anda.

  9. Berinteraksi dengan Qwen3 menggunakan curl.

  10. Jalankan pembersihan.

Biaya

Tutorial ini menggunakan komponen Google Cloudyang dapat ditagih, termasuk:

Untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda, gunakan Kalkulator Harga.

Sebelum memulai

  1. Login ke akun Google Cloud Anda. Jika Anda baru menggunakan Google Cloud, buat akun untuk mengevaluasi performa produk kami dalam skenario dunia nyata. Pelanggan baru juga mendapatkan kredit gratis senilai $300 untuk menjalankan, menguji, dan men-deploy workload.
  2. Instal Google Cloud CLI.

  3. Jika Anda menggunakan penyedia identitas (IdP) eksternal, Anda harus login ke gcloud CLI dengan identitas gabungan Anda terlebih dahulu.

  4. Untuk melakukan inisialisasi gcloud CLI, jalankan perintah berikut:

    gcloud init
  5. Buat atau pilih Google Cloud project.

    Peran yang diperlukan untuk memilih atau membuat project

    • Pilih project: Memilih project tidak memerlukan peran IAM tertentu—Anda dapat memilih project mana pun yang telah diberi peran.
    • Membuat project: Untuk membuat project, Anda memerlukan peran Project Creator (roles/resourcemanager.projectCreator), yang berisi izin resourcemanager.projects.create. Pelajari cara memberikan peran.
    • Buat Google Cloud project:

      gcloud projects create PROJECT_ID

      Ganti PROJECT_ID dengan nama untuk Google Cloud project yang Anda buat.

    • Pilih project Google Cloud yang Anda buat:

      gcloud config set project PROJECT_ID

      Ganti PROJECT_ID dengan nama project Google Cloud Anda.

  6. Verifikasi bahwa penagihan diaktifkan untuk project Google Cloud Anda.

  7. Aktifkan API yang diperlukan:

    Peran yang diperlukan untuk mengaktifkan API

    Untuk mengaktifkan API, Anda memerlukan izin serviceusage.services.enable. Jika Anda membuat project, kemungkinan Anda sudah memiliki izin ini melalui peran Pemilik (roles/owner). Jika tidak, Anda bisa mendapatkan izin ini melalui peran Admin Penggunaan Layanan (roles/serviceusage.serviceUsageAdmin). Pelajari cara memberikan peran.

    gcloud services enable container.googleapis.com
  8. Instal Google Cloud CLI.

  9. Jika Anda menggunakan penyedia identitas (IdP) eksternal, Anda harus login ke gcloud CLI dengan identitas gabungan Anda terlebih dahulu.

  10. Untuk melakukan inisialisasi gcloud CLI, jalankan perintah berikut:

    gcloud init
  11. Buat atau pilih Google Cloud project.

    Peran yang diperlukan untuk memilih atau membuat project

    • Pilih project: Memilih project tidak memerlukan peran IAM tertentu—Anda dapat memilih project mana pun yang telah diberi peran.
    • Membuat project: Untuk membuat project, Anda memerlukan peran Project Creator (roles/resourcemanager.projectCreator), yang berisi izin resourcemanager.projects.create. Pelajari cara memberikan peran.
    • Buat Google Cloud project:

      gcloud projects create PROJECT_ID

      Ganti PROJECT_ID dengan nama untuk Google Cloud project yang Anda buat.

    • Pilih project Google Cloud yang Anda buat:

      gcloud config set project PROJECT_ID

      Ganti PROJECT_ID dengan nama project Google Cloud Anda.

  12. Verifikasi bahwa penagihan diaktifkan untuk project Google Cloud Anda.

  13. Aktifkan API yang diperlukan:

    Peran yang diperlukan untuk mengaktifkan API

    Untuk mengaktifkan API, Anda memerlukan izin serviceusage.services.enable. Jika Anda membuat project, kemungkinan Anda sudah memiliki izin ini melalui peran Pemilik (roles/owner). Jika tidak, Anda bisa mendapatkan izin ini melalui peran Admin Penggunaan Layanan (roles/serviceusage.serviceUsageAdmin). Pelajari cara memberikan peran.

    gcloud services enable container.googleapis.com
  14. Memberikan peran ke akun pengguna Anda. Jalankan perintah berikut satu kali untuk setiap peran IAM berikut: roles/container.admin

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE

    Ganti kode berikut:

    • PROJECT_ID: Project ID Anda.
    • USER_IDENTIFIER: ID untuk akun pengguna Anda. Misalnya, myemail@example.com.
    • ROLE: Peran IAM yang Anda berikan ke akun pengguna Anda.
  15. Login atau buat akun Hugging Face.

Mengakses Qwen3 menggunakan Hugging Face

Untuk menggunakan Hugging Face guna mengakses Qwen3, ikuti langkah-langkah berikut:

  1. Login ke Hugging Face
  2. Buat token akses read Hugging Face. Klik Profil Anda > Setelan > Token Akses > +Buat token baru.
  3. Tentukan nama pilihan Anda untuk token, lalu pilih peran. Tingkat izin peran minimum yang dapat Anda pilih untuk tutorial ini adalah Baca.
  4. Pilih Buat token.
  5. Salin dan simpan token yang dihasilkan ke papan klip Anda. Anda akan menggunakannya nanti dalam tutorial ini.

Menyiapkan lingkungan Anda

Untuk menyiapkan lingkungan Anda, tetapkan variabel lingkungan default:

export PROJECT_ID="YOUR_PROJECT_ID"
export RESERVATION_NAME="YOUR_RESERVATION_NAME"
export REGION="YOUR_REGION"
export CLUSTER_NAME="YOUR_CLUSTER_NAME"
export GCS_BUCKET_NAME="YOUR_GCS_BUCKET"
export HUGGING_FACE_TOKEN="YOUR_HF_TOKEN"
export NETWORK="YOUR_NETWORK_NAME"
export SUBNETWORK="YOUR_SUBNETWORK_NAME"

gcloud config set project "${PROJECT_ID}"
gcloud config set billing/quota_project "${PROJECT_ID}"

Ganti kode berikut:

  • YOUR_PROJECT_ID: ID Google Cloud project tempat Anda ingin membuat cluster GKE.

  • YOUR_RESERVATION_NAME: nama reservasi yang ingin Anda gunakan untuk membuat cluster GKE. Berdasarkan project tempat pemesanan berada, tentukan salah satu nilai berikut:

    • Reservasi ada di project Anda: RESERVATION_NAME

    • Pemesanan ada di project lain, dan project Anda dapat menggunakan pemesanan tersebut: projects/RESERVATION_PROJECT_ID/reservations/RESERVATION_NAME

  • YOUR_REGION: region tempat Anda ingin membuat cluster GKE. Anda hanya dapat membuat cluster di region tempat reservasi Anda berada.

  • YOUR_CLUSTER_NAME: nama cluster GKE yang akan dibuat.

  • YOUR_BUCKET_NAME: nama bucket Cloud Storage regional yang akan dibuat.

  • YOUR_HF_TOKEN: token akses Hugging Face yang Anda buat di bagian sebelumnya.

  • YOUR_NETWORK_NAME: jaringan yang digunakan cluster GKE. Tentukan salah satu nilai berikut:

    • Jika Anda membuat jaringan kustom, tentukan nama jaringan Anda.

    • Jika tidak, tentukan default.

  • YOUR_SUBNETWORK_NAME: subnetwork yang digunakan cluster GKE. Tentukan salah satu nilai berikut:

    • Jika Anda membuat subnetwork kustom, tentukan nama subnetwork Anda. Anda hanya dapat menentukan subnet yang ada di region yang sama dengan reservasi.

    • Jika tidak, tentukan default.

Membuat cluster GKE dalam mode Autopilot

Untuk membuat cluster GKE dalam mode Autopilot, jalankan perintah berikut:

gcloud container clusters create-auto "$CLUSTER_NAME" \
    --project="$PROJECT_ID" \
    --region="$REGION" \
    --release-channel=rapid \
    --network="$NETWORK" \
    --subnetwork="$SUBNETWORK"
Mungkin perlu waktu beberapa saat untuk menyelesaikan pembuatan cluster GKE. Untuk memverifikasi bahwa Google Cloud telah selesai membuat cluster Anda, buka Kubernetes clusters di konsol Google Cloud .

Membuat bucket Cloud Storage

Untuk membuat bucket Cloud Storage regional guna menyimpan model Anda, jalankan perintah berikut:

gcloud storage buckets create gs://$GCS_BUCKET_NAME \
    --project=$PROJECT_ID \
    --location=$REGION

Buat secret Kubernetes untuk kredensial Hugging Face

Untuk membuat secret Kubernetes untuk kredensial Hugging Face, ikuti langkah-langkah berikut:

  1. Konfigurasi kubectl untuk berkomunikasi dengan cluster GKE Anda:

    gcloud container clusters get-credentials "$CLUSTER_NAME" \
        --location="$REGION" \
        --project="$PROJECT_ID"
  2. Buat secret Kubernetes untuk menyimpan token Hugging Face Anda:

    kubectl create secret generic hf-secret \
        --from-literal=hf_token="${HUGGING_FACE_TOKEN}" \
        --dry-run=client -o yaml | kubectl apply -f -

Mengonfigurasi Workload Identity Federation untuk Cloud Storage

Agar GKE dapat mengakses bucket Cloud Storage dengan aman, siapkan Federasi Workload Identity GKE:

gcloud iam service-accounts create qwen-gcs-sa \
    --project=$PROJECT_ID

gcloud storage buckets add-iam-policy-binding gs://$GCS_BUCKET_NAME \
    --member="serviceAccount:qwen-gcs-sa@$PROJECT_ID.iam.gserviceaccount.com" \
    --role="roles/storage.objectAdmin"

kubectl create serviceaccount qwen-ksa \
    --namespace=default

gcloud iam service-accounts add-iam-policy-binding qwen-gcs-sa@$PROJECT_ID.iam.gserviceaccount.com \
    --project=$PROJECT_ID \
    --role=roles/iam.workloadIdentityUser \
    --member="serviceAccount:$PROJECT_ID.svc.id.goog[default/qwen-ksa]"

kubectl annotate serviceaccount qwen-ksa \
    --namespace=default \
    iam.gke.io/gcp-service-account="qwen-gcs-sa@$PROJECT_ID.iam.gserviceaccount.com"

Isi bucket Cloud Storage dengan bobot model Qwen3

Untuk mengisi bucket Cloud Storage Anda dengan bobot model Qwen3, jalankan Job Kubernetes yang menggunakan driver CSI Cloud Storage FUSE untuk memasang bucket Anda sebagai volume. Tugas ini mendownload model dari Hugging Face jika model belum ada di bucket.

  1. Buat file bernama qwen3-model-loader.yaml dengan konten berikut:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: qwen3-model-loader
    spec:
      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: qwen-ksa
          restartPolicy: OnFailure
          containers:
          - name: downloader
            image: python:3.11-slim
            resources:
              requests:
                cpu: "4"
                memory: "16Gi"
                ephemeral-storage: "100Gi"
              limits:
                cpu: "4"
                memory: "16Gi"
                ephemeral-storage: "100Gi"
            command: ["/bin/sh", "-c"]
            args:
            - |
              pip install huggingface_hub
              python3 -c '
              import os
              from huggingface_hub import snapshot_download
              model_id = "Qwen/Qwen3-235B-A22B-Instruct-2507"
              local_dir = "/data/Qwen/Qwen3-235B-A22B-Instruct-2507"
              config_path = os.path.join(local_dir, "config.json")
              if os.path.exists(config_path):
                  print(f"Model already exists at {local_dir}. Skipping download.")
              else:
                  print(f"Downloading model {model_id} to {local_dir}...")
                  snapshot_download(
                      repo_id=model_id,
                      local_dir=local_dir,
                      local_dir_use_symlinks=False,
                      token=os.environ.get("HUGGING_FACE_HUB_TOKEN")
                  )
                  print("Download completed successfully!")
              '
            env:
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_token
            volumeMounts:
            - name: gcs-fuse-volume
              mountPath: /data
          volumes:
          - name: gcs-fuse-volume
            csi:
              driver: gcsfuse.csi.storage.gke.io
              volumeAttributes:
                bucketName: $GCS_BUCKET_NAME
                mountOptions: "implicit-dirs"
  2. Terapkan manifes qwen3-model-loader.yaml untuk memulai tugas download:

    envsubst < qwen3-model-loader.yaml | kubectl apply -f -
  3. Untuk memverifikasi bahwa tugas sedang berjalan, streaming log tugas download:

    kubectl logs -f job/qwen3-model-loader -c downloader
    
  4. Tunggu hingga tugas download model selesai:

    kubectl wait \
        --for=condition=Complete \
        --timeout=1800s job/qwen3-model-loader
  5. Untuk menghapus tugas, jalankan perintah berikut:

    kubectl delete job qwen3-model-loader --ignore-not-found

Men-deploy container vLLM ke cluster GKE Anda

Untuk men-deploy container vLLM guna menyajikan model Qwen3 menggunakan Deployment Kubernetes, lakukan hal berikut:

  1. Buat file qwen3-235b-deploy.yaml dengan deployment vLLM pilihan Anda:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: vllm-qwen3-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: qwen3-server
      template:
        metadata:
          labels:
            app: qwen3-server
            ai.gke.io/model: Qwen3-235B-A22B-Instruct-2507
            ai.gke.io/inference-server: vllm
            examples.ai.gke.io/source: user-guide
        spec:
          serviceAccountName: qwen-ksa
          containers:
          - name: qwen-inference-server
            image: us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250801_0916_RC01
            resources:
              requests:
                cpu: "10"
                memory: "1000Gi"
                ephemeral-storage: "500Gi"
                nvidia.com/gpu: "8"
              limits:
                cpu: "10"
                memory: "1000Gi"
                ephemeral-storage: "500Gi"
                nvidia.com/gpu: "8"
            command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
            args:
            - --model=$(MODEL_ID)
            - --load-format=runai_streamer
            - --model-loader-extra-config={"distributed":true}
            - --tensor-parallel-size=8
            - --host=0.0.0.0
            - --port=8000
            - --max-model-len=8192
            - --max-num-seqs=4
            - --dtype=bfloat16
            env:
            - name: MODEL_ID
              value: "gs://$GCS_BUCKET_NAME/Qwen/Qwen3-235B-A22B-Instruct-2507"
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_token
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
            livenessProbe:
              httpGet:
                path: /health
                port: 8000
              initialDelaySeconds: 200
              periodSeconds: 10
            readinessProbe:
              httpGet:
                path: /health
                port: 8000
              initialDelaySeconds: 200
              periodSeconds: 5
          volumes:
          - name: dshm
            emptyDir:
              medium: Memory
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-b200
            cloud.google.com/reservation-name: $RESERVATION_NAME
            cloud.google.com/reservation-affinity: "specific"
            cloud.google.com/gke-gpu-driver-version: latest
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: qwen3-service
    spec:
      selector:
        app: qwen3-server
      type: ClusterIP
      ports:
        - protocol: TCP
          port: 8000
          targetPort: 8000
    ---
    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: vllm-qwen3-monitoring
    spec:
      selector:
        matchLabels:
          app: qwen3-server
      endpoints:
      - port: 8000
        path: /metrics
        interval: 30s
  2. Terapkan file qwen3-235b-deploy.yaml ke cluster GKE Anda:

    envsubst < qwen3-235b-deploy.yaml | kubectl apply -f -
    Karena container menggunakan Run:ai Model Streamer untuk melakukan streaming bobot model langsung dari Cloud Storage, waktu mulai dipercepat secara signifikan.

  3. Untuk melihat status penyelesaian, jalankan perintah berikut:

    kubectl wait \
        --for=condition=Available \
        --timeout=1800s deployment/vllm-qwen3-deployment
    Flag --timeout=600s memungkinkan perintah memantau deployment hingga 10 menit.

Berinteraksi dengan Qwen3 menggunakan curl

Untuk memverifikasi model Qwen3 yang Anda deploy, lakukan hal berikut:

  1. Siapkan penerusan port ke Qwen3:

    kubectl port-forward service/qwen3-service 8000:8000
  2. Buka jendela terminal baru. Kemudian, Anda dapat melakukan percakapan dengan model menggunakan curl:

    curl http://127.0.0.1:8000/v1/chat/completions \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{
      "model": "Qwen/Qwen3-235B-A22B-Instruct-2507",
      "messages": [
        {
          "role": "user",
          "content": "Describe a GPU in one short sentence?"
        }
      ],
      "stream": false
    }' | jq .
  3. Outputnya mirip dengan hal berikut ini:

    {
      "id": "chatcmpl-a926ddf7ef2745ca832bda096e867764",
      "object": "chat.completion",
      "created": 1755023619,
      "model": "Qwen/Qwen3-235B-A22B-Instruct-2507",
      "choices": [
        {
          "index": 0,
          "message": {
            "role": "assistant",
            "content": "A GPU is a specialized electronic circuit designed to rapidly process and render graphics and perform parallel computations.",
            "refusal": null,
            "annotations": null,
            "audio": null,
            "function_call": null,
            "tool_calls": [],
            "reasoning_content": null
          },
          "logprobs": null,
          "finish_reason": "stop",
          "stop_reason": null
        }
      ],
      "service_tier": null,
      "system_fingerprint": null,
      "usage": {
        "prompt_tokens": 16,
        "total_tokens": 36,
        "completion_tokens": 20,
        "prompt_tokens_details": null
      },
      "prompt_logprobs": null,
      "kv_transfer_params": null
    }
    

Mengamati performa model

Jika ingin mengamati performa model, Anda dapat menggunakan integrasi dasbor vLLM di Cloud Monitoring. Dasbor ini membantu Anda melihat metrik performa penting untuk model Anda seperti throughput token, latensi jaringan, dan rasio error. Untuk mengetahui informasi, lihat vLLM dalam dokumentasi Monitoring.

Pembersihan

Agar tidak perlu membayar biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam tutorial ini, hapus project yang berisi resource tersebut, atau simpan project dan hapus setiap resource.

Agar tidak menimbulkan biaya pada akun Penagihan Cloud Anda untuk resource yang digunakan dalam tutorial ini, hapus project yang berisi resource tersebut, atau simpan project dan hapus setiap resource.

Menghapus resource

Untuk menghapus resource tutorial, jalankan perintah berikut:

envsubst < qwen3-235b-deploy.yaml | kubectl delete -f -
envsubst < qwen3-model-loader.yaml | kubectl delete -f -
kubectl delete secret hf-secret
kubectl delete serviceaccount qwen-ksa

gcloud iam service-accounts delete qwen-gcs-sa@$PROJECT_ID.iam.gserviceaccount.com \
    --project=$PROJECT_ID --quiet

gcloud storage rm --recursive gs://$GCS_BUCKET_NAME

Menghapus cluster GKE Anda

Untuk menghapus cluster GKE, jalankan perintah berikut:

gcloud container clusters delete "$CLUSTER_NAME" \
    --region="$REGION" \
    --project="$PROJECT_ID" \
    --quiet

Menghapus project Anda

Menghapus Google Cloud project:

gcloud projects delete PROJECT_ID

Langkah berikutnya