Infrastruttura di model serving

Scopri come deployare e configurare gli endpoint dei modelli quando il tuo ambiente non dispone già di una soluzione di model serving.

Prima di poter connettere IBM Bob a un large language model (LLM), devi avere accesso a un endpoint del modello deployato. Bob non esegue il provisioning, l'hosting o la gestione dell'infrastruttura di model serving. Se la tua organizzazione fornisce già endpoint dei modelli tramite OpenShift AI, server di inference basati su GPU, servizi AI cloud o altre piattaforme di inference, procedi direttamente alla Configurazione del Model Gateway.

Opzioni di deployment

Scegli l'opzione che meglio si adatta al tuo ambiente e ai tuoi requisiti operativi.

OpzioneQuando usarla
OpenShift AI (on-cluster, OCI/ModelCar)Modelli air-gapped o self-hosted; RHOAI già disponibile nel cluster
Cloud pubblicoModelli frontier tramite AWS Bedrock, Azure OpenAI o Google Vertex AI
Infrastruttura privataModello servito su server GPU separati o un cluster di inference dedicato

OpenShift AI (on-cluster, OCI/ModelCar)

Red Hat OpenShift AI (RHOAI) è la piattaforma consigliata per il serving di modelli on-cluster, inclusi i deployment air-gapped. L'approccio preferito per caricare i pesi del modello è il pattern OCI/ModelCar: i file del modello vengono incorporati in un'immagine OCI sotto /models/ e inviati a un registry privato. Quando l'InferenceService viene deployato, KServe inietta un init container modelcar-init che estrae l'immagine e copia i pesi in un volume condiviso in /mnt/models/, dal quale il serving runtime (ad esempio, vLLM) li carica. L'immagine del modello viene memorizzata nella cache del nodo dopo la prima estrazione — i riavvii successivi sullo stesso nodo saltano completamente il download.

Prerequisiti:

  • Operator Red Hat OpenShift AI installato nel cluster
  • KServe abilitato e configurato
  • Nodi worker con GPU abilitata con l'NVIDIA GPU Operator (o equivalente) configurato
  • CLI oc autenticata al cluster di destinazione con permesso di creare risorse nel namespace di destinazione
  • Un container registry privato accessibile dal cluster, con credenziali per inviare immagini

Configurare Red Hat OpenShift AI

Configura le risorse DataScienceClusterInitialization e DataScienceCluster come segue:

  • Disabilita serviceMesh.
  • Abilita KServe impostando managementState: Managed.
  • Configura KServe per usare la modalità RawDeployment.
  • Rimuovi tutti i componenti Red Hat OpenShift AI non utilizzati.

Esempio di configurazione KServe:

kserve:
  defaultDeploymentMode: RawDeployment
  nim:
    managementState: Managed
  rawDeploymentServiceConfig: Headed
  serving:
    ingressGateway:
      certificate:
        type: OpenshiftDefaultIngress
    managementState: Removed
    name: knative-serving
  managementState: Managed

Abilitare il supporto ModelCar

Il supporto ModelCar è controllato dalla ConfigMap inferenceservice-config nel namespace redhat-ods-applications. La chiave storageInitializer deve contenere "enableModelcar": true.

Verifica la configurazione attuale:

oc get configmap inferenceservice-config \
  -n redhat-ods-applications \
  -o jsonpath='{.data.storageInitializer}'

L'output deve contenere:

{
  "enableModelcar": true,
  "cpuModelcar": "10m",
  "memoryModelcar": "15Mi"
}

Se enableModelcar è assente o false, aggiorna la ConfigMap:

# Retrieve current value, merge the flag, and patch
CURRENT=$(oc get configmap inferenceservice-config \
  -n redhat-ods-applications \
  -o jsonpath='{.data.storageInitializer}')
PATCHED=$(echo "$CURRENT" | python3 -c "
import json, sys
d = json.load(sys.stdin)
d['enableModelcar'] = True
print(json.dumps(d))
")
oc patch configmap inferenceservice-config \
  -n redhat-ods-applications \
  --type merge \
  -p "{\"data\":{\"storageInitializer\":$(echo $PATCHED | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))')}}"

Riavvia il controller KServe per applicare la modifica:

oc rollout restart deployment kserve-controller-manager -n redhat-ods-applications
oc rollout status deployment kserve-controller-manager -n redhat-ods-applications

Impacchettare i file del modello in un'immagine OCI

Scarica i pesi del modello da Hugging Face e impacchettali in un'immagine OCI. L'immagine deve avere tutti i file del modello sotto la directory /models. Per ulteriori informazioni, vedere la documentazione KServe. Per i deployment vLLM, includi gli shard del modello safetensors ed escludi i file checkpoint legacy come .bin, .pt e original/*.

Dockerfile di esempio:

FROM busybox:latest

# Model weights — safetensors shards and index
COPY <model-name>/model-*.safetensors         /models/
COPY <model-name>/model.safetensors.index.json /models/

# Model configuration
COPY <model-name>/config.json             /models/
COPY <model-name>/generation_config.json  /models/

# Tokenizer
COPY <model-name>/tokenizer.json           /models/
COPY <model-name>/tokenizer_config.json    /models/
COPY <model-name>/special_tokens_map.json  /models/

Se il modello include un template di chat (ad esempio, chat_template.jinja), aggiungilo. In alternativa, copia l'intera directory in un'unica istruzione — più semplice, ma include file non necessari per vLLM:

FROM busybox:latest
COPY <model-name>/ /models/

Inviare l'immagine a un registry privato

Invia l'immagine OCI a un container registry privato raggiungibile dal cluster:

<registry>/<project>/<model-name>:latest

Puoi usare qualsiasi tool di gestione delle immagini supportato, inclusi:

  • Podman
  • Skopeo
  • Pipeline CI/CD
  • Tool specifici del registry

Creare il namespace di destinazione e il pull secret dell'immagine

Crea il namespace del progetto e configura le credenziali per estrarre l'immagine del modello:

oc new-project <namespace>

Crea il pull secret del registry:

# Pull secret so KServe can pull the model image from your private registry
oc create secret docker-registry model-registry-secret \
  --docker-server=<registry> \
  --docker-username=<username> \
  --docker-password=<password-or-token> \
  -n <namespace>

Crea un service account:

# Service account used by the KServe predictor
oc create sa model-puller-sa -n <namespace>

Associa il pull secret al service account:

# Attach the pull secret — both commands are required:
# oc secrets link covers general secret use;
# imagePullSecrets is needed by KServe's ModelCar init container specifically
oc secrets link model-puller-sa model-registry-secret --for=pull -n <namespace>
oc patch serviceaccount model-puller-sa -n <namespace> \
  -p '{"imagePullSecrets": [{"name": "model-registry-secret"}]}'
Nota:

Entrambi i comandi sono necessari. La voce imagePullSecrets viene usata dal container di inizializzazione ModelCar durante il recupero dell'immagine del modello.

Creare un ServingRuntime

Deploya un ServingRuntime basato su vLLM nel namespace di destinazione:

apiVersion: serving.kserve.io/v1alpha1
kind: ServingRuntime
metadata:
  name: vllm-runtime
  namespace: <namespace>
spec:
  multiModel: false
  supportedModelFormats:
    - name: pytorch
      autoSelect: true
  containers:
    - name: kserve-container
      image: vllm/vllm-openai:<version>
      ports:
        - containerPort: 3000
          protocol: TCP
      livenessProbe:
        httpGet:
          path: /health
          port: 3000
        periodSeconds: 30
        timeoutSeconds: 5
        failureThreshold: 3
      readinessProbe:
        httpGet:
          path: /health
          port: 3000
        periodSeconds: 10
        timeoutSeconds: 5
        failureThreshold: 3
      startupProbe:
        httpGet:
          path: /health
          port: 3000
        periodSeconds: 10
        timeoutSeconds: 5
        failureThreshold: 60

Applica la configurazione del runtime:

oc apply -n <namespace> -f serving-runtime-vllm.yaml

Deployare l'InferenceService

Crea un InferenceService che fa riferimento all'immagine OCI del modello usando un URI di storage oci://.

Requisiti di configurazione chiave:

  • Fai riferimento al ServingRuntime creato in precedenza.
  • Specifica la posizione dell'immagine OCI in storageUri.
  • Configura i limiti di risorse CPU, memoria e GPU che corrispondono ai requisiti del modello.
  • Monta la memoria condivisa (/dev/shm) per vLLM.
  • Configura gli argomenti runtime e le variabili d'ambiente di vLLM.

Esempio:

apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
  name: <model-name>
  annotations:
    serving.kserve.io/autoscalerClass: external
    serving.kserve.io/deploymentMode: RawDeployment
spec:
  predictor:
    affinity:
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
            - matchExpressions:
                - key: kubernetes.io/arch
                  operator: In
                  values:
                    - amd64
    tolerations:
      - key: nvidia.com/gpu
        operator: Exists
        effect: NoSchedule
    volumes:
      - name: shm
        emptyDir:
          medium: Memory
          sizeLimit: 64Gi
    model:
      modelFormat:
        name: pytorch
      runtime: vllm-runtime
      storageUri: "oci://<registry>/<namespace-or-project>/<model-name>:latest"
      resources:
        requests:
          cpu: "<cpu-request>"          # e.g. "8"
        limits:
          cpu: "<cpu-limit>"            # e.g. "16"
          memory: <memory-limit>        # e.g. 96Gi — size to model VRAM requirements
          nvidia.com/gpu: "<gpu-count>" # e.g. "1"
      volumeMounts:
        - name: shm
          mountPath: /dev/shm
      args:
        - /mnt/models/
        - --served-model-name=<model-name>
        - --port=3000
        - --enable-auto-tool-choice
        - --tool-call-parser=openai
      env:
        - name: HOME
          value: /tmp
        - name: MAX_LOG_LEN
          value: "100"        # truncate vLLM log lines to avoid log flooding
        - name: HF_HUB_CACHE
          value: /tmp
        - name: TRITON_CACHE_DIR
          value: /tmp
        - name: XDG_CACHE_HOME
          value: /tmp
        - name: HF_HOME
          value: /tmp/hf_home
        - name: NUM_GPUS
          value: "<gpu-count>" # must match nvidia.com/gpu limit above
        - name: CUDA_VISIBLE_DEVICES
          value: "<gpu-indices>" # e.g. "0" for a single GPU; "0,1" for two
        - name: VLLM_WORKER_MULTIPROC_METHOD
          value: spawn
        - name: LOGNAME
          value: vllm
        - name: USER
          value: vllm

Applica il manifest InferenceService:

oc apply -n <namespace> -f isvc-<model-name>.yaml

Verificare il deployment

Monitora lo stato del deployment, l'avvio dei pod e i log del runtime:

# Watch the InferenceService reach Ready state
oc get inferenceservice <model-name> -n <namespace> -w

# Watch the predictor pod start up
oc get pods -n <namespace> -w

# Tail predictor logs (model load can take several minutes once Running)
oc logs -f deployment/<model-name>-predictor -n <namespace>

Quando l'InferenceService riporta READY: True, valida l'endpoint.

Verifica la registrazione del modello e invia una richiesta di inference di test:

POD=$(oc get pods -n <namespace> \
  -l app=isvc.<model-name>-predictor \
  -o jsonpath='{.items[0].metadata.name}')

oc exec -n <namespace> "$POD" -c kserve-container -- \
  curl -fsS http://127.0.0.1:3000/v1/models

oc exec -n <namespace> "$POD" -c kserve-container -- \
  curl -fsS http://127.0.0.1:3000/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "<model-name>",
    "messages": [{"role": "user", "content": "Hello"}],
    "max_tokens": 50
  }'

Risoluzione dei problemi

ProblemaCausa possibileSoluzione
ErrImagePullCredenziali del registry mancanti o non valideVerifica che model-registry-secret esista, abbia credenziali valide e sia collegato a model-puller-sa usando sia oc secrets link che la patch imagePullSecrets.
ImagePullBackOffPull secret dell'immagine non configurato per ModelCarAssicurati che il service account includa la configurazione imagePullSecrets. Esegui oc patch serviceaccount model-puller-sa -n <namespace> -p '{"imagePullSecrets": [{"name": "model-registry-secret"}]}'
Il predictor rimane in Init:0/1Download dell'immagine del modello in corsoControlla gli eventi di oc describe pod per il progresso di Pulling/Pulled; il tempo di estrazione scala con la dimensione dell'immagine e la larghezza di banda del registry.
Il predictor rimane in Init:0/1 indefinitamenteFile del modello non trovatiVerifica che i file del modello siano archiviati sotto /models nell'immagine OCI.
Engine core initialization failedTimeout della compilazione CUDA inizialeIl primo avvio può richiedere più tempo durante la generazione delle cache. Riavvia e riprova.
Il caricamento del modello fallisceFormato del file del modello non supportatoUsa i file safetensors di Hugging Face ed escludi i checkpoint legacy.
Errori nel self-test OpenSSL FIPSL'immagine container non è compatibile con FIPSUsa un'immagine vLLM compatibile con FIPS.
OutOfMemory / OOMKilledMemoria GPU insufficienteAumenta le risorse GPU, riduci la lunghezza del contesto o usa un modello quantizzato.
InferenceService rimane in PendingRisorse cluster non disponibiliVerifica la disponibilità della GPU e libera risorse dai workload non utilizzati.

Per ulteriori informazioni, vedere:

Endpoint dei modelli su cloud pubblico

Usa questa opzione quando i modelli sono ospitati da un provider cloud, come IBM watsonx, AWS Bedrock, Azure OpenAI o Google Vertex AI.

Prerequisiti:

  • Connettività HTTPS in uscita (porta 443) dal cluster OpenShift all'endpoint del servizio cloud.
  • Chiavi API, credenziali IAM o credenziali di autenticazione equivalenti valide.

Prima di configurare IBM Bob

Assicurati che:

  • Il deployment del modello sia provisioning e attivo.
  • Le credenziali di autenticazione siano generate e archiviate in modo sicuro.
  • Eventuali requisiti di rete o di accesso specifici del provider siano completati.

Dopo che l'endpoint è disponibile, procedi alla Configurazione del Model Gateway.

Endpoint dei modelli su infrastruttura privata

Usa questa opzione quando i modelli sono ospitati su infrastruttura gestita dal cliente al di fuori del cluster IBM Bob, come:

  • Server GPU dedicati
  • Cluster OpenShift separati
  • Server di inference bare-metal
  • Piattaforme AI aziendali

Prerequisiti:

  • L'endpoint del modello espone un'API compatibile con OpenAI.
  • Esiste connettività HTTPS tra il cluster IBM Bob e l'endpoint.
  • Le credenziali di autenticazione sono disponibili come secret Kubernetes.

Prima di configurare IBM Bob

Verifica quanto segue:

  • Connettività di rete dal cluster all'endpoint.
  • Configurazione TLS o mutual TLS, se richiesta.
  • Le network policy e i firewall consentono l'accesso.
  • L'autenticazione dell'endpoint funziona correttamente.

Dopo che la connettività e l'autenticazione sono verificate, procedi alla Configurazione del Model Gateway.

Come valuti questo argomento?