🙋🏻♀️ 编者按:本文是支付宝体验科技沙龙第 3 期-走进蚂蚁端智能技术回顾系列文章。作者是蚂蚁集团研发工程师南烽,介绍了蚂蚁千 X 千模技术(包括千人千模、千机千模等)的适用场景,以及在蚂蚁端智能中,千 X 千模从模型研发、模型发布、线上监控等各个环节的技术方案,和在一些实际业务中取得的阶段进展。
背景介绍
传统模型应用方式-千人千面
在介绍千 X 千模之前,先来举个例子,用传统的方法,我们是如何使用模型,对不同的用户进行预测的。
比如我们想要预测小明晚上会选择吃什么,是会吃米饭呢、还是面条呢、还是饺子。那我们会怎么做,第一步去选择一些能够对预测结果有帮助的特征,比如小明老家是哪里的,要是在西安可能喜欢吃面的概率会大一些,也会加入一些节气的信息,比如当天立冬,那吃饺子的概率也会增加一些。
有了特征之后,就需要构造一些训练样本,比如观察1万个用户,老家是哪里的、今天是什么日子作为特征,以及他今天吃的是什么作为标签。有了这些信息,就可以训练一个模型了,让模型去预测小明晚上会吃什么。
显而易见,这里是如何预测每个用户呢,就是通过提取到的特征的差异,去预测出不同的结果。大家一般把这种模式叫做千人千面。这种模式在云智能里是得到广泛运用的,也得到了很不错的效果。对于端智能来讲,最开始也是采用的这种模式,但在运行的过程当中,我们也发现了一些问题。
问题1:机型算力差异
第一个问题,就是机型算力的差异。相比于服务端的部署环境来说,端智能的情况会更复杂。
先来看下服务端的模型部署方式。服务端的模型都会部署在服务器里,虽然有的部署在物理机、有的在虚拟机、有的在容器中,但对于同一个模型来讲,部署的环境和介质基本都是一致的,也就是模型在各个容器中运行的性能是基本一致的。另外,如果当我们发现模型运行时间偏长,并发量又比较高的时候,现有的服务器资源已经不能满足业务的诉求的时候,我们也可以采用增加一些服务器资源的方式来抗住。
但是在端上,就麻烦的多。一个是用户手机的性能参差不齐,支付宝的用户覆盖范围很广,使用的手机的算力也都不尽相同,有使用今年最新款旗舰机的用户,也有两三年没有更换手机,那手机的算力差异是很大的。可以看下右边的四张图片,是我们统计的线上模型的实际运行耗时,可以看到,同一个模型,在不同手机里,运算耗时的分布差异还是很大的。另外,对于一些运行的慢的手机,我们也不能像服务端一样去扩容,所以对于这种情况,算法同学采用的更多的方法,就是去调整模型的复杂度,把模型做的更简单,去提高执行的成功率,但也就会带来一个问题,就是模型的精度会有所下降。
问题2:人群特征差异
除了算力的差异,还会存在人群特征的差异。这个问题其实是端智能和云智能都会遇到的。
在训练模型的时候,会使用所有的数据作为训练样本。模型在训练的时候,会朝着全局最优的方向去搜索模型的参数。这里我们展开来分析一下。对于一些高频的用户,会贡献出更多的训练样本,那模型在训练的时候,就会更倾向于这些用户,因为这些用户在实际的业务结果中,也会有更高的权重。但是对于一些低频甚至长尾的用户,他们的行为有可能是和高频用户不一致的,但是在模型搜索全局最优解的时候,就会一定程度上忽略模型在这些用户身上的表现,也就是会出现马太效应。
千X千模
解题思路
针对于以上的这两个问题,介绍下我们的解题思路,也就是大家常说的千机千模、千人千模。
对于客户端算力的差异,我们会思考,如何让高端机发挥出更大的算力能力,同时也让低端机也能够去运行一些模型。那说到这解法就比较明显了,就是我们准备一组模型,有复杂的、也有简单的,让高端机去跑复杂模型,拿到更好的模型预测结果,让低端机去跑简单模型,保证模型的执行成功率,也就是按照算力,去分配不同复杂度的模型。
对于人群的差异,现在有一个词比较流行,叫“精细化”,这个词和千人千模的思路也是比较契合的。针对于用户的特点,我们可以对用户进行聚类,将相似的用户聚到一起,去针对这个人群,单独去训练一个模型,那这个模型对这个人群的描述,肯定会强于全局模型对这个用户的描述。所以我们在给用户发布模型的时候,也会根据用户所在的人群,去匹配对应的模型。
千机千模和千人千模分别解决了算力和人群的差异问题,我们自然而然就会有一个思路,是不是可以将这两者结合起来,同时解决算力和人群的差异问题,除此之外,蚂蚁端智能还有一些其他维度的“千模”,我们将这些统一称之为千X千模。
千 X 千模工程链路升级
从单模型做到千模型,是不是只需要把 1 个模型复制 1000 遍就可以了呢,实际的生产过程远没有这么简单。由 1 到 1000,会对两个环节产生挑战,一个是离线研发阶段,一个是线上发布阶段。
先来看离线研发。在做千 X 千模之前,我们的离线研发主要以手动为主,从模型训练、到 xNN 转换、再到 git 打包、真机评测,都需要手动来完成,并且需要在三四个平台之间来回跳转和传输数据。当只有一个模型的时候,我们觉着效率还好,10 分钟左右就能够完成全部的流程,但是当模型变成 1000 个,如果还是依靠手动来做,那就可不接受了。所以在离线研发阶段,我们做了全链路的升级,将多个平台打通,串联起相关的流程,自动的完成离线的所有准备工作。除此之外,与单模型相比,千 X 千模在离线研发阶段,还需要多产生两份数据,一个是人群库,另一个是设备库,用于在用户拉取模型时,判断用户到底需要拉取的是哪个模型。
前面也提到过,千人千模的这个问题不止在端智能中会遇到,在云智能中,也会有同样的问题,并且云智能的发展远远早于端智能,但为什么云智能没有去解决这个问题呢。我们知道服务端的模型部署方式是依赖服务器的提前部署的,所以当模型数量从 1 个变为 1000 个的时候,对服务端模型的部署速度、资源的利用率都会带来很大的挑战,甚至于是无法实现的。但是对于端智能来讲,虽然全局看模型数量从 1 变为 1000,但是对于用户来讲,只会拉取到一个模型,所以对端的运行时来讲,复杂度没有明显的增加,更多的难点在于云上如何去准确的发布模型。
端智能统一发布链路升级
接下来介绍下发布阶段的工程实现过程。蚂蚁端智能的发布也是经历的两个阶段,左边是第一阶段,是在蚂蚁端智能刚起步的时候,我们采用的技术方案。这里需要说一个前提,蚂蚁对线上故障的重视程度是很高的,也有标准的流程把控,以及相关的配套能力。所有线上变更,都需要严格的遵循三板斧原则,也就是可监控、可灰度、可回滚。对于客户端的发布,会有客户端配置中心来承担这个职责,这个链路具备完整的三板斧能力,并且在发生稳定性风险的时候,可以自动的对变更进行熔断,快速止血。所以端智能最开始直接复用了这个链路,能够让业务快速的跑起来。
随着端智能业务规模的发展,我们也遇到了一些问题:第一点,千 X 千模的发布,客户端配置的方案无法支持。客户端配置是基于规则做的发布,比如基于品牌、机型、操作系统、版本号等等,但千 X 千模是需要基于每个用户的维度单独计算;第二点,客户端配置作为一个支付宝 APP 的基础服务,在日常以及大促阶段都是需要高保的,但端智能的场景,对发布的时效性和到达率的要求并没有那么高,导致客户端配置需要更多的资源来保障端智能业务,这其实是不需要的;第三点,客户端配置是有配置大小的限制的,而端智能的发布任务,经常会有比较大的数据传输,很容易就超过了限制大小。
所以基于以上的问题,我们对端智能的统一发布进行了链路升级,采用二阶段的方法来实现。先利用客户端配置通道完善的三板斧能力,将端智能的配置 ID 下发下去,端智能再基于 ID 信息,重新计算和拉取真正需要用的配置内容。这样虽然多了一次网络请求,但是能够完美的解决上面提到的这三个问题。
千 X 千模的挑战
在做千 X 千模的时候,也会遇到一些问题,挑几个典型的来说一下:
- 是不是模型数量越多,效果越好。最开始我们的想法是这样的,所以模型数量做的比较多,但实际的情况来看,随着模型数量的增加,效果并不一定会增长,甚至递减。分析原因,可能是由于某些人群的样本不够丰富,导致过拟合的情况
- 千机千模里,模型与设备算力如何关联呢 算力是一个自定义的指标,主要是由硬件来决定的。所以我们会在离线通过真机测试的方式,对设备进行分级,用于线上的匹配 当然,对于同一个手机,在不同的运行环境下,所能提供的算力也是有差别的。所以未来我们也会基于线上的运行数据,甚至手机当时的运行环境,去做动态的千机千模
- 上线后,如何才能发现有问题的模型呢 我们采用的方案是在线上做圈人实验,监控各个模型的线上表现,发现效果较差的模型的话,会将这个模型替换掉
业务结果
最后看一下千 X 千模给业务带来的帮助。
业务 1 使用的是千人千模,这个业务在 20 年的时候开始使用端智能,经过了 2 年的时间,指标从 92.5 提升到了 94.6,也达到了一个瓶颈。在今天升级到千 X 千模的模式,从离线分析看,绝对值又提升了 1 个百分点,最近看了下线上的指标,会有 1.5 个百分点的提升,效果还是很明显的。
业务 2 使用的是千机千模的能力,在之前为了保证线上模型的执行成功率,是能使用最小的模型,准确率只有 85.7,通过对机型进行分级,可以对部分设备下发更大的模型,模型的表现也有一定的提升。