Guía del usuario de modelos de Gemma con vLLM en GDC aislado

En este documento, se proporcionan instrucciones paso a paso para implementar modelos de pesos abiertos de Google DeepMind, específicamente la familia Gemma 4, en entornos aislados de Google Distributed Cloud (GDC). Se explica cómo usar vLLM para la entrega de alta capacidad de procesamiento, con las capacidades de la plataforma de GDC, incluidos los recursos de Kubernetes, Harbor y GPU. Selecciona el modelo y la opción de GPU en la sección Modelo. Todos los demás pasos son iguales para todos los modelos.

Modelos compatibles

Modelo Repositorio de Hugging Face Parámetros Licencia Opciones de GPU
Gemma 4 E2B Instruct google/gemma-4-E2B-it 5,100 millones (2,000 millones efectivos) Condiciones de Uso de Gemma 1 GPU de cualquier tipo
Gemma 4 E4B Instruct google/gemma-4-E4B-it 8,000 millones (4,000 millones efectivos) Condiciones de Uso de Gemma 1 GPU de cualquier tipo
Gemma 4 12B Instruct google/gemma-4-12B-it 12,000 millones (denso) Condiciones de Uso de Gemma 1 GPU de cualquier tipo
Gemma 4 26B-A4B Instruct google/gemma-4-26B-A4B-it 25,800 millones en total/4,000 millones activos (mezcla de expertos) Condiciones de Uso de Gemma 1 NVIDIA A100 de 80 GB
1 NVIDIA H100 de 94 GB
1 NVIDIA H200 de 141 GB o B300 de 288 GB
Gemma 4 31B Instruct google/gemma-4-31B-it 31.3B (denso) Condiciones de Uso de Gemma 1 NVIDIA A100 de 80 GB
1 NVIDIA H100 de 94 GB
1 NVIDIA H200 de 141 GB o B300 de 288 GB

Arquitectura

La solución implica implementar un backend de entrega alojado en contenedores (vLLM) como un Deployment dentro de un clúster estándar. Los pesos del modelo se almacenan en PersistentVolumes, que se completan a partir de archivos descargados de forma local y subidos con un Pod de cargador. Un Service de Kubernetes de tipo LoadBalancer expone la API de backend, y los objetos NetworkPolicy / ProjectNetworkPolicy protegen el acceso a ella.

Antes de comenzar

Completa la implementación de referencia de modelos de ponderación abierta con vLLM en la estación de trabajo y asegúrate de tener acceso al directorio ${HOME}/gdcag-solutions.

Identity and Access Management

Asegúrate de que las cuentas, los roles y los permisos de IAM necesarios estén configurados de forma correcta.

Roles de usuario de GDC en la organización:

  • Opcional: Administrador de clústeres estándar (visualiza clústeres desde la consola)

Roles de usuario de GDC en el proyecto:

  • Administrador de clústeres estándar (standard-cluster-admin)

Rol de usuario de GDC en el clúster estándar:

  • StandardClusterRoleBinding a la StandardClusterRole cluster-admin (creada por un administrador de proyectos de IAM, consulta la sección Identity and Access Management de la implementación de referencia)

Estación de trabajo

Ejecuta todos los comandos de esta guía desde una estación de trabajo con las herramientas y la conectividad necesarias para el entorno y para Internet, a menos que un paso indique lo contrario.

La configuración del entorno se divide en capas:

  • ${HOME}/gdcag-solutions/env.sh carga la configuración de la plataforma y del registro.
  • ${HOME}/gdcag-solutions/open-weight-models/vllm/env.sh agrega la configuración de vLLM.

  • En esta guía del usuario, se agregan env.d/model.sh (el modelo) y env.d/accelerator.sh (la opción de GPU y la configuración del entorno de ejecución), que escribes en la sección Modelo, y env.d/model-common.sh (los valores derivados de ellos).

  1. Crea la estructura de directorios de la guía del usuario:

    mkdir -p ${HOME}/gdcag-solutions/open-weight-models/vllm/gemma/env.d
    
  2. Crea el archivo de configuración del entorno del modelo común. Deriva cada ruta de acceso y nombre de recurso de GDCS_HF_MODEL, por lo que es igual para todos los modelos:

    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. Crea el archivo de carga del entorno de la guía del usuario:

    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
    

Modelo

Selecciona el modelo y la opción de GPU que coincidan con los nodos de GPU de tu clúster estándar. GDC aislado ofrece las siguientes GPUs (consulta Tipos de máquinas de nodos de clúster); el tipo de recurso de acelerador es el nombre con el que los nodos exponen la GPU a Kubernetes.

GPU Memoria Tipos de máquina Tipo de recurso de acelerador
NVIDIA A100 40 GB a2-highgpu-1g-gdc nvidia.com/gpu-pod-NVIDIA_A100_PCIE_40GB
NVIDIA A100 80 GB a2-ultragpu-1g-gdc, a2-ultragpu-2g-gdc nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE
NVIDIA H100 94 GB a3-highgpu-1g-gdc (versión preliminar), a3-highgpu-2g-gdc (versión preliminar) y a3-highgpu-4g-gdc nvidia.com/gpu-pod-NVIDIA_H100_NVL
NVIDIA H200 141 GB a3-ultragpu-8g-gdc nvidia.com/gpu-pod-NVIDIA_H200
NVIDIA B300 288 GB a4-ultragpu-8g-gdc nvidia.com/gpu-pod-NVIDIA_B300_SXM6_AC

En cada pestaña, se enumeran los datos del modelo, el comando que escribe el archivo de entorno del modelo env.d/model.sh y las pestañas anidadas que escriben el archivo de entorno del acelerador env.d/accelerator.sh para la opción de GPU que elegiste con tipos de recursos precompletados y parámetros de configuración de vLLM. Para cambiar de modelo o de opción de GPU más adelante, escribe diferentes archivos de entorno, vuelve a obtener el entorno y repite la sección Implementación. Las cargas de trabajo de varios modelos se pueden ejecutar en paralelo en el mismo espacio de nombres, ya que cada nombre de recurso se deriva del nombre del modelo.

  1. Crea los archivos de entorno del modelo y del acelerador para el modelo y la opción de GPU que deseas implementar.

    Gemma 4 E2B Instruct

    Atributo Valor
    Repositorio de Hugging Face google/gemma-4-E2B-it
    Parámetros 5,100 millones (2,000 millones efectivos)
    Licencia Condiciones de Uso de Gemma
    Pesos que usa vLLM Formato de Hugging Face (model-*.safetensors), alrededor de 10.2 GB
    Longitud de contexto 128,000 tokens; esta guía entrega --max-model-len 32768

    Crea el archivo de entorno del modelo:

    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
    

    Crea el archivo de entorno del acelerador para tu opción de GPU:

    NVIDIA A100 de 40 GB

    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 GB

    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 de 94 GB

    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 de 141 GB

    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 de 288 GB

    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

    Atributo Valor
    Repositorio de Hugging Face google/gemma-4-E4B-it
    Parámetros 8,000 millones (4,000 millones efectivos)
    Licencia Condiciones de Uso de Gemma
    Pesos que usa vLLM Formato de Hugging Face (model-*.safetensors), alrededor de 16.0 GB
    Longitud de contexto 128,000 tokens; esta guía entrega --max-model-len 32768

    Crea el archivo de entorno del modelo:

    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
    

    Crea el archivo de entorno del acelerador para tu opción de GPU:

    NVIDIA A100 de 40 GB

    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 GB

    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 de 94 GB

    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 de 141 GB

    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 de 288 GB

    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

    Atributo Valor
    Repositorio de Hugging Face google/gemma-4-12B-it
    Parámetros 12,000 millones (denso)
    Licencia Condiciones de Uso de Gemma
    Pesos que usa vLLM Formato de Hugging Face (model-*.safetensors), alrededor de 23.9 GB
    Longitud de contexto 256,000 tokens; esta guía entrega --max-model-len 32768

    Crea el archivo de entorno del modelo:

    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
    

    Crea el archivo de entorno del acelerador para tu opción de GPU:

    NVIDIA A100 de 40 GB

    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 GB

    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 de 94 GB

    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 de 141 GB

    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 de 288 GB

    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

    Atributo Valor
    Repositorio de Hugging Face google/gemma-4-26B-A4B-it
    Parámetros 25,800 millones en total/4,000 millones activos (mezcla de expertos)
    Licencia Condiciones de Uso de Gemma
    Pesos que usa vLLM Formato de Hugging Face (model-*.safetensors), alrededor de 51.6 GB
    Longitud de contexto 256,000 tokens; esta guía entrega --max-model-len 32768

    Crea el archivo de entorno del modelo:

    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
    

    Crea el archivo de entorno del acelerador para tu opción de GPU:

    NVIDIA A100 80 GB

    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 de 94 GB

    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 de 141 GB

    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 de 288 GB

    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

    Atributo Valor
    Repositorio de Hugging Face google/gemma-4-31B-it
    Parámetros 31.3B (denso)
    Licencia Condiciones de Uso de Gemma
    Pesos que usa vLLM Formato de Hugging Face (model-*.safetensors), alrededor de 62.5 GB
    Longitud de contexto 256,000 tokens; esta guía entrega --max-model-len 32768

    Crea el archivo de entorno del modelo:

    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
    

    Crea el archivo de entorno del acelerador para tu opción de GPU:

    NVIDIA A100 80 GB

    La entrega en una GPU de 80 GB deja poca memoria para la caché de KV, por lo que esta opción establece --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 de 94 GB

    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 de 141 GB

    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 de 288 GB

    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. Carga el archivo de entorno:

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

    El resultado es similar a lo siguiente:

    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)
    

Clúster

  1. Configura 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. Autentícate en el entorno de GDC:

    gdcloud auth login
    
  3. Recupera las credenciales del clúster:

    gdcloud clusters get-credentials "${GDC_STANDARD_CLUSTER_NAME}" \
    --project="${GDC_PROJECT}" \
    --standard \
    --zone="${GDC_ZONE}"
    
  4. Verifica la conectividad con el clúster:

    kubectl get nodes -L node.cluster.private.gdc.goog/machine-class
    
  5. Verifica que el tipo de recurso de acelerador del archivo de entorno del acelerador esté disponible en el clúster. El comando enumera los tipos de recursos de acelerador que exponen los nodos (el nombre depende del modelo de GPU instalado; está vacío en los clústeres sin nodos de GPU) y el valor configurado:

    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}"
    

Implementación

Espacio de nombres

  1. Crea el espacio de nombres:

    kubectl create namespace "${GDCS_WORKLOAD_NAMESPACE}" \
    --dry-run=client \
    --output=yaml | kubectl apply -f -
    
  2. Agrega 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 -
    

Pesos del modelo

  1. Descarga los pesos del modelo (solo los archivos que vLLM necesita para el modelo seleccionado, GDCS_HF_DOWNLOAD_EXCLUDE omite el resto) y quita el directorio .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. Calcula el tamaño de PersistentVolumeClaim requerido a partir de los pesos del modelo descargados con un 25% de sobrecarga (redondeado al siguiente GiB entero):

    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. Crea el manifiesto para el PersistentVolumeClaim ReadWriteOnce para los pesos del modelo:

    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. Aplica el manifiesto para el PersistentVolumeClaim de los pesos del modelo:

    kubectl apply \
    --filename="${GDCS_USER_GUIDE_HOME}/${GDCS_WORKLOAD_NAME}-rwo-pvc.yaml" \
    --namespace="${GDCS_WORKLOAD_NAMESPACE}"
    
  5. Espera a que se vincule el PersistentVolumeClaim y se impriman los valores que el operador de infraestructura necesita para ajustar la política de calidad de servicio (QoS) de 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 no está disponible en tu clúster, pídele al operador de infraestructura que aplique la política de QoS de alto rendimiento (system-performance-<ORG>-admin, 30 IOPS por GiB con un mínimo de 6,148 IOPS) al volumen que respalda el PersistentVolumeClaim. Proporciona los valores de BACKING_PVC y ORG que se imprimieron en el paso anterior. El operador de infraestructura aplica la política como se describe en el runbook FILE-R0097 de la documentación del operador de infraestructura. Esta se aplica al volumen activo, por lo que puedes continuar con los siguientes pasos.

  7. Crea el manifiesto para el Pod del cargador de modelos:

    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. Aplica el manifiesto para el Pod del cargador de modelos:

    kubectl apply \
    --filename="${GDCS_USER_GUIDE_HOME}/${GDCS_MODEL_LOADER_POD_NAME}-pod.yaml" \
    --namespace="${GDCS_WORKLOAD_NAMESPACE}"
    
  9. Espera a que el Pod del cargador de modelos esté en ejecución:

    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. Sube los pesos del modelo al PersistentVolume (la secuencia de comandos omite los archivos que ya existen con el mismo tamaño, por lo que se puede volver a ejecutar):

    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. Borra el Pod del cargador de modelos:

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

Servidor de inferencia

  1. Crea el manifiesto para el Deployment de vLLM. El ConfigMap lleva la configuración de vLLM específica del modelo desde el entorno, por lo que el manifiesto es el mismo para cada modelo y opción 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. Aplica el manifiesto para el Deployment de vLLM:

    kubectl apply \
    --filename="${GDCS_USER_GUIDE_HOME}/${GDCS_WORKLOAD_NAME}-deployment.yaml" \
    --namespace="${GDCS_WORKLOAD_NAMESPACE}"
    
  3. Crea el manifiesto para el NetworkPolicy de 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. Aplica el manifiesto para el NetworkPolicy de vLLM:

    kubectl apply \
    --filename="${GDCS_USER_GUIDE_HOME}/vllm-networkpolicy.yaml"
    
  1. Espera a que el Pod esté en ejecución:

    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. Espera a que el Deployment esté listo:

    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. Opcional: Transmite los registros del contenedor para supervisar el progreso del inicio:

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

Validación

  1. Recupera la dirección IP del LoadBalancer para 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. Envía una solicitud de prueba a vLLM. El valor de max_tokens es 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 no se puede acceder a la dirección IP del LoadBalancer desde la estación de trabajo, por ejemplo, porque ningún ProjectNetworkPolicy la admite aún, envía las solicitudes a través de la redirección de puertos:

    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}