模型提供基础架构

当你的环境尚未提供模型提供解决方案时,为 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 模式:模型文件被打包到 /models/ 下的 OCI 镜像中并推送到私有镜像仓库。部署 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 控制器以应用更改:

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 目录下。有关更多信息,请参阅关于准备包含模型数据的 OCI 镜像的 KServe 文档。对于 vLLM 部署,包含 safetensors 模型分片并排除旧版检查点文件(如 .bin、.pt 和 original/*)。

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/

# 分词器
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 流水线等)。

创建目标命名空间和镜像拉取 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 预测器使用的服务账号
oc create sa model-puller-sa -n <namespace>

将拉取 Secret 与服务账号关联:

# 附加拉取 Secret -- 两条命令都是必需的:
# oc secrets link 涵盖常规 Secret 使用;
# KServe 的 ModelCar 初始化容器专门需要 imagePullSecrets
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"}]}'
注意:

两条命令都是必需的。ModelCar 初始化容器在模型镜像检索期间使用 imagePullSecrets 条目。

创建 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 -- 根据模型显存要求调整大小
          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";两个为 "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

# 观察预测器 Pod 启动
oc get pods -n <namespace> -w

# 跟踪预测器日志(一旦运行,模型加载可能需要几分钟)
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。
ImagePullBackOff未针对 ModelCar 配置镜像拉取 Secret确保服务账号包含 imagePullSecrets 条目。请参阅步骤 3 中的 oc patch serviceaccount 命令。
预测器保持在 Init:0/1正在下载模型镜像检查 oc describe pod 事件中的 Pulling/Pulled 进度;拉取时间与镜像大小和镜像仓库带宽成比例。
预测器无限期保持在 Init:0/1未找到模型文件验证模型文件是否存储在 OCI 镜像中的 /models 下。
Engine core initialization failed初始 CUDA 编译超时在生成缓存时,首次启动可能需要更长时间。重启并重试。
模型加载失败不支持的模型文件格式使用 Hugging Face safetensors 文件并排除旧版检查点。
OpenSSL FIPS 自检错误容器镜像不兼容 FIPS使用兼容 FIPS 的 vLLM 镜像。
OutOfMemory / OOMKilledGPU 内存不足增加 GPU 资源、减少上下文长度或使用量化模型。
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 配置(如果需要)。
  • 网络策略和防火墙允许访问。
  • 端点身份验证正常工作。

在验证连接和身份验证后,请转到配置模型推理网关。

这个主题怎么样?