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çãoQuando 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úblicaModelos frontier via AWS Bedrock, Azure OpenAI ou Google Vertex AI
Endpoints de modelos em infraestrutura privadaModelo 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 oc autenticado 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: Managed

Habilitando 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-applications

Empacotar 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>:latest

Use 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"}]}'
Nota:

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: 60

Aplique a configuração do runtime:

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

Implantar 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 ServingRuntime criado 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: vllm

Aplique o manifesto do InferenceService:

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

Verificar 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

ProblemaPossível causaResolução
ErrImagePullCredenciais de registro ausentes ou inválidasConfirme 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.
ImagePullBackOffImage pull secret não configurado para o ModelCarGaranta que a service account inclua a entrada imagePullSecrets. Consulte o comando oc patch serviceaccount no passo 3.
Predictor permanece em Init:0/1Download da imagem do modelo em andamentoVerifique 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 indefinidamenteArquivos do modelo não encontradosVerifique se os arquivos do modelo estão armazenados sob /models na imagem OCI.
Engine core initialization failedTimeout inicial de compilação CUDAA primeira inicialização pode levar mais tempo enquanto os caches são gerados. Reinicie e tente novamente.
Falha no carregamento do modeloFormato de arquivo de modelo não suportadoUse arquivos safetensors do Hugging Face e exclua checkpoints legados.
Erros de autoteste FIPS do OpenSSLA imagem do contêiner não é compatível com FIPSUse uma imagem vLLM compatível com FIPS.
OutOfMemory / OOMKilledMemória GPU insuficienteAumente os recursos de GPU, reduza o tamanho do contexto ou use um modelo quantizado.
InferenceService permanece em PendingRecursos do cluster indisponíveisVerifique 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.

Como está este tópico?