Infrastruktura obsługi modeli

Wdróż i skonfiguruj punkty końcowe modeli dla IBM Bob on-premises, gdy środowisko nie dysponuje jeszcze rozwiązaniem do obsługi modeli.

Zanim będziesz mógł podłączyć IBM Bob do dużego modelu językowego (LLM), musisz mieć dostęp do wdrożonego punktu końcowego modelu. Bob IDE nie udostępnia, nie hostuje ani nie zarządza infrastrukturą obsługi modeli. Jeśli Twoja organizacja udostępnia już punkty końcowe modeli za pośrednictwem Red Hat OpenShift Container Platform (OCP) AI, serwerów wnioskowania opartych na GPU, usług AI w chmurze lub innych platform wnioskowania, przejdź bezpośrednio do Konfiguracja bramy wnioskowania modelu.

Wybierz opcję najlepiej dopasowaną do środowiska i wymagań operacyjnych.

OpcjaKiedy używać
OpenShift AI (on-cluster, OCI/ModelCar)Modele hostowane lokalnie lub w środowisku air-gapped; Red Hat OpenShift AI jest już dostępny w klastrze
Punkty końcowe modeli w chmurze publicznejModele czołowe przez AWS Bedrock, Azure OpenAI lub Google Vertex AI
Punkty końcowe modeli na prywatnej infrastrukturzeModel obsługiwany na dedykowanych serwerach GPU lub dedykowanym klastrze wnioskowania

Wdrażanie modeli z OpenShift AI (on-cluster, OCI/ModelCar)

Red Hat OpenShift AI (RHOAI) to zalecana platforma do obsługi modeli w klastrze, w tym wdrożeń air-gapped. Preferowanym podejściem do ładowania wag modeli jest wzorzec OCI/ModelCar: pliki modelu są wbudowane w obraz OCI w katalogu /models/ i przesyłane do prywatnego rejestru. Gdy wdrażany jest InferenceService, KServe wprowadza kontener inicjalizacyjny modelcar-init, który pobiera obraz i kopiuje wagi do woluminu współdzielonego w ścieżce /mnt/models/, skąd środowisko wykonawcze obsługi (np. vLLM) je wczytuje. Obraz modelu jest buforowany na węźle po pierwszym pobraniu; kolejne restarty na tym samym węźle pomijają pobieranie.

Wymagania wstępne:

  • Operator Red Hat OpenShift AI zainstalowany w klastrze
  • KServe włączony i skonfigurowany
  • Węzły robocze obsługujące GPU z skonfigurowanym operatorem NVIDIA GPU (lub równoważnym)
  • Narzędzie oc CLI uwierzytelnione w docelowym klastrze z uprawnieniami do tworzenia zasobów w docelowej przestrzeni nazw
  • Prywatny rejestr kontenerów dostępny z klastra, z danymi uwierzytelniającymi do wypychania obrazów

Konfiguracja Red Hat OpenShift AI

Skonfiguruj zasoby DataScienceClusterInitialization i DataScienceCluster w następujący sposób:

  • Wyłącz serviceMesh.
  • Włącz KServe, ustawiając managementState: Managed.
  • Skonfiguruj KServe w trybie RawDeployment.
  • Usuń wszystkie nieużywane komponenty Red Hat OpenShift AI.

Przykładowa konfiguracja KServe:

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

Włączanie obsługi ModelCar

Obsługa ModelCar jest kontrolowana przez ConfigMap inferenceservice-config w przestrzeni nazw redhat-ods-applications. Klucz storageInitializer musi zawierać "enableModelcar": true.

Zweryfikuj bieżącą konfigurację:

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

Dane wyjściowe muszą zawierać:

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

Jeśli enableModelcar jest brakujące lub ma wartość false, zaktualizuj ConfigMap:

# Pobierz bieżącą wartość, scal flagę i zastosuj 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()))')}}"

Zrestartuj kontroler KServe, aby zastosować zmianę:

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

Spakuj pliki modelu do obrazu OCI

Pobierz wagi modelu z Hugging Face i spakuj je do obrazu OCI. Obraz musi zawierać wszystkie pliki modelu w katalogu /models. Więcej informacji można znaleźć w dokumentacji KServe dotyczącej przygotowania obrazu OCI z danymi modelu. W przypadku wdrożeń vLLM dołącz fragmenty modelu safetensors i wyklucz starsze pliki punktów kontrolnych, takie jak .bin, .pt oraz original/*.

Przykładowy Dockerfile:

FROM busybox:latest

# Wagi modelu -- fragmenty i indeks safetensors
COPY <model-name>/model-*.safetensors        /models/
COPY <model-name>/model.safetensors.index.json /models/

# Konfiguracja modelu
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/

Jeśli model zawiera szablon czatu (np. chat_template.jinja), dodaj go. Alternatywnie skopiuj cały katalog jedną instrukcją, co jest prostsze, ale obejmuje pliki niewymagane przez vLLM:

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

Wypchnij obraz do prywatnego rejestru

Wypchnij obraz OCI do prywatnego rejestru kontenerów dostępnego z klastra:

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

Użyj narzędzia odpowiedniego dla swojego środowiska (podman push, skopeo copy, pipeline CI itp.).

Utwórz docelową przestrzeń nazw i sekret do pobierania obrazu

Utwórz przestrzeń nazw projektu i skonfiguruj dane uwierzytelniające do pobierania obrazu modelu.

Utwórz przestrzeń nazw:

oc new-project <namespace>

Utwórz sekret do pobierania z rejestru:

# Sekret pull, aby KServe mógł pobierać obraz modelu z prywatnego rejestru
oc create secret docker-registry model-registry-secret \
  --docker-server=<registry> \
  --docker-username=<username> \
  --docker-password=<password-or-token> \
  -n <namespace>

Utwórz konto usługi:

# Konto usługi używane przez predyktor KServe
oc create sa model-puller-sa -n <namespace>

Powiąż sekret pull z kontem usługi:

# Dołącz sekret pull -- obie komendy są wymagane:
# oc secrets link obejmuje ogólne użycie sekretu;
# imagePullSecrets jest wymagane konkretnie przez kontener init ModelCar 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"}]}'
Uwaga:

Obie komendy są wymagane. Wpis imagePullSecrets jest używany przez kontener inicjalizacyjny ModelCar podczas pobierania obrazu modelu.

Utwórz ServingRuntime

Wdróż ServingRuntime oparty na vLLM w docelowej przestrzeni nazw.

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

Zastosuj konfigurację środowiska wykonawczego:

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

Wdróż InferenceService

Utwórz InferenceService odwołujący się do obrazu OCI modelu przy użyciu URI pamięci masowej oci://.

Kluczowe wymagania konfiguracyjne:

  • Odwołaj się do wcześniej utworzonego ServingRuntime.
  • Określ lokalizację obrazu OCI w storageUri.
  • Skonfiguruj limity zasobów CPU, pamięci i GPU odpowiadające wymaganiom modelu.
  • Zamontuj pamięć współdzieloną (/dev/shm) dla vLLM.
  • Skonfiguruj argumenty środowiska wykonawczego vLLM i zmienne środowiskowe.
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>"          # np. "8"
        limits:
          cpu: "<cpu-limit>"            # np. "16"
          memory: <memory-limit>        # np. 96Gi -- dostosuj do wymagań VRAM modelu
          nvidia.com/gpu: "<gpu-count>" # np. "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"        # skróć linie dziennika vLLM, aby uniknąć zalewania logami
        - 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>" # musi odpowiadać limitowi nvidia.com/gpu powyżej
        - name: CUDA_VISIBLE_DEVICES
          value: "<gpu-indices>" # np. "0" dla jednego GPU; "0,1" dla dwóch
        - name: VLLM_WORKER_MULTIPROC_METHOD
          value: spawn
        - name: LOGNAME
          value: vllm
        - name: USER
          value: vllm

Zastosuj manifest InferenceService:

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

Zweryfikuj wdrożenie

Monitoruj stan wdrożenia, uruchamianie podów i dzienniki środowiska wykonawczego:

# Obserwuj osiąganie stanu Ready przez InferenceService
oc get inferenceservice <model-name> -n <namespace> -w

# Obserwuj uruchamianie poda predyktora
oc get pods -n <namespace> -w

# Śledź dzienniki predyktora (ładowanie modelu może potrwać kilka minut po uruchomieniu)
oc logs -f deployment/<model-name>-predictor -n <namespace>

Gdy InferenceService zgłosi READY: True, zweryfikuj punkt końcowy.

Sprawdź rejestrację modelu i wyślij testowe żądanie wnioskowania:

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

Rozwiązywanie problemów

ProblemMożliwa przyczynaRozwiązanie
ErrImagePullBrakujące lub nieprawidłowe dane uwierzytelniające rejestruUpewnij się, że model-registry-secret istnieje, ma prawidłowe dane uwierzytelniające i jest powiązany z model-puller-sa przy użyciu zarówno oc secrets link, jak i patcha imagePullSecrets.
ImagePullBackOffSekret pull obrazu nie skonfigurowany dla ModelCarUpewnij się, że konto usługi zawiera wpis imagePullSecrets. Zobacz komendę oc patch serviceaccount w kroku 3.
Predyktor pozostaje w Init:0/1Pobieranie obrazu modelu w tokuSprawdź zdarzenia oc describe pod dotyczące postępu Pulling/Pulled; czas pobierania zależy od rozmiaru obrazu i przepustowości rejestru.
Predyktor pozostaje w Init:0/1 w nieskończonośćNie znaleziono plików modeluSprawdź, czy pliki modelu są przechowywane w katalogu /models w obrazie OCI.
Engine core initialization failedPrzekroczenie limitu czasu wstępnej kompilacji CUDAPierwsze uruchomienie może trwać dłużej podczas generowania pamięci podręcznych. Zrestartuj i spróbuj ponownie.
Ładowanie modelu kończy się niepowodzeniemNieobsługiwany format pliku modeluUżywaj plików safetensors z Hugging Face i wyklucz starsze punkty kontrolne.
Błędy autotestu FIPS OpenSSLObraz kontenera nie jest zgodny z FIPSUżyj obrazu vLLM zgodnego z FIPS.
OutOfMemory / OOMKilledNiewystarczająca pamięć GPUZwiększ zasoby GPU, zmniejsz długość kontekstu lub użyj skwantyzowanego modelu.
InferenceService pozostaje w stanie PendingZasoby klastra niedostępneSprawdź dostępność GPU i zwolnij zasoby z nieużywanych obciążeń.

Dodatkowe zasoby

Używanie punktów końcowych modeli w chmurze publicznej

Użyj tej opcji, gdy modele są hostowane przez dostawcę chmury, na przykład IBM watsonx, AWS Bedrock, Azure OpenAI lub Google Vertex AI.

Wymagania wstępne:

  • Wychodząca łączność HTTPS (port 443) z klastra Red Hat OpenShift Container Platform (OCP) do punktu końcowego usługi chmurowej.
  • Prawidłowe klucze API, dane uwierzytelniające IAM lub równoważne dane uwierzytelniające.

Przed rozpoczęciem:

Upewnij się, że:

  • Wdrożenie modelu jest zaaprowizowane i aktywne.
  • Dane uwierzytelniające są wygenerowane i bezpiecznie przechowywane.
  • Wszelkie specyficzne dla dostawcy wymagania sieciowe lub dotyczące dostępu są spełnione.

Gdy punkt końcowy jest dostępny, przejdź do Konfiguracja bramy wnioskowania modelu.

Używanie punktów końcowych modeli na prywatnej infrastrukturze

Użyj tej opcji, gdy modele są hostowane na infrastrukturze zarządzanej przez klienta poza klastrem IBM Bob, na przykład:

  • Dedykowane serwery GPU
  • Oddzielne klastry OpenShift
  • Serwery wnioskowania bare-metal
  • Korporacyjne platformy AI

Wymagania wstępne:

  • Punkt końcowy modelu udostępnia API zgodne z OpenAI.
  • Łączność HTTPS istnieje między klastrem IBM Bob a punktem końcowym.
  • Dane uwierzytelniające są dostępne jako Kubernetes secrets.

Przed rozpoczęciem:

Zweryfikuj następujące kwestie:

  • Łączność sieciowa z klastra do punktu końcowego.
  • Konfiguracja TLS lub wzajemnego TLS, jeśli jest wymagana.
  • Zasady sieciowe i zapory sieciowe zezwalają na dostęp.
  • Uwierzytelnianie punktu końcowego działa poprawnie.

Po zweryfikowaniu łączności i uwierzytelniania przejdź do Konfiguracja bramy wnioskowania modelu.

Jak oceniasz ten temat?