Présentation
Ce document sert de guide d'implémentation de référence de la solution (SRI). Il décrit les étapes concrètes requises pour déployer, mettre en service et valider la solution Open Model Serving sur Distributed Cloud (logiciel uniquement).
Ce guide explique comment déployer le moteur de diffusion vLLM optimisé exécutant Gemma 4 (google/gemma-4-31B-it) sur une configuration de cluster à nœud unique Distributed Cloud logicielle uniquement, ciblant le déploiement en périphérie et utilisant des ressources GPU NVIDIA physiques (par exemple, RTX PRO 6000).
Cette procédure pas à pas est conçue pour être exécutée à partir d'un client de terminal CLI avec un accès kubectl au cluster Distributed Cloud (logiciel uniquement).
Objectifs
En suivant cette implémentation de référence de solution, vous allez :
- Configurez les paramètres de l'environnement de diffusion à l'aide d'un fichier
.envlocal. - Déployez une PersistentVolumeClaim (PVC) à l'aide de la classe de stockage
local-sharedpour conserver les pondérations du modèle. - Déployez le moteur de diffusion vLLM optimisé à l'aide de conteneurs qualifiés Vertex AI, en mappant les ressources physiques
nvidia.com/gpu. - Déployez l'interface utilisateur Web Gradio pour fournir une interface de chat interactive.
- Établissez des tunnels de transfert de port local pour valider la réactivité du service via les API et l'interface utilisateur Web.
- Vérifiez l'intégration de l'observabilité en confirmant l'ingestion des journaux et des métriques (y compris la télémétrie GPU) dans Cloud Logging et Cloud Monitoring.
Avant de commencer
Conditions préalables (configuration du cluster)
Ce guide suppose que vous disposez d'un cluster Distributed Cloud fonctionnel avec la compatibilité avec les GPU configurée. Pour installer le cluster, consultez la documentation officielle sur Distributed Cloud (logiciel uniquement) pour Bare Metal. La configuration du GPU doit être conforme à la documentation officielle Google CloudConfigurer et utiliser des GPU NVIDIA.
Conditions préalables pour les postes de travail clients
Assurez-vous que les outils suivants sont installés et configurés dans votre environnement de terminal local :
- gcloud CLI : obligatoire pour configurer le projet et interroger les journaux.
Doit être authentifié (
gcloud auth login) et configuré pour le projetGoogle Cloud actif dans lequel le cluster Distributed Cloud (logiciel uniquement) est enregistré. - kubectl : requis pour gérer les ressources du cluster. Doit être configuré avec le contexte approprié pour accéder au cluster logiciel Distributed Cloud cible uniquement (par exemple, via une passerelle de connexion ou un accès direct au réseau local).
- curl : requis pour envoyer des requêtes de test au point de terminaison de service.
- jq : requis pour analyser le résultat JSON du point de terminaison de diffusion.
Accès aux modèles Hugging Face
Pour télécharger et déployer le modèle Gemma 4, vous devez avoir accès au dépôt Hugging Face :
- Compte Hugging Face : assurez-vous d'avoir un compte enregistré sur Hugging Face.
- Accepter la licence du modèle : accédez à la page du modèle Gemma 4 31B IT et acceptez les conditions de licence pour accéder aux poids du modèle fermé.
- Générer un jeton d'accès : générez un jeton d'accès utilisateur avec les autorisations Lecture dans les paramètres de votre compte Hugging Face (Settings > Access Tokens). Ce jeton sera utilisé comme
HF_TOKENdans votre configuration.
Configuration de référence centrale
Tous les paramètres de déploiement sont gérés via un fichier .env centralisé situé à l'adresse <local-config-dir>/.env. Assurez-vous que ce fichier existe et qu'il contient vos paramètres spécifiques (jeton Hugging Face, espace de noms, nom du modèle, etc.).
Exemple de structure .env :
# 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"
Configurer l'environnement et les identifiants
Créer un espace de noms et un secret Hugging Face
Avant le déploiement, vous devez créer l'espace de noms et le secret du jeton Hugging Face :
# 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 -
Déploiement de vLLM sur Kubernetes
Le déploiement se compose de trois principaux fichiers manifestes : PVC, Service et Deployment. Ces modèles utilisent des variables d'environnement qui sont remplacées au moment du déploiement.
Persistent Volume Claim (PVC)
La PVC garantit la persistance des pondérations du modèle lors des redémarrages de pods, à l'aide de la classe de stockage local-shared de Distributed Cloud (logiciel uniquement).
Créez un fichier nommé vllm-pvc.yaml avec le contenu suivant :
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: model-cache-pvc
namespace: ${NAMESPACE_NAME}
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-shared
resources:
requests:
storage: 100Gi
Service
Expose le serveur d'API vLLM en interne sur le port 8000.
Créez un fichier nommé vllm-service.yaml avec le contenu suivant :
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
Déploiement
Exécute le conteneur vLLM, installe le volume du cache de modèle et demande des ressources GPU physiques. Bien que 96 Go de VRAM conviennent aux poids BF16 non quantifiés (~62 Go), cette implémentation de référence permet la quantification Blackwell FP8 (--quantization=fp8, ~31 Go de poids) pour étendre le cache KV à 56,53 Gio (61,728 jetons) pour un débit simultané plus élevé.
Créez un fichier nommé vllm-deployment.yaml avec le contenu suivant :
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
Déploiement de l'interface utilisateur Gradio
L'interface utilisateur Gradio fournit une interface Web interactive pour discuter avec le modèle. Il est déployé dans le cluster et se connecte au service vLLM via le réseau Kubernetes interne.
Déploiement de Gradio
Créez un fichier nommé gradio-deployment.yaml avec le contenu suivant :
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
Service Gradio
Créez un fichier nommé gradio-service.yaml avec le contenu suivant :
apiVersion: v1
kind: Service
metadata:
name: gradio-service
namespace: ${NAMESPACE_NAME}
spec:
selector:
app: gradio
ports:
- protocol: TCP
port: 8080
targetPort: 7860
type: ClusterIP
Configuration de l'observabilité
Pour savoir comment configurer la journalisation et la surveillance des applications, consultez le guide officiel Journalisation et surveillance des applications.
Surveillance de vLLM
Pour activer le scraping des métriques vLLM par Google Cloud Managed Service pour Prometheus (GMP), nous déployons une ressource PodMonitoring ciblant les pods vLLM.
Créez un fichier nommé vllm-pod-monitoring.yaml avec le contenu suivant :
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
Surveillance des GPU
Pour activer le scraping des métriques GPU à partir de l'exportateur NVIDIA DCGM par Google Cloud Managed Service pour Prometheus (GMP), nous déployons une ressource PodMonitoring dans l'espace de noms gpu-operator. Pour en savoir plus, consultez Envoyer des métriques GPU à Cloud Monitoring.
Créez un fichier nommé gpu-pod-monitoring.yaml avec le contenu suivant :
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
Étapes d'exécution
Déployer des fichiers manifestes
Appliquez les fichiers manifestes au cluster. Étant donné que les fichiers YAML contiennent des espaces réservés pour les variables d'environnement, utilisez envsubst pour remplacer les variables de votre fichier .env avant de les appliquer.
Accédez à votre répertoire de travail contenant les fichiers YAML :
cd <local-working-dir>Définissez les variables d'environnement :
source <local-config-dir>/.envAppliquez les fichiers manifestes dans l'ordre :
# 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 -
Validation
Surveiller la séquence de démarrage des pods
Diffusez les journaux du conteneur pour suivre la séquence de démarrage :
# 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}
Attendez que le signal de diffusion active s'affiche dans vos journaux :
INFO: Application startup complete.
Établir un tunnel de transfert de port
Pour tester le point de terminaison en local, transférez le port 8000 du service :
kubectl port-forward service/vllm-service 8000:8000 -n ${NAMESPACE_NAME}
Gardez ce terminal ouvert ou exécutez-le en arrière-plan.
Point de terminaison de diffusion des requêtes
Dans un autre terminal, testez la réactivité de l'API :
1. Liste des modèles de requêtes
curl -s http://localhost:8000/v1/models | jq
2. Interroger les complétions de chat
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
Vérifier les allocations de GPU et de VRAM
Pour vous assurer que le modèle utilise le matériel de manière efficace et que l'empreinte mémoire est correcte, vous pouvez exécuter un audit du GPU.
Auditer le GPU via nvidia-smi dans le pod
Récupérez le nom de votre pod vLLM actif et exécutez nvidia-smi dans le conteneur :
# 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
Résultat attendu : le résultat doit indiquer une utilisation de la VRAM physique correspondant à votre paramètre GPU_MEMORY_UTILIZATION. Par exemple, sur une station de travail équipée d'une carte NVIDIA RTX PRO 6000 (environ 96 Go de VRAM) exécutant google/gemma-4-31B-it avec GPU_MEMORY_UTILIZATION=0.95, vous devriez voir environ 95 800 Mio alloués à VLLM::EngineCore :
+-----------------------------------------------------------------------------------------+
| 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 |
+-----------------------------------------+------------------------+----------------------+
Vérifier l'allocation du cache KV dans les journaux
Vous pouvez également consulter les journaux d'allocation interne vLLM pour vérifier la taille du cache KV et la simultanéité des jetons :
kubectl logs ${VLLM_POD_NAME} -n ${NAMESPACE_NAME} | grep -E "Available KV cache|GPU KV cache size"
Résultat attendu :
(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
Cela confirme que 56,53 Gio de VRAM sont réservés au cache KV de contexte, ce qui permet un grand nombre de jetons simultanés.
Vérifier le déploiement de l'interface utilisateur Gradio
Une fois le pod Gradio en cours d'exécution, vous pouvez accéder à l'UI en établissant un tunnel de redirection de port.
Surveiller l'état du pod Gradio
Assurez-vous que le pod Gradio est en cours d'exécution :
kubectl get pods -n ${NAMESPACE_NAME} -l app=gradio
Résultat attendu :
NAME READY STATUS RESTARTS AGE
gradio-deployment-yyyyyyyy-yyyyy 1/1 Running 0 1m
Établir un tunnel de transfert de port vers Gradio
Transférez le port 8080 du service Gradio vers votre port local 7860 :
kubectl port-forward service/gradio-service 7860:8080 -n ${NAMESPACE_NAME}
Gardez ce terminal ouvert ou exécutez-le en arrière-plan :
kubectl port-forward service/gradio-service 7860:8080 -n ${NAMESPACE_NAME} > pf_gradio.log 2>&1 & sleep 3
Accéder à l'UI Web
- Si vous exécutez l'application sur une station de travail locale : ouvrez votre navigateur et accédez directement à
http://localhost:7860. - Si vous exécutez le code dans Cloud Shell : utilisez le bouton Aperçu sur le Web, sélectionnez Modifier le port, saisissez
7860, puis cliquez sur Modifier et prévisualiser.
L'interface du chatbot Gradio devrait s'afficher. Vous pouvez saisir un message pour interagir avec le modèle Gemma. Le pod Gradio acheminera la requête en interne vers le point de terminaison vllm-service.
Nettoyer les tunnels
Pour arrêter le tunnel de transfert de port :
pkill -f "port-forward service/gradio-service"
Validation de la surveillance
Une fois vLLM déployé et la ressource PodMonitoring appliquée, vous pouvez vérifier que les métriques sont ingérées dans Cloud Monitoring.
Vérifier l'état de PodMonitoring
Assurez-vous que la ressource PodMonitoring est créée et active :
kubectl get podmonitoring -n ${NAMESPACE_NAME}
Vérifier l'ingestion des métriques à l'aide de la console Google Cloud
Vous pouvez vérifier que les métriques sont ingérées à l'aide de la console Google Cloud (explorateur de métriques) :
- Ouvrez l'explorateur de métriques dans la console Google Cloud :
- Accédez à
https://console.cloud.google.com/monitoring/metrics-explorer(assurez-vous de sélectionner votre projet${GCP_PROJECT_ID}).
- Accédez à
- Dans le menu déroulant Sélectionner une métrique, recherchez et sélectionnez :
prometheus.googleapis.com/vllm:num_requests_running/gaugepour vérifier les métriques vLLM.prometheus.googleapis.com/DCGM_FI_DEV_GPU_UTIL/gaugepour vérifier les métriques d'utilisation du GPU.
- Observez le graphique pour vérifier que les points de données sont tracés activement.
Validation de la journalisation
Une fois la charge de travail en cours d'exécution, vous pouvez vérifier que les journaux sont exportés vers Cloud Logging.
Vérifier l'ingestion des journaux vLLM
Vérifiez que les journaux du conteneur vLLM sont exportés vers Cloud Logging :
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}
Vérifier l'ingestion des journaux de l'exportateur de GPU
Vérifiez que les journaux du conteneur de l'exportateur de GPU sont exportés vers Cloud Logging :
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}
Vérifier les journaux à l'aide de la console Google Cloud (explorateur de journaux)
Vous pouvez également vérifier l'ingestion des journaux à l'aide de la console Google Cloud :
- Ouvrez l'explorateur de journaux dans la console Google Cloud :
- Accédez à
https://console.cloud.google.com/logs/query(assurez-vous de sélectionner votre projet${GCP_PROJECT_ID}).
- Accédez à
Dans le champ Requête, saisissez la requête suivante pour afficher les journaux vLLM :
resource.type="k8s_container" resource.labels.namespace_name="<NAMESPACE_NAME>" resource.labels.container_name="vllm-container"(Remplacez
<NAMESPACE_NAME>par votre espace de noms réel, par exempleyour-custom-namespace.)Cliquez sur Exécuter la requête. Les entrées de journal du conteneur vLLM devraient s'afficher.
Pour vérifier les journaux de l'exportateur de GPU, exécutez la requête suivante :
resource.type="k8s_container" resource.labels.namespace_name="gpu-operator" resource.labels.container_name="nvidia-dcgm-exporter"