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.
| Opzione | Quando usarla |
|---|---|
| OpenShift AI (on-cluster, OCI/ModelCar) | Modelli air-gapped o self-hosted; RHOAI già disponibile nel cluster |
| Cloud pubblico | Modelli frontier tramite AWS Bedrock, Azure OpenAI o Google Vertex AI |
| Infrastruttura privata | Modello 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
ocautenticata 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: ManagedAbilitare 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-applicationsImpacchettare 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>:latestPuoi 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"}]}'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: 60Applica la configurazione del runtime:
oc apply -n <namespace> -f serving-runtime-vllm.yamlDeployare 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
ServingRuntimecreato 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: vllmApplica il manifest InferenceService:
oc apply -n <namespace> -f isvc-<model-name>.yamlVerificare 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
| Problema | Causa possibile | Soluzione |
|---|---|---|
ErrImagePull | Credenziali del registry mancanti o non valide | Verifica che model-registry-secret esista, abbia credenziali valide e sia collegato a model-puller-sa usando sia oc secrets link che la patch imagePullSecrets. |
ImagePullBackOff | Pull secret dell'immagine non configurato per ModelCar | Assicurati 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/1 | Download dell'immagine del modello in corso | Controlla 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 indefinitamente | File del modello non trovati | Verifica che i file del modello siano archiviati sotto /models nell'immagine OCI. |
Engine core initialization failed | Timeout della compilazione CUDA iniziale | Il primo avvio può richiedere più tempo durante la generazione delle cache. Riavvia e riprova. |
| Il caricamento del modello fallisce | Formato del file del modello non supportato | Usa i file safetensors di Hugging Face ed escludi i checkpoint legacy. |
| Errori nel self-test OpenSSL FIPS | L'immagine container non è compatibile con FIPS | Usa un'immagine vLLM compatibile con FIPS. |
OutOfMemory / OOMKilled | Memoria GPU insufficiente | Aumenta le risorse GPU, riduci la lunghezza del contesto o usa un modello quantizzato. |
InferenceService rimane in Pending | Risorse cluster non disponibili | Verifica 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.