基于Kubernetes的ML平台架构设计

本文主要关注模型训练和模型部署两个部分的技术架构设计。

ML平台功能组成

ML平台的功能组成图见上图。

  • 数据仓库:用于存储原始数据,包括图片、视频、语音、文本等非结构化数据和结构化数据。
  • 数据集:按照机器学习流程从原始数据中提取的训练数据集和测试数据集。
  • 特征商店:用于训练用的特征计算过程或者特征数据。
  • 模型训练:基于数据集和模型算法的训练迭代。
  • 超参数寻优:超参数是模型算法的属性,对模型算法的超参数进行调优,寻找最合适的参数设置。
  • A/B试验平台:通过划分试验组和控制组,对模型效果进行对比,评价模型的优劣。
  • 模型商店:存储训练好的模型,对模型文件进行版本管理和权限控制。
  • 模型服务:是机器学习的推理过程,将训练好的模型进行部署发布,对外提供接口服务。
  • 工作流:负责提供ML流程编排能力。

ML平台技术架构和组件介绍

上图描述的是整个ML平台的技术架构,参考了Shopify的Merlin平台的设计

  1. 核心模块为算力中心部分,算力中心的底层为GPU/CPU异构服务器集群,用Kubernetes进行纳管,GPU资源对Kubernetes的暴露和底层共享能力依托于GPU厂商提供的Kubernetes插件实现。基于Kubernetes提供任务层算力共享、服务弹性伸缩和对任务进行调度的能力,应用层算力共享和弹性伸缩既可以依赖任务调度组件实现,也可以依赖分布式计算组件Ray实现,还可以依赖Tensorflow和Pytorch等自带的功能实现。
  2. 特征商店和数据仓库本质上都是提供数据存储能力,本文不多做介绍。
  3. 工作流编排模块提供流水线的编排能力,这里可以依赖于Argo、Ariflow和Kubeflow Pipeline实现。
  4. Jupyter Notebook是模型开发阶段必不可少的交互式开发工具。
  5. ML平台通过统一的API接口实现对集群资源的调用。

工作流编排

Kubeflow Pipeline是在Argo基础之上开发的,Argo是云原生主流的流程引擎,Airflow则更加通用,底层不必依赖于Kubernetes,用户编写Python进行对工作流的定义和调度。

图3 Ariflow工作流示意图

Jupyter Notebook

本地Jupyter Notebook和Kubeflow Notebook均可实现对Kubernete Ray集群的调用,本地的缺点是,需要在本地提前安装好相关的依赖,而利用Kubeflow的Notebook则无需在本地进行相关配置,可以在网上下载相关镜像,提供用户多种不同版本依赖包的Notebook。

Nvidia GPU底层算力共享方案

目前有Nvidia GPU有4种底层共享的方案,MPS、MIG、Time-Slicing和DRA。前三者的对比如下表:

特性

MPS

MIG

Time-Slicing

类型(Partition Type)

Logical

Physical

Temporal (Single process)

最大分区数量(Max Partitions)

48

7

Unlimited

SM 性能隔离(SM Performance Isolation)

Yes (by percentage, not partitioning)

Yes

Yes

内存保护(Memory Protection)

Yes

Yes

No

内存带宽质量保证(Memory Bandwidth QoS)

No

Yes

No

错误隔离(Error Isolation)

Yes

Yes

No

跨区互操作(Cross-Partition Interop)

IPC

Limited IPC

Limited IPC

更新配置(Reconfigure)

仅在 mps server 进程启动/重启时

当显卡空闲时

N/A

DRA是最新的共享方案,针对其他三种方案的不足,DRA进行了以下优化:

        支持单节点拥有多种GPU类型

        支持请求GPU时的复杂约束

        支持作业之间共享超额订阅的GPU申请

        支持根据请求动态提供MIG设备

        支持单个GPU在NVIDIA和vfio驱动程序之间动态选择

        避免对MPS负担过重的支持

需要特别强调的是每种共享方案都是和型号绑定的,在进行GPU选型时需要咨询清楚对应的Kubernetes插件可支持哪种方案。

应用层算力共享

前面介绍了Nvidia GPU底层提供的Kubernetes插件算力共享方案,本部分介绍应用层算力共享,两者需要配合起来,才能实现GPU算力的共享。

通过诸如Tensorflow、Pytorch这些深度学习工具本身提供的能力,就能实现算力共享,比如在任务中设置GPU的个数为0.5。但是这些工具不能对程序中自定义的方法提供算力共享能力,借助Ray可以实现,后文介绍了Ray进行分布式计算的原理。

任务调度

Kubernetes本身的调度器只能不断重试并且当有适当资源时启动任务,不能提供批处理等高级调度策略,特别是ML任务,为了弥补该方面的不足,需要引入任务调度组件,常用的包括Volcano和Kueue。

任务调度组件在ML任务中的优势包括:

  • 资源管理和调度优化:机器学习任务通常对计算资源、存储资源和网络资源有着较高的需求。组件提供了更灵活、细粒度的资源管理机制,可以更好地满足机器学习任务对资源的不同需求。通过自定义资源需求和约束,并结合高级调度策略,可以更有效地利用集群资源,提高任务执行效率。
  • 作业队列和优先级:在机器学习中,通常会有多个不同优先级和重要性的任务需要运行。组件提供了作业队列和优先级调度的功能,可以根据任务的重要性和优先级进行调度,确保高优先级任务能够及时获得资源并执行。
  • 容错性和可靠性:机器学习任务通常需要长时间运行,并且可能会受到各种因素的干扰,如节点故障、网络问题等。任务调度组件引入了容错性机制,使得任务在遇到异常情况时能够恢复或重新调度,保障任务的稳定性和可靠性。
  • 弹性伸缩:任务调度组件可提供弹性伸缩能力,根据服务的请求压力进行弹性伸缩。

Ray分布式计算(GPU共享)原理

Ray框架介绍

Ray包括以下组件:

  • Ray Core:一个开源的Python通用分布式计算库,使ML工程师和Python开发人员能够扩展Python应用程序进行加速。
  • Ray Data:支撑模型训练、调优和预测的数据分布式组件库。
  • Ray Train:能够集成多种算法库的多节点和多核模型训练组件库。
  • Ray Tune:分布式超参数调优组件库。
  • Ray Serve:分布式模型在线推理组件库。
  • RLlib:分布式强化学习组件库

Ray集群

Ray通常是以集群的方式部署在多台服务器上,Head node是主节点,Worker node是工作节点,每个节点上可用运行多个Worker process进程。

  • 一个任务需要多个worker process进程来执行,worker进程可以是无状态方法task或者有状态类actor,每个worker进程都属于某个任务。
  • 每个worker进程存储着方法或者变量调用的关系和small objects。object指的是Ray中的变量,比如task的返回值或者用户自定义put的变量。

在代码中进行显式说明,即可实现对方法或者类的分布式计算配置。

from ray.train import ScalingConfig
scaling_config = ScalingConfig(
    num_workers=2,
    resources_per_worker={
        "CPU": 4,
        "GPU": 0.5,
    },
    use_gpu=True,
)
# 增加装饰器`@ray.remote`将方法转变为远程方法
@ray.remote
def my_function():
    return 1

Worker process节点调度

根据Worker process进程请求的资源情况,将节点可以分为如下几种:

  • 可行:节点具有运行任务或参与者所需的资源。根据这些资源的当前可用性,有两种子状态:
    • 可用:节点拥有所需的资源,并且这些资源现在是免费的。
    • 不可用:节点具有所需的资源,但它们当前正被其他任务或参与者使用。
  • 不可行:节点没有所需的资源。例如,仅包含 CPU 的节点对于 GPU 任务是不可行的。

Ray Serve弹性伸缩

Ray是通过对Worker process进程数量的增减实现弹性伸缩的,弹性伸缩主要用在模型服务中,对应的是Ray Serve模块,通过4个参数对其进行控制。

  • target_num_ongoing_requests_per_replica,每个worker副本单位时间能提供的平均请求数。
  • max_concurrent_queries,每个worker副本可接受的最大请求数。
  • min_replicas,最小worker副本数。
  • max_replicas,最大worker副本数。

代码如下:

from ray import serve
@serve.deployment(
    ray_actor_options={"num_cpus": 1},
    max_concurrent_queries=5,
    autoscaling_config={
        "target_num_ongoing_requests_per_replica": 1,
        "min_replicas": 0,
        "initial_replicas": 0,
        "max_replicas": 200,
    },
)

KubeRay

使用KubeRay可以很容易地在Kubernetes集群中启动关闭Ray集群、提交任务。KubeRay提供了三种CRD: RayCluster、RayJob、RayService。

  • RayCluster:KubeRay 完全管理 RayCluster 的生命周期,包括集群创建/删除、自动扩展和确保容错。
  • RayJob:通过 RayJob,KubeRay 自动创建 RayCluster,并在集群准备就绪时提交作业任务,可以将 RayJob 配置为在作业完成后自动删除 RayCluster。
  • RayService:用于部署Service服务,支持滚动升级。

在Kubernetes中的每个Ray集群包括一个Head Pod和多个Worker Pod,需要为每个Pod设置所需的cpu、gpu资源,这里的Pod等价于Ray服务器集群中的worker process进程,用来实现任务的分布式处理和弹性伸缩。

ML平台最小化实践设计

如图所示,通过Kubeflow、Ray、Kueue几个组件的组合,就能够提供包括分布式数据处理、模型开发、训练、超参数寻优、模型服务和工作流等ML全流程的功能。在ML平台初期可以参考以上架构进行设计开发,具体细节需要仔细阅读相关组件的API接口设计。

其他关注点

本文主要关注了GPU调度层面的架构设计,以下技术点在设计ML平台的过程中也需要特别考虑:

  • 多租户如何实现,不同租户间进行资源隔离
  • ML平台监控能力,比如任务监控和数据监控
  • 待补充

如果大家关注MLOps相关的技术,欢迎大家点赞收藏关注👏👏👏

  • 22
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值