1. Giriş
Bu codelab'de, Google Cloud TPU'ları kullanarak Google Kubernetes Engine'de (GKE) yüksek performanslı, çok ana bilgisayarlı vLLM (Sanal Büyük Dil Modeli) çıkarım hizmetlerini nasıl dağıtacağınızı öğreneceksiniz. Ray'i kullanarak dağıtılmış çıkarımı yapılandıracak ve LeaderWorkerSets'i kullanarak iş yükünü GKE'de yerel olarak yöneteceksiniz.
Bu adım adım açıklama, Qwen 30B gibi büyük modellerin sunulması için üretim kurulumunu simüle eder.
Yapacaklarınız
- Hızlandırıcı trafiği için özel bir VPC ağı oluşturun.
- Ray Operator ve GCS Fuse CSI sürücüsü ile bir GKE kümesi sağlayın.
- Hızlandırılmış model yükleme için GCS Rapid Cache'i başlatın.
- Ayrılmış kapasiteye sahip çok ana bilgisayarlı bir TPU v6e düğüm havuzu sağlayın.
- Model ağırlıklarına güvenli erişim için Workload Identity'yi yapılandırın.
- 30 milyar parametreli bir modele hizmet veren vLLM motorunu dağıtın ve test edin.

İhtiyacınız olanlar
- Faturalandırmanın etkin olduğu bir Google Cloud projesi.
- TPU v6e kaynakları (32 çip,
ct6e-standard-4t) için Google Cloud Rezervasyonu. - Kaynak paketten model ağırlıklarını kopyalama erişimi.
- Cloud Shell veya
gcloud,kubectlvehelm'nin yüklü olduğu yerel bir terminal.
- Tahmini Süre: 60 dakika
- Tahmini Maliyet: 60 ABD dolarının altında (sökme işleminin hemen yapıldığı varsayılır).
2. Başlamadan önce
Google Cloud projesi oluşturma veya seçme
- Google Cloud Console'da bir Google Cloud projesi seçin veya oluşturun.
- Cloud projeniz için faturalandırmanın etkinleştirildiğinden emin olun.
Cloud Shell'i Başlatma
- Google Cloud Console'un üst kısmından Cloud Shell'i etkinleştir'i tıklayın.
- Kimlik doğrulamayı doğrulayın:
gcloud auth list
- Projenizi onaylayın:
gcloud config get project
- Gerekirse ayarlayın:
export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID
Ortam değişkenlerini ayarlama
Komut yürütmeyi kolaylaştırmak için kabuğunuzda aşağıdaki değişkenleri tanımlayın. <YOUR_ZONE> kısmını ayrılan TPU bölgenizle, <YOUR_RESERVATION_NAME> kısmını ise rezervasyon kimliğinizle değiştirin. Kısıtlanmış model ağırlıklarını indirmek için Hugging Face kullanıcı erişim jetonu oluşturmanız gerekir. Oluşturduktan sonra <YOUR_HUGGING_FACE_TOKEN> ifadesini yeni oluşturduğunuz jetonla değiştirin.
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)")
export ZONE="<YOUR_ZONE>" # e.g., us-east5-a
export REGION=${ZONE%-*}
export CLUSTER_NAME="qwen-serving-cluster"
export GVNIC_NETWORK_PREFIX="qwen-serving"
export BUCKET_NAME="inf-demo-model-storage-${PROJECT_NUMBER}"
export RESERVATION_NAME="<YOUR_RESERVATION_NAME>"
export NODE_POOL_NAME="tpu-v6e-32-resvd-pool"
export MULTIHOST_COLLECTION_NAME="tpu-6-collection"
export HF_TOKEN="<YOUR_HUGGING_FACE_TOKEN>" # Token with access to Qwen model if restricted
API'leri etkinleştir
Gerekli Google Cloud hizmetlerini etkinleştirin:
gcloud services enable \
container.googleapis.com \
compute.googleapis.com \
iam.googleapis.com \
cloudresourcemanager.googleapis.com
3. Özel ağ oluşturma
Çok ana bilgisayarlı TPU iş yükleri, verimli hızlandırıcı iletişimi için daha yüksek MTU boyutları da dahil olmak üzere belirli ağ yapılandırmaları gerektirir. Kümeniz için özel bir VPC ağı oluşturun.
- Büyük bir MTU (8896) ile VPC ağı oluşturun:
gcloud compute --project=${PROJECT_ID} \ networks create ${GVNIC_NETWORK_PREFIX}-main \ --subnet-mode=custom \ --mtu=8896 - Küme için alt ağ oluşturun:
gcloud compute --project=${PROJECT_ID} \ networks subnets create ${GVNIC_NETWORK_PREFIX}-tpu \ --network=${GVNIC_NETWORK_PREFIX}-main \ --region=${REGION} \ --range=192.168.100.0/24 - Çalışanların iletişim kurmasını sağlamak için dahili trafiğe izin veren güvenlik duvarı kuralları oluşturun:
gcloud compute --project=${PROJECT_ID} firewall-rules create ${GVNIC_NETWORK_PREFIX}-allow-internal \ --network=${GVNIC_NETWORK_PREFIX}-main \ --allow=all \ --source-ranges=172.16.0.0/12,192.168.0.0/16,10.0.0.0/8 \ --description="Allow all internal traffic within the network."
4. GKE kümesi sağlama
GCS Fuse bağlamalarını ve Ray Operator iş yüklerini destekleyecek şekilde yapılandırılmış bir Standart GKE kümesi kurulumu oluşturun.
- Kümeyi oluşturun:
gcloud container clusters create ${CLUSTER_NAME} \ --project=${PROJECT_ID} \ --location=${REGION} \ --release-channel=rapid \ --machine-type=e2-standard-4 \ --network=${GVNIC_NETWORK_PREFIX}-main \ --subnetwork=${GVNIC_NETWORK_PREFIX}-tpu \ --num-nodes=1 \ --gateway-api=standard \ --enable-managed-prometheus \ --enable-dataplane-v2 \ --enable-dataplane-v2-metrics \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --addons=GcsFuseCsiDriver,RayOperator \ --enable-ip-alias - Küme Kimlik Bilgilerini Alma:
gcloud container clusters get-credentials ${CLUSTER_NAME} --region=${REGION} - Hugging Face gizli anahtarı oluşturma: Kapsayıcı erişimi indirmeleri için jetonunuzu güvenli bir şekilde kaydedin:
kubectl create secret generic hf-secret \ --from-literal=hf_api_token=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f - - Helm aracılığıyla LeaderWorkerSet'i (LWS) yükleyin. LWS, birlikte planlanması gereken pod gruplarını yönetir:
helm install lws oci://registry.k8s.io/lws/charts/lws \ --version=0.7.0 \ --namespace lws-system \ --create-namespace \ --wait
5. GCS Rapid Cache'i etkinleştirme
Sunum sırasında Cloud Storage'dan onlarca GB ağırlık okumayı hızlandırmak için bir GCS paketi oluşturun ve bölgenizde GCS Rapid Cache'i etkinleştirin.
- Paketi oluşturun:
gcloud storage buckets create gs://$BUCKET_NAME \ --location=$REGION \ --uniform-bucket-level-access - TPU bölgenizde Rapid Cache'i başlatın:
gcloud storage buckets anywhere-caches create gs://$BUCKET_NAME $ZONE \ --ttl=1d \ --admission-policy=ADMIT_ON_FIRST_MISS
6. Workload Identity ve depolama alanı izinlerini ayarlama
Uzun süreli anahtarlar yerleştirmeden ağırlık grubunu GKE pod'larınıza güvenli bir şekilde monte etmek için kimlik bağlantılarını yapılandırın.
- Özel bir IAM hizmet hesabı oluşturun:
gcloud iam service-accounts create tpu-reader-sa - Paket okuma izinleri verme:
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_NAME} \ --member="serviceAccount:tpu-reader-sa@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/storage.objectAdmin" defaultad alanı Kubernetes hizmet hesabı için Workload Identity bağlaması oluşturun:gcloud iam service-accounts add-iam-policy-binding tpu-reader-sa@${PROJECT_ID}.iam.gserviceaccount.com \ --role="roles/iam.workloadIdentityUser" \ --member="serviceAccount:${PROJECT_ID}.svc.id.goog[default/default]"- Kubernetes SA'yı açıklama ekleyin:
kubectl annotate serviceaccount default iam.gke.io/gcp-service-account=tpu-reader-sa@${PROJECT_ID}.iam.gserviceaccount.com
7. Model Ağırlıkları Ayarları
30B parametreli bir model sunmak için ağırlıkları Hugging Face'ten GCS paketinize indirmeniz gerekir. Cloud Shell disk kotası sınırını (5 GB) aşmak için doğrudan kümenin içine indirmek ve bağlı GCS Fuse birimine güvenli bir şekilde yazmak üzere Standart Kubernetes işi kullanın.
- Model İndirici İşini Dağıtma: İndirme işlemini başlatmak için aşağıdaki manifest'i oluşturup uygulayın:
cat <<EOF | kubectl apply -f - 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: default restartPolicy: OnFailure containers: - name: downloader image: python:3.10-slim command: ["/bin/sh", "-c"] args: - | pip install -U "huggingface_hub[hf_transfer]" filelock export HF_HUB_ENABLE_HF_TRANSFER=1 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="Qwen/Qwen3-30B-A3B", local_dir="/models/qwen3-30b-weights", local_dir_use_symlinks=False ) ' env: - name: HF_TOKEN valueFrom: secretKeyRef: name: hf-secret key: hf_api_token volumeMounts: - name: model-weights mountPath: /models volumes: - name: model-weights csi: driver: gcsfuse.csi.storage.gke.io volumeAttributes: bucketName: ${BUCKET_NAME} mountOptions: "implicit-dirs" EOF - İndirme İşlemini İzleme: İlerleme durumunu takip etmek için indirici pod'un günlüklerini kontrol edin:
İşin başarı durumuyla tamamlanmasını bekleyin.kubectl logs -f job/model-downloader
8. Ayrılmış TPU düğüm havuzu oluşturma
Mevcut kapasite rezervasyonunuzu kullanarak gerçek çok ana bilgisayarlı TPU dilimini sağlayın.
- Oluşturma komutunu çalıştırın:
gcloud beta container node-pools create ${NODE_POOL_NAME} \ --project=${PROJECT_ID} \ --cluster=${CLUSTER_NAME} \ --region=${REGION} \ --node-locations=${ZONE} \ --machine-type=ct6e-standard-4t \ --tpu-topology=4x8 \ --num-nodes=8 \ --scopes=https://www.googleapis.com/auth/cloud-platform \ --reservation-affinity=specific \ --reservation=${RESERVATION_NAME} \ --accelerator-network-profile=auto \ --node-labels=cloud.google.com/gke-nodepool-group-name=${MULTIHOST_COLLECTION_NAME} \ --node-labels=cloud.google.com/gke-workload-type=HIGH_AVAILABILITY \ --node-labels=cloud.google.com/gke-networking-dra-driver=true - Düğümlerin katılması bekleniyor: Düğüm toplama ölçeklendirmesini doğrudan gözlemleyebilirsiniz.
ct6eiçeren 8 düğümkubectl get nodes'ye katılana kadar bekleyin.
9. vLLM hizmetini dağıtma
- Ağ talepleri oluşturma: Ağ ortamını talep etmeniz gerekir:
cat <<EOF | kubectl apply -f - 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 EOF - Yük Dengeleyici API Uç Noktasını Dağıtma:
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Service metadata: name: vllm-tpu-service spec: type: LoadBalancer selector: leaderworkerset.sigs.k8s.io/name: vllm-tpu-qwen leaderworkerset.sigs.k8s.io/worker-index: "0" ports: - protocol: TCP port: 8000 targetPort: 8000 EOF - Deploy LeaderWorkerSet workload: Bu bildirim, 8 dilim ana makinesinde Ray başlığı/çalışanı toplama işlemini dinamik olarak başlatır.
cat <<EOF | kubectl apply -f - apiVersion: leaderworkerset.x-k8s.io/v1 kind: LeaderWorkerSet metadata: name: vllm-tpu-qwen spec: replicas: 1 leaderWorkerTemplate: size: 8 restartPolicy: RecreateGroupOnPodRestart workerTemplate: metadata: annotations: gke-gcsfuse/volumes: "true" gke-gcsfuse/memory-limit: "0" labels: leaderworkerset.sigs.k8s.io/name: vllm-tpu-qwen gke-gcsfuse/volumes: "true" spec: hostname: vllm-tpu-qwen serviceAccountName: default containers: - name: vllm-tpu image: vllm/vllm-tpu:nightly command: ["sh", "-c"] args: - | MY_TPU_IP=\$(hostname -I | awk '{print \$1}') echo "My TPU Network IP is: \$MY_TPU_IP" LEADER_DNS="vllm-tpu-qwen-0.vllm-tpu-qwen" until getent hosts \$LEADER_DNS; do echo "DNS not ready. Sleeping 5s..." sleep 5 done LEADER_IP=\$(getent hosts \$LEADER_DNS | awk '{print \$1}') export JAX_PLATFORMS='' export SCAN_TPU_CHIPS=True export TPU_MULTIHOST_BACKEND=ray export JAX_DISTRIBUTED_INITIALIZATION_TIMEOUT=300 export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:/usr/local/lib export VLLM_HOST_IP=\$MY_TPU_IP if [ "\$LWS_WORKER_INDEX" = "0" ]; then echo "Starting Ray Head..." ray start --head --port=6379 --node-ip-address=\$MY_TPU_IP --resources='{"TPU": 4}' --block & sleep 20 until ray status; do sleep 5; done echo "Starting vLLM API Server..." python3 -m vllm.entrypoints.openai.api_server \ --model=/models/qwen3-30b-weights \ --tensor-parallel-size=32 \ --pipeline-parallel-size=1 \ --distributed-executor-backend=ray \ --host=0.0.0.0 --port=8000 \ --enforce-eager \ --gpu-memory-utilization=0.90 else ray start --address=\${LEADER_IP}:6379 --node-ip-address=\$MY_TPU_IP --resources='{"TPU": 4}' --block fi ports: - containerPort: 8000 - containerPort: 6379 volumeMounts: - name: model-weights mountPath: /models readOnly: true - name: dshm mountPath: /dev/shm resources: claims: - name: net-resources limits: google.com/tpu: 4 memory: "100Gi" requests: google.com/tpu: 4 memory: "100Gi" nodeSelector: cloud.google.com/gke-tpu-accelerator: tpu-v6e-slice cloud.google.com/gke-tpu-topology: 4x8 gke.networks.io/accelerator-network-profile: auto resourceClaims: - name: net-resources resourceClaimTemplateName: all-netdev volumes: - name: model-weights csi: driver: gcsfuse.csi.storage.gke.io volumeAttributes: bucketName: ${BUCKET_NAME} mountOptions: "implicit-dirs" - name: dshm emptyDir: medium: Memory EOF
10. Test Dağıtım Yanıtı
LeaderWorkerSet'teki tüm kapsüllerin container görüntülerini çekmesi, Ray'i başlatması ve tamamen Ready olması 5-10 dakika sürebilir. Pod başlatma işlemini izleyerek durumu takip edebilirsiniz:
kubectl get pods -l leaderworkerset.sigs.k8s.io/name=vllm-tpu-qwen -w
8 kapsülün tamamı vllm-tpu-qwen- STATUS olarak Running ve READY olarak 2/2 gösterilene kadar bekleyin ve devam etmeden önce yük dengeleyicinin harici IP aldığından emin olun. Bu işlem 7-10 dakika sürebilir.
- Harici IP'yi alma:
export EXTERNAL_IP=$(kubectl get svc vllm-tpu-service -o jsonpath='{.status.loadBalancer.ingress[0].ip}') echo $EXTERNAL_IP
Dikkat: Üretim hizmetinde bu uç nokta, Identity-Aware Proxy (IAP) gibi bir yöntemle güvenli hale getirilmelidir.
curlkullanarak çıkarım isteği gönderin: Oluşturulan çıkarımınızı temsil eden metni içeren bir JSON yanıtına benzeyen bir çıkış görmelisiniz.curl -N -s http://$EXTERNAL_IP:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "/models/qwen3-30b-weights", "messages": [{"role": "user", "content": "Write a haiku about high-performance computing on TPUs."}], "temperature": 0.7, "max_tokens": 100, "stream": true }' | sed 's/^data: //' | grep -v '\[DONE\]' | grep -v '^$' | jq -rj '.choices[0].delta.content // empty' ; echo ""
11. Temizleme
Google Cloud hesabınızın sürekli olarak ücretlendirilmesini önlemek için bu codelab sırasında oluşturulan kaynakları silin.
- Düğüm havuzunu silme:
gcloud container node-pools delete "${NODE_POOL_NAME}" \ --cluster="${CLUSTER_NAME}" \ --region="${REGION}" \ --project="${PROJECT_ID}" --quiet - Kümeyi Sil:
gcloud container clusters delete "${CLUSTER_NAME}" \ --region="${REGION}" \ --project="${PROJECT_ID}" --quiet - Ağ ve güvenlik duvarı ayarlarını silme:
gcloud compute firewall-rules delete \ "${GVNIC_NETWORK_PREFIX}-allow-internal" \ --project="${PROJECT_ID}" --quiet gcloud compute networks subnets delete "${GVNIC_NETWORK_PREFIX}-tpu" \ --region="${REGION}" --quiet gcloud compute networks delete "${GVNIC_NETWORK_PREFIX}-main" --quiet - Hizmet Hesabının Bağlantısını Kaldırma ve Silme:
# 1. Create the cleanup script cat << 'EOF' > clean_up_sa.sh #!/bin/bash # Validate that PROJECT_ID is available if [ -z "$PROJECT_ID" ]; then echo "Error: PROJECT_ID environment variable is not set." exit 1 fi SA_EMAIL="tpu-reader-sa@${PROJECT_ID}.iam.gserviceaccount.com" SA_MEMBER="serviceAccount:${SA_EMAIL}" echo "Gathering IAM policy for ${SA_EMAIL}..." # Fetch roles assigned to this specific SA ROLES=$(gcloud projects get-iam-policy ${PROJECT_ID} \ --flatten="bindings[].members" \ --filter="bindings.members:${SA_MEMBER}" \ --format="value(bindings.role)") if [ -z "$ROLES" ]; then echo "No IAM bindings found for this service account." else for ROLE in $ROLES; do echo "Removing binding for: ${ROLE}..." gcloud projects remove-iam-policy-binding ${PROJECT_ID} \ --member="${SA_MEMBER}" \ --role="${ROLE}" --quiet > /dev/null done echo "Successfully unbound all roles." fi # 2. Delete the service account itself echo "Deleting service account..." gcloud iam service-accounts delete ${SA_EMAIL} --project=${PROJECT_ID} --quiet echo "Cleanup complete." EOF # 2. Make the script executable and run it chmod +x clean_up_sa.sh ./clean_up_sa.sh - GCS paketini silme: Cloud Console'a gidin, Cloud Storage -> Buckets'ı (Cloud Storage -> Paketler) seçin, inf-demo-model-storage'ı seçin ve ardından "Sil"i seçin.
12. Tebrikler
Tebrikler! Google Kubernetes Engine'de Ray'i yerel olarak kullanan, çok ana makine TPU'lu yüksek çıkarım hızlı vLLM yığınını başarıyla dağıttınız.
Öğrendikleriniz
- Yüksek hızlı TPU trafiğine göre uyarlanmış özel yollar sağlama.
- GCS Fuse ve bölgesel hızlı önbellekler kullanılarak ağırlıkların monte edilmesi.
- LeaderWorkerSets aracılığıyla yerel olarak senkronize edilen çok ana bilgisayarlı iş yükü dilimlerini düzenleme.
- Daha fazla bilgi edinmek için vLLM Kullanıcı Kılavuzu ve llm-d Dağıtım Kılavuzları'na göz atın.