Exécuter l'inférence du modèle Gemma 4 sur Cloud Run avec le GPU RTX 6000 Pro et vLLM

1. Introduction

Présentation

Points abordés

  • Déployer un modèle Gemma 4 sur un GPU Cloud Run RTX 6000 Pro
  • Utiliser vLLM et Run:ai Model Streamer pour une inférence plus rapide et un démarrage d'instance plus court

2. Préparation

Définissez les variables d'environnement qui seront utilisées tout au long de cet atelier de programmation :

# Model name on HuggingFace Hub
export MODEL_NAME="google/gemma-4-31B-it"

# Cloud Run Service name
export SERVICE_NAME=gemma-rtx-vllm-codelab

# Cloud Project and Region for Cloud Run
export GOOGLE_CLOUD_PROJECT=<YOUR_PROJECT_ID> # Change to your Project Id
export GOOGLE_CLOUD_REGION=us-central1 # or europe-west4

# Optional HuggingFace User Access Token for accessing model weights 
# (https://huggingface.co/docs/hub/en/security-tokens),
# if you are loading a private model.
export HF_TOKEN=""

# Service account for Cloud Run service
export SERVICE_ACCOUNT="vllm-service-sa"
export SERVICE_ACCOUNT_EMAIL="${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com"

# GCS Bucket for the model cache.
export MODEL_CACHE_BUCKET="${GOOGLE_CLOUD_PROJECT}-${GOOGLE_CLOUD_REGION}-hf-model-cache"
# Model cache location in GSC bucket
export GCS_MODEL_LOCATION="gs://${MODEL_CACHE_BUCKET}/model-cache/${MODEL_NAME}"

# VPC Network for Direct VPC Egress
export VPC_NETWORK="vllm-${GOOGLE_CLOUD_REGION}-net"
export VPC_SUBNET="vllm-${GOOGLE_CLOUD_REGION}-subnet"
export SUBNET_RANGE="10.8.0.0/26"

# set the project
gcloud config set project $GOOGLE_CLOUD_PROJECT
gcloud config set run/region $GOOGLE_CLOUD_REGION

Activer les API nécessaires pour cet atelier de programmation

gcloud services enable --project "${GOOGLE_CLOUD_PROJECT}" \
    run.googleapis.com \
    cloudbuild.googleapis.com \
    artifactregistry.googleapis.com \
    iam.googleapis.com \
    compute.googleapis.com \
    vpcaccess.googleapis.com \
    storage.googleapis.com

3. Créer un compte de service

Si vous ne spécifiez pas de compte de service lors de la création du service ou du job Cloud Run, Cloud Run utilise le compte de service Compute Engine par défaut. Nous vous recommandons d'utiliser un compte de service distinct pour le service Cloud Run afin d'éviter d'exécuter le service avec des autorisations excessives.

Créer un compte de service pour le service Cloud Run

gcloud iam service-accounts create ${SERVICE_ACCOUNT} \
  --project "${GOOGLE_CLOUD_PROJECT}" \
  --display-name "vLLM Service Account"

4. Configurer Cloud Storage

Créez un bucket Cloud Storage pour stocker les pondérations du modèle. Cela vous permettra d'utiliser la sortie VPC directe pour télécharger plus rapidement les pondérations du modèle chaque fois que Cloud Run démarre une instance de service.

Combinée à la fonctionnalité Run:ai Model Streamer de vLLM, elle réduit considérablement le temps de chargement du modèle.

Créer un bucket

Assurez-vous qu'il s'agit d'un bucket à une seule région colocalisé avec le service Cloud Run.

gcloud storage buckets create "gs://${MODEL_CACHE_BUCKET}" \
    --uniform-bucket-level-access --public-access-prevention \
    --project "${GOOGLE_CLOUD_PROJECT}" --location "${GOOGLE_CLOUD_REGION}"

5. Récupérer et mettre en cache les pondérations du modèle

Ensuite, téléchargez le modèle Gemma 4 dans votre bucket Cloud Storage.

Les pondérations des modèles représentent des dizaines de gigaoctets, et il peut être impossible de les télécharger sur votre machine locale ou dans Cloud Shell.

Nous utilisons plutôt Cloud Build avec suffisamment de stockage pour contenir les pondérations du modèle.

gcloud builds submit --project="${GOOGLE_CLOUD_PROJECT}" --region="${GOOGLE_CLOUD_REGION}" --no-source \
    --substitutions="_MODEL_NAME=${MODEL_NAME},_HF_TOKEN=${HF_TOKEN},_GCS_MODEL_LOCATION=${GCS_MODEL_LOCATION}" \
    --config=/dev/stdin <<'EOF'
steps:
- name: 'gcr.io/google.com/cloudsdktool/google-cloud-cli:slim'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    set -e
    pip3 install --root-user-action=ignore --break-system-packages huggingface_hub[cli]
    echo "Downloading the model..."
    if [[ "$_HF_TOKEN" != "" ]]; then
      hf download "$_MODEL_NAME" --token $_HF_TOKEN --local-dir "./model-cache/$_MODEL_NAME"
    else
      hf download "$_MODEL_NAME" --local-dir "./model-cache/$_MODEL_NAME"
    fi
    echo "Uploading the model..."
    gcloud storage cp -r "./model-cache/$_MODEL_NAME" "$_GCS_MODEL_LOCATION"
options:
  machineType: 'E2_HIGHCPU_32'
  diskSizeGb: 500
EOF

6. Configurer la mise en réseau pour la sortie VPC directe

La configuration de la sortie VPC directe nécessite la création d'un réseau et d'un sous-réseau avec l'accès privé à Google activé.

Cela permet aux services Cloud Run de se connecter à l'ensemble des adresses IP externes utilisées par les API et services Google, y compris Cloud Storage.

Créer un réseau

gcloud compute networks create "$VPC_NETWORK" \
        --subnet-mode=custom \
        --bgp-routing-mode=regional \
        --project "$GOOGLE_CLOUD_PROJECT"

Créer un sous-réseau

gcloud compute networks subnets create "$VPC_SUBNET" \
        --network="$VPC_NETWORK" \
        --region="$GOOGLE_CLOUD_REGION" \
        --range="$SUBNET_RANGE" \
        --enable-private-ip-google-access \
        --project "$GOOGLE_CLOUD_PROJECT"

7. Configurer la stratégie d'accès au compte de service

Le compte de service Cloud Run a besoin d'autorisations pour accéder aux pondérations du modèle dans le bucket Storage que vous avez créé.

gcloud storage buckets add-iam-policy-binding "gs://${MODEL_CACHE_BUCKET}" \
    --member "serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
    --role "roles/storage.admin" \
    --project "${GOOGLE_CLOUD_PROJECT}"

8. Initialiser les variables de configuration

Définissez les variables pour le moteur d'inférence vLLM et le service Cloud Run.

# vLLM variables
export MAX_MODEL_LEN=32767      # 32767 to improve concurrency. Keep it empty to use model's maximim context length (256K)
export QUANTIZATION_TYPE="fp8"  # Model quantization for faster performance and lower memory usage.
export KV_CACHE_DTYPE="fp8"     # KV-cache quantization to save GPU memory.
export GPU_MEM_UTIL="0.95"      # Fraction of GPU memory to be used by the vLLM engine.
export TENSOR_PARALLEL_SIZE="1" # Partitioning model across GPUs (1 here as we have only 1 GPU).
export MAX_NUM_SEQS=8           # Max concurrent requests vLLM processes in one batch.

# Cloud Run variables
export CLOUD_RUN_CPU_NUM=20
export CLOUD_RUN_MEMORY_GB=80
export CLOUD_RUN_MAX_INSTANCES=3
export CLOUD_RUN_CONCURRENCY=16

9. Déployer dans Cloud Run

Préparer la ligne de commande du conteneur vLLM

vLLM nécessite de nombreux paramètres pour exécuter des modèles volumineux rapidement et efficacement.

CONTAINER_ARGS=(
    "vllm"
    "serve"
    "${GCS_MODEL_LOCATION}"
    "--served-model-name" "${MODEL_NAME}"
    "--enable-log-requests"
    "--enable-chunked-prefill"
    "--enable-prefix-caching"
    "--generation-config" "auto"
    "--enable-auto-tool-choice"
    "--tool-call-parser" "gemma4"
    "--reasoning-parser" "gemma4"
    "--dtype" "bfloat16"
    "--quantization" "${QUANTIZATION_TYPE}"
    "--kv-cache-dtype" "${KV_CACHE_DTYPE}"
    "--max-num-seqs" "${MAX_NUM_SEQS}"
    "--limit-mm-per-prompt" '{"image":4,"video":2}'
    "--gpu-memory-utilization" "${GPU_MEM_UTIL}"
    "--tensor-parallel-size" "${TENSOR_PARALLEL_SIZE}"
    "--load-format" "runai_streamer"
    "--port" "8080"
    "--host" "0.0.0.0"
)

if [[ "${MAX_MODEL_LEN}" != "" ]]; then
    CONTAINER_ARGS+=("--max-model-len" "${MAX_MODEL_LEN}")
fi

export CONTAINER_ARGS_STR="${CONTAINER_ARGS[*]}"

Déployer le service Cloud Run

Exécutez la commande suivante pour déployer le service Cloud Run.

gcloud beta run deploy "${SERVICE_NAME}" \
    --image="us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:gemma4" \
    --project "${GOOGLE_CLOUD_PROJECT}" \
    --region "${GOOGLE_CLOUD_REGION}" \
    --service-account "${SERVICE_ACCOUNT_EMAIL}" \
    --execution-environment gen2 \
    --no-allow-unauthenticated \
    --cpu="${CLOUD_RUN_CPU_NUM}" \
    --memory="${CLOUD_RUN_MEMORY_GB}Gi" \
    --gpu=1 \
    --gpu-type=nvidia-rtx-pro-6000 \
    --no-gpu-zonal-redundancy \
    --no-cpu-throttling \
    --max-instances ${CLOUD_RUN_MAX_INSTANCES} \
    --concurrency ${CLOUD_RUN_CONCURRENCY} \
    --network ${VPC_NETWORK} \
    --subnet ${VPC_SUBNET} \
    --vpc-egress all-traffic \
    --set-env-vars "MODEL_NAME=${MODEL_NAME}" \
    --set-env-vars "GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT}" \
    --set-env-vars "GOOGLE_CLOUD_REGION=${GOOGLE_CLOUD_REGION}" \
    --startup-probe tcpSocket.port=8080,initialDelaySeconds=240,failureThreshold=1,timeoutSeconds=240,periodSeconds=240 \
    --command "bash" \
    --args="^;^-c;${CONTAINER_ARGS_STR}"

10. Tester le service

Une fois déployé, vous pouvez interagir avec votre modèle Gemma 4 à l'aide de l'API compatible avec vLLM OpenAI.

Obtenir l'URL du service

Récupérez l'URL de votre service Cloud Run déployé.

SERVICE_URL=$(gcloud run services describe $SERVICE_NAME --project "${GOOGLE_CLOUD_PROJECT}" --region "${GOOGLE_CLOUD_REGION}" --format 'value(status.url)')
echo "Service URL: $SERVICE_URL"

Exécuter une inférence

Envoyez une requête au modèle à l'aide de curl.

curl -s "$SERVICE_URL/v1/chat/completions" \
  -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "'"${MODEL_NAME}"'",
  "messages": [
    {"role": "user", "content": "Why is the sky blue?"}
  ],
  "chat_template_kwargs": {
    "enable_thinking": true
  },
  "skip_special_tokens": false
}' | jq -r '.choices[0].message.content'

11. Félicitations !

Bravo ! Vous avez terminé cet atelier de programmation.

Nous vous recommandons de consulter la documentation Cloud Run.

Points abordés

  • Déployer un modèle Gemma 4 sur un GPU Cloud Run RTX 6000 Pro
  • Configurer la sortie VPC directe et le streaming de modèle vLLM avec Cloud Storage pour un démarrage plus rapide du service

12. Effectuer un nettoyage

Pour éviter que les ressources utilisées lors de ce tutoriel continuent d'être facturées sur votre compte Google Cloud, supprimez le projet ou les ressources individuelles.

Option 1 : Supprimer les ressources

Supprimer le service Cloud Run

gcloud run services delete $SERVICE_NAME \
      --project "${GOOGLE_CLOUD_PROJECT}" \
      --region "${GOOGLE_CLOUD_REGION}"
      --quiet

Supprimer le compte de service

gcloud iam service-accounts delete \
      ${SERVICE_ACCOUNT_EMAIL} \
      --project "${GOOGLE_CLOUD_PROJECT}" \
      --quiet

Supprimer le bucket Cloud Storage

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

Supprimer le réseau et le sous-réseau VPC

gcloud compute networks subnets delete $VPC_SUBNET \
    --region "${GOOGLE_CLOUD_REGION}" \
    --project "${GOOGLE_CLOUD_PROJECT}" \
    --quiet

gcloud compute networks delete $VPC_NETWORK \
    --project "${GOOGLE_CLOUD_PROJECT}" \
    --quiet

Option 2 : Supprimer le projet

Pour supprimer l'intégralité du projet, accédez à Gérer les ressources, sélectionnez le projet que vous avez créé à l'étape 2, puis choisissez Supprimer. Si vous supprimez le projet, vous devrez modifier les projets dans votre SDK Cloud. Vous pouvez afficher la liste de tous les projets disponibles en exécutant gcloud projects list.