🙋🏻♀️ 编者按:本文是支付宝体验科技沙龙第 3 期-走进蚂蚁端智能技术的回顾系列文章,蚂蚁集团客户端工程师朱木分享了蚂蚁端侧计算容器面临的挑战、思考和设计方案。
背景与挑战
一个应用场景要落地端智能方案,一般分为以下几个阶段:
- 决策链路研发:决策的调用、决策逻辑的执行和决策结果的响应。
- 端特征的研发:特征数据采集、计算,并以服务的形式提供给训练和决策环节。
- 端模型的研发:样本数据采集、端模型的研发、转换。
- 决策逻辑研发:业务前置处理、模型推理、业务后置处理。
端智能解决方案研发过程中,面临的几大问题与挑战:
- 基础功能支持:具备丰富的数据供给、特征生产加工、端模型推理、业务逻辑编写等基础能力。
- 迭代部署效率:云端模型一天一迭代,而客户端按月发版,无法满足迭代效率的诉求,需要能快速搭建工程链路并具备动态化执行能力来承载各业务定制化的复杂逻辑。
- 端高性能计算:在云端,具备流批一体的计算能力、高性能存储和查询能力。在移动端,一方面需要具备毫秒级别的计算能力,保障业务调用成功率,另一方面计算任务天然消耗资源,需要平衡用户使用体验。
- 端侧高稳定性:移动端碎片化验证,稳定性可谓是重中之重。我们需要从研发、发布、运行、监控、熔断等全链路进行梳理和重点保障。
针对上面提到的几大挑战,我们设计了端智能计算容器,来提供端侧的数据特征服务和解决方案的运行时支撑和保障,并能在稳定性、研发效率、计算性能等方面满足要求。
整体架构
端计算容器的整体架构如图所示,端上运行时环节,分为三部分:
- 计算引擎:提供特征和决策逻辑的基础计算环境,包括了实时计算、模型推理、PythonVm、任务管理等。
- 特征引擎:提供端云一体的统一端特征服务供各业务方使用。
- 决策引擎:封装了基础的服务框架,给算法和工程同学提供便捷的研发环境。
在平台侧,通过端智能研发平台 Moobileaix 和研发套件,给研发同学提供便捷的研发体验。在计算引擎部分,重点绍一下端侧实时计算引擎。
实时计算引擎
为了在端智能场景中提供用秒级的用户响应和满足决策引擎对特征生产高时效的要求,我们也探索出在端侧的进行实时计算的引擎,及对产生的数据,直接在端侧进行复杂流式计算处理。大致的设计方案如图所示:
- 接口层:提供强大的实时计算任务定义能力,并实现了端侧计算任务动态化更新部署。
- 服务层:提供端实时聚合、实时匹配、实时串联的底层数据模型结构以及DSL的运行时环境。
- 数据层:提供多技术栈数据统一采集,实现实时数据源统一化、标准化,为上层数据消费服务提供订阅管理服务。
事件标准化
实时计算数据层面临的问题和挑战:
- 采集覆盖:技术栈涉及到原生 Native、H5/小程序、卡片等,覆盖全场景的数据有较大的难度。
- 研发效率:很多业务场景数据依赖纯手动埋点,任何埋点改动都需要依赖客户端发版或者业务发布,加之数据采集的需求复杂多变,日常投入了大量时间在数据埋点上,研发效率较低,
- 埋点时机:手动埋点的触发时机完全是业务手动控制的,一旦时机错乱会导致归因不准;
- 数据口径:各业务手动埋点采集口径不统一,比如曝光口径,不同业务对于曝光比例多少算作有效曝光有不同的定义;
我们通过统一的采集框架,基于切面、注入等技术,实现了不同技术栈、不同类型数据的统一采集,数据口径统一,事件模型统一。采集框架标准化事件后,通过实时事件流 pipeline,源事件快照源源不断的,向各引擎上的任务实例进行分发。
实时聚合
实时聚合的三个演进阶段:
- 1.0 阶段:功能快速落地。我们称之为刀耕火种阶段,native 侧硬编码业务逻辑,支撑了 poc 场景的快速落地和验证,但需求改动都需要跟随客户端发版,无法满足业务对于迭代效率的要求。
- 2.0 阶段:解决研发效率问题。数据存储在关系型数据库或者时序数据库,上层通过编写 sql 查询加工数据。但随着业务数据的增多,性能问题急剧突增,一次查询多则需要几百毫秒甚至秒级,影响业务调用成功率和用户的使用体验。而为了支撑不同业务的不同诉求,大量的数据写入也会造成高频 IO 和存储浪费。
- 3.0 阶段:解决性能存储问题。为了解决特征计算在性能、存储、动态性方面的问题,我们设计了端侧实时聚合引擎,可以针对端数据进行切分、拼接、取参的操作,以及计次、求和、平均值、序列等多种聚合计算,同时对结果快照进行分级缓存,在使用时提供毫秒级的获取能力。随着接入业务的增多,不同业务之间的计算任务不免有重复,为了进一步降低计算资源消耗,我们还设计了任务的相似度检测和自动合并的方案,实现了跨任务的计算复用,并通过分级的任务调度,实现了任务的按需计算。
实时匹配
端智能业务对于复杂事件匹配的主要核心诉求如下:
- 支持多事件匹配:一开始端智能任务的触发模式是按钮点击、页面打开等单一事件,随着应用场景越来越广泛,业务对于复杂事件触发的诉求越来越多,比如从 A 页面进入 B 页面,停留 10s 又退回 A 页面
- 能够动态部署:初期我们可以通过硬编码的方式去支持场景的触发;可当类似的场景诉求越来越多时,算法对效率、实时性要求越来越高时,受限端发布、开发成本等问题,原方法慢慢变的不再可行。
- 能够实时相应:云端实时计算,需要把先原数据明细即时上报,云端流处理服务处理完成后再下发结果,网络延迟加上处理耗时,只能做到准实时,而无法实时响应当前交互操作
基于上述考虑,我们在端上设计一套支持动态下发自定义规则的规则引擎来完成事件序列的匹配与触发工作。
- 首先,我们通过定义一套基于 json 格式描述的 DSL 描述语言来定义规则;
- 之后,我们将自定义 DSL 内容动态下发到端上,并在端上实现相应的自定义语言解析器,解析器解析出同样表达能力的一个 Pattern 链表(RE);
- 再之,基于已解析出的 Pattern 链表,通过实现的 NFA 编译器,把目标编译成 NFA 实例;
- 最后, NFA 实例初始化完成即可以开始对输入信息进行处理。
实时匹配引擎的核心运行处理是 NFA 非确定性状态机,其运行时首先会把 DSL 任务编译成一个有向无环图,再基于有向无环图,实时处理输入的数据流,当 NFA 成功到达终点的节点时,即匹配结果成功,成功识别一个目标状态实例。
实时串联
在云端蚂蚁域内各业务间相互调用、依赖关系等都是通过一系列的 ID 体系进行规范约束,方便链路串联分析。但在端侧,传统串联体系面临的几大问题:
- 串联相互割裂:由于端侧环境的复杂性,加上多方业务的接入、接口调用、服务端网络请求等的介入,很多域有自己的 ID 体系,这些 id 体系之间相互独立,只能部分还原用户动线,无法还原一个用户动线的全貌,而其中一些资源的串联现在还没有一套可跟踪的体系。
- 计算资源消耗大:以上数据绝大部分通过埋点回流到云端进行计算,而为了准确的还原用户动线,需要经过云端海量数据的计算聚合,这个对计算资源、存储占用、实时性都是一个巨大的挑战。
因此,我们设计了一套完整实时串联的能力,解决上诉的问题。
我们使用表示行为的节点来构建分层树模型表示各模型的生命周期,比如 Session 代表行为会话、app 代码应用启动、Scene 代码页面实例、Page 代表页面访问等。其中 Session/App/Scene/Page 节点构成了树的骨架结构,而 Behavior 行为做为叶子节点表示用户在当次页面访问中的具体操作行为。骨架节点之间保持层级强约束关系,即 Session->App->Scene->Page 之间为父子关系,节点不可越层级添加子节点;
同时通过来去源引用关系,表示出用户行为中的跳转关系。仅有 Page 节点才有逻辑去源子节点,表示由当前 Page 节点去到其它目标节点的逻辑跳转行为,触发的原因为 page 下的某一具体叶子节点行为。
特征引擎
问题与挑战
在刀耕火种的年代是将特征代码逻辑放在业务逻辑代码中的,特征研发面临的困难和挑战:
- 特征难以复用:每个算法同学都需要从 0 开始研发特征,一些公用特征无法沉淀,也会造成数据的重复计算。
- 研发环境不友好:算法同学熟悉的是云端的研发环节,但到了端上,涉及到数据口径沟通、运行环境部署、任务配置、代码研发、业务触发、代码验证等环节,流程长,研发难。
- 稳定性保障难道大:手机端的计算资源有限、碎片化严重,一个简单的计算查询语句可能会对性能和稳定性造成影响较大的代码,如何保障端侧运行的稳定性,是我们面临的一大挑战。
要解决上诉问题,需要从特征的研发和使用两个方面进行优化,提升研发体验。
低代码特征研发
我们设计了低代码特征研发平台来提升研发效率、保障用户体验。特征研发分为了四个环节:特征研发、特征调试、特征集成、特征发布。
- 特征研发:特征研发有三种模式:配置/配置+脚本/脚本。经过前面的介绍,多数行为特征可以通过实时聚合的能力进行计算,但是 dsl 语言理解成本较高,为此我们提供了可视化的配置页面,业务同学填写简单的参数即可完成研发,实现 0 代码研发。而对于有复杂计算诉求的,例如矩阵变化、甚至模型计算,可以在脚本层进行处理,并通过提供的研发脚手架来提升研发效率。
- 特征调试:在调试验证环节,提供了研发 IDE,支持真机部署、日志查看、断点调试、全链路 mock 等能力,修改完配置或代码后,可以实时部署查看特征数据。
- 特征集成:研发完成之后,基于端上稳定性和权限等因素,我们会对特征进行稳定性、性能等测试和集中的审批。
- 特征发布:发布能力极其灵活,支持机型、版本、人群的灰度、ab 控制,并且还可以同云端系统一起进行联合实验。
通过上面的设计,特征从研发到上线,最快半天即可完成。
端特征服务
我们通过端特征服务对外提供特征数据。使用时,传入特征名称即可查询到对应的特征值,特征服务内部进行统一路由,屏蔽特征实现,降低了调用成本,并通过统一的管控,对调用方进行权限的校验。平台侧我们也提供了端特征中心,对特征进行元数据的管理,可以便捷的查询到目前已沉淀的特征和特征的预览值,方便研发同学 在使用过程中发现的几个问题:
- 特征无效计算:业务下线掉特征调用后,特征还在继续生产,对于资源有限的手机端存在非常大的浪费。
- 特征数据异动:诸多特征依赖上游业务数据,业务某些小的改动可能造成数据缺失,影响模型的准确率。
因此我们还建设了特征实时监控能力,例如特征血缘、特征质量、特征耗时,当发生无效计算或者特征异动之后,可以及时发出告警进行诊断和优化。传统云端特征生成消费链路的几个痛点:
- 特征时效性低:云端传统的行为数据获取使用埋点,埋点上报到云端,通常有分钟级别延迟,服务端通过实时计算引擎解析,存在任务延迟,导致实时特征进一步延迟。
- 计算资源消耗高:全量用户行为关联时,需要对多个数据进行聚合,这在云端是非常消费资源的,尤其是实时数据流的聚合。
我们封装了产品化的方案,用户可以在平台侧便捷的配置触发时机、勾选特征列表和选择分级的实时通道,便可在云端通过实时特征服务获取的对应的特征。
决策引擎
随着端智能的基础设施逐渐完善,参与的算法同学越来越多,端决策面临的挑战:
- 更快的进行开发和上线解决方案和进行 AB 实验
- 在端用户体验不变的情况下,支撑更多的端智能方案部署
为此,我们定义了基于决策框架的业务接入引擎,包括三部分:
触发时机(Trigger) + 决策逻辑+ 决策响应(Action)
三段式的设计很好的区分了工程和算法的边界,工程专注于工程链路的建设,算法专注于决策逻辑的开发和部署
- 触发时机提供了基于自动化埋点和行为规则引擎的事件,可以满足 90% 的使用场景,避免重复开发
- 决策响应提供了端上常用的用户触达通道,简化了工程侧链路
- 触发时机和决策响应可以随意组合来实现不同的工程链路,已有工程链路也可以被多个决策逻辑使用,可以进行方案间的 AB,这样来提升工程链路的复用度。
- 决策逻辑就是端智能脚本,是运行在经过我们裁剪、优化、扩展的 python 虚拟机运行环境中的。在研发阶段,建设开箱即用的框架和算法模版方案,例如 predict 和 rerank 模板方案,来降低研发难度。代码写完之后,需要提供一套能与端上运行时环境相匹配的调试工具,也是我们面临的较大难题,举几个例子,比如编写完代码后如何查看运行结果,如果需要走一次发布流程肯定是不行的,耗时费力;实现快速调试,脚本是运行在手机端还是 pc 端,是我们面临的选型问题;端决策脚本通常需要业务数据的输入和特征数据,受限于工程链路研发的进度、环境等因素,在没有这些数据的情况下,如何快速的进行决策逻辑的研发。我们基于 VSCode 的插件体系提供了端智能脚本的扫码部署能力,具体包括了一键打包、真机部署、断点调试、日志查看、全链路的数据 mock 等功能。
在发布阶段,提供了灰度管控、多模型 AB 和端云联合 AB 能力,联合 AB 支持端云系统的不同实验室实验之间的流量穿透。
另外,提供了统一的调度和管控能力,主要包括基于触发时机的审核、调度和算力配额。