使用 KServe Modelcar 进行模型存储

Overview

KServe Modelcar,也称为基于 OCI 容器的模型存储,是在云原生环境中部署模型的强大方法。通过将模型打包为 OCI 容器镜像,您可以利用容器运行时的能力,实现更快的启动时间和更高效的资源利用。

使用 OCI 容器进行模型存储的优势

  • 减少启动时间:避免多次下载相同模型
  • 降低磁盘空间使用:减少本地下载的模型数量
  • 提升模型性能:允许预先拉取镜像以加快加载速度
  • 支持离线环境:适合网络访问受限的环境
  • 简化模型分发:使用企业内部镜像仓库,如 Quay 或 Harbor

前提条件

  • 已安装并运行 Alauda AI 平台
  • 模型文件已准备好进行打包
  • 可访问容器镜像仓库(例如 Harbor、Quay)
  • 本地机器已安装 Podman 和 nerdctl

将模型打包为 OCI 镜像

方案一:使用 Busybox 基础镜像(Alauda AI 推荐)

创建一个 Containerfile,内容如下:

# 使用轻量级 busybox 作为基础镜像
FROM busybox
 
# 创建模型目录并设置权限
RUN mkdir -p /models && chmod 775 /models
 
# 注意:Harbor 对每个镜像层的文件大小有限制。
# 建议将大文件(例如 4GB 的 .safetensors)分批复制,每层复制 2 个文件。
# 最后一层复制剩余的模型配置文件。
# 示例:
# COPY models/model-00001-of-00004.safetensors models/model-00002-of-00004.safetensors /models/
# COPY models/model-00003-of-00004.safetensors models/model-00004-of-00004.safetensors /models/
# COPY models/*.json models/*.md models/*.txt /models/

# 如果大小不是问题,可以直接复制所有内容:
COPY models/ /models/
 
# 根据 KServe 约定,模型加载器通常只需要镜像层
# 无需保持运行状态,但调试时可添加 CMD

方案二:使用 UBI Micro 基础镜像(Red Hat 推荐)

创建一个 Containerfile,内容如下:

FROM registry.access.redhat.com/ubi9/ubi-micro:latest
COPY --chown=0:0 models /models
RUN chmod -R a=rX /models

# nobody 用户
USER 65534

构建并推送模型镜像

  1. 创建一个临时目录用于存放模型及支持文件:

    cd $(mktemp -d)
  2. 创建 models 文件夹(对于 OpenVINO 等框架,可选创建版本子目录):

    mkdir -p models/1
  3. 将模型文件复制到对应目录:

    • 对于大多数框架:cp -r your-model-folder/* models/
    • 对于 OpenVINO:cp -r your-model-folder/* models/1/
  4. 构建 OCI 容器镜像:

    # 使用 Podman
    podman build --format=oci -t <registry>/<repository>:<tag> .
    
    # 使用 nerdctl
    nerdctl build -t <registry>/<repository>:<tag> .
  5. 将镜像推送到容器镜像仓库:

    # 使用 Podman
    podman push <registry>/<repository>:<tag>
    
    # 使用 nerdctl
    nerdctl push <registry>/<repository>:<tag>

    注意 如果您的仓库是私有的,请确保在上传容器镜像前已完成镜像仓库的认证。

从 OCI 镜像部署模型

部署前提条件

除上述通用前提条件外,无需额外条件。

创建 InferenceService

创建一个 InferenceService YAML 文件,内容如下:

kind: InferenceService
apiVersion: serving.kserve.io/v1beta1
metadata:
  annotations:
    aml-model-repo: Qwen2.5-0.5B-Instruct
    aml-pipeline-tag: text-generation
    serving.kserve.io/deploymentMode: Standard
  labels:
    aml-pipeline-tag: text-generation
    aml.cpaas.io/runtime-type: vllm
  name: oci-demo
  namespace: demo-space
spec:
  predictor:
    maxReplicas: 1
    minReplicas: 1
    model:
      modelFormat:
        name: transformers
      protocolVersion: v2
      resources:
        limits:
          cpu: '2'
          ephemeral-storage: 10Gi
          memory: 8Gi
        requests:
          cpu: '2'
          memory: 4Gi
      runtime: aml-vllm-0.11.2-cpu
      storageUri: oci://<registry>/<repository>:<tag>
    securityContext:
      seccompProfile:
        type: RuntimeDefault
  1. Qwen2.5-0.5B-Instruct 替换为您的实际模型名称。
  2. aml.cpaas.io/runtime-type: vllm 指定代码运行时类型。有关自定义推理运行时的更多信息,请参见 Extend Inference Runtimes
  3. demo-space 替换为已存在的命名空间,或先使用 kubectl create namespace demo-space 创建。
  4. aml-vllm-0.11.2-cpu 替换为您平台中已安装的运行时名称(对应 ClusterServingRuntime CRD 实例)。
  5. storageUri 指定存储模型的带标签 OCI 镜像 URI。请使用完整的镜像仓库 URL。例如:storageUri: oci://docker.io/alaudadockerhub/models-qwen2.5:v1

应用 InferenceService

使用 kubectl 应用 InferenceService 配置:

kubectl apply -f oci-inference-service.yaml

验证部署

检查 InferenceService 状态:

kubectl get inferenceservices -n demo-space

部署成功后,您应看到服务处于 Ready 状态。

如果服务启动失败或一直处于未就绪状态,可以通过以下方式排查:

  1. 查看 InferenceService 事件以获取详细错误信息:
    kubectl describe inferenceservice oci-demo -n demo-space
  2. 查看预测器 Pod 日志:
    kubectl logs -n demo-space -l serving.kserve.io/inferenceservice=oci-demo
  3. 验证模型镜像能否在集群节点上成功拉取:
    # 在集群节点上执行
    crictl pull <registry>/<repository>:<tag>

最佳实践

  1. 模型版本管理:使用容器镜像标签对模型进行版本控制
  2. 镜像体积优化:使用轻量级基础镜像,仅包含必要的模型文件
  3. 仓库管理:使用具备访问控制的私有仓库
  4. 安全性:遵循容器安全最佳实践,定期进行漏洞扫描
  5. 缓存利用:利用容器镜像仓库缓存提升拉取速度

故障排查

常见问题

  1. 权限错误:确保镜像中的模型文件权限正确
  2. 仓库认证:确认集群有权限访问容器镜像仓库

结论

使用 KServe Modelcar(基于 OCI 容器的模型存储)为 Alauda AI 平台提供了一种高效的模型部署方式。通过本指南中的步骤,您可以将模型打包为 OCI 镜像,并实现更快的启动时间和更优的资源利用。