Infraestructura de servicio de modelos
Despliega y configura endpoints de modelos para IBM Bob on-premises cuando tu entorno no dispone ya de una solución de servicio de modelos.
Antes de poder conectar IBM Bob a un modelo de lenguaje grande (LLM), debes tener acceso a un endpoint de modelo desplegado. Bob IDE no aprovisiona, aloja ni gestiona la infraestructura de servicio de modelos. Si tu organización ya proporciona endpoints de modelos a través de Red Hat OpenShift Container Platform (OCP) AI, servidores de inferencia basados en GPU, servicios de IA en la nube u otras plataformas de inferencia, procede directamente a Configurar el gateway de inferencia de modelos.
Elige la opción que mejor se adapte a tu entorno y requisitos operativos.
| Opción | Cuándo usarla |
|---|---|
| OpenShift AI (en clúster, OCI/ModelCar) | Modelos air-gapped o autoalojados; Red Hat OpenShift AI ya disponible en el clúster |
| Endpoints de modelos en nube pública | Modelos de frontera a través de AWS Bedrock, Azure OpenAI o Google Vertex AI |
| Endpoints de modelos en infraestructura privada | Modelo servido en servidores GPU separados o un clúster de inferencia dedicado |
Despliegue de modelos con OpenShift AI (en clúster, OCI/ModelCar)
Red Hat OpenShift AI (RHOAI) es la plataforma recomendada para servir modelos en el clúster, incluidos los despliegues air-gapped. El enfoque preferido para cargar los pesos del modelo es el patrón OCI/ModelCar: los archivos del modelo se integran en una imagen OCI bajo /models/ y se publican en un registro privado. Cuando se despliega el InferenceService, KServe inyecta un contenedor init modelcar-init que descarga la imagen y copia los pesos en un volumen compartido en /mnt/models/, desde el que los carga el runtime de servicio (por ejemplo, vLLM). La imagen del modelo se almacena en caché en el nodo tras la primera descarga; los reinicios posteriores en el mismo nodo omiten la descarga por completo.
Requisitos previos:
- Operador de Red Hat OpenShift AI instalado en el clúster
- KServe habilitado y configurado
- Nodos worker con GPU habilitadas y el Operador GPU de NVIDIA (o equivalente) configurado
- CLI
ocautenticado en el clúster destino con permiso para crear recursos en el namespace destino - Un registro de contenedores privado accesible desde el clúster, con credenciales para publicar imágenes en él
Configurar Red Hat OpenShift AI
Configura los recursos DataScienceClusterInitialization y DataScienceCluster de la siguiente manera:
- Deshabilita
serviceMesh. - Habilita KServe estableciendo
managementState: Managed. - Configura KServe para usar el modo
RawDeployment. - Elimina todos los componentes no utilizados de Red Hat OpenShift AI.
Ejemplo de configuración de KServe:
kserve:
defaultDeploymentMode: RawDeployment
nim:
managementState: Managed
rawDeploymentServiceConfig: Headed
serving:
ingressGateway:
certificate:
type: OpenshiftDefaultIngress
managementState: Removed
name: knative-serving
managementState: ManagedHabilitar la compatibilidad con ModelCar
La compatibilidad con ModelCar está controlada por el ConfigMap inferenceservice-config en el namespace redhat-ods-applications. La clave storageInitializer debe contener "enableModelcar": true.
Verifica la configuración actual:
oc get configmap inferenceservice-config \
-n redhat-ods-applications \
-o jsonpath='{.data.storageInitializer}'La salida debe contener:
{
"enableModelcar": true,
"cpuModelcar": "10m",
"memoryModelcar": "15Mi"
}Si enableModelcar está ausente o es false, actualiza el ConfigMap:
# Recuperar el valor actual, combinar el flag y aplicar el parche
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()))')}}"Reinicia el controlador de KServe para aplicar el cambio:
oc rollout restart deployment kserve-controller-manager -n redhat-ods-applications
oc rollout status deployment kserve-controller-manager -n redhat-ods-applicationsEmpaquetar los archivos del modelo en una imagen OCI
Descarga los pesos del modelo desde Hugging Face y empaquétalos en una imagen OCI. La imagen debe tener todos los archivos del modelo bajo el directorio /models. Para más información, consulta la documentación de KServe sobre cómo preparar una imagen OCI con datos del modelo. Para despliegues vLLM, incluye los fragmentos del modelo safetensors y excluye los archivos de checkpoint heredados como .bin, .pt y original/*.
Ejemplo de Dockerfile:
FROM busybox:latest
# Pesos del modelo -- fragmentos safetensors e índice
COPY <model-name>/model-*.safetensors /models/
COPY <model-name>/model.safetensors.index.json /models/
# Configuración del modelo
COPY <model-name>/config.json /models/
COPY <model-name>/generation_config.json /models/
# Tokenizador
COPY <model-name>/tokenizer.json /models/
COPY <model-name>/tokenizer_config.json /models/
COPY <model-name>/special_tokens_map.json /models/Si el modelo incluye una plantilla de chat (por ejemplo, chat_template.jinja), agrégala. Alternativamente, copia todo el directorio en una instrucción, que es más sencillo pero incluye archivos que vLLM no necesita:
FROM busybox:latest
COPY <model-name>/ /models/Publicar la imagen en un registro privado
Publica la imagen OCI en un registro de contenedores privado accesible desde el clúster:
<registry>/<project>/<model-name>:latestUsa las herramientas que se adapten a tu entorno (podman push, skopeo copy, un pipeline de CI, etc.).
Crear el namespace destino y el secreto de extracción de imágenes
Crea el namespace del proyecto y configura las credenciales para extraer la imagen del modelo.
Crea el namespace:
oc new-project <namespace>Crea el secreto de extracción del registro:
# Secreto de extracción para que KServe pueda extraer la imagen del modelo de tu registro privado
oc create secret docker-registry model-registry-secret \
--docker-server=<registry> \
--docker-username=<username> \
--docker-password=<password-or-token> \
-n <namespace>Crea una cuenta de servicio:
# Cuenta de servicio usada por el predictor de KServe
oc create sa model-puller-sa -n <namespace>Asocia el secreto de extracción con la cuenta de servicio:
# Adjuntar el secreto de extracción -- ambos comandos son necesarios:
# oc secrets link cubre el uso general de secretos;
# imagePullSecrets es necesario específicamente para el contenedor init ModelCar de KServe
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"}]}'Ambos comandos son necesarios. La entrada imagePullSecrets es usada por el contenedor de inicialización ModelCar durante la recuperación de la imagen del modelo.
Crear un ServingRuntime
Despliega un ServingRuntime basado en vLLM en el namespace destino.
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: 60Aplica la configuración del runtime:
oc apply -n <namespace> -f serving-runtime-vllm.yamlDesplegar el InferenceService
Crea un InferenceService que referencie la imagen del modelo OCI usando un URI de almacenamiento oci://.
Requisitos clave de configuración:
- Referenciar el
ServingRuntimecreado anteriormente. - Especificar la ubicación de la imagen OCI en
storageUri. - Configurar los límites de recursos de CPU, memoria y GPU que coincidan con los requisitos del modelo.
- Montar memoria compartida (
/dev/shm) para vLLM. - Configurar los argumentos de runtime de vLLM y las variables de entorno.
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>" # p. ej. "8"
limits:
cpu: "<cpu-limit>" # p. ej. "16"
memory: <memory-limit> # p. ej. 96Gi -- ajusta a los requisitos de VRAM del modelo
nvidia.com/gpu: "<gpu-count>" # p. ej. "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" # truncar líneas de log de vLLM para evitar inundación de logs
- 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>" # debe coincidir con el límite nvidia.com/gpu anterior
- name: CUDA_VISIBLE_DEVICES
value: "<gpu-indices>" # p. ej. "0" para una GPU; "0,1" para dos
- name: VLLM_WORKER_MULTIPROC_METHOD
value: spawn
- name: LOGNAME
value: vllm
- name: USER
value: vllmAplica el manifiesto del InferenceService:
oc apply -n <namespace> -f isvc-<model-name>.yamlVerificar el despliegue
Monitorea el estado del despliegue, el inicio del pod y los logs del runtime:
# Observar el InferenceService alcanzar el estado Ready
oc get inferenceservice <model-name> -n <namespace> -w
# Observar el inicio del pod predictor
oc get pods -n <namespace> -w
# Seguir los logs del predictor (la carga del modelo puede tardar varios minutos una vez en Running)
oc logs -f deployment/<model-name>-predictor -n <namespace>Cuando el InferenceService informe READY: True, valida el endpoint.
Verifica el registro del modelo y envía una solicitud de inferencia de prueba:
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
}'Solución de problemas
| Problema | Posible causa | Resolución |
|---|---|---|
ErrImagePull | Credenciales del registro ausentes o inválidas | Confirma que model-registry-secret existe, tiene credenciales válidas y está vinculado a model-puller-sa usando tanto oc secrets link como el parche imagePullSecrets. |
ImagePullBackOff | Secreto de extracción de imagen no configurado para ModelCar | Asegúrate de que la cuenta de servicio incluye la entrada imagePullSecrets. Consulta el comando oc patch serviceaccount en el paso 3. |
El predictor permanece en Init:0/1 | Descarga de imagen del modelo en curso | Consulta los eventos de oc describe pod para ver el progreso de Pulling/Pulled; el tiempo de descarga escala con el tamaño de la imagen y el ancho de banda del registro. |
El predictor permanece en Init:0/1 indefinidamente | Archivos del modelo no encontrados | Verifica que los archivos del modelo están almacenados bajo /models en la imagen OCI. |
Engine core initialization failed | Tiempo de espera de compilación CUDA inicial | El primer inicio puede tardar más mientras se generan las cachés. Reinicia y vuelve a intentarlo. |
| La carga del modelo falla | Formato de archivo del modelo no compatible | Usa archivos safetensors de Hugging Face y excluye los checkpoints heredados. |
| Errores de auto-prueba FIPS de OpenSSL | La imagen del contenedor no es compatible con FIPS | Usa una imagen vLLM compatible con FIPS. |
OutOfMemory / OOMKilled | Memoria GPU insuficiente | Aumenta los recursos GPU, reduce la longitud del contexto o usa un modelo cuantizado. |
InferenceService permanece en Pending | Recursos del clúster no disponibles | Verifica la disponibilidad de GPU y libera recursos de cargas de trabajo no utilizadas. |
Recursos adicionales
- Red Hat OpenShift AI - Servir modelos
- Documentación de KServe
- KServe ModelCar - Empaquetado de modelos OCI
Uso de endpoints de modelos en nube pública
Usa esta opción cuando los modelos están alojados por un proveedor de nube, como IBM watsonx, AWS Bedrock, Azure OpenAI o Google Vertex AI.
Requisitos previos:
- Conectividad HTTPS de salida (puerto 443) desde el clúster de Red Hat OpenShift Container Platform (OCP) al endpoint del servicio en la nube.
- Claves API válidas, credenciales IAM o credenciales de autenticación equivalentes.
Antes de comenzar:
Asegúrate de que:
- El despliegue del modelo está aprovisionado y activo.
- Las credenciales de autenticación están generadas y almacenadas de forma segura.
- Se han completado los requisitos de red o acceso específicos del proveedor.
Una vez que el endpoint esté disponible, procede a Configurar el gateway de inferencia de modelos.
Uso de endpoints de modelos en infraestructura privada
Usa esta opción cuando los modelos están alojados en infraestructura gestionada por el cliente fuera del clúster de IBM Bob, como:
- Servidores GPU dedicados
- Clústeres OpenShift separados
- Servidores de inferencia bare-metal
- Plataformas de IA empresariales
Requisitos previos:
- El endpoint del modelo expone una API compatible con OpenAI.
- Existe conectividad HTTPS entre el clúster de IBM Bob y el endpoint.
- Las credenciales de autenticación están disponibles como secretos de Kubernetes.
Antes de comenzar:
Valida lo siguiente:
- Conectividad de red desde el clúster hasta el endpoint.
- Configuración TLS o TLS mutuo, si es necesario.
- Las políticas de red y los firewalls permiten el acceso.
- La autenticación del endpoint funciona correctamente.
Una vez verificadas la conectividad y la autenticación, procede a Configurar el gateway de inferencia de modelos.