Übersicht
Dieses Dokument dient als Solution Reference Implementation (SRI)-Leitfaden und beschreibt die konkreten Schritte, die zum Bereitstellen, Ausführen und Validieren der Lösung Open Model Serving on Distributed Cloud software only erforderlich sind.
In dieser Anleitung wird die Bereitstellung der optimierten vLLM-Serving-Engine mit Gemma 4 (google/gemma-4-31B-it) in einer reinen Softwarekonfiguration von Distributed Cloud implementiert, die auf eine Einzelknoten-Clusterkonfiguration für die Edge-Bereitstellung ausgerichtet ist und physische NVIDIA-GPU-Ressourcen (z.B. RTX PRO 6000) nutzt.
Diese Anleitung ist für die Ausführung über einen CLI-Terminalclient mit kubectl-Zugriff auf den Cluster mit nur Distributed Cloud-Software vorgesehen.
Ziele
Wenn Sie diese Referenzimplementierung für Lösungen durchführen, erreichen Sie Folgendes:
- Parameter für die Bereitstellungsumgebung über eine lokale
.env-Datei konfigurieren. - Stellen Sie einen PersistentVolumeClaim (PVC) mit der StorageClass
local-sharedbereit, um Modellgewichte beizubehalten. - Optimierte vLLM-Bereitstellungs-Engine bereitstellen mit Vertex AI-qualifizierten Containern, die physische
nvidia.com/gpu-Ressourcen zuordnen. - Gradio-Web-UI bereitstellen, um eine interaktive Chatoberfläche zu erhalten.
- Lokale Portweiterleitungstunnel einrichten, um die Reaktionsfähigkeit der Bereitstellung über APIs und die Web-UI zu validieren.
- Observability-Integration prüfen, indem Sie die Aufnahme von Logs und Messwerten (einschließlich GPU-Telemetrie) in Cloud Logging und Cloud Monitoring bestätigen.
Hinweis
Voraussetzungen (Clustereinrichtung)
In diesem Leitfaden wird davon ausgegangen, dass Sie einen laufenden Cluster mit Distributed Cloud-Software only und konfigurierter GPU-Unterstützung haben. Informationen zur Installation des Clusters finden Sie in der offiziellen Dokumentation zu Distributed Cloud (nur Software) für Bare Metal. Die GPU-Konfiguration muss der offiziellen Google CloudDokumentation zum Einrichten und Verwenden von NVIDIA-GPUs entsprechen.
Voraussetzungen für Client-Workstations
Prüfen Sie, ob in Ihrer lokalen Terminalumgebung die folgenden Tools installiert und konfiguriert sind:
- gcloud CLI:Erforderlich für die Projektkonfiguration und das Abfragen von Logs.
Muss authentifiziert sein (
gcloud auth login) und für das aktiveGoogle Cloud -Projekt konfiguriert sein, in dem der reine Softwarecluster von Distributed Cloud registriert ist. - kubectl:Erforderlich für die Verwaltung von Clusterressourcen. Muss mit dem entsprechenden Kontext konfiguriert werden, um auf den Zielcluster für Distributed Cloud-Software zuzugreifen, z.B. über ein Connect-Gateway oder direkten lokalen Netzwerkzugriff.
- curl:Erforderlich zum Senden von Testanfragen an den Serving-Endpunkt.
- jq:Erforderlich zum Parsen der JSON-Ausgabe des Serving-Endpunkts.
Zugriff auf Hugging Face-Modelle
Wenn Sie das Gemma 4-Modell herunterladen und bereitstellen möchten, benötigen Sie Zugriff auf das Hugging Face-Repository:
- Hugging Face-Konto:Sie benötigen ein registriertes Konto bei Hugging Face.
- Modelllizenz akzeptieren:Rufen Sie die Seite zum Gemma 4 31B IT-Modell auf und stimmen Sie den Lizenzbedingungen zu, um Zugriff auf die eingeschränkten Modellgewichte zu erhalten.
- Zugriffstoken generieren:Generieren Sie in den Einstellungen Ihres Hugging Face-Kontos (Einstellungen –> Zugriffstokens) ein Nutzerzugriffstoken mit Leseberechtigungen. Dieses Token wird in Ihrer Konfiguration als
HF_TOKENverwendet.
Zentrale Referenzkonfiguration
Alle Bereitstellungsparameter werden über eine zentrale .env-Datei unter <local-config-dir>/.env verwaltet. Achten Sie darauf, dass diese Datei vorhanden ist und Ihre spezifischen Parameter enthält (Hugging Face-Token, Namespace, Modellname usw.).
Beispiel für die .env-Struktur:
# 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"
Umgebung und Anmeldedaten einrichten
Namespace und Hugging Face-Secret erstellen
Vor der Bereitstellung müssen Sie den Namespace und das Secret für das Hugging Face-Token erstellen:
# 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 -
vLLM-Bereitstellung in Kubernetes
Die Bereitstellung besteht aus drei Hauptmanifesten: PVC, Service und Deployment. In diesen Vorlagen werden Umgebungsvariablen verwendet, die zur Bereitstellungszeit ersetzt werden.
Anspruch auf nichtflüchtiges Volume (Persistent Volume Claim, PVC)
Der PVC sorgt dafür, dass Modellgewichte bei Neustarts von Pods beibehalten werden. Dazu wird die Speicherklasse local-shared der Distributed Cloud-Software verwendet.
Erstellen Sie eine Datei mit dem Namen vllm-pvc.yaml und dem folgendem Inhalt:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: model-cache-pvc
namespace: ${NAMESPACE_NAME}
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-shared
resources:
requests:
storage: 100Gi
Dienst
Stellt den vLLM API-Server intern auf Port 8000 bereit.
Erstellen Sie eine Datei mit dem Namen vllm-service.yaml und dem folgendem Inhalt:
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
Bereitstellung
Führt den vLLM-Container aus, stellt das Modellcache-Volume bereit und fordert physische GPU-Ressourcen an. Während 96 GB VRAM für nicht quantisierte BF16-Gewichte (~62 GB) ausreichen, ermöglicht diese Referenzimplementierung die Blackwell-FP8-Quantisierung (--quantization=fp8, ~31 GB Gewichte), um den KV-Cache auf 56,53 GiB (61,728 Tokens) zu erweitern und so den gleichzeitigen Durchsatz zu erhöhen.
Erstellen Sie eine Datei mit dem Namen vllm-deployment.yaml und dem folgendem Inhalt:
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
Bereitstellung der Gradio-Benutzeroberfläche
Die Gradio-Benutzeroberfläche bietet eine interaktive Weboberfläche, über die Sie mit dem Modell chatten können. Sie wird im Cluster bereitgestellt und stellt über das interne Kubernetes-Netzwerk eine Verbindung zum vLLM-Dienst her.
Gradio-Bereitstellung
Erstellen Sie eine Datei mit dem Namen gradio-deployment.yaml und dem folgendem Inhalt:
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-Dienst
Erstellen Sie eine Datei mit dem Namen gradio-service.yaml und dem folgendem Inhalt:
apiVersion: v1
kind: Service
metadata:
name: gradio-service
namespace: ${NAMESPACE_NAME}
spec:
selector:
app: gradio
ports:
- protocol: TCP
port: 8080
targetPort: 7860
type: ClusterIP
Konfiguration der Beobachtbarkeit
Weitere Informationen zum Konfigurieren von Anwendungs-Logging und -Monitoring finden Sie im offiziellen Leitfaden Anwendungs-Logging und -Monitoring.
vLLM-Monitoring
Damit Google Cloud Managed Service for Prometheus (GMP) vLLM-Messwerte erfassen kann, stellen wir eine PodMonitoring-Ressource bereit, die auf die vLLM-Pods ausgerichtet ist.
Erstellen Sie eine Datei mit dem Namen vllm-pod-monitoring.yaml und dem folgendem Inhalt:
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-Überwachung
Damit Google Cloud Managed Service for Prometheus (GMP) GPU-Messwerte aus dem NVIDIA DCGM-Exporter erfassen kann, stellen wir eine PodMonitoring-Ressource im Namespace gpu-operator bereit. Weitere Informationen finden Sie unter GPU-Messwerte an Cloud Monitoring senden.
Erstellen Sie eine Datei mit dem Namen gpu-pod-monitoring.yaml und dem folgendem Inhalt:
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
Ausführungsschritte
Manifeste bereitstellen
Wenden Sie die Manifeste auf den Cluster an. Da die YAML-Dateien Platzhalter für Umgebungsvariablen enthalten, verwenden Sie envsubst, um die Variablen aus der Datei .env zu ersetzen, bevor Sie sie anwenden.
Wechseln Sie zu Ihrem Arbeitsverzeichnis, das die YAML-Dateien enthält:
cd <local-working-dir>Quellen Sie die Umgebungsvariablen:
source <local-config-dir>/.envWenden Sie die Manifeste nacheinander an:
# 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 -
Überprüfung
Boot-Sequenz des Monitor-Pods überwachen
Streamen Sie die Containerlogs, um die Startsequenz zu verfolgen:
# 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}
Warten Sie, bis in Ihren Logs das Signal für die aktive Auslieferung angezeigt wird:
INFO: Application startup complete.
Portweiterleitungstunnel einrichten
Wenn Sie den Endpunkt lokal testen möchten, leiten Sie den Dienstport 8000 weiter:
kubectl port-forward service/vllm-service 8000:8000 -n ${NAMESPACE_NAME}
Lassen Sie dieses Terminal geöffnet oder führen Sie es im Hintergrund aus.
Endpunkt für die Bereitstellung von Anfragen
Testen Sie in einem separaten Terminal die Reaktionsfähigkeit der API:
1. Liste der Abfragemodelle
curl -s http://localhost:8000/v1/models | jq
2. Chat-Vervollständigungen abfragen
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- und VRAM-Zuweisungen prüfen
Um sicherzustellen, dass das Modell die Hardware effizient nutzt und der Speicherbedarf korrekt ist, können Sie eine GPU-Prüfung durchführen.
GPU über nvidia-smi im Pod prüfen
Rufen Sie den Namen Ihres aktiven vLLM-Pods ab und führen Sie nvidia-smi im Container aus:
# 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
Erwartete Ausgabe: Die Ausgabe sollte die physische VRAM-Auslastung entsprechend dem Parameter GPU_MEMORY_UTILIZATION angeben. Auf einer Workstation mit einer NVIDIA RTX PRO 6000 (ca. 96 GB VRAM), auf der google/gemma-4-31B-it mit GPU_MEMORY_UTILIZATION=0.95 ausgeführt wird, sollten beispielsweise etwa 95.800 MiB für VLLM::EngineCore zugewiesen sein:
+-----------------------------------------------------------------------------------------+
| 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-Cache-Zuweisung in Logs prüfen
Sie können auch die internen Zuweisungs-Protokolle von vLLM prüfen, um die KV-Cache-Größe und die Token-Nebenläufigkeit zu überprüfen:
kubectl logs ${VLLM_POD_NAME} -n ${NAMESPACE_NAME} | grep -E "Available KV cache|GPU KV cache size"
Erwartete Ausgabe:
(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
Dies bestätigt, dass 56,53 GiB VRAM für den Kontext-KV-Cache reserviert sind, was eine große Anzahl gleichzeitiger Tokens ermöglicht.
Gradio-UI-Bereitstellung prüfen
Sobald der Gradio-Pod ausgeführt wird, können Sie auf die Benutzeroberfläche zugreifen, indem Sie einen Portweiterleitungstunnel einrichten.
Status des Gradio-Pods überwachen
Prüfen Sie, ob der Gradio-Pod ausgeführt wird:
kubectl get pods -n ${NAMESPACE_NAME} -l app=gradio
Erwartete Ausgabe:
NAME READY STATUS RESTARTS AGE
gradio-deployment-yyyyyyyy-yyyyy 1/1 Running 0 1m
Portweiterleitungstunnel zu Gradio einrichten
Leiten Sie den Gradio-Dienstport 8080 an Ihren lokalen Port 7860 weiter:
kubectl port-forward service/gradio-service 7860:8080 -n ${NAMESPACE_NAME}
Lassen Sie dieses Terminal geöffnet oder führen Sie es im Hintergrund aus:
kubectl port-forward service/gradio-service 7860:8080 -n ${NAMESPACE_NAME} > pf_gradio.log 2>&1 & sleep 3
Auf die Web-UI zugreifen
- Wenn Sie die Anwendung auf einer lokalen Workstation ausführen: Öffnen Sie Ihren Browser und rufen Sie direkt
http://localhost:7860auf. - Wenn die Anwendung in Cloud Shell ausgeführt wird:Klicken Sie auf den Button Webvorschau, wählen Sie Port ändern aus, geben Sie
7860ein und klicken Sie auf Ändern und Vorschau.
Die Gradio-Chatbot-Oberfläche sollte angezeigt werden. Sie können eine Nachricht eingeben, um mit dem Gemma-Modell zu interagieren. Der Gradio-Pod leitet die Anfrage intern an den vllm-service-Endpunkt weiter.
Tunnel bereinigen
So beenden Sie den Portweiterleitungstunnel:
pkill -f "port-forward service/gradio-service"
Überprüfung des Monitorings
Sobald vLLM bereitgestellt und die PodMonitoring-Ressource angewendet wurde, können Sie prüfen, ob Messwerte in Cloud Monitoring aufgenommen werden.
PodMonitoring-Status prüfen
Prüfen Sie, ob die PodMonitoring-Ressource erstellt wurde und aktiv ist:
kubectl get podmonitoring -n ${NAMESPACE_NAME}
Messwertaufnahme über die Google Cloud Console prüfen
Sie können mit der Google Cloud Console (Metrics Explorer) prüfen, ob Messwerte erfasst werden:
- Öffnen Sie den Metrics Explorer in der Google Cloud Console:
- Rufen Sie
https://console.cloud.google.com/monitoring/metrics-explorerauf (achten Sie darauf, dass Sie Ihr Projekt auswählen${GCP_PROJECT_ID}).
- Rufen Sie
- Suchen Sie im Drop-down-Menü Messwert auswählen nach Folgendem und wählen Sie es aus:
prometheus.googleapis.com/vllm:num_requests_running/gauge, um vLLM-Messwerte zu überprüfen.prometheus.googleapis.com/DCGM_FI_DEV_GPU_UTIL/gauge, um Messwerte zur GPU-Auslastung zu prüfen.
- Sehen Sie sich das Diagramm an, um zu prüfen, ob Datenpunkte aktiv dargestellt werden.
Logging-Bestätigung
Wenn die Arbeitslast ausgeführt wird, können Sie prüfen, ob Logs nach Cloud Logging exportiert werden.
vLLM-Logaufnahme prüfen
Prüfen Sie, ob vLLM-Containerlogs nach Cloud Logging exportiert werden:
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}
Aufnahme von GPU-Exporter-Logs prüfen
Prüfen Sie, ob die Containerlogs des GPU-Exporters nach Cloud Logging exportiert werden:
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}
Logs mit der Google Cloud -Console (Log-Explorer) prüfen
Sie können die Logaufnahme auch mit der Google Cloud Console überprüfen:
- Öffnen Sie den Log-Explorer in der Google Cloud Console:
- Rufen Sie
https://console.cloud.google.com/logs/queryauf (achten Sie darauf, dass Sie Ihr Projekt auswählen${GCP_PROJECT_ID}).
- Rufen Sie
Geben Sie im Feld Abfrage die folgende Abfrage ein, um vLLM-Logs aufzurufen:
resource.type="k8s_container" resource.labels.namespace_name="<NAMESPACE_NAME>" resource.labels.container_name="vllm-container"Ersetzen Sie
<NAMESPACE_NAME>durch Ihren tatsächlichen Namespace, z.B.your-custom-namespace.Klicken Sie auf Abfrage ausführen. Sie sollten die Logeinträge aus dem vLLM-Container sehen.
Führen Sie die folgende Abfrage aus, um die Logs des GPU-Exporters zu prüfen:
resource.type="k8s_container" resource.labels.namespace_name="gpu-operator" resource.labels.container_name="nvidia-dcgm-exporter"