Infraestrutura de model serving
Implante e configure endpoints de modelos para o IBM Bob on-premises quando o seu ambiente não fornece ainda uma solução de model serving.
Antes de conectar o IBM Bob a um large language model (LLM), você deve ter acesso a um endpoint de modelo implantado. O Bob IDE não provisiona, hospeda nem gerencia infraestrutura de model serving. Se a sua organização já fornece endpoints de modelos por meio do Red Hat OpenShift Container Platform (OCP) AI, servidores de inferência baseados em GPU, serviços de IA em nuvem ou outras plataformas de inferência, prossiga diretamente para Configurando o model inference gateway.
Escolha a opção que melhor se adapta ao seu ambiente e requisitos operacionais.
| Opção | Quando usar |
|---|---|
| OpenShift AI (on-cluster, OCI/ModelCar) | Modelos air-gapped ou self-hosted; Red Hat OpenShift AI já disponível no cluster |
| Endpoints de modelos em nuvem pública | Modelos frontier via AWS Bedrock, Azure OpenAI ou Google Vertex AI |
| Endpoints de modelos em infraestrutura privada | Modelo servido em servidores GPU separados ou em um cluster de inferência dedicado |
Implantando modelos com OpenShift AI (on-cluster, OCI/ModelCar)
O Red Hat OpenShift AI (RHOAI) é a plataforma recomendada para servir modelos on-cluster, incluindo implantações air-gapped. A abordagem preferida para carregar os pesos do modelo é o padrão OCI/ModelCar: os arquivos do modelo são incorporados em uma imagem OCI sob /models/ e enviados para um registro privado. Quando o InferenceService é implantado, o KServe injeta um init container modelcar-init que extrai a imagem e copia os pesos para um volume compartilhado em /mnt/models/, do qual o runtime de serving (por exemplo, vLLM) então carrega. A imagem do modelo é armazenada em cache no nó após a primeira extração; reinicializações subsequentes no mesmo nó ignoram o download completamente.
Pré-requisitos:
- Operador Red Hat OpenShift AI instalado no cluster
- KServe habilitado e configurado
- Nós de trabalho habilitados para GPU com o NVIDIA GPU Operator (ou equivalente) configurado
- CLI
ocautenticado no cluster de destino com permissão para criar recursos no namespace de destino - Um registro de contêiner privado acessível a partir do cluster, com credenciais para enviar imagens a ele
Configurando o Red Hat OpenShift AI
Configure os recursos DataScienceClusterInitialization e DataScienceCluster da seguinte forma:
- Desative
serviceMesh. - Habilite o KServe definindo
managementState: Managed. - Configure o KServe para usar o modo
RawDeployment. - Remova todos os componentes do Red Hat OpenShift AI não utilizados.
Exemplo de configuração do KServe:
kserve:
defaultDeploymentMode: RawDeployment
nim:
managementState: Managed
rawDeploymentServiceConfig: Headed
serving:
ingressGateway:
certificate:
type: OpenshiftDefaultIngress
managementState: Removed
name: knative-serving
managementState: ManagedHabilitando o suporte ao ModelCar
O suporte ao ModelCar é controlado pelo ConfigMap inferenceservice-config no namespace redhat-ods-applications. A chave storageInitializer deve conter "enableModelcar": true.
Verifique a configuração atual:
oc get configmap inferenceservice-config \
-n redhat-ods-applications \
-o jsonpath='{.data.storageInitializer}'A saída deve conter:
{
"enableModelcar": true,
"cpuModelcar": "10m",
"memoryModelcar": "15Mi"
}Se enableModelcar estiver ausente ou for false, atualize o ConfigMap:
# Recupera o valor atual, mescla a flag e aplica o 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()))')}}"Reinicie o controlador KServe para aplicar a alteração:
oc rollout restart deployment kserve-controller-manager -n redhat-ods-applications
oc rollout status deployment kserve-controller-manager -n redhat-ods-applicationsEmpacotar os arquivos do modelo em uma imagem OCI
Faça download dos pesos do modelo do Hugging Face e empacote-os em uma imagem OCI. A imagem deve ter todos os arquivos do modelo sob o diretório /models. Para mais informações, consulte a documentação do KServe sobre como preparar uma imagem OCI com dados do modelo. Para implantações vLLM, inclua os shards do modelo safetensors e exclua arquivos de checkpoint legados como .bin, .pt e original/*.
Exemplo de Dockerfile:
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 o modelo incluir um chat template (por exemplo, chat_template.jinja), adicione-o. Como alternativa, copie o diretório inteiro em uma única instrução, o que é mais simples, mas inclui arquivos não necessários pelo vLLM:
FROM busybox:latest
COPY <model-name>/ /models/Enviar a imagem para um registro privado
Envie a imagem OCI para um registro de contêiner privado acessível a partir do cluster:
<registry>/<project>/<model-name>:latestUse qualquer ferramenta adequada ao seu ambiente (podman push, skopeo copy, um pipeline de CI, etc.).
Criar o namespace de destino e o image pull secret
Crie o namespace do projeto e configure as credenciais para extrair a imagem do modelo.
Crie o namespace:
oc new-project <namespace>Crie o pull secret do registro:
# Pull secret para que o KServe possa extrair a imagem do modelo do seu registro privado
oc create secret docker-registry model-registry-secret \
--docker-server=<registry> \
--docker-username=<username> \
--docker-password=<password-or-token> \
-n <namespace>Crie uma service account:
# Service account usada pelo predictor do KServe
oc create sa model-puller-sa -n <namespace>Associe o pull secret à service account:
# Anexa o pull secret -- ambos os comandos são necessários:
# oc secrets link cobre o uso geral de secrets;
# imagePullSecrets é necessário especificamente pelo init container ModelCar do 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 os comandos são necessários. A entrada imagePullSecrets é usada pelo container de inicialização do ModelCar durante a recuperação da imagem do modelo.
Criar um ServingRuntime
Implante um ServingRuntime baseado em vLLM no namespace de 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: 60Aplique a configuração do runtime:
oc apply -n <namespace> -f serving-runtime-vllm.yamlImplantar o InferenceService
Crie um InferenceService que referencie a imagem OCI do modelo usando uma URI de armazenamento oci://.
Requisitos de configuração principais:
- Referencie o
ServingRuntimecriado anteriormente. - Especifique o local da imagem OCI em
storageUri. - Configure os limites de recursos de CPU, memória e GPU que correspondam aos requisitos do modelo.
- Monte memória compartilhada (
/dev/shm) para o vLLM. - Configure os argumentos de runtime e variáveis de ambiente do vLLM.
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>" # ex.: "8"
limits:
cpu: "<cpu-limit>" # ex.: "16"
memory: <memory-limit> # ex.: 96Gi -- dimensione conforme os requisitos de VRAM do modelo
nvidia.com/gpu: "<gpu-count>" # ex.: "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" # trunca as linhas de log do vLLM para evitar sobrecarga 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>" # deve corresponder ao limite nvidia.com/gpu acima
- name: CUDA_VISIBLE_DEVICES
value: "<gpu-indices>" # ex.: "0" para uma única GPU; "0,1" para duas
- name: VLLM_WORKER_MULTIPROC_METHOD
value: spawn
- name: LOGNAME
value: vllm
- name: USER
value: vllmAplique o manifesto do InferenceService:
oc apply -n <namespace> -f isvc-<model-name>.yamlVerificar a implantação
Monitore o status da implantação, a inicialização dos pods e os logs do runtime:
# Aguarda o InferenceService atingir o estado Ready
oc get inferenceservice <model-name> -n <namespace> -w
# Aguarda a inicialização do pod predictor
oc get pods -n <namespace> -w
# Acompanha os logs do predictor (o carregamento do modelo pode levar vários minutos após Running)
oc logs -f deployment/<model-name>-predictor -n <namespace>Quando o InferenceService reportar READY: True, valide o endpoint.
Verifique o registro do modelo e envie uma requisição de inferência de teste:
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
}'Solução de problemas
| Problema | Possível causa | Resolução |
|---|---|---|
ErrImagePull | Credenciais de registro ausentes ou inválidas | Confirme que model-registry-secret existe, tem credenciais válidas e está vinculado a model-puller-sa usando tanto oc secrets link quanto o patch imagePullSecrets. |
ImagePullBackOff | Image pull secret não configurado para o ModelCar | Garanta que a service account inclua a entrada imagePullSecrets. Consulte o comando oc patch serviceaccount no passo 3. |
Predictor permanece em Init:0/1 | Download da imagem do modelo em andamento | Verifique os eventos oc describe pod para o progresso de Pulling/Pulled; o tempo de extração escala com o tamanho da imagem e a largura de banda do registro. |
Predictor permanece em Init:0/1 indefinidamente | Arquivos do modelo não encontrados | Verifique se os arquivos do modelo estão armazenados sob /models na imagem OCI. |
Engine core initialization failed | Timeout inicial de compilação CUDA | A primeira inicialização pode levar mais tempo enquanto os caches são gerados. Reinicie e tente novamente. |
| Falha no carregamento do modelo | Formato de arquivo de modelo não suportado | Use arquivos safetensors do Hugging Face e exclua checkpoints legados. |
| Erros de autoteste FIPS do OpenSSL | A imagem do contêiner não é compatível com FIPS | Use uma imagem vLLM compatível com FIPS. |
OutOfMemory / OOMKilled | Memória GPU insuficiente | Aumente os recursos de GPU, reduza o tamanho do contexto ou use um modelo quantizado. |
InferenceService permanece em Pending | Recursos do cluster indisponíveis | Verifique a disponibilidade de GPU e libere recursos de cargas de trabalho não utilizadas. |
Recursos adicionais
Usando endpoints de modelos em nuvem pública
Use esta opção quando os modelos são hospedados por um provedor de nuvem, como IBM watsonx, AWS Bedrock, Azure OpenAI ou Google Vertex AI.
Pré-requisitos:
- Conectividade HTTPS de saída (porta 443) do cluster Red Hat OpenShift Container Platform (OCP) para o endpoint do serviço de nuvem.
- Chaves de API válidas, credenciais IAM ou credenciais de autenticação equivalentes.
Antes de começar:
Garanta que:
- A implantação do modelo está provisionada e ativa.
- As credenciais de autenticação foram geradas e armazenadas com segurança.
- Quaisquer requisitos de rede ou acesso específicos do provedor foram concluídos.
Após o endpoint estar disponível, prossiga para Configurando o model inference gateway.
Usando endpoints de modelos em infraestrutura privada
Use esta opção quando os modelos são hospedados em infraestrutura gerenciada pelo cliente fora do cluster IBM Bob, como:
- Servidores GPU dedicados
- Clusters OpenShift separados
- Servidores de inferência bare-metal
- Plataformas de IA empresariais
Pré-requisitos:
- O endpoint do modelo expõe uma API compatível com OpenAI.
- Há conectividade HTTPS entre o cluster IBM Bob e o endpoint.
- As credenciais de autenticação estão disponíveis como Kubernetes secrets.
Antes de começar:
Valide o seguinte:
- Conectividade de rede do cluster para o endpoint.
- Configuração de TLS ou mutual TLS, se necessário.
- As políticas de rede e firewalls permitem o acesso.
- A autenticação do endpoint está funcionando corretamente.
Após a conectividade e a autenticação serem verificadas, prossiga para Configurando o model inference gateway.