一、前言
在过去的几年中,以容器技术为代表的云原生领域受到了极大的关注和发展,容器化的落地是企业降本增效的一个重要手段,截止目前得物已基本完成了全域的容器化。容器化过程中,一方面平稳地将服务的部署和运维方式从以前的ECS模式切换到了容器化模式;另一方面为公司在资源利用率、研发效率上拿到了许多提效的收益。
得物作为新一代潮流网购社区,以AI和大数据技术为基础的搜索引擎、个性化推荐系统是业务开展的强大支撑力,所以业务应用当中算法域的应用占了的很大比例。容器化过程中,针对算法应用服务的研发流程和普通服务的差异性,在充分调研算法域研发同学需求的基础上,我们面向算法域的研发场景建设了得物云原生AI平台—KubeAI平台。经过功能的不断迭代,在支持的场景上不断拓展,KubeAI当前已经支持CV、搜索推荐、风控算法和数据分析等涉及AI能力的业务域顺利完成了容器化,在资源利用率提升、研发效率提升上面均拿到了不错的成果,本文将带大家一起了解KubeAI的落地实践过程。
二、AI业务的容器化推进
2.1 AI算法模型开发流程
AI业务更多的是针对模型的迭代开发过程,通常模型的开发过程可以归纳为以下几个步骤:
确定需求场景:这个过程要明确解决的问题是什么,为哪种场景提供功能,功能/服务的输入是什么,输出是什么?例如:针对哪种品牌的鞋子做鉴别或质检,该品牌的产品特征是什么,样本有哪些维度的特征,特征类型等等。不同的场景对样本数据的要求、使用的处理算法也是不一样的。
数据准备:按照场景需求分析的结果,通过各种方式(线上/线下/mock等)获取样本数据,对数据做必要的清洗、标注等操作。这个过程是AI业务开发的基础,因为后续的所有过程都是在数据的基础上进行的。
确定算法,编写训练脚本:基于对业务目标的理解,在这个环节算法同学会根据过往的经验,或者针对该场景调研、实验结果,选择合适的算法,编写模型训练脚本。
模型训练:对于算法模型,我们可以将它理解为是一个复杂的数学公式,这个公式里会有很多参数,就像f(x)=wx+b里的w和b一样。训练就是为了使得模型具有高识别率,而使用大量的样本数据,找到较优参数的过程。模型训练是AI业务开发过程中很重要的一环,可以说业务目标的达成就靠模型的准确度。所以,这个环节相比其它环节要花费更多的时间、精力和资源,而且要反复地进行实验训练,以期望达到更好的模型精度和预测准确性。这个过程也不是一次性的,而是周期性的,根据业务场景的更新,数据的更新,要周期性的进行。针对算法模型的开发和训练工作,业界有一些主流的AI引擎可供选择,比如TensorFlow、PyTorch、MXNet等,这些引擎可以提供一定程度上的API支持,方便算法开发人员将复杂的模型进行分布式训练,或者针对硬件做一些优化,以提高模型训练效率。模型训练的结果是拿到模型文件,这个文件的内容可以理解为保存的是模型的参数。
模型评估:为了防止由于偏差过大造成模型欠拟合或者由于方差过大导致的过拟合,通常需要一些评价指标来指导开发人员评估模型的泛化能力。常用的一些评价指标,比如:精度、召回率、ROC曲线/AUC、PR曲线等。
模型部署:通过反复的训练和评估,得到较为理想的模型之后就可以帮助业务去处理在线/生产数据了。这就需要把模型以服务的形态,或者以任务的形态部署起来,以达到接受输入数据,给出推理结果的目的,我们把这个服务称之为模型服务。模型服务是一个在线服务脚本对模型进行加载,就绪以后,对预处理之后的数据进行推理计算。
一个模型服务上线之后,会随着数据特征的变更、算法的升级、在线推理服务脚本的升级、业务对推理指标的新要求等情况,需要对模型服务进行迭代。需要注意的是,这个迭代过程,有可能需要对模型进行重新训练、重新评估;也有可能只是推理服务脚本的迭代升级。
2.2 如火如荼的容器化迁移
从去年开始,我们逐步推进得物各域业务服务的容器化落地。为了减少容器化过程中因部署方式的变化而引起用户操作习惯的改变,我们继续沿用发布平台的部署流程,将容器部署与ECS部署的差异进行屏蔽。
在CI过程中,根据不同的开发语言类型,定制不同的编译构建模板,从源码编译再到容器镜像制作,由容器平台层统一完成,解决了普通研发同学因对容器相关知识不了解而无法将工程代码制成一个容器镜像的问题。在CD过程中,我们在应用类型级别、环境级别、环境组级别进行配置分层管理,执行部署时将多层配置合并成Helm Chart的values.yaml,向容器集群提交编排文件。用户只需根据自己实际需求,设置相应的环境变量,即可提交部署,而后获取应用集群实例(容器实例,类似于ECS服务实例)。
针对应用集群的运维操作,容器平台提供WebShell登陆容器实例的功能,就像登陆到ECS实例一样,便于排查应用进程相关问题;容器平台也提供了文件的上传和下载、实例的重启和重建、资源监控等运维功能。
AI业务(CV、搜推、风控算法服务等)作为占比较大的业务,与普通的业务服务一起参与到容器化过程中,我们逐步完成了以社区、交易的瀑布流、金刚位为代表的核心场景服务的迁移。容器化之后,测试环境的资源利用率得到了极大的提升,生产环境也有了大幅的提升,运维效率倍增。
2.3 算法同学不能承受之痛
得物容器化的过程,是伴随着公司技术体系快速发展一起的,这让初期不成熟的AI服务研发流程对容器化提出了更多的需求,让本来只关注在线推理服务容器化的我们看到了算法同学在模型开发过程中的痛点和难点。
痛点1:模型的管理和推理服务的管理是不连贯的。CV的模型大多是在台式机上训练的,然后手动上传到OSS上,然后将模型文件在OSS上的地址配置给在线推理服务。搜推的模型大多是在PAI上进行训练,但是也是手动存储在OSS上,发布时与CV的类似。可以看到,对模型这个产物的管理,在模型训练和发布的过程中是不连贯的,无法追踪一个模型到底部署在了哪几个服务上,也没法直观看到一个服务部署了哪一个或者多个模型,模型版本管理不方便。
痛点2:模型开发环境准备耗时长,资源申请和使用缺少弹性机制。在容器化之前,资源一般以ECS实例的方式提供,要走流程申请资源,申请到以后要做各种初始化工作,安软件,装依赖,传数据(算法研究工作使用的软件库大多体积较大,安装也较复杂)。当一台ECS搞定以后,后续如果资源不够要再申请,相同的流程再走一遍,效率较低。同时,资源的申请在配额(预算)的约束下,缺少自主管理、按需弹性申请和释放的机制。
痛点3:想尝试云原生支持的一些模型解决方案难。随着云原生技术在各个领域的不断落地,Kubeflow,Argo Workflow等解决方案为AI场景提供了很好的支持。比如:tfjob-operator可以将基于TensorFlow框架的分布式训练任务以CRD的方式进行管理,用户只需要设置相应组件(Chief、PS、Worker等)的参数后,就可以向Kubernetes集群提交训练任务。在容器化以前,如果算法的同学想要尝试这种方案,就必须熟悉和掌握Docker、Kubernetes等容器相关知识,而并不能以一个普通用户的角色去使用这种能力。
痛点4:非算法部门想快速验证一个算法时找不到可以很好支撑的平台。AI的能力显然在各个业务域都会用到,特别是一些成熟的算法,业务团队可以很轻松地用它来做一些基线指标预测,或者分类预测工作,以便帮助业务取得更好的效果。这时就需要有一个能提供AI相关能力的平台,满足这些场景对异构资源(CPU/GPU/存储/网络等)的需求,对算法模型管理等需求,为用户提供上手即用的功能。
立足于对以上痛点和难点问题的梳理和分析,同时基于容器化过程中算法同学对容器平台提出的其它需求(比如:模型统一管理需求、日志采集需求、资源池需求、数据持久化需求等),我们逐一讨论,各个击破,在解决当前问题的同时,也考虑平台长远的功能规划,逐步建成了以容器平台为基础,面向AI业务的KubeAI平台解决方案。
三、KubeAI平台解决方案
在充分调研和学习了业内AI平台的基本架构、产品形态的基础上,着眼于AI业务场景及其周边业务需求,容器技术团队在得物容器化过程中设计和逐步落地了云原生AI平台-KubeAI平台。KubeAI平台着力于解决算法同学的痛点需求,提供必要的功能模块,贯穿模型的开发、发布和运维流程,帮助算法开发者快速、低成本地获取和使用AI基础设施资源,快速高效地进行算法模型设计、开发和实验。
3.1 整体架构
KubeAI平台围绕模型的整个生命周期,提供了以下功能模块:
数据集管理:主要是对不同的数据源进行兼容,此外提供了数据缓存加速能力。
模型训练:既提供了Notebook进行模型开发和训练,又支持对一次性/周期性任务进行管理;这个流程中对异构资源(CPU/GPU/存储)弹性申请和释放。
模型管理:对模型元数据(模型基本信息,版本列表等)进行统一管理,与模型服务发布、运维过程无缝衔接。
推理服务管理:把模型与推理代码解耦,不需要把模型打包到镜像里面,提高了推理服务更新的效率;支持对在线服务升级模型。
AI-Pipeline引擎:支持以流水线的方式编排任务,满足数据分析、模型周期性例行训练任务、模型迭代等场景的需求。
KubeAI平台不仅支持个人用户,也支持平台用户。个人开发者同学使用KubeAI的Notebook进行模型脚本开发,较小的模型可直接在Notebook中进行训练,复杂模型通过任务的方式进行训练。模型产出后在KubeAI上进行统一管理,包括发布为推理服务,以及新版本的迭代。第三方业务平台以OpenAPI的方式获取KubeAI的能力进行上层业务创新。
下面我们重点介绍下数据集管理、模型训练、模型服务管理和AI-Pipeline引擎 4个模块的功能。
3.2 数据集管理
经过梳理,算法同学使用的数据要么保存在NAS里,要么从ODPS里读取,或者从OSS上拉取。为了统一数据管理,KubeAI以Kubernetes PVC(Persistent Volume Claim)资源为基础,向用户提供数据集的概念,兼容了不同的数据源格式。同时,为了解决因计算和存储分离架构带来的数据访问开销大的问题,我们使用Fluid为数据集配置缓存服务,既可以将数据缓存在本地供下轮迭代计算使用,也可以将任务调度到数据集已有缓存的计算节点上来。
3.3 模型训练
针对模型训练,我们主要做了三方面的工作:
(1)以JupyterLab为基础,提供了Notebook功能,用户可通过shell或者Web IDE以等同于本地的开发模式展开算法模型开发工作。
(2)以任务的方式进行模型训练,能更灵活地申请和释放资源,提高了资源的使用率,极大降低模型训练的成本。基于Kubernetes良好的扩展性,业内各种TrainingJob CRD都可轻松对接,Tensorflow、PyTorch、xgbost等训练框架均可支持。任务支持批调度,支持任务优先级队列。
(3)与算法团队合作,对Tensorflow训练框架做了部分优化,在批量数据读取效率、PS/Worker间通信速率上取得了一些提升效果;在PS负载不均衡、慢worker等问题上做了一些解决方案。
3.4 模型服务管理
模型服务与普通的服务相比,最大的特点是服务需要加载一个或者多个模型文件。在容器化的初期,因历史原因大多CV的模型服务都是直接将模型文件与推理脚本一起打包到容器镜像里的,这就导致容器镜像比较大,模型版本更新繁琐。
KubeAI改变了上述问题,基于对模型的规范化管理,把模型服务通过配置与模型进行关联,发布时由平台根据模型配置去拉取相应的模型文件,供推理脚本加载。这种方式减轻了算法模型开发者对推理服务镜像/版本的管理压力,减少了存储冗余,提升了模型更新/回滚的效率,提高了模型复用率,帮助算法团队更加方便快捷地管理模型及其关联的在线推理服务。
3.5 AI-Pipeline引擎
实际的业务场景不会是一个单一的任务节点,比如一个完整的模型迭代过程大致包含了数据处理环节、模型训练环节、使用新的模型更新在线推理服务、小流量验证环节和正式发布环节。KubeAI平台在Argo Workflow的基础上提供了工作流编排引擎,工作流节点支持自定义任务、平台预置模板任务,以及各种深度学习AI训练任务(TFJob、PyTorchJob等)。
四、AI业务场景的在KubeAI上落地典型案例
4.1 CV算法模型开发流程
CV算法模型的开发模式一般是边研究理论算法,边开发工程实践算法模型,随时调试。因为模型一般比较小,相比搜推类的模型,训练代价更低一些,所以CV的同学更习惯于在Notebook当中开发好训练脚本以后,直接在Notebook里进行训练。用户可以自主为Notebook选择配置CPU、GPU卡以及网络存储盘等资源。
通过开发调试,训练脚本满足需求以后,用户就可以使用KubeAI提供的任务管理功能,将训练脚本配置为一个单机训练任务,或者分布式训练任务,提交给KubeAI平台去执行。平台会调度任务到资源充足的资源池进行运行,在运行成功之后将模型推送到模型仓库,并注册到KubeAI的模型列表中;或者将模型保存在指定位置,供用户做选择和确认。
模型产出以后,用户可以直接在KubeAI的模型服务管理中将模型部署为推理服务。后续有新版本的模型产出时,用户可以为推理服务配置新的模型版本。而后,根据推理引擎是否支持模型热更新,可以通过重新部署服务或者创建模型升级任务,来完成推理服务中模型的升级。
在机器鉴别业务场景中,通过AI-Pipeline工作流,将上述过程进行编排,周期性执行模型迭代,模型迭代效率提高65%左右。CV场景接入KubeAI平台之后,弃用了以前本地训练的方式,在平台上灵活按需获取资源的方式大大提高了资源使用率;在模型管理、推理服务管理和模型迭代等方面,研发效率提高50%左右。
4.2 搜推模型训练任务从PAI迁移到KubeAI平台
相比CV的模型,搜推的模型训练成本较高,主要体现在数据样本大,训练时间长,单个任务需要的资源量大。在KubeAI落地之前,由于我们的数据存储在ODPS(阿里通用计算平台提供的一种数据仓库解决方案,现在已更名为MaxCompute)上,所以搜推的算法同学基本都在Dataworks(基于ODPS的大数据开发治理平台)控制台上构建数据处理任务,同时向PAI平台提交模型训练任务。但由于PAI是一款公有云产品,提交给它的单个任务成本是要高于任务本身所需要的资源成本的,高出部分其实可以理解为技术服务费;另外,这种公有云产品,对企业内部的成本管控需求也是无法满足的。
在KubeAI逐步落地之后,我们将搜推场景在PAI上的模型训练任务,按照2个方式逐步迁移到我们的平台上。方式1是保持用户在Dataworks进行作业的习惯,将一些SQL任务依然放在Dataworks去完成,然后通过shell命令向KubeAI平台提交任务;方式2是用户直接向KubeAI平台提交任务。我们期望随着数仓基础设施的完善,后续会逐步完全切成第二种方式。
搜推的模型训练任务开发过程,充分使用了KubeAI提供的开发环境和工具。通过自研训练工程Framwork,在仅使用CPU的情况下,训练时长可与在PAI上使用GPU训练的时长打齐;训练引擎侧还针对大模型训练、实时训练场景做了支持,配合多类型存储(OSS/文件存储)方案、模型分发方案,确保大模型训练任务的成功率,以及高效率地完成对在线服务的模型更新。
在资源调度和管理上,KubeAI充分使用集群联邦、超卖机制、任务绑核等技术手段,逐步将训练任务使用专有资源池转变为为任务Pod分配弹性资源,调度到在线资源池、公共资源池。充分利用生产任务周期性执行、开发任务白天为主的特点,实施错峰调度、差异化调度(比如:小规格使用弹性资源,大规格使用常规资源等策略)。从近几个月的数据来看,我们做到了在总的资源增量变化不大的情况下,持续承接较大幅度的任务增量。
4.3 基线指标预测场景
这是一个典型的非算法业务场景使用AI的能力。比如,使用Facebook的prophet算法预测某个业务指标基线。KubeAI为这些场景的需求提供了基础AI能力,解决了他们“想快速验证成熟算法难”的问题。用户只需将算法模型进行工程化的实现,然后制成一个容器镜像,在KubeAI上提交一个任务,启动执行,便可获取想要的结果;或者周期性地执行训练和推理,获取基线预测结果。
用户对任务所需的计算资源,或者其它异构的资源,按需配置即可使用。当前,以线上某业务场景的12个指标为例,每天有近2万次的任务执行,相比以往类似需求的资源成本,KubeAI帮助其节省近90%的成本,在研发效率上提升3倍左右。
五、展望
得物在较短的时间里顺利实现了业务的容器化,这一方面得益于越来越成熟的云原生技术本身,另一方面得益于我们对自身业务场景需求的深入理解,并能针对性地给出解决方案。KubeAI平台就是我们在深入分析算法业务场景的痛点需求之后,立足于如何持续提升AI业务场景的工程化效率,提高资源使用率,降低AI模型/服务开发门槛而思考构建、逐步迭代落地实现的。
后续,我们将继续在训练引擎优化、AI任务精细化调度、弹性模型训练等方面继续努力,进一步提升AI模型训练和迭代效率,提高资源使用率。