使用 KServe Modelcar 进行模型存储

概述

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

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

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

先决条件

  • 已安装并运行 Alauda AI platform
  • 已准备好可用于打包的模型文件
  • 对 container registry(例如 Harbor、Quay)具有写入/推送权限
  • 本地机器上已安装 Podman 或 nerdctl

将模型打包为 OCI Image

选项 1:使用 Busybox Base Image(Alauda AI 推荐)

创建一个包含以下内容的 Containerfile:

# Use lightweight busybox as base image
FROM busybox
 
# Create directory for model and set permissions
RUN mkdir -p /models && chmod 775 /models
 
# Note: Harbor has a file size limit per image layer. 
# It is recommended to copy large files (e.g. 4GB .safetensors) in chunks of 2 files per layer.
# The last layer should copy the remaining model configuration files.
# Example:
# 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/

# If size is not an issue, you can simply copy everything:
COPY models/ /models/
 
# According to KServe convention, model loader usually only needs image layers
# No need to keep running, but can add CMD if debugging is needed

选项 2:使用 UBI Micro Base Image(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
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 container 镜像:

    # Using Podman
    podman build --format=oci -t <registry>/<repository>:<tag> .
    
    # Using nerdctl
    nerdctl build -t <registry>/<repository>:<tag> .
  5. 将镜像推送到您的 container registry:

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

    注意 如果您的 repository 是私有的,请确保在上传 container image 之前已通过 registry 身份验证。

从 OCI Image 部署模型

部署先决条件

除上述通用先决条件外,无需其他额外先决条件。

创建 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 指定了代码运行时类型。有关自定义推理运行时的更多信息,请参见 扩展推理运行时
  3. demo-space 替换为一个已存在的 namespace,或者先使用 kubectl create namespace demo-space 创建它。
  4. aml-vllm-0.11.2-cpu 替换为平台中已安装的运行时名称(对应一个 ClusterServingRuntime CRD instance)。
  5. storageUri 指定模型存储所在的带标签 OCI image URI。请使用完整的 registry URL。例如:storageUri: oci://docker.io/alaudapublic/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. 检查 predictor pod 日志:
    kubectl logs -n demo-space -l serving.kserve.io/inferenceservice=oci-demo
  3. 验证模型镜像是否可以在集群本地成功拉取:
    # On a node in the cluster
    crictl pull <registry>/<repository>:<tag>

最佳实践

  1. 模型版本管理:在 container image 中使用 tag 对模型进行版本管理
  2. 镜像大小优化:使用轻量级 base image,并且仅包含必要的模型文件
  3. Registry 管理:使用具备适当访问控制的私有 registry
  4. 安全性:遵循 container 安全最佳实践,包括定期漏洞扫描
  5. 缓存:利用 container registry 缓存来提升拉取速度

故障排查

常见问题

  1. 权限错误:确保镜像中的模型文件具有正确的权限
  2. Ascend 910 vLLM-ascend 权限模式:对于 Huawei Ascend 910 的 vLLM-ascend 部署,尤其是单节点多卡服务,请参见 Ascend 910 的 Modelcar 权限模式
  3. Registry 身份验证:验证集群是否能够访问 container registry

结论

使用 KServe Modelcar(基于 OCI container 的模型存储)可以在 Alauda AI platform 中提供一种高效的模型部署方式。按照本指南中的步骤,您可以将模型打包为 OCI image,并以更快的启动时间和更高的资源利用率进行部署。