Guide de l'utilisateur des modèles Gemma avec vLLM sur GDC sous air gap

Ce document fournit des instructions détaillées pour déployer des modèles de pondérations ouverts de Google DeepMind, en particulier la famille Gemma 4, dans des environnements Google Distributed Cloud (GDC) air gap. Il explique comment utiliser vLLM pour une diffusion à haut débit, en exploitant les fonctionnalités de la plate-forme GDC, y compris les ressources Kubernetes, Harbor et GPU. Sélectionnez le modèle et l'option GPU dans la section "Modèle". Toutes les autres étapes sont identiques pour tous les modèles.

Modèles compatibles

Modèle Dépôt Hugging Face Paramètres Licence Options de GPU
Gemma 4 E2B Instruct google/gemma-4-E2B-it 5,1 milliards (2 milliards effectifs) Conditions d'utilisation de Gemma 1 GPU (n'importe lequel)
Gemma 4 E4B Instruct google/gemma-4-E4B-it 8 milliards (4 milliards effectifs) Conditions d'utilisation de Gemma 1 GPU (n'importe lequel)
Gemma 4 12B Instruct google/gemma-4-12B-it 12B (dense) Conditions d'utilisation de Gemma 1 GPU (n'importe lequel)
Gemma 4 26B-A4B Instruct google/gemma-4-26B-A4B-it 25,8 milliards au total / 4 milliards actifs (Mixture of Experts) Conditions d'utilisation de Gemma 1 NVIDIA A100 80 Go
1 NVIDIA H100 94 Go
1 NVIDIA H200 141 Go ou B300 288 Go
Gemma 4 31B Instruct google/gemma-4-31B-it 31,3 milliards (dense) Conditions d'utilisation de Gemma 1 NVIDIA A100 80 Go
1 NVIDIA H100 94 Go
1 NVIDIA H200 141 Go ou B300 288 Go

Architecture

La solution consiste à déployer un backend de diffusion conteneurisé (vLLM) en tant que déploiement dans un cluster standard. Les pondérations du modèle sont stockées sur des volumes persistants, renseignés à partir de fichiers téléchargés localement et importés à l'aide d'un pod de chargement. Un Service Kubernetes de type LoadBalancer expose l'API backend, et les objets NetworkPolicy / ProjectNetworkPolicy sécurisent l'accès à celle-ci.

Avant de commencer

Suivez l'implémentation de référence des modèles Open Weights avec vLLM sur le poste de travail et assurez-vous d'avoir accès au répertoire ${HOME}/gdcag-solutions.

Identity and Access Management

Assurez-vous que les comptes, rôles et autorisations IAM nécessaires sont correctement configurés.

Rôles Utilisateur GDC sur l'organisation :

  • Facultatif : Administrateur de cluster standard (afficher les clusters depuis la console)

Utilisateur GDC sur le projet :

  • Administrateur de cluster standard (standard-cluster-admin)

Utilisateur GDC sur le cluster standard :

  • StandardClusterRoleBinding au StandardClusterRole cluster-admin (créé par un administrateur IAM du projet, consultez la section Identity and Access Management de l'implémentation de référence)

Station de travail

Sauf indication contraire, exécutez toutes les commandes de ce guide à partir d'un poste de travail disposant des outils requis et d'une connectivité à l'environnement et à Internet.

La configuration de l'environnement est divisée en plusieurs couches :

  • ${HOME}/gdcag-solutions/env.sh charge les paramètres de la plate-forme et du registre.
  • ${HOME}/gdcag-solutions/open-weight-models/vllm/env.sh ajoute les paramètres vLLM.

  • Ce guide de l'utilisateur ajoute env.d/model.sh (le modèle) et env.d/accelerator.sh (l'option de GPU et les paramètres d'exécution), que vous écrivez dans la section "Modèle", ainsi que env.d/model-common.sh (les valeurs qui en découlent).

  1. Créez la structure de répertoires du guide de l'utilisateur :

    mkdir -p ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d
    
  2. Créez le fichier de configuration de l'environnement du modèle commun. Il dérive chaque chemin d'accès et nom de ressource de GDCS_HF_MODEL, de sorte qu'il est identique pour tous les modèles :

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/model-common.sh && echo "Successfully created." || echo "Failed to create!"
    # Model (derived from env.d/model.sh)
    export GDCS_HF_DOWNLOAD_PATH="${GDCS_USER_GUIDE_HOME}/hf-models"
    export GDCS_HF_MODEL_LOWERCASE="${GDCS_HF_MODEL,,}"
    export GDCS_HF_MODEL_DOWNLOAD_DIR="${GDCS_HF_DOWNLOAD_PATH}/${GDCS_HF_MODEL_LOWERCASE}"
    export GDCS_HF_PV_MOUNT_PATH="/mnt/hf-model"
    
    GDCS_HF_MODEL_KUBERNETES="${GDCS_HF_MODEL_LOWERCASE//\//-}"
    export GDCS_HF_MODEL_KUBERNETES="${GDCS_HF_MODEL_KUBERNETES//./-}"
    
    # Workload
    export GDCS_WORKLOAD_NAMESPACE="vllm-gemma"
    export GDCS_WORKLOAD_NAME="${GDCS_HF_MODEL_KUBERNETES}"
    export GDCS_MODEL_LOADER_POD_NAME="loader-${GDCS_HF_MODEL_KUBERNETES}"
    EOF
    
  3. Créez le fichier de chargement de l'environnement du guide de l'utilisateur :

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.sh && echo "Successfully created." || echo "Failed to create!"
    source "${HOME}/gdcag-solutions/open-weight-models/vllm/env.sh"
    
    export GDCS_USER_GUIDE_HOME="${HOME}/gdcag-solutions/open-weight-models/vllm/gemma"
    echo "GDCS_USER_GUIDE_HOME=${GDCS_USER_GUIDE_HOME}"
    
    # Sourced in dependency order: the model selection, the accelerator and runtime settings, then the values derived from them
    source "${GDCS_USER_GUIDE_HOME}/env.d/model.sh"
    source "${GDCS_USER_GUIDE_HOME}/env.d/accelerator.sh"
    source "${GDCS_USER_GUIDE_HOME}/env.d/model-common.sh"
    echo "GDCS_HF_MODEL=${GDCS_HF_MODEL} (${GDCS_WORKLOAD_ACCELERATOR_COUNT} x ${GDCS_WORKLOAD_ACCELERATOR_TYPE:-unset})"
    EOF
    

Modèle

Sélectionnez le modèle et l'option de GPU qui correspondent aux nœuds GPU de votre cluster standard. GDC sous air gap propose les GPU suivants (voir Types de machines des nœuds de cluster). Le type de ressource d'accélérateur est le nom sous lequel les nœuds exposent le GPU à Kubernetes.

GPU Mémoire Types de machine Type de ressource d'accélérateur
NVIDIA A100 40 Go a2-highgpu-1g-gdc nvidia.com/gpu-pod-NVIDIA_A100_PCIE_40GB
NVIDIA A100 80 Go a2-ultragpu-1g-gdc, a2-ultragpu-2g-gdc nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE
NVIDIA H100 94 Go a3-highgpu-1g-gdc (Preview), a3-highgpu-2g-gdc (Preview), a3-highgpu-4g-gdc nvidia.com/gpu-pod-NVIDIA_H100_NVL
NVIDIA H200 141 Go a3-ultragpu-8g-gdc nvidia.com/gpu-pod-NVIDIA_H200
NVIDIA B300 288 Go a4-ultragpu-8g-gdc nvidia.com/gpu-pod-NVIDIA_B300_SXM6_AC

Chaque onglet liste les informations sur le modèle, la commande qui écrit le fichier d'environnement du modèle env.d/model.sh et les onglets imbriqués qui écrivent le fichier d'environnement de l'accélérateur env.d/accelerator.sh pour l'option de GPU choisie avec des types de ressources et des paramètres vLLM préremplis. Pour changer de modèle ou d'option de GPU ultérieurement, écrivez différents fichiers d'environnement, sourcez à nouveau l'environnement et répétez la section "Implémentation". Les charges de travail de plusieurs modèles peuvent s'exécuter côte à côte dans le même espace de noms, car chaque nom de ressource est dérivé du nom du modèle.

  1. Créez les fichiers d'environnement du modèle et de l'accélérateur pour le modèle et l'option de GPU que vous souhaitez déployer.

    Gemma 4 E2B Instruct

    Attribut Valeur
    Dépôt Hugging Face google/gemma-4-E2B-it
    Paramètres 5,1 milliards (2 milliards effectifs)
    Licence Conditions d'utilisation de Gemma
    Poids utilisés par vLLM Format Hugging Face (model-*.safetensors), environ 10,2 Go
    Longueur de contexte 128 000 jetons ; ce guide utilise --max-model-len 32768

    Créez le fichier d'environnement du modèle :

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/model.sh && echo "Successfully created." || echo "Failed to create!"
    # Model: Gemma 4 E2B Instruct
    export GDCS_HF_MODEL="google/gemma-4-E2B-it"
    export GDCS_HF_MODEL_REVISION="main"  # Hugging Face branch, tag, or commit to download
    export GDCS_HF_DOWNLOAD_EXCLUDE=""
    EOF
    

    Créez le fichier d'environnement de l'accélérateur pour votre option de GPU :

    NVIDIA A100 40 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA A100 40 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_A100_PCIE_40GB"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="60"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA A100 80 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA A100 80 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="60"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA H100 94 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA H100 94 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_H100_NVL"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="60"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA H200 141 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA H200 141 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_H200"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="60"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA B300 288 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA B300 288 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_B300_SXM6_AC"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="60"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    Gemma 4 E4B Instruct

    Attribut Valeur
    Dépôt Hugging Face google/gemma-4-E4B-it
    Paramètres 8 milliards (4 milliards effectifs)
    Licence Conditions d'utilisation de Gemma
    Poids utilisés par vLLM Format Hugging Face (model-*.safetensors), environ 16 Go
    Longueur de contexte 128 000 jetons ; ce guide utilise --max-model-len 32768

    Créez le fichier d'environnement du modèle :

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/model.sh && echo "Successfully created." || echo "Failed to create!"
    # Model: Gemma 4 E4B Instruct
    export GDCS_HF_MODEL="google/gemma-4-E4B-it"
    export GDCS_HF_MODEL_REVISION="main"  # Hugging Face branch, tag, or commit to download
    export GDCS_HF_DOWNLOAD_EXCLUDE=""
    EOF
    

    Créez le fichier d'environnement de l'accélérateur pour votre option de GPU :

    NVIDIA A100 40 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA A100 40 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_A100_PCIE_40GB"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="120"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA A100 80 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA A100 80 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="120"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA H100 94 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA H100 94 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_H100_NVL"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="120"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA H200 141 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA H200 141 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_H200"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="120"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA B300 288 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA B300 288 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_B300_SXM6_AC"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="120"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    Gemma 4 12B Instruct

    Attribut Valeur
    Dépôt Hugging Face google/gemma-4-12B-it
    Paramètres 12B (dense)
    Licence Conditions d'utilisation de Gemma
    Poids utilisés par vLLM Format Hugging Face (model-*.safetensors), environ 23,9 Go
    Longueur de contexte 256 000 jetons ; ce guide utilise --max-model-len 32768

    Créez le fichier d'environnement du modèle :

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/model.sh && echo "Successfully created." || echo "Failed to create!"
    # Model: Gemma 4 12B Instruct
    export GDCS_HF_MODEL="google/gemma-4-12B-it"
    export GDCS_HF_MODEL_REVISION="main"  # Hugging Face branch, tag, or commit to download
    export GDCS_HF_DOWNLOAD_EXCLUDE=""
    EOF
    

    Créez le fichier d'environnement de l'accélérateur pour votre option de GPU :

    NVIDIA A100 40 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA A100 40 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_A100_PCIE_40GB"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="180"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA A100 80 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA A100 80 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="180"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA H100 94 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA H100 94 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_H100_NVL"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="180"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA H200 141 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA H200 141 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_H200"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="180"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA B300 288 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA B300 288 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_B300_SXM6_AC"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="180"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    Gemma 4 26B-A4B Instruct

    Attribut Valeur
    Dépôt Hugging Face google/gemma-4-26B-A4B-it
    Paramètres 25,8 milliards au total / 4 milliards actifs (Mixture of Experts)
    Licence Conditions d'utilisation de Gemma
    Poids utilisés par vLLM Format Hugging Face (model-*.safetensors), environ 51,6 Go
    Longueur de contexte 256 000 jetons ; ce guide utilise --max-model-len 32768

    Créez le fichier d'environnement du modèle :

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/model.sh && echo "Successfully created." || echo "Failed to create!"
    # Model: Gemma 4 26B-A4B Instruct
    export GDCS_HF_MODEL="google/gemma-4-26B-A4B-it"
    export GDCS_HF_MODEL_REVISION="main"  # Hugging Face branch, tag, or commit to download
    export GDCS_HF_DOWNLOAD_EXCLUDE=""
    EOF
    

    Créez le fichier d'environnement de l'accélérateur pour votre option de GPU :

    NVIDIA A100 80 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA A100 80 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="300"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA H100 94 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA H100 94 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_H100_NVL"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="300"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA H200 141 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA H200 141 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_H200"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="300"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA B300 288 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA B300 288 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_B300_SXM6_AC"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="300"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    Gemma 4 31B Instruct

    Attribut Valeur
    Dépôt Hugging Face google/gemma-4-31B-it
    Paramètres 31,3 milliards (dense)
    Licence Conditions d'utilisation de Gemma
    Poids utilisés par vLLM Format Hugging Face (model-*.safetensors), environ 62,5 Go
    Longueur de contexte 256 000 jetons ; ce guide utilise --max-model-len 32768

    Créez le fichier d'environnement du modèle :

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/model.sh && echo "Successfully created." || echo "Failed to create!"
    # Model: Gemma 4 31B Instruct
    export GDCS_HF_MODEL="google/gemma-4-31B-it"
    export GDCS_HF_MODEL_REVISION="main"  # Hugging Face branch, tag, or commit to download
    export GDCS_HF_DOWNLOAD_EXCLUDE=""
    EOF
    

    Créez le fichier d'environnement de l'accélérateur pour votre option de GPU :

    NVIDIA A100 80 Go

    La diffusion sur un GPU de 80 Go laisse peu de mémoire pour le cache KV. Cette option définit donc --max-model-len 16384.

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA A100 80 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="16384"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="360"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA H100 94 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA H100 94 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_H100_NVL"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="360"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA H200 141 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA H200 141 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_H200"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="360"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    

    NVIDIA B300 288 Go

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d/accelerator.sh && echo "Successfully created." || echo "Failed to create!"
    # Accelerator: NVIDIA B300 288 GB
    export GDCS_WORKLOAD_ACCELERATOR_TYPE="nvidia.com/gpu-pod-NVIDIA_B300_SXM6_AC"
    export GDCS_WORKLOAD_ACCELERATOR_COUNT="1"
    
    # vLLM
    export GDCS_VLLM_MAX_MODEL_LEN="32768"
    export GDCS_VLLM_EXTRA_ARGS=""
    export GDCS_VLLM_STARTUP_FAILURE_THRESHOLD="360"
    export GDCS_VLLM_TEST_MAX_TOKENS="128"
    EOF
    
  2. Sourcez le fichier d'environnement :

    source ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.sh
    

    Le résultat ressemble à ce qui suit :

    GDCS_ROOT_HOME=HOME_DIRECTORY_PATH/gdcag-solutions
    GDCS_IMPLEMENTATION_HOME=HOME_DIRECTORY_PATH/gdcag-solutions/open-weight-models/vllm
    GDCS_USER_GUIDE_HOME=HOME_DIRECTORY_PATH/gdcag-solutions/open-weight-models/vllm/gemma
    GDCS_HF_MODEL=HUGGING_FACE_REPOSITORY (ACCELERATOR_COUNT x ACCELERATOR_RESOURCE_TYPE)
    

Cluster

  1. Configurez gdcloud :

    gdcloud config set core/account "default-user"
    gdcloud config set core/organization_console_url "${GDC_ZONAL_CONSOLE_URL}"
    gdcloud config set core/project "${GDC_PROJECT}"
    gdcloud config set core/zone "${GDC_ZONE}"
    
  2. Authentifiez-vous auprès de l'environnement GDC :

    gdcloud auth login
    
  3. Récupérez les identifiants du cluster :

    gdcloud clusters get-credentials "${GDC_STANDARD_CLUSTER_NAME}" \
    --project="${GDC_PROJECT}" \
    --standard \
    --zone="${GDC_ZONE}"
    
  4. Vérifiez la connectivité au cluster :

    kubectl get nodes -L node.cluster.private.gdc.goog/machine-class
    
  5. Vérifiez que le type de ressource d'accélérateur du fichier d'environnement de l'accélérateur est disponible dans le cluster. La commande liste les types de ressources d'accélérateur exposés par les nœuds (le nom dépend du modèle de GPU installé ; il est vide sur les clusters sans nœuds GPU) et la valeur configurée :

    kubectl get nodes --output=json | jq -r '[.items[].status.allocatable | keys[] | select(startswith("nvidia.com/"))] | unique[]'
    echo "GDCS_WORKLOAD_ACCELERATOR_TYPE=${GDCS_WORKLOAD_ACCELERATOR_TYPE}"
    

Implémentation

Espace de noms

  1. Créez l'espace de noms :

    kubectl create namespace "${GDCS_WORKLOAD_NAMESPACE}" \
    --dry-run=client \
    --output=yaml | kubectl apply -f -
    
  2. Ajoutez le imagePullSecret :

    kubectl create secret docker-registry "${GDCS_HARBOR_K8S_PULL_SECRET}" \
    --dry-run=client \
    --from-file=.dockerconfigjson=${GDCS_HARBOR_K8S_DOCKER_CONFIG}/config.json \
    --namespace="${GDCS_WORKLOAD_NAMESPACE}" \
    --output=yaml | kubectl apply -f -
    

Pondérations de modèle

  1. Téléchargez les pondérations du modèle (uniquement les fichiers dont vLLM a besoin pour le modèle sélectionné, GDCS_HF_DOWNLOAD_EXCLUDE ignore le reste) et supprimez le répertoire .cache :

    EXCLUDE_ARGS=()
    if [[ -n "${GDCS_HF_DOWNLOAD_EXCLUDE:-}" ]]; then
      read -r -a EXCLUDE_PATTERNS <<< "${GDCS_HF_DOWNLOAD_EXCLUDE}"
      EXCLUDE_ARGS=(--exclude "${EXCLUDE_PATTERNS[@]}")
    fi
    hf download "${GDCS_HF_MODEL}" --revision "${GDCS_HF_MODEL_REVISION}" --local-dir "${GDCS_HF_MODEL_DOWNLOAD_DIR}" "${EXCLUDE_ARGS[@]}" && \
    rm -rf "${GDCS_HF_MODEL_DOWNLOAD_DIR}/.cache"
    
  2. Calculez la taille de PersistentVolumeClaim requise à partir des pondérations du modèle téléchargé avec une surcharge de 25 % (arrondie au Gio entier supérieur) :

    MODEL_KIB=$(du -sk "${GDCS_HF_MODEL_DOWNLOAD_DIR}" | awk '{print $1}')
    export GDCS_MODEL_PVC_SIZE="$(( (MODEL_KIB * 125 / 100 + 1048575) / 1048576 ))Gi"
    echo "GDCS_MODEL_PVC_SIZE=${GDCS_MODEL_PVC_SIZE}"
    
  3. Créez le fichier manifeste du PersistentVolumeClaim ReadWriteOnce pour les pondérations du modèle :

    cat <<EOF > "${GDCS_USER_GUIDE_HOME}/${GDCS_WORKLOAD_NAME}-rwo-pvc.yaml"
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: ${GDCS_WORKLOAD_NAME}-rwo
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: ${GDCS_MODEL_PVC_SIZE}
      storageClassName: standard-rwo
      volumeMode: Filesystem
    EOF
    
  4. Appliquez le fichier manifeste pour le PersistentVolumeClaim des pondérations du modèle :

    kubectl apply \
    --filename="${GDCS_USER_GUIDE_HOME}/${GDCS_WORKLOAD_NAME}-rwo-pvc.yaml" \
    --namespace="${GDCS_WORKLOAD_NAMESPACE}"
    
  5. Attendez que PersistentVolumeClaim lie et affiche les valeurs dont l'opérateur d'infrastructure a besoin pour ajuster la règle de qualité de service (QoS) des E/S :

    kubectl wait \
    --for=jsonpath='{.status.phase}'=Bound \
    "pvc/${GDCS_WORKLOAD_NAME}-rwo" \
    --namespace="${GDCS_WORKLOAD_NAMESPACE}" \
    --timeout=120s
    BACKING_PVC=$(kubectl get pvc "${GDCS_WORKLOAD_NAME}-rwo" \
    --namespace="${GDCS_WORKLOAD_NAMESPACE}" \
    --output=jsonpath='{.spec.volumeName}')
    echo "BACKING_PVC=${BACKING_PVC} ORG=${GDC_ORG}"
    
  6. Si performance-rwo n'est pas disponible sur votre cluster, demandez à votre opérateur d'infrastructure d'appliquer la règle de QoS hautes performances (system-performance-<ORG>-admin, 30 IOPS par Gio avec un seuil minimal de 6 148 IOPS) au volume qui sauvegarde le PersistentVolumeClaim. Indiquez les valeurs BACKING_PVC et ORG affichées à l'étape précédente. L'opérateur d'infrastructure applique la règle comme décrit dans FILE-R0097. Elle prend effet sur le volume actif, ce qui vous permet de passer aux étapes suivantes.

  7. Créez le fichier manifeste pour le pod du chargeur de modèle :

    cat <<EOF > "${GDCS_USER_GUIDE_HOME}/${GDCS_MODEL_LOADER_POD_NAME}-pod.yaml"
    apiVersion: v1
    kind: Pod
    metadata:
      name: ${GDCS_MODEL_LOADER_POD_NAME}
    spec:
      containers:
        - name: uploader
          image: ${GDCS_HARBOR_PROJECT_URI}/library/busybox:${GDCS_BUSYBOX_IMAGE_TAG}
          command: ["sleep", "infinity"]
          volumeMounts:
            - name: model-data
              mountPath: ${GDCS_HF_PV_MOUNT_PATH}
      imagePullSecrets:
        - name: ${GDCS_HARBOR_K8S_PULL_SECRET}
      volumes:
        - name: model-data
          persistentVolumeClaim:
            claimName: ${GDCS_WORKLOAD_NAME}-rwo
    EOF
    
  8. Appliquez le fichier manifeste pour le pod du chargeur de modèle :

    kubectl apply \
    --filename="${GDCS_USER_GUIDE_HOME}/${GDCS_MODEL_LOADER_POD_NAME}-pod.yaml" \
    --namespace="${GDCS_WORKLOAD_NAMESPACE}"
    
  9. Attendez que le pod du chargeur de modèle soit en cours d'exécution :

    watch --color --interval 5 --no-title \
    "kubectl get pod/${GDCS_MODEL_LOADER_POD_NAME} \
    --namespace=${GDCS_WORKLOAD_NAMESPACE} | GREP_COLORS='mt=01;92' grep -E --color=always -e '^' -e 'Running'"
    
  10. Importez les pondérations du modèle dans PersistentVolume (le script ignore les fichiers qui existent déjà avec la même taille, il peut donc être réexécuté) :

    export LOCAL_MODEL_DIR="${GDCS_HF_MODEL_DOWNLOAD_DIR}"
    export REMOTE_MODEL_DIR="${GDCS_HF_PV_MOUNT_PATH}/${GDCS_HF_MODEL_LOWERCASE}"
    export REMOTE_MOUNT_DIR="${GDCS_HF_PV_MOUNT_PATH}"
    
    ${GDCS_IMPLEMENTATION_HOME}/model_weight_upload.sh
    
  11. Supprimez le pod du chargeur de modèle :

    kubectl delete pod/${GDCS_MODEL_LOADER_POD_NAME} \
    --namespace="${GDCS_WORKLOAD_NAMESPACE}"
    

Serveur d'inférence

  1. Créez le fichier manifeste pour le déploiement vLLM. Le ConfigMap contient les paramètres vLLM spécifiques au modèle de l'environnement. Le fichier manifeste est donc le même pour chaque modèle et option de GPU :

    cat <<EOF > "${GDCS_USER_GUIDE_HOME}/${GDCS_WORKLOAD_NAME}-deployment.yaml"
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ${GDCS_WORKLOAD_NAME}
    data:
      MAX_MODEL_LEN: "${GDCS_VLLM_MAX_MODEL_LEN}"
      MODEL: "${GDCS_HF_PV_MOUNT_PATH}/${GDCS_HF_MODEL_LOWERCASE}"
      PORT: "8000"
      TENSOR_PARALLEL_SIZE: "${GDCS_WORKLOAD_ACCELERATOR_COUNT}"
      VLLM_EXTRA_ARGS: "${GDCS_VLLM_EXTRA_ARGS}"
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: ${GDCS_WORKLOAD_NAME}
      labels:
        app: ${GDCS_WORKLOAD_NAME}
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ${GDCS_WORKLOAD_NAME}
      strategy:
        type: Recreate
      template:
        metadata:
          labels:
            app: ${GDCS_WORKLOAD_NAME}
        spec:
          containers:
            - command:
                - /bin/sh
                - -c
              args:
                - exec vllm serve "\$MODEL" --port="\$PORT" --tensor-parallel-size="\$TENSOR_PARALLEL_SIZE" --max-model-len="\$MAX_MODEL_LEN" \$VLLM_EXTRA_ARGS
              envFrom:
                - configMapRef:
                    name: ${GDCS_WORKLOAD_NAME}
              image: ${GDCS_HARBOR_PROJECT_URI}/vllm/vllm-openai:${GDCS_VLLM_IMAGE_TAG}-fips
              livenessProbe:
                failureThreshold: 3
                httpGet:
                  path: /health
                  port: 8000
                periodSeconds: 20
                timeoutSeconds: 5
              name: vllm
              ports:
                - containerPort: 8000
              readinessProbe:
                failureThreshold: 3
                httpGet:
                  path: /health
                  port: 8000
                periodSeconds: 10
                successThreshold: 1
                timeoutSeconds: 5
              resources:
                limits:
                  ${GDCS_WORKLOAD_ACCELERATOR_TYPE}: "${GDCS_WORKLOAD_ACCELERATOR_COUNT}"
                requests:
                  ${GDCS_WORKLOAD_ACCELERATOR_TYPE}: "${GDCS_WORKLOAD_ACCELERATOR_COUNT}"
              startupProbe:
                httpGet:
                  path: /health
                  port: 8000
                failureThreshold: ${GDCS_VLLM_STARTUP_FAILURE_THRESHOLD}
                periodSeconds: 10
                timeoutSeconds: 5
              volumeMounts:
                - name: model-weights
                  mountPath: ${GDCS_HF_PV_MOUNT_PATH}
                - name: shm
                  mountPath: /dev/shm
          securityContext:
            seLinuxOptions:
              type: spc_t
          imagePullSecrets:
            - name: ${GDCS_HARBOR_K8S_PULL_SECRET}
          volumes:
            - name: model-weights
              persistentVolumeClaim:
                claimName: ${GDCS_WORKLOAD_NAME}-rwo
            - name: shm
              emptyDir:
                medium: Memory
                sizeLimit: "8Gi"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: ${GDCS_WORKLOAD_NAME}
    spec:
      ports:
        - name: vllm-http
          port: 80
          protocol: TCP
          targetPort: 8000
      selector:
        app: ${GDCS_WORKLOAD_NAME}
      type: LoadBalancer
    EOF
    
  2. Appliquez le fichier manifeste pour le déploiement vLLM :

    kubectl apply \
    --filename="${GDCS_USER_GUIDE_HOME}/${GDCS_WORKLOAD_NAME}-deployment.yaml" \
    --namespace="${GDCS_WORKLOAD_NAMESPACE}"
    
  3. Créez le fichier manifeste pour le NetworkPolicy vLLM :

    cat << EOF > "${GDCS_USER_GUIDE_HOME}/vllm-networkpolicy.yaml" && echo "Successfully created." || echo "Failed to create!"
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-vllm-ingress
      namespace: ${GDCS_WORKLOAD_NAMESPACE}
    spec:
      ingress:
      - from:
        - ipBlock:
            cidr: 0.0.0.0/0
        - namespaceSelector: {}
        ports:
        - port: 8000
          protocol: TCP
      podSelector: {}
      policyTypes:
      - Ingress
    EOF
    
  4. Appliquez le fichier manifeste pour le NetworkPolicy vLLM :

    kubectl apply \
    --filename="${GDCS_USER_GUIDE_HOME}/vllm-networkpolicy.yaml"
    
  1. Attendez que le pod soit en cours d'exécution :

    watch --color --interval 5 --no-title \
    "kubectl get pods --selector=app=${GDCS_WORKLOAD_NAME} \
    --namespace=${GDCS_WORKLOAD_NAMESPACE} | GREP_COLORS='mt=01;92' grep -E --color=always -e '^' -e 'Running'"
    
  2. Attendez que le déploiement soit prêt :

    watch --color --interval 5 --no-title \
    "kubectl get deployment/${GDCS_WORKLOAD_NAME} \
    --namespace=${GDCS_WORKLOAD_NAMESPACE} | GREP_COLORS='mt=01;92' grep -E --color=always -e '^' -e '1/1     1            1'"
    
  3. Facultatif : Diffusez les journaux du conteneur pour surveiller la progression du démarrage :

    kubectl logs deployment/${GDCS_WORKLOAD_NAME} \
    --follow \
    --namespace="${GDCS_WORKLOAD_NAMESPACE}"
    

Validation

  1. Récupérez l'adresse IP de l'équilibreur de charge pour vLLM :

    export VLLM_LB_IP=$(kubectl get service/${GDCS_WORKLOAD_NAME} --namespace="${GDCS_WORKLOAD_NAMESPACE}" --output=jsonpath='{.status.loadBalancer.ingress[*].ip}')
    echo "VLLM_LB_IP=${VLLM_LB_IP}"
    
  2. Envoyez une requête de test à vLLM. La valeur max_tokens est GDCS_VLLM_TEST_MAX_TOKENS de env.d/accelerator.sh :

    curl http://${VLLM_LB_IP}/v1/models
    
    curl http://${VLLM_LB_IP}/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d '{
      "model": "'${GDCS_HF_PV_MOUNT_PATH}/${GDCS_HF_MODEL_LOWERCASE}'",
      "messages": [
        {"role": "user", "content": "Explain Google Distributed Cloud air-gapped briefly."}
      ],
      "max_tokens": '${GDCS_VLLM_TEST_MAX_TOKENS}'
    }'
    
  3. Si l'adresse IP de l'équilibreur de charge n'est pas accessible depuis le poste de travail, par exemple parce qu'aucun ProjectNetworkPolicy ne l'accepte encore, envoyez les requêtes via le transfert de port :

    kubectl port-forward service/${GDCS_WORKLOAD_NAME} \
    --namespace="${GDCS_WORKLOAD_NAMESPACE}" 8000:80 &
    PF_PID=$!
    
    sleep 1
    
    curl http://127.0.0.1:8000/v1/models
    
    kill ${PF_PID}