查看原文
其他

机器学习平台的模型发布指南

廖国龙 凯哥讲故事系列 2022-05-08

导读:近两年,各式各样的机器学习平台如雨后春笋一样出现,极大地降低了从业者的门槛。大家的关注点往往在平台如何能够高效地进行各种花样地数据预处理,如何简单易用地训练出各种模型上。但是在产出模型之后呢?我们应该通过怎样的方式才能让模型产生价值呢?

    作为机器学习平台的构建者,在得到应用于不同场景、不同类型的模型后,接下来需要思考的就是模型产生价值的场景,比如:

  • 实时预测服务:兼容不同模型,包装成用于预测的功能,进一步发布面向用户的高时效性的预测服务,亦或是高性能的批处理任务。

  • 优化平台自身:在得到相对比较成熟的模型后,反哺平台的流程,以模型算法增强平台的功能。这样,才能产生平台 -> 模型 -> better平台 -> better模型 -> … 的良性闭环。

模型的本质是什么?


    首先,为了把各种模型发布成应用服务,我们需要明白模型的本质是什么。如今各种不同的机器学习框架,如tensorflow、caffe、pytorch等,都定义了自家的模型格式,以下以tensorflow为例。

                            

    模型作为一种图结构,无论是数据在模型中的计算,还是对数据的预处理、后处理都可以融入到模型中,作为图的一部分。所以无论深达N层、具有过亿参数的模型,还是上图这么朴素的结构,模型的信息都承载在两个方面:图结构和对应位置的参数,对应了tensorflow中的GraphDef和Weight

  • GraphDef
    模型网络中所有的节点都代表一种数学上的计算,它们都接收上一层节点的输出,同时输出到下一层节点作为输入。正是通过繁琐的计算,把所有节点都联系在一起,组成了Graph对象。

  • Weight
    在如今如此多开源Graph结构的情况下,weight其实是大部分模型的真正产出,是模型训练阶段大部分时间优化的目标。这一方面是因为成熟Graph结构的易得性,另一方面也反应了Graph优化的高门槛。即使可能成为未来趋势的AutoML,在如今因为极高的算力要求下,也使大多数公司望而却步。

    模型的训练就是在Graph的骨架下,通过大量的数据流动,不断寻找最适合某个场景的的肌肉(weight)的过程。因此,模型训练时,会不断地把weight保存成checkpoint达到持久化存储的目的,也可以加载任何其它兼容Graph的weight,作为训练的起点,这也是预训练、迁移学习的基础。

基于tensorflow的模型发布


    平台为了响应用户的预测请求,以对象识别为例,需要提供的API是图片到代表坐标、准确率的数字,然而对于自然语言处理的场景,输入和输出又变成文本。所以模型发布常常碰到如下挑战:

  • 平台往往会提供交互式的云端机器学习开发环境,供用户训练自己的模型,所以平台API需要兼容输入输出差异巨大的模型

  • 在通过GraphDef重构模型,Weight复现参数后,作为一个图结构,需要明确知道输入输出node的tensor名称,以实现模型的inference,增加了标准化的难度

  • 模型的训练是建立在大量的数据集基础上,实际的输入不会是图片和标注数据这样的原始数据,而是tfrecord、LMDB等经过压缩的数据集,就造成了模型的输入和预测服务输入的偏差。

    为了解决问题,需要用到tensorflow的saved_model模块:

  

    一个savedModel对象可以保存多份Graph的信息,以及共享的变量和资源子集。在模型保存的时候,只需要提供用于inference的输入函数,该函数需要:

  • 定义模型做inference时,作为输入的数据结构

  • 定义数据预处理方法,将输入转变成能被模型真正接受的tensor数据

    因此,通过引入inference时特有的数据预处理,使得模型可以兼容各种预测API的输入,而不受制于训练数据集。作为平台,只需要定义运行其上的模型做预测的输入标准,便可以无视不同模型在发布时差异性。

模型发布的工程实践


    平台模型千千万,为了让所有模型都可以一键发布,并提供给用户实时弹性的预测服务,就需要:

  • 满足不同模型在做inference时的运行依赖

  • 包装inference成restful api,并发布成平台服务,暴露给用户

    得力于机器学习框架对运行时环境要求的一致性,平台只需要针对每种机器学习框架,把模型发布代码及依赖打包成一个Docker镜像,就能满足该框架里所有模型的发布需求。当然,这要求待发布的模型满足平台制定的inference时输入输出的标准。 

    同时,出于模型发布标注化的要求,镜像中是不包含具体模型的数据的,只需要完成了诸如加载模型数据、模型重建、模型预测、数据的预处理和后处理等标准接口,实现发布和模型的分离。

 

    进一步,为了把docker容器中的service暴露到平台外部,这就需要用到kubernets的ingress功能。Ingress通过路由提供集群内的services的外部http/https访问入口,并提供诸如负载均衡、SSL终止等功能。

    平台首先把模型发布的镜像发布成kuberntes的Service资源,通过副本集的设置实现负载的功能。在这个过程中可以通过StorageClass和PVC挂载外部存储的方式注入待发布的模型数据。最后在ingress中注册预测服务的名称和端口完成发布。

模型发布的应用实例


    AI平台作为模型的生成工厂,生产出应用于各种场景的智能服务,当然不会只许百姓放火,不许州官点灯,忽略自身的智能场景应用。实际上,在构建机器学习平台的后期,在平台的功能点趋于稳定,各个功能的模块化日益完善的条件下,下一步必然向着更加自动化进行的,是离不开自身模型的应用的。

  • 预标注
        模型的训练需求海量带label的数据,对原始采集的数据进行标注的工作,基本都是人工完成的。这是一项极其耗时的任务,并且对准确的要求很高。数据的质量决定了最终产生的模型的上限(shit in, shit out)。因此,在我们得到对应场景的模型后,便可以发布成预标注的任务,先于人工进行标注,大大优化平台的标注流程,从而得到更好的模型,再更好的优化平台,再。。。

  • 场景采集
        成熟的模型需要在不同的需求场景下都有优秀的表现,以自动驾驶为例,就需要应对不同的天气、路况、突发情况等。与预标注类似,平台可以利用模型计算源数据各场景数据的稀缺性,来指导平台数据的采集工作,以加强模型较薄弱性能的场景。

  • 模型训练
        作为“调参工程师”的主要工作,训练模型的工作同样机械的复杂和繁琐。因此,平台如果有能力训练出能应用于模型训练过程中的各种优化、压缩算法,比如剪枝、hyperparameter search、精度计算优化等,能进一步优化了平台的流程。

    这样,平台就通过发布自身产出的模型,来优化平台的数据的采集、数据加工、模型训练等各个流程,从而得到更好的模型,达到自动持续的优化的效果,形成良好的闭环。

技术总结

    上面只阐述了上述策略在tensorflow框架下的实现,这是由于不同框架对于模型的定义、数据的要求及各项特性实在相差很大。因此,AI平台兼容更多的框标准化自动化之间属于不可调和的矛盾。个人感觉平台作为一个标准制定者,谨慎兼容过多框架,平台在做很多技术选型、数据选型基本都是基于框架的基础上,否则后期的effort指数上升。



相关文章:

持续智能-机器学习项目的11类问题及解决之道

从中台大战看思想领导力的重新定义

你真的需要那么多报表么?



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存