Guida dell'utente dei modelli Gemma con Ollama su GDC con air gap

Questo documento fornisce istruzioni passo passo per il deployment di modelli open weight di Google DeepMind, in particolare della famiglia Gemma 4, utilizzando Ollama in ambienti con air gap di Google Distributed Cloud (GDC). Illustra l'utilizzo di Ollama per la gestione semplificata, utilizzando le funzionalità della piattaforma GDC, tra cui Kubernetes, Harbor e le risorse GPU. Seleziona il modello e l'opzione GPU nella sezione Modello. Tutti gli altri passaggi sono uguali per tutti i modelli.

Modelli supportati

Modello Tag Ollama Parametri Licenza Opzioni GPU
Gemma 4 E2B gemma4:e2b 5,1 mld (2 mld effettivi) Termini e condizioni d'uso di Gemma 1 x qualsiasi GPU
Gemma 4 E4B gemma4:e4b 8,0 B (4 B effettivi) Termini e condizioni d'uso di Gemma 1 x qualsiasi GPU
Gemma 4 12B gemma4:12b 12B (dense) Termini e condizioni d'uso di Gemma 1 x qualsiasi GPU
Gemma 4 26B-A4B gemma4:26b 25,8 miliardi totali / 4 miliardi attivi (Mixture of Experts) Termini e condizioni d'uso di Gemma 1 x qualsiasi GPU
Gemma 4 31B gemma4:31b 31,3 miliardi (dense) Termini e condizioni d'uso di Gemma 1 x qualsiasi GPU

Architettura

La soluzione prevede il deployment di Ollama come backend di gestione containerizzato (Deployment) all'interno di un cluster standard. I pesi del modello sono archiviati su volumi permanenti, compilati da file scaricati localmente e caricati utilizzando un pod del caricatore. Un Service Kubernetes di tipo LoadBalancer espone l'API di backend e gli oggetti NetworkPolicy / ProjectNetworkPolicy ne proteggono l'accesso.

Prima di iniziare

Completa l'implementazione di riferimento dei modelli open weight con Ollama sulla workstation e assicurati di avere accesso alla directory ${HOME}/gdcag-solutions.

Identity and Access Management

Questa guida presuppone che tu disponga dei seguenti ruoli nel cluster standard:

  • (Facoltativo) Amministratore cluster standard (visualizza i cluster dalla console)
  • Standard Cluster Admin (standard-cluster-admin)
  • StandardClusterRoleBinding al cluster-admin StandardClusterRole (creato da un Project IAM Admin, consulta la sezione Identity and Access Management dell'implementazione di riferimento)

Workstation

Esegui tutti i comandi di questa guida da una workstation con gli strumenti e la connettività necessari per l'ambiente e internet, se non diversamente indicato in un passaggio.

La configurazione dell'ambiente è strutturata su più livelli:

  • ${HOME}/gdcag-solutions/env.sh carica le impostazioni della piattaforma e del registry.
  • ${HOME}/gdcag-solutions/open-weight-models/ollama/env.sh aggiunge le impostazioni di Ollama.

  • Questa guida dell'utente aggiunge env.d/model.sh (il modello) e env.d/accelerator.sh (l'opzione GPU e le impostazioni di runtime), che scrivi nella sezione Modello, e env.d/model-common.sh (i valori derivati).

  1. Crea la struttura di directory della guida dell'utente:

    mkdir -p ${HOME}/gdcag-solutions/open-weight-models/ollama/gemma/env.d
    
  2. Crea il file di configurazione dell'ambiente del modello comune. Calcola i nomi e i percorsi derivati dal nome del modello:

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/gemma/env.d/model-common.sh && echo "Successfully created." || echo "Failed to create!"
    # Model (derived from env.d/model.sh)
    export GDCS_OLLAMA_MODEL_LOWERCASE="${GDCS_OLLAMA_MODEL,,}"
    export GDCS_OLLAMA_MODEL_KUBERNETES="$(echo "${GDCS_OLLAMA_MODEL_LOWERCASE}" | tr ':' '-')"
    
    # Paths
    export GDCS_OLLAMA_MODEL_DOWNLOAD_DIR="${GDCS_USER_GUIDE_HOME}/models/${GDCS_OLLAMA_MODEL_LOWERCASE}"
    export GDCS_OLLAMA_PV_MOUNT_PATH="/root/.ollama/models"
    
    # Workload
    export GDCS_WORKLOAD_NAMESPACE="ollama-gemma"
    export GDCS_WORKLOAD_NAME="${GDCS_OLLAMA_MODEL_KUBERNETES}"
    export GDCS_MODEL_LOADER_POD_NAME="loader-${GDCS_OLLAMA_MODEL_KUBERNETES}"
    EOF
    
  3. Crea il file del caricatore dell'ambiente della guida dell'utente. Genera l'ambiente root, l'ambiente di implementazione e l'ambiente del modello:

    cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/gemma/env.sh && echo "Successfully created." || echo "Failed to create!"
    source "${HOME}/gdcag-solutions/open-weight-models/ollama/env.sh"
    
    export GDCS_USER_GUIDE_HOME="${HOME}/gdcag-solutions/open-weight-models/ollama/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"
    EOF
    

Modello

Ogni scheda elenca i dati del modello, il comando che scrive il file di ambiente del modello env.d/model.sh e le schede nidificate che scrivono il file di ambiente dell'acceleratore env.d/accelerator.sh per l'opzione GPU scelta con tipi di risorse e impostazioni Ollama precompilati. Per cambiare modello o opzioni GPU in un secondo momento, scrivi file di ambiente diversi, esegui nuovamente il sourcing dell'ambiente e ripeti la sezione Implementazione. I workload di diversi modelli possono essere eseguiti contemporaneamente nello stesso spazio dei nomi perché ogni nome di risorsa deriva dal nome del modello.

GPU Memoria Tipi di macchina Tipo di risorsa acceleratore
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 (anteprima), a3-highgpu-2g-gdc (anteprima), 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
  • Crea i file dell'ambiente del modello e dell'acceleratore per l'opzione del modello e della GPU di cui vuoi eseguire il deployment.

Gemma 4 E2B

Attributo Valore
Tag Ollama gemma4:e2b
Parametri 5,1 mld (2 mld effettivi)
Licenza Termini e condizioni d'uso di Gemma
Pesi Quantizzazione predefinita di Ollama, circa 4,6 GB
Finestra contestuale 128.000 token

Crea il file di ambiente del modello:

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/gemma/env.d/model.sh && echo "Successfully created." || echo "Failed to create!"
# Model: Gemma 4 E2B
export GDCS_OLLAMA_MODEL="gemma4:e2b"
EOF

Crea il file dell'ambiente dell'acceleratore per l'opzione GPU:

NVIDIA A100 da 40 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="12Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="6Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA A100 da 80 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="12Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="6Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA H100 da 94 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="12Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="6Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA H200 141 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="12Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="6Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA B300 288 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="12Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="6Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

Gemma 4 E4B

Attributo Valore
Tag Ollama gemma4:e4b
Parametri 8,0 B (4 B effettivi)
Licenza Termini e condizioni d'uso di Gemma
Pesi Quantizzazione predefinita di Ollama, circa 6,6 GB
Finestra contestuale 128.000 token

Crea il file di ambiente del modello:

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/gemma/env.d/model.sh && echo "Successfully created." || echo "Failed to create!"
# Model: Gemma 4 E4B
export GDCS_OLLAMA_MODEL="gemma4:e4b"
EOF

Crea il file dell'ambiente dell'acceleratore per l'opzione GPU:

NVIDIA A100 da 40 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="16Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="8Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA A100 da 80 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="16Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="8Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA H100 da 94 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="16Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="8Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA H200 141 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="16Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="8Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA B300 288 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="16Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="8Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

Gemma 4 12B

Attributo Valore
Tag Ollama gemma4:12b
Parametri 12B (dense)
Licenza Termini e condizioni d'uso di Gemma
Pesi Quantizzazione predefinita di Ollama, circa 7,7 GB
Finestra contestuale 256.000 token

Crea il file di ambiente del modello:

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/gemma/env.d/model.sh && echo "Successfully created." || echo "Failed to create!"
# Model: Gemma 4 12B
export GDCS_OLLAMA_MODEL="gemma4:12b"
EOF

Crea il file dell'ambiente dell'acceleratore per l'opzione GPU:

NVIDIA A100 da 40 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="16Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="8Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA A100 da 80 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="16Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="8Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA H100 da 94 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="16Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="8Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA H200 141 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="16Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="8Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA B300 288 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="16Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="8Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

Gemma 4 26B-A4B

Attributo Valore
Tag Ollama gemma4:26b
Parametri 25,8 miliardi totali / 4 miliardi attivi (Mixture of Experts)
Licenza Termini e condizioni d'uso di Gemma
Pesi Quantizzazione predefinita di Ollama, circa 16 GB
Finestra contestuale 256.000 token

Crea il file di ambiente del modello:

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/gemma/env.d/model.sh && echo "Successfully created." || echo "Failed to create!"
# Model: Gemma 4 26B-A4B
export GDCS_OLLAMA_MODEL="gemma4:26b"
EOF

Crea il file dell'ambiente dell'acceleratore per l'opzione GPU:

NVIDIA A100 da 40 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="32Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="16Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA A100 da 80 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="32Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="16Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA H100 da 94 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="32Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="16Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA H200 141 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="32Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="16Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA B300 288 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="32Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="16Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

Gemma 4 31B

Attributo Valore
Tag Ollama gemma4:31b
Parametri 31,3 miliardi (dense)
Licenza Termini e condizioni d'uso di Gemma
Pesi Quantizzazione predefinita di Ollama, circa 19 GB
Finestra contestuale 256.000 token

Crea il file di ambiente del modello:

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/gemma/env.d/model.sh && echo "Successfully created." || echo "Failed to create!"
# Model: Gemma 4 31B
export GDCS_OLLAMA_MODEL="gemma4:31b"
EOF

Crea il file dell'ambiente dell'acceleratore per l'opzione GPU:

NVIDIA A100 da 40 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="40Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="20Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA A100 da 80 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="40Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="20Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA H100 da 94 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="40Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="20Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA H200 141 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="40Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="20Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF

NVIDIA B300 288 GB

cat << 'EOF' > ${HOME}/gdcag-solutions/open-weight-models/ollama/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"

# Resources
export GDCS_WORKLOAD_CPU_LIMIT="4"
export GDCS_WORKLOAD_CPU_REQUEST="2"
export GDCS_WORKLOAD_MEMORY_LIMIT="40Gi"
export GDCS_WORKLOAD_MEMORY_REQUEST="20Gi"

# Ollama
export GDCS_OLLAMA_NUM_PARALLEL="4"
export GDCS_OLLAMA_TEST_NUM_PREDICT="128"
EOF
  1. Esegui il sourcing del file di ambiente:

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

Cluster

  1. Recupera le credenziali del cluster:

    gdcloud clusters get-credentials "${GDC_STANDARD_CLUSTER_NAME}" \
    --project="${GDC_PROJECT}"
    
  2. Verifica che il tipo di risorsa dell'acceleratore del file dell'ambiente dell'acceleratore sia disponibile nel cluster:

    kubectl get nodes \
    -o custom-columns='NAME:.metadata.name,ACCELERATOR:.status.allocatable.'"${GDCS_WORKLOAD_ACCELERATOR_TYPE}"
    

Implementazione

Spazio dei nomi

  1. Crea lo spazio dei nomi:

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

Pesi del modello

  1. Scarica i pesi del modello:

    ${GDCS_IMPLEMENTATION_HOME}/ollama_model_weight_download.sh
    
  2. Calcola la dimensione PersistentVolumeClaim richiesta dai pesi del modello scaricati con un overhead del 25% (arrotondato per eccesso al GiB intero successivo):

    MODEL_KIB=$(du -sk "${GDCS_OLLAMA_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 il manifest per il PersistentVolumeClaim per i pesi del modello:

    cat <<EOF > "${GDCS_USER_GUIDE_HOME}/${GDCS_WORKLOAD_NAME}-pvc.yaml" && echo "Successfully created." || echo "Failed to create!"
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: ${GDCS_WORKLOAD_NAME}-rwo
      namespace: ${GDCS_WORKLOAD_NAMESPACE}
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: ${GDCS_MODEL_PVC_SIZE}
    EOF
    
  4. Applica il manifest per PersistentVolumeClaim per i pesi del modello:

    kubectl apply --filename="${GDCS_USER_GUIDE_HOME}/${GDCS_WORKLOAD_NAME}-pvc.yaml"
    
  5. Attendi che l'oggetto PersistentVolumeClaim esegua il binding e stampi i valori necessari all'operatore dell'infrastruttura per regolare la policy di qualità del servizio (QoS) di I/O:

    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. Se performance-rwo non è disponibile nel tuo cluster, chiedi all'operatore dell'infrastruttura di applicare la policy QoS ad alte prestazioni (system-performance-<ORG>-admin, 30 IOPS per GiB con un limite minimo di 6148 IOPS) al volume che supporta PersistentVolumeClaim. Fornisci i valori BACKING_PVC e ORG stampati nel passaggio precedente. L'operatore dell'infrastruttura applica la policy come descritto in FILE-R0097; la policy ha effetto sul volume attivo, quindi puoi procedere con i passaggi successivi.

  7. Crea il manifest per il caricatore del modello Pod:

    cat <<EOF > "${GDCS_USER_GUIDE_HOME}/${GDCS_WORKLOAD_NAME}-loader.yaml" && echo "Successfully created." || echo "Failed to create!"
    apiVersion: v1
    kind: Pod
    metadata:
      name: ${GDCS_MODEL_LOADER_POD_NAME}
      namespace: ${GDCS_WORKLOAD_NAMESPACE}
    spec:
      containers:
        - command: ["/bin/sh", "-c", "trap 'exit 0' TERM; while :; do sleep 1; done"]
          image: ${GDCS_HARBOR_PROJECT_URI}/busybox/busybox:${GDCS_BUSYBOX_IMAGE_TAG}
          imagePullPolicy: IfNotPresent
          name: loader
          volumeMounts:
            - mountPath: ${GDCS_OLLAMA_PV_MOUNT_PATH}
              name: model-cache
      imagePullSecrets:
        - name: ${GDCS_HARBOR_K8S_PULL_SECRET}
      restartPolicy: Never
      volumes:
        - name: model-cache
          persistentVolumeClaim:
            claimName: ${GDCS_WORKLOAD_NAME}-rwo
    EOF
    
  8. Applica il manifest per il caricatore del modello Pod:

    kubectl apply --filename="${GDCS_USER_GUIDE_HOME}/${GDCS_WORKLOAD_NAME}-loader.yaml"
    
  9. Attendi che il caricatore del modello Pod sia in esecuzione:

    kubectl wait \
    --for=jsonpath='{.status.phase}'=Running \
    "pod/${GDCS_MODEL_LOADER_POD_NAME}" \
    --namespace="${GDCS_WORKLOAD_NAMESPACE}" \
    --timeout=120s
    
  10. Carica i pesi del modello:

    ${GDCS_IMPLEMENTATION_HOME}/model_weight_upload.sh \
    --local-dir="${GDCS_OLLAMA_MODEL_DOWNLOAD_DIR}" \
    --pod="${GDCS_MODEL_LOADER_POD_NAME}" \
    --target-dir="${GDCS_OLLAMA_PV_MOUNT_PATH}"
    
  11. Elimina il caricatore del modello Pod:

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

Server di inferenza

  1. Crea il manifest per Ollama Deployment:

    cat <<EOF > "${GDCS_USER_GUIDE_HOME}/${GDCS_WORKLOAD_NAME}-deployment.yaml" && echo "Successfully created." || echo "Failed to create!"
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: ${GDCS_WORKLOAD_NAME}
    data:
      OLLAMA_FLASH_ATTENTION: "1"
      OLLAMA_HOST: "0.0.0.0"
      OLLAMA_KEEP_ALIVE: "-1"
      OLLAMA_MODELS: "${GDCS_OLLAMA_PV_MOUNT_PATH}"
      OLLAMA_NUM_PARALLEL: "${GDCS_OLLAMA_NUM_PARALLEL}"
      OLLAMA_ORIGINS: "*"
    ---
    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:
            - envFrom:
                - configMapRef:
                    name: ${GDCS_WORKLOAD_NAME}
              image: ${GDCS_HARBOR_PROJECT_URI}/ollama/ollama:${GDCS_OLLAMA_IMAGE_TAG}
              imagePullPolicy: IfNotPresent
              lifecycle:
                postStart:
                  exec:
                    command:
                      - /bin/sh
                      - -c
                      - |
                        echo "Waiting for local API to respond..."
                        timeout=60
                        until /bin/ollama list > /dev/null 2>&1 || [ "\$timeout" -le 0 ]; do
                          sleep 1
                          timeout=\$((timeout - 1))
                        done
                        if [ "\$timeout" -le 0 ]; then
                          echo "Timed out waiting for Ollama server to start." >&2
                          exit 1
                        fi
                        echo "Preloading model into memory..."
                        /bin/ollama run "${GDCS_OLLAMA_MODEL}" ""
              livenessProbe:
                failureThreshold: 3
                httpGet:
                  path: /
                  port: 11434
                periodSeconds: 30
                timeoutSeconds: 10
              name: ollama
              ports:
                - containerPort: 11434
                  name: http-ollama
              readinessProbe:
                failureThreshold: 3
                httpGet:
                  path: /api/tags
                  port: 11434
                periodSeconds: 10
                successThreshold: 1
                timeoutSeconds: 5
              resources:
                limits:
                  cpu: ${GDCS_WORKLOAD_CPU_LIMIT}
                  memory: ${GDCS_WORKLOAD_MEMORY_LIMIT}
                  ${GDCS_WORKLOAD_ACCELERATOR_TYPE}: "${GDCS_WORKLOAD_ACCELERATOR_COUNT}"
                requests:
                  cpu: ${GDCS_WORKLOAD_CPU_REQUEST}
                  memory: ${GDCS_WORKLOAD_MEMORY_REQUEST}
                  ${GDCS_WORKLOAD_ACCELERATOR_TYPE}: "${GDCS_WORKLOAD_ACCELERATOR_COUNT}"
              securityContext:
                allowPrivilegeEscalation: false
                seLinuxOptions:
                  type: spc_t
              startupProbe:
                failureThreshold: 60
                httpGet:
                  path: /
                  port: 11434
                periodSeconds: 10
                timeoutSeconds: 5
              volumeMounts:
                - mountPath: ${GDCS_OLLAMA_PV_MOUNT_PATH}
                  name: model-cache
                - mountPath: /dev/shm
                  name: shm
          imagePullSecrets:
            - name: ${GDCS_HARBOR_K8S_PULL_SECRET}
          volumes:
            - name: model-cache
              persistentVolumeClaim:
                claimName: ${GDCS_WORKLOAD_NAME}-rwo
            - emptyDir:
                medium: Memory
                sizeLimit: "8Gi"
              name: shm
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: ${GDCS_WORKLOAD_NAME}
    spec:
      ports:
        - name: http-ollama
          port: 80
          protocol: TCP
          targetPort: 11434
      selector:
        app: ${GDCS_WORKLOAD_NAME}
      type: LoadBalancer
    EOF
    
  2. Applica il manifest per Ollama Deployment:

    kubectl apply --filename="${GDCS_USER_GUIDE_HOME}/${GDCS_WORKLOAD_NAME}-deployment.yaml" --namespace="${GDCS_WORKLOAD_NAMESPACE}"
    
  3. Crea il manifest per Ollama NetworkPolicy:

    cat <<EOF > "${GDCS_USER_GUIDE_HOME}/ollama-netpol.yaml" && echo "Successfully created." || echo "Failed to create!"
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-ollama-ingress
      namespace: ${GDCS_WORKLOAD_NAMESPACE}
    spec:
      ingress:
      - from:
        - ipBlock:
            cidr: 0.0.0.0/0
        - namespaceSelector: {}
        ports:
        - port: 11434
          protocol: TCP
      podSelector: {}
      policyTypes:
      - Ingress
    EOF
    
  4. Applica il manifest per Ollama NetworkPolicy:

    kubectl apply --filename="${GDCS_USER_GUIDE_HOME}/ollama-netpol.yaml"
    
  5. Attendi che Pod sia in esecuzione:

    kubectl wait \
    --for=jsonpath='{.status.phase}'=Running \
    "pod" \
    --selector="app=${GDCS_WORKLOAD_NAME}" \
    --namespace="${GDCS_WORKLOAD_NAMESPACE}" \
    --timeout=300s
    
  6. Attendi che Deployment sia pronto:

    kubectl wait \
    --for=condition=Available \
    "deployment/${GDCS_WORKLOAD_NAME}" \
    --namespace="${GDCS_WORKLOAD_NAMESPACE}" \
    --timeout=600s
    
  7. (Facoltativo) Trasmetti in streaming i log del container per monitorare l'avanzamento dell'avvio:

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

Convalida

  1. Recupera l'indirizzo IP del bilanciatore del carico per Ollama:

    export OLLAMA_LB_IP=$(kubectl get service/${GDCS_WORKLOAD_NAME} --namespace="${GDCS_WORKLOAD_NAMESPACE}" --output=jsonpath='{.status.loadBalancer.ingress[*].ip}')
    echo "OLLAMA_LB_IP=${OLLAMA_LB_IP}"
    
  2. Invia una richiesta di test a Ollama utilizzando il bilanciatore del carico (API Ollama, generazione di testo):

    curl http://${OLLAMA_LB_IP}/api/generate \
    -H "Content-Type: application/json" \
    -d '{
      "model": "'${GDCS_OLLAMA_MODEL}'",
      "prompt": "Explain Google Distributed Cloud air-gapped briefly.",
      "stream": false
    }'
    
  3. Invia una richiesta di test in streaming:

    curl http://${OLLAMA_LB_IP}/api/generate \
    -H "Content-Type: application/json" \
    -d '{
      "model": "'${GDCS_OLLAMA_MODEL}'",
      "prompt": "Explain Google Distributed Cloud air-gapped briefly.",
      "stream": true
    }'
    
  4. Invia una richiesta di test all'API compatibile con OpenAI di Ollama utilizzando il bilanciatore del carico:

    curl http://${OLLAMA_LB_IP}/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d '{
      "model": "'${GDCS_OLLAMA_MODEL}'",
      "messages": [
        {"role": "user", "content": "Explain Google Distributed Cloud air-gapped briefly."}
      ]
    }'
    
  5. Invia una richiesta di test a Ollama utilizzando il port forwarding:

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