KubeDL 0.4.0 - Kubernetes AI 模型版本管理与追踪

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 欢迎更多的用户试用 KubeDL,并向我们提出宝贵的意见,也期待有更多的开发者关注以及参与 KubeDL 社区的建设!

作者:陈裘凯( 求索)


前言


KubeDL 是阿里开源的基于 Kubernetes 的 AI 工作负载管理框架,取自"Kubernetes-Deep-Learning"的缩写,希望能够依托阿里巴巴的场景,将大规模机器学习作业调度与管理的经验反哺社区。目前 KubeDL 已经进入 CNCF Sandbox 项目孵化,我们会不断探索云原生 AI 场景中的最佳实践,助力算法科学家们简单高效地实现创新落地。


在最新的 KubeDL Release 0.4.0 版本中,我们带来了模型版本管理(ModelVersion)的能力,AI 科学家们可以像管理镜像一样轻松地对模型版本进行追踪,打标及存储。更重要的是,在经典的机器学习流水线中,“训练”与“推理”两个阶段相对独立,算法科学家视角中的“训练->模型->推理”流水线缺乏断层,而“模型”作为两者的中间产物正好能够充当那个“承前启后”的角色。


Github:https://github.com/kubedl-io/kubedl

网站:https://kubedl.io/model/intro/


模型管理现状


模型文件是分布式训练的产物,是经过充分迭代与搜索后保留的算法精华,在工业界算法模型已经成为了宝贵的数字资产。通常不同的分布式框架会输出不同格式的模型文件,如 Tensorflow 训练作业通常输出 CheckPoint(*.ckpt)、GraphDef(*.pb)、SavedModel 等格式,而 PyTorch 则通常以 .pth 后缀,不同的框架会在加载模型时解析其中承载的运行时的数据流图、运行参数及其权重等信息,对于文件系统来说,它们都是一个(或一组)特殊格式的文件,就像 JPEG 和 PNG 格式的图像文件一样。


因此典型的管理方式就是把它们当作文件,托管在统一的对象存储中(如阿里云 OSS 和AWS S3),每个租户/团队分配一个目录,各自成员再把模型文件存储在自己对应的子目录中,由 SRE 来统一进行读写权限的管控:


1.png

image.gif

这种管理方式的优缺点都很明显:


  • 好处是保留了用户的 API 使用习惯,在训练代码中将自己的目录指定为输出路径,之后将云存储的对应目录 mount 到推理服务的容器内加载模型即可;


  • 但这对 SRE 提出了较高的要求,不合理的读写权限授权及误操作,可能造成文件权限泄露,甚至大面积的误删除;同时基于文件的管理方式不易实现模型的版本管理,通常要求用户自身根据文件名来标记,或是上层平台自己承担版本管理的复杂度;此外,模型文件与算法代码/训练参数的对应关系也无法直接映射,甚至同个文件在多次训练中会被多次覆写,难以追溯历史;


基于以上现状,KubeDL 充分结合了 Docker 镜像管理的优势,引入了一套 Image-Based 的镜像管理 API,让分布式训练和推理服务结合得更紧密自然,同时也极大简化了模型管理的复杂度。


从镜像出发


镜像(Image)是 Docker 的灵魂,也是容器时代的核心基础设施。镜像本身即分层的不可变文件系统,模型文件天然地可以作为其中的一个独立镜像层,两者结合的还会迸发出其他火花:


  • 用户不用再面向文件管理模型,而是直接使用 KubeDL 提供的 ModelVersion API 即可,训练与推理服务之间通过 ModelVersion API 桥接;


  • 与镜像一样,可以对模型打 Tag 实现版本追溯,并推送到统一的镜像 Registry 存储,通过 Registry 进行鉴权,同时镜像 Registry 的存储后端还可以替换成用户自己的 OSS/S3,用户可以平滑过渡;


  • 模型镜像一旦构建完毕,即成为只读的模板,无法再被覆盖及篡写,践行 Serverless “不可变基础设施” 的理念;


  • 镜像层(Layer)通过压缩算法及哈希去重,减少模型文件存储的成本并加快了分发的效率;


在“模型镜像化”的基础上,还可以充分结合开源的镜像管理组件,最大化镜像带来的优势:


  • 大规模的推理服务扩容场景中,可以通过 Dragonfly来加速镜像分发效率,面对流量突发型场景时可以快速弹出无状态的推理服务实例,同时避免了挂载云存储卷可能出现的大规模实例并发读时的限流问题;


  • 日常的推理服务部署,也可以通过 OpenKruise 中的 ImagePullJob来提前对节点上的模型镜像进行预热,提升扩容发布的效率。


Model 与 ModelVersion


KubeDL 模型管理引入了 2 个资源对象:Model 及 ModelVersion,Model 代表某个具体的模型,ModelVersion 则表示该模型迭代过程中的一个具体版本,一组 ModelVersion 从同一个 Model 派生而来。以下是示例:


apiVersion: model.kubedl.io/v1alpha1
kind: ModelVersion
metadata:
  name: my-mv
  namespace: default
spec:
  # The model name for the model version
  modelName: model1
  # The entity (user or training job) that creates the model
  createdBy: user1
  # The image repo to push the generated model
  imageRepo: modelhub/resnet
  imageTag: v0.1
  # The storage will be mounted at /kubedl-model inside the training container.
  # Therefore, the training code should export the model at /kubedl-model path.
  storage:
    # The local storage to store the model
    localStorage:
      # The local host path to export the model
      path: /foo
       # The node where the chief worker run to export the model
      nodeName: kind-control-plane
    # The remote NAS  to store the model
    nfs:
      # The NFS server address
      server: ***.cn-beijing.nas.aliyuncs.com
      # The path under which the model is stored
      path: /foo
      # The mounted path inside the container
      mountPath: /kubedl/models
---
apiVersion: model.kubedl.io/v1alpha1
kind: Model
metadata:
  name: model1
spec: 
  description: "this is my model"
status:
  latestVersion:
    imageName: modelhub/resnet:v1c072
    modelVersion: mv-3


Model 资源本身只对应某类模型的描述,并追踪最新的版本的模型及其镜像名告知给用户,用户主要通过 ModelVersion 来自定义模型的配置:


  • modelName:用来指向对应的模型名称;


  • createBy:创建该 ModelVersion 的实体,用来追溯上游的生产者,通常是一个分布式训练作业;


  • imageRepo:镜像 Registry 的地址,构建完成模型镜像后将镜像推送到该地址;


  • storage:模型文件的存储载体,当前我们支持了 NAS,AWSEfs 和 LocalStorage 三种存储介质,未来会支持更多主流的存储方式。以上的例子中展示了两种模型输出的方式(本地存储卷和 NAS 存储卷),一般只允许指定一种存储方式。


2.png

image.gif

当 KubeDL 监听到 ModelVersion 的创建时,便会触发模型构建的工作流:


  1. 监听 ModelVersion 事件,发起一次模型构建;

  2. 根据 storage 的类型创建出对应的 PV 与 PVC 并等待 volume 就绪;

  3. 创建出 Model Builder 进行用户态的镜像构建,Model Builder 我们采用了 kaniko 的方案,其构建的过程与镜像格式,和标准的 Docker 完全一致,只不过这一切都在用户态发生,不依赖任何宿主机的 Docker Daemon;

  4. Builder 会从 volume 的对应路径中拷贝出模型文件(可以是单文件也可以是一个目录),并将其作为独立的镜像层来构建出一个完整的 Model Image;

  5. 把产出的 Model Image 推送到 ModelVersion 对象中指定的镜像 Registry 仓库;

  6. 结束整个构建过程;


至此,该 ModelVersion 对应版本的模型便固化在了镜像仓库中,可以分发给后续的推理服务进行消费。


从训练到模型


虽然 ModelVersion 支持独立创建并发起构建,但我们更期望在分布式训练作业成功结束后自动触发模型的构建,天然串联成一个流水线。


KubeDL 支持这种提交方式,以 TFJob 作业为例,在发起分布式训练时即指定好模型文件的输出路径和推送的仓库地址,当作业成功执行完毕时就会自动创建出一个 ModelVersion 对象,并将 createdBy 指向上游的作业名,而当作业执行失败或提前终止时并不会触发 ModelVersion 的创建。


以下是一个分布式 mnist 训练的例子,其将模型文件输出到本地节点的 /models/model-example-v1 路径,当顺利运行结束后即触发模型的构建:


apiVersion: "training.kubedl.io/v1alpha1"
kind: "TFJob"
metadata:
  name: "tf-mnist-estimator"
spec:
  cleanPodPolicy: None
  # modelVersion defines the location where the model is stored.
  modelVersion:
    modelName: mnist-model-demo
    # The dockerhub repo to push the generated image
    imageRepo: simoncqk/models
    storage:
      localStorage:
        path: /models/model-example-v1
        mountPath: /kubedl-model
        nodeName: kind-control-plane
  tfReplicaSpecs:
    Worker:
      replicas: 3
      restartPolicy: Never
      template:
        spec:
          containers:
            - name: tensorflow
              image: kubedl/tf-mnist-estimator-api:v0.1
              imagePullPolicy: Always
              command:
                - "python"
                - "/keras_model_to_estimator.py"
                - "/tmp/tfkeras_example/" # model checkpoint dir
                - "/kubedl-model"         # export dir for the saved_model format


% kubectl get tfjob
NAME                  STATE       AGE   MAX-LIFETIME   MODEL-VERSION
tf-mnist-estimator   Succeeded   10min              mnist-model-demo-e7d65
% kubectl get modelversion
NAME                      MODEL                    IMAGE                CREATED-BY          FINISH-TIME
mnist-model-demo-e7d65  tf-mnist-model-example   simoncqk/models:v19a00  tf-mnist-estimator   2021-09-19T15:20:42Z
% kubectl get po
NAME                                              READY   STATUS  RESTARTS   AGE
image-build-tf-mnist-estimator-v19a00   0/1     Completed     0         9min


通过这种机制,还可以将其他“仅当作业执行成功才会输出的 Artifacts 文件”一起固化到镜像中,并在后续的阶段中使用。


从模型到推理


有了前面的基础,在部署推理服务时直接引用已构建好的 ModelVersion,便能加载对应模型并直接对外提供推理服务。至此,算法模型生命周期(代码->训练->模型->部署上线)各阶段通过模型相关的 API 联结了起来。

通过 KubeDL 提供的 Inference 资源对象部署一个推理服务时,只需在某个 predictor 模板中填充对应的 ModelVersion 名,Inference Controller 在创建 predictor 时会注入一个 Model Loader,它会拉取承载了模型文件的镜像到本地,并通过容器间共享 Volume 的方式把模型文件挂载到主容器中,实现模型的加载。如上文所述,与 OpenKruise 的 ImagePullJob 相结合我们能很方便地实现模型镜像预热,来为模型的加载提速。为了用户感知的一致性,推理服务的模型挂载路径与分布式训练作业的模型输出路径默认是一致的。


apiVersion: serving.kubedl.io/v1alpha1
kind: Inference
metadata:
  name: hello-inference
spec:
  framework: TFServing
  predictors:
  - name: model-predictor
    # model built in previous stage.
    modelVersion: mnist-model-demo-abcde
    replicas: 3
    batching:
      batchSize: 32
    template:
      spec:
        containers:
        - name: tensorflow
          args:
          - --port=9000
          - --rest_api_port=8500
          - --model_name=mnist
          - --model_base_path=/kubedl-model/
          command:
          - /usr/bin/tensorflow_model_server
          image: tensorflow/serving:1.11.1
          imagePullPolicy: IfNotPresent
          ports:
          - containerPort: 9000
          - containerPort: 8500
          resources:
            limits:
              cpu: 2048m
              memory: 2Gi
            requests:
              cpu: 1024m
              memory: 1Gi

对于一个完整的推理服务,可能同时 Serve 多个不同模型版本的 predictor,比如在常见搜索推荐的场景中,期望以 A/B Testing 实验来同时对比多次模型迭代的效果,通过 Inference+ModelVersion 可以很容易做到。我们对不同的 predictor 引用不同版本的模型,并分配合理权重的流量,即可达到一个推理服务下同时 Serve 不同版本的模型并灰度比较效果的目的:


apiVersion: serving.kubedl.io/v1alpha1
kind: Inference
metadata:
  name: hello-inference-multi-versions
spec:
  framework: TFServing
  predictors:
  - name: model-a-predictor-1
    modelVersion: model-a-version1
    replicas: 3
    trafficWeight: 30  # 30% traffic will be routed to this predictor.
    batching:
      batchSize: 32
    template:
      spec:
        containers:
        - name: tensorflow
          // ...
  - name: model-a-predictor-2
    modelVersion: model-version2
    replicas: 3
    trafficWeight: 50  # 50% traffic will be roted to this predictor.
    batching:
      batchSize: 32
    template:
      spec:
        containers:
        - name: tensorflow
          // ...
  - name: model-a-predictor-3
    modelVersion: model-version3
    replicas: 3
    trafficWeight: 20  # 20% traffic will be roted to this predictor.
    batching:
      batchSize: 32
    template:
      spec:
        containers:
        - name: tensorflow
          // ...

image.gif


3.png


总结


KubeDL 通过引入 Model 和 ModelVersion 两种资源对象,与标准的容器镜像相结合实现了模型构建,打标与版本追溯,不可变存储与分发等功能,解放了粗放型的模型文件管理模式,镜像化还可以与其他优秀的开源社区相结合,实现镜像分发加速,模型镜像预热等功能,提升模型部署的效率。同时,模型管理 API 的引入很好地连接了分布式训练与推理服务两个原本割裂的阶段,显著提升了机器学习流水线的自动化程度,以及算法科学家上线模型、实验对比的体验和效率。我们欢迎更多的用户试用 KubeDL,并向我们提出宝贵的意见,也期待有更多的开发者关注以及参与 KubeDL 社区的建设!


KubeDL Github 地址:

https://github.com/kubedl-io/kubedl


此处,立即了解 KubeDL 项目!



相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
1月前
|
机器学习/深度学习 人工智能 并行计算
"震撼!CLIP模型:OpenAI的跨模态奇迹,让图像与文字共舞,解锁AI理解新纪元!"
【10月更文挑战第14天】CLIP是由OpenAI在2021年推出的一种图像和文本联合表示学习模型,通过对比学习方法预训练,能有效理解图像与文本的关系。该模型由图像编码器和文本编码器组成,分别处理图像和文本数据,通过共享向量空间实现信息融合。CLIP利用大规模图像-文本对数据集进行训练,能够实现zero-shot图像分类、文本-图像检索等多种任务,展现出强大的跨模态理解能力。
110 2
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
当语言遇见智慧火花:GPT家族历代模型大起底,带你见证从平凡到卓越的AI进化奇迹!
【10月更文挑战第6天】随着自然语言处理技术的进步,GPT系列模型(Generative Pre-trained Transformers)成为该领域的明星。从GPT-1的开创性工作,到GPT-2在规模与性能上的突破,再到拥有1750亿参数的GPT-3及其无需微调即可执行多种NLP任务的能力,以及社区驱动的GPT-NeoX,这些模型不断进化。虽然它们展现出强大的语言理解和生成能力,但也存在如生成错误信息或偏见等问题。本文将对比分析各代GPT模型的特点,并通过示例代码展示其部分功能。
121 2
|
1月前
|
人工智能 Kubernetes 监控
Kubernetes 故障诊断 AI 助手
【10月更文挑战第6天】
|
2月前
|
机器学习/深度学习 人工智能 UED
OpenAI o1模型:AI通用复杂推理的新篇章
OpenAI发布了其最新的AI模型——o1,这款模型以其独特的复杂推理能力和全新的训练方式,引起了业界的广泛关注。今天,我们就来深入剖析o1模型的特点、背后的原理,以及一些有趣的八卦信息。
338 73
|
28天前
|
人工智能
AI科学家太多,谁靠谱一试便知!普林斯顿新基准CORE-Bench:最强模型仅有21%准确率
【10月更文挑战第21天】普林斯顿大学研究人员提出了CORE-Bench,一个基于计算可重复性的AI代理基准,涵盖计算机科学、社会科学和医学领域的270个任务。该基准旨在评估AI代理在科学研究中的准确性,具有多样性、难度级别和现实相关性等特点,有助于推动AI代理的发展并提高计算可重复性。
46 4
|
1月前
|
人工智能 自然语言处理
从迷茫到精通:揭秘模型微调如何助你轻松驾驭AI新热点,解锁预训练模型的无限潜能!
【10月更文挑战第13天】本文通过简单的问题解答形式,结合示例代码,详细介绍了模型微调的全流程。从选择预训练模型、准备新任务数据集、设置微调参数,到进行微调训练和评估调优,帮助读者全面理解模型微调的技术细节和应用场景。
74 6
|
1月前
|
人工智能 自然语言处理 安全
【通义】AI视界|Adobe推出文生视频AI模型,迎战OpenAI和Meta
本文精选了过去24小时内的重要科技新闻,包括微软人工智能副总裁跳槽至OpenAI、Adobe推出文本生成视频的AI模型、Meta取消高端头显转而开发超轻量设备、谷歌与核能公司合作为数据中心供电,以及英伟达股价创下新高,市值接近3.4万亿美元。这些动态展示了科技行业的快速发展和激烈竞争。点击链接或扫描二维码获取更多资讯。
|
1月前
|
机器学习/深度学习 人工智能 TensorFlow
解锁AI潜力:让开源模型在私有环境绽放——手把手教你搭建专属智能服务,保障数据安全与性能优化的秘密攻略
【10月更文挑战第8天】本文介绍了如何将开源的机器学习模型(如TensorFlow下的MobileNet)进行私有化部署,包括环境准备、模型获取与转换、启动TensorFlow Serving服务及验证部署效果等步骤,适用于希望保护用户数据并优化服务性能的企业。
59 4
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
揭开模型微调Fine-Tuning的神秘面纱:如何在预训练基础上巧妙调整,解锁定制AI解决方案的秘密武器
【10月更文挑战第8天】模型微调是在预训练模型基础上,利用特定领域数据进一步训练,以优化模型在特定任务上的表现。此方法广泛应用于自然语言处理和计算机视觉等领域,通过调整预训练模型的部分或全部参数,结合适当的正则化手段,有效提升模型性能。例如,使用Hugging Face的Transformers库对BERT模型进行微调,以改善文本匹配任务的准确率。
59 1
|
2月前
|
存储 人工智能 算法
阿里云AI基础设施升级亮相,模型算力利用率提升超20%
阿里云AI基础设施升级亮相,模型算力利用率提升超20%
236 18

相关产品

  • 容器服务Kubernetes版
  • 下一篇
    无影云桌面