模型服務基礎架構

當你的環境尚未提供模型服務解決方案時,為 IBM Bob 本地部署和設定模型端點。

在將 IBM Bob 連線到大型語言模型(LLM)之前,你必須先能夠存取已部署的模型端點。Bob IDE 不會佈建、託管或管理模型服務基礎架構。如果你的組織已透過 Red Hat OpenShift Container Platform(OCP)AI、GPU 推論伺服器、雲端 AI 服務或其他推論平台提供模型端點,請直接前往設定模型推論閘道。

選擇最適合你的環境和維運需求的選項。

選項適用場景
OpenShift AI(叢集內,OCI/ModelCar)氣隙或自託管模型;叢集上已有 Red Hat OpenShift AI
公有雲模型端點透過 AWS Bedrock、Azure OpenAI 或 Google Vertex AI 使用前沿模型
私有基礎架構模型端點模型部署於獨立 GPU 伺服器或專用推論叢集上

使用 OpenShift AI 部署模型(叢集內,OCI/ModelCar)

Red Hat OpenShift AI(RHOAI)是在叢集內部署模型的建議平台,包括氣隙部署。載入模型權重的首選方法是 OCI/ModelCar 模式:模型檔案被打包到 OCI 映像檔的 /models/ 目錄下,並推送到私有登錄。部署 InferenceService 時,KServe 會注入 modelcar-init 初始化容器,該容器拉取映像檔並將權重複製到共用磁碟區的 /mnt/models/,供服務執行環境(例如 vLLM)載入。模型映像檔在首次拉取後會在節點上快取;後續在同一節點上重啟時不需要重新下載。

前提條件:

  • 叢集上已安裝 Red Hat OpenShift AI Operator
  • KServe 已啟用並設定完畢
  • 已啟用 GPU 的工作節點,並配置了 NVIDIA GPU Operator(或同等解決方案)
  • oc CLI 已通過目標叢集的身分驗證,且具有在目標命名空間中建立資源的權限
  • 叢集可存取的私有容器登錄,以及推送映像檔的憑證

設定 Red Hat OpenShift AI

如下所示設定 DataScienceClusterInitialization 和 DataScienceCluster 資源:

  • 停用 serviceMesh。
  • 透過設定 managementState: Managed 啟用 KServe。
  • 設定 KServe 使用 RawDeployment 模式。
  • 移除所有未使用的 Red Hat OpenShift AI 元件。

KServe 設定範例:

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

啟用 ModelCar 支援

ModelCar 支援由 redhat-ods-applications 命名空間中的 inferenceservice-config ConfigMap 控制。storageInitializer 金鑰必須包含 "enableModelcar": true。

驗證目前設定:

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

輸出必須包含:

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

如果 enableModelcar 缺失或為 false,請更新 ConfigMap:

# 擷取目前值,合併旗標,然後套用修補
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 以套用變更:

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

將模型檔案打包成 OCI 映像檔

從 Hugging Face 下載模型權重,並將其打包成 OCI 映像檔。映像檔必須將所有模型檔案存放在 /models 目錄下。如需詳細資訊,請參閱 KServe 關於準備含有模型資料的 OCI 映像檔的文件。對於 vLLM 部署,請包含 safetensors 模型分片,並排除 .bin、.pt 和 original/* 等舊版 checkpoint 檔案。

Dockerfile 範例:

FROM busybox:latest

# 模型權重——safetensors 分片和索引
COPY <model-name>/model-*.safetensors        /models/
COPY <model-name>/model.safetensors.index.json /models/

# 模型設定
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/

如果模型包含聊天範本(例如 chat_template.jinja),請將其加入。或者,以單一指令複製整個目錄,這樣更簡單,但會包含 vLLM 不需要的檔案:

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

將映像檔推送到私有登錄

將 OCI 映像檔推送到叢集可存取的私有容器登錄:

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

使用適合你環境的工具(podman push、skopeo copy、CI pipeline 等)。

建立目標命名空間和映像檔提取 Secret

建立專案命名空間,並設定拉取模型映像檔的憑證。

建立命名空間:

oc new-project <namespace>

建立登錄提取 Secret:

# 提取 Secret,讓 KServe 能從你的私有登錄拉取模型映像檔
oc create secret docker-registry model-registry-secret \
  --docker-server=<registry> \
  --docker-username=<username> \
  --docker-password=<password-or-token> \
  -n <namespace>

建立服務帳戶:

# KServe predictor 使用的服務帳戶
oc create sa model-puller-sa -n <namespace>

將提取 Secret 與服務帳戶關聯:

# 附加提取 Secret——兩個指令都是必要的:
# oc secrets link 負責一般的 Secret 使用;
# imagePullSecrets 是 KServe 的 ModelCar init 容器特別需要的
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"}]}'
注意:

兩個指令都是必要的。imagePullSecrets 條目在模型映像檔擷取期間由 ModelCar 初始化容器使用。

建立 ServingRuntime

在目標命名空間中部署以 vLLM 為基礎的 ServingRuntime。

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

套用執行環境設定:

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

部署 InferenceService

建立使用 oci:// 儲存 URI 參照 OCI 模型映像檔的 InferenceService。

主要設定需求:

  • 參照先前建立的 ServingRuntime。
  • 在 storageUri 中指定 OCI 映像檔位置。
  • 設定符合模型需求的 CPU、記憶體和 GPU 資源限制。
  • 為 vLLM 掛載共用記憶體(/dev/shm)。
  • 設定 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>"          # 例如 "8"
        limits:
          cpu: "<cpu-limit>"            # 例如 "16"
          memory: <memory-limit>        # 例如 96Gi——依模型 VRAM 需求設定
          nvidia.com/gpu: "<gpu-count>" # 例如 "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 日誌行以避免日誌過多
        - 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>" # 必須與上方 nvidia.com/gpu 限制相符
        - name: CUDA_VISIBLE_DEVICES
          value: "<gpu-indices>" # 例如單個 GPU 使用 "0";兩個 GPU 使用 "0,1"
        - name: VLLM_WORKER_MULTIPROC_METHOD
          value: spawn
        - name: LOGNAME
          value: vllm
        - name: USER
          value: vllm

套用 InferenceService 清單:

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

驗證部署

監控部署狀態、Pod 啟動和執行環境日誌:

# 監看 InferenceService 達到 Ready 狀態
oc get inferenceservice <model-name> -n <namespace> -w

# 監看 predictor Pod 啟動
oc get pods -n <namespace> -w

# 追蹤 predictor 日誌(模型載入在 Running 後可能需要幾分鐘)
oc logs -f deployment/<model-name>-predictor -n <namespace>

當 InferenceService 回報 READY: True 時,驗證端點。

驗證模型註冊並發送測試推論請求:

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

疑難排解

問題可能原因解決方案
ErrImagePull登錄憑證遺失或無效確認 model-registry-secret 存在、憑證有效,並已使用 oc secrets link 和 imagePullSecrets 修補連結到 model-puller-sa。
ImagePullBackOffModelCar 的映像檔提取 Secret 未設定確保服務帳戶包含 imagePullSecrets 條目。請參閱步驟 3 中的 oc patch serviceaccount 指令。
Predictor 持續停留在 Init:0/1模型映像檔下載中查看 oc describe pod 事件中的 Pulling/Pulled 進度;拉取時間取決於映像檔大小和登錄頻寬。
Predictor 無限期停留在 Init:0/1找不到模型檔案確認模型檔案存放在 OCI 映像檔的 /models 目錄下。
Engine core initialization failedCUDA 初始編譯逾時首次啟動時生成快取可能需要較長時間。重新啟動後重試。
模型載入失敗不支援的模型檔案格式使用 Hugging Face safetensors 檔案,並排除舊版 checkpoint。
OpenSSL FIPS 自我測試錯誤容器映像檔不符合 FIPS使用符合 FIPS 的 vLLM 映像檔。
OutOfMemory / OOMKilledGPU 記憶體不足增加 GPU 資源、縮短 context 長度,或使用量化模型。
InferenceService 持續處於 Pending叢集資源不足驗證 GPU 可用性並釋放未使用工作負載的資源。

其他資源

使用公有雲模型端點

當模型由雲端供應商託管時(例如 IBM watsonx、AWS Bedrock、Azure OpenAI 或 Google Vertex AI),請使用此選項。

前提條件:

  • 從 Red Hat OpenShift Container Platform(OCP)叢集到雲端服務端點的輸出 HTTPS(連接埠 443)連線能力。
  • 有效的 API 金鑰、IAM 憑證或同等的身分驗證憑證。

開始之前:

請確認:

  • 模型部署已佈建且正常運作。
  • 身分驗證憑證已生成並安全儲存。
  • 所有供應商特定的網路或存取需求均已完成。

端點可用後,請前往設定模型推論閘道。

使用私有基礎架構模型端點

當模型託管在 IBM Bob 叢集外的客戶管理基礎架構上時,請使用此選項,例如:

  • 專用 GPU 伺服器
  • 獨立的 OpenShift 叢集
  • 裸機推論伺服器
  • 企業 AI 平台

前提條件:

  • 模型端點公開 OpenAI 相容的 API。
  • IBM Bob 叢集與端點之間具備 HTTPS 連線能力。
  • 身分驗證憑證可作為 Kubernetes Secret 使用。

開始之前:

驗證以下事項:

  • 從叢集到端點的網路連線能力。
  • TLS 或雙向 TLS 設定(如有需要)。
  • 網路政策和防火牆允許存取。
  • 端點身分驗證運作正常。

驗證連線和身分驗證後,請前往設定模型推論閘道。

這個主題如何?