Modell-Serving-Infrastruktur

Modell-Endpoints für IBM Bob On-Premises deployen und konfigurieren, wenn deine Umgebung keine Modell-Serving-Lösung bereitstellt.

Bevor du IBM Bob mit einem Large Language Model (LLM) verbinden kannst, musst du Zugriff auf einen deployten Modell-Endpoint haben. Bob IDE stellt keine Modell-Serving-Infrastruktur bereit, hostet oder verwaltet sie nicht. Wenn deine Organisation bereits Modell-Endpoints über Red Hat OpenShift Container Platform (OCP) AI, GPU-basierte Inferenzserver, Cloud-KI-Dienste oder andere Inferenzplattformen bereitstellt, fahre direkt mit Konfiguration des Modell-Inferenz-Gateways fort.

Wähle die Option, die am besten zu deiner Umgebung und deinen betrieblichen Anforderungen passt.

OptionVerwendung wenn
OpenShift AI (on-cluster, OCI/ModelCar)Air-Gapped- oder Self-Hosted-Modelle; Red Hat OpenShift AI bereits auf dem Cluster verfügbar
Öffentliche Cloud-Modell-EndpointsFrontier-Modelle über AWS Bedrock, Azure OpenAI oder Google Vertex AI
Modell-Endpoints auf privater InfrastrukturModell auf separaten GPU-Servern oder einem dedizierten Inferenz-Cluster bereitgestellt

Modelle mit OpenShift AI deployen (on-cluster, OCI/ModelCar)

Red Hat OpenShift AI (RHOAI) ist die empfohlene Plattform für das Serving von Modellen on-cluster, einschließlich Air-Gapped-Deployments. Der bevorzugte Ansatz zum Laden von Modellgewichten ist das OCI/ModelCar-Muster: Modelldateien werden in ein OCI-Image unter /models/ gebacken und in eine private Registry gepusht. Wenn der InferenceService deployed wird, injiziert KServe einen modelcar-init Init-Container, der das Image pullt und die Gewichte in ein gemeinsames Volume unter /mnt/models/ kopiert, aus dem die Serving-Runtime (z. B. vLLM) sie dann lädt. Das Modell-Image wird nach dem ersten Pull auf dem Node gecacht; nachfolgende Neustarts auf demselben Node überspringen den Download vollständig.

Voraussetzungen:

  • Red Hat OpenShift AI Operator auf dem Cluster installiert
  • KServe aktiviert und konfiguriert
  • GPU-fähige Worker-Nodes mit dem NVIDIA GPU Operator (oder gleichwertig) konfiguriert
  • oc CLI am Ziel-Cluster authentifiziert mit der Berechtigung, Ressourcen im Ziel-Namespace zu erstellen
  • Eine private Container-Registry, die vom Cluster aus erreichbar ist, mit Anmeldedaten zum Pushen von Images

Red Hat OpenShift AI konfigurieren

Konfiguriere die Ressourcen DataScienceClusterInitialization und DataScienceCluster wie folgt:

  • serviceMesh deaktivieren.
  • KServe durch Setzen von managementState: Managed aktivieren.
  • KServe für den RawDeployment-Modus konfigurieren.
  • Alle nicht verwendeten Red Hat OpenShift AI-Komponenten entfernen.

Beispiel für eine KServe-Konfiguration:

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

ModelCar-Unterstützung aktivieren

Die ModelCar-Unterstützung wird über die ConfigMap inferenceservice-config im Namespace redhat-ods-applications gesteuert. Der Schlüssel storageInitializer muss "enableModelcar": true enthalten.

Aktuelle Konfiguration prüfen:

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

Die Ausgabe muss Folgendes enthalten:

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

Wenn enableModelcar fehlt oder false ist, aktualisiere die ConfigMap:

# Aktuellen Wert abrufen, Flag zusammenführen und patchen
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()))')}}"

KServe-Controller neu starten, um die Änderung anzuwenden:

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

Modelldateien in ein OCI-Image packen

Lade die Modellgewichte von Hugging Face herunter und packe sie in ein OCI-Image. Das Image muss alle Modelldateien im Verzeichnis /models haben. Weitere Informationen findest du in der KServe-Dokumentation zur Vorbereitung eines OCI-Images mit Modelldaten. Schließe für vLLM-Deployments die safetensors-Modell-Shards ein und schließe Legacy-Checkpoint-Dateien wie .bin, .pt und original/* aus.

Beispiel-Dockerfile:

FROM busybox:latest

# Modellgewichte -- safetensors-Shards und Index
COPY <model-name>/model-*.safetensors        /models/
COPY <model-name>/model.safetensors.index.json /models/

# Modellkonfiguration
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/

Wenn das Modell ein Chat-Template enthält (z. B. chat_template.jinja), füge es hinzu. Alternativ kopiere das gesamte Verzeichnis in einer Anweisung, was einfacher ist, aber Dateien einschließt, die von vLLM nicht benötigt werden:

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

Das Image in eine private Registry pushen

Pushe das OCI-Image in eine private Container-Registry, die vom Cluster aus erreichbar ist:

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

Verwende die Tools, die zu deiner Umgebung passen (podman push, skopeo copy, eine CI-Pipeline usw.).

Ziel-Namespace und Image-Pull-Secret erstellen

Erstelle den Projekt-Namespace und konfiguriere Anmeldedaten zum Pullen des Modell-Images.

Namespace erstellen:

oc new-project <namespace>

Registry-Pull-Secret erstellen:

# Pull-Secret, damit KServe das Modell-Image aus deiner privaten Registry pullen kann
oc create secret docker-registry model-registry-secret \
  --docker-server=<registry> \
  --docker-username=<username> \
  --docker-password=<password-or-token> \
  -n <namespace>

Service-Account erstellen:

# Service-Account, der vom KServe-Predictor verwendet wird
oc create sa model-puller-sa -n <namespace>

Pull-Secret mit dem Service-Account verknüpfen:

# Pull-Secret verknüpfen -- beide Befehle sind erforderlich:
# oc secrets link deckt die allgemeine Secret-Nutzung ab;
# imagePullSecrets wird speziell vom KServe-ModelCar-Init-Container benötigt
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"}]}'
Hinweis:

Beide Befehle sind erforderlich. Der Eintrag imagePullSecrets wird vom ModelCar-Initialisierungs-Container während des Modell-Image-Abrufs verwendet.

ServingRuntime erstellen

Deploye eine vLLM-basierte ServingRuntime im Ziel-Namespace.

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

Runtime-Konfiguration anwenden:

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

InferenceService deployen

Erstelle einen InferenceService, der das OCI-Modell-Image über eine oci://-Storage-URI referenziert.

Wichtige Konfigurationsanforderungen:

  • Die zuvor erstellte ServingRuntime referenzieren.
  • Den OCI-Image-Speicherort in storageUri angeben.
  • CPU-, Memory- und GPU-Ressourcenlimits konfigurieren, die den Modellanforderungen entsprechen.
  • Shared Memory (/dev/shm) für vLLM einbinden.
  • vLLM-Runtime-Argumente und Umgebungsvariablen konfigurieren.
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>"          # z. B. "8"
        limits:
          cpu: "<cpu-limit>"            # z. B. "16"
          memory: <memory-limit>        # z. B. 96Gi -- an die Modell-VRAM-Anforderungen anpassen
          nvidia.com/gpu: "<gpu-count>" # z. B. "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"        # vLLM-Protokollzeilen kürzen, um Log-Flooding zu vermeiden
        - 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>" # muss mit dem nvidia.com/gpu-Limit übereinstimmen
        - name: CUDA_VISIBLE_DEVICES
          value: "<gpu-indices>" # z. B. "0" für eine GPU; "0,1" für zwei
        - name: VLLM_WORKER_MULTIPROC_METHOD
          value: spawn
        - name: LOGNAME
          value: vllm
        - name: USER
          value: vllm

InferenceService-Manifest anwenden:

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

Deployment überprüfen

Deployment-Status, Pod-Start und Runtime-Protokolle überwachen:

# InferenceService beobachten, bis er den Status Ready erreicht
oc get inferenceservice <model-name> -n <namespace> -w

# Predictor-Pod beim Start beobachten
oc get pods -n <namespace> -w

# Predictor-Protokolle verfolgen (Modell-Laden kann nach dem Start mehrere Minuten dauern)
oc logs -f deployment/<model-name>-predictor -n <namespace>

Wenn der InferenceService READY: True meldet, den Endpoint validieren.

Modellregistrierung prüfen und eine Test-Inferenzanfrage senden:

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
  }'

Fehlerbehebung

ProblemMögliche UrsacheLösung
ErrImagePullFehlende oder ungültige Registry-AnmeldedatenSicherstellen, dass model-registry-secret existiert, gültige Anmeldedaten hat und mit model-puller-sa über oc secrets link und den imagePullSecrets-Patch verknüpft ist.
ImagePullBackOffImage-Pull-Secret nicht für ModelCar konfiguriertSicherstellen, dass der Service-Account den Eintrag imagePullSecrets enthält. Siehe oc patch serviceaccount-Befehl in Schritt 3.
Predictor verbleibt in Init:0/1Modell-Image-Download läuftoc describe pod-Ereignisse auf Pulling/Pulled-Fortschritt prüfen; Pull-Zeit skaliert mit Image-Größe und Registry-Bandbreite.
Predictor verbleibt dauerhaft in Init:0/1Modelldateien nicht gefundenSicherstellen, dass Modelldateien unter /models im OCI-Image gespeichert sind.
Engine core initialization failedInitiales CUDA-Kompilierungs-TimeoutDer erste Start kann länger dauern, während Caches generiert werden. Neu starten und erneut versuchen.
Modell-Laden schlägt fehlNicht unterstütztes Modell-DateiformatHugging-Face-safetensors-Dateien verwenden und Legacy-Checkpoints ausschließen.
OpenSSL FIPS-Selbsttest-FehlerContainer-Image ist nicht FIPS-kompatibelEin FIPS-kompatibles vLLM-Image verwenden.
OutOfMemory / OOMKilledUnzureichender GPU-SpeicherGPU-Ressourcen erhöhen, Kontextlänge reduzieren oder ein quantisiertes Modell verwenden.
InferenceService verbleibt in PendingCluster-Ressourcen nicht verfügbarGPU-Verfügbarkeit prüfen und Ressourcen von ungenutzten Workloads freigeben.

Weitere Ressourcen

Öffentliche Cloud-Modell-Endpoints verwenden

Verwende diese Option, wenn Modelle von einem Cloud-Anbieter gehostet werden, z. B. IBM watsonx, AWS Bedrock, Azure OpenAI oder Google Vertex AI.

Voraussetzungen:

  • Ausgehende HTTPS-Verbindung (Port 443) vom Red Hat OpenShift Container Platform (OCP)-Cluster zum Cloud-Service-Endpoint.
  • Gültige API-Schlüssel, IAM-Anmeldedaten oder gleichwertige Authentifizierungsdaten.

Vor dem Start:

Sicherstellen, dass:

  • Das Modell-Deployment bereitgestellt und aktiv ist.
  • Authentifizierungsdaten generiert und sicher gespeichert sind.
  • Alle anbieterspezifischen Netzwerk- oder Zugriffsanforderungen erfüllt sind.

Nach Verfügbarkeit des Endpoints mit Konfiguration des Modell-Inferenz-Gateways fortfahren.

Modell-Endpoints auf privater Infrastruktur verwenden

Verwende diese Option, wenn Modelle auf kundenverwalteter Infrastruktur außerhalb des IBM-Bob-Clusters gehostet werden, z. B.:

  • Dedizierte GPU-Server
  • Separate OpenShift-Cluster
  • Bare-Metal-Inferenzserver
  • Enterprise-KI-Plattformen

Voraussetzungen:

  • Der Modell-Endpoint stellt eine OpenAI-kompatible API bereit.
  • HTTPS-Konnektivität zwischen dem IBM-Bob-Cluster und dem Endpoint ist vorhanden.
  • Authentifizierungsdaten sind als Kubernetes-Secrets verfügbar.

Vor dem Start:

Folgendes validieren:

  • Netzwerkkonnektivität vom Cluster zum Endpoint.
  • TLS- oder Mutual-TLS-Konfiguration, falls erforderlich.
  • Netzwerkrichtlinien und Firewalls erlauben den Zugriff.
  • Endpoint-Authentifizierung funktioniert korrekt.

Nach Überprüfung der Konnektivität und Authentifizierung mit Konfiguration des Modell-Inferenz-Gateways fortfahren.

Wie ist dieses Thema?