导读:近两年,各式各样的机器学习平台如雨后春笋一样出现,极大地降低了从业者的门槛。大家的关注点往往在平台如何能够高效地进行各种花样地数据预处理,如何简单易用地训练出各种模型上。但是在产出模型之后呢?我们应该通过怎样的方式才能让模型产生价值呢?
作为机器学习平台的构建者,在得到应用于不同场景、不同类型的模型后,接下来需要思考的就是模型产生价值的场景,比如:
模型的本质是什么?
首先,为了把各种模型发布成应用服务,我们需要明白模型的本质是什么。如今各种不同的机器学习框架,如tensorflow、caffe、pytorch等,都定义了自家的模型格式,以下以tensorflow为例。
模型作为一种图结构,无论是数据在模型中的计算,还是对数据的预处理、后处理都可以融入到模型中,作为图的一部分。所以无论深达N层、具有过亿参数的模型,还是上图这么朴素的结构,模型的信息都承载在两个方面:图结构和对应位置的参数,对应了tensorflow中的GraphDef和Weight。
模型的训练就是在Graph的骨架下,通过大量的数据流动,不断寻找最适合某个场景的的肌肉(weight)的过程。因此,模型训练时,会不断地把weight保存成checkpoint达到持久化存储的目的,也可以加载任何其它兼容Graph的weight,作为训练的起点,这也是预训练、迁移学习的基础。
基于tensorflow的模型发布
平台为了响应用户的预测请求,以对象识别为例,需要提供的API是图片到代表坐标、准确率的数字,然而对于自然语言处理的场景,输入和输出又变成文本。所以模型发布常常碰到如下挑战:
为了解决问题,需要用到tensorflow的saved_model模块:
一个savedModel对象可以保存多份Graph的信息,以及共享的变量和资源子集。在模型保存的时候,只需要提供用于inference的输入函数,该函数需要:
因此,通过引入inference时特有的数据预处理,使得模型可以兼容各种预测API的输入,而不受制于训练数据集。作为平台,只需要定义运行其上的模型做预测的输入标准,便可以无视不同模型在发布时差异性。
模型发布的工程实践
平台模型千千万,为了让所有模型都可以一键发布,并提供给用户实时弹性的预测服务,就需要:
得力于机器学习框架对运行时环境要求的一致性,平台只需要针对每种机器学习框架,把模型发布代码及依赖打包成一个Docker镜像,就能满足该框架里所有模型的发布需求。当然,这要求待发布的模型满足平台制定的inference时输入输出的标准。
同时,出于模型发布标注化的要求,镜像中是不包含具体模型的数据的,只需要完成了诸如加载模型数据、模型重建、模型预测、数据的预处理和后处理等标准接口,实现发布和模型的分离。
进一步,为了把docker容器中的service暴露到平台外部,这就需要用到kubernets的ingress功能。Ingress通过路由提供集群内的services的外部http/https访问入口,并提供诸如负载均衡、SSL终止等功能。
平台首先把模型发布的镜像发布成kuberntes的Service资源,通过副本集的设置实现负载的功能。在这个过程中可以通过StorageClass和PVC挂载外部存储的方式注入待发布的模型数据。最后在ingress中注册预测服务的名称和端口完成发布。
模型发布的应用实例
AI平台作为模型的生成工厂,生产出应用于各种场景的智能服务,当然不会只许百姓放火,不许州官点灯,忽略自身的智能场景应用。实际上,在构建机器学习平台的后期,在平台的功能点趋于稳定,各个功能的模块化日益完善的条件下,下一步必然向着更加自动化进行的,是离不开自身模型的应用的。
这样,平台就通过发布自身产出的模型,来优化平台的数据的采集、数据加工、模型训练等各个流程,从而得到更好的模型,达到自动持续的优化的效果,形成良好的闭环。
技术总结
上面只阐述了上述策略在tensorflow框架下的实现,这是由于不同框架对于模型的定义、数据的要求及各项特性实在相差很大。因此,AI平台兼容更多的框架和标准化自动化之间属于不可调和的矛盾。个人感觉平台作为一个标准制定者,谨慎兼容过多框架,平台在做很多技术选型、数据选型基本都是基于框架的基础上,否则后期的effort指数上升。