查看原文
其他

YoDA统一数据应用——融合计算在蚂蚁风险场景下的探索与实践

郭振宇 蚂蚁技术AntTech
2024-08-22

前 言

层出不穷的线上金融活动相关风险,以及它们之间愈来愈多的“跨界协作”(例如欺诈、赌博、洗钱等),多年来一直是蚂蚁大安全部门风险数据系统聚焦的问题。长期的强对抗、资金风险的敏感、客户体验和风险防范的矛盾、复杂风险带来的跨域融合、大数据和人工智能技术的“百花齐放” ,这些挑战使得整个风险数据智能系统臃态尽显,带来了一系列管理、部署、迭代、可靠性、合规、成本效能的问题。


为了应对这种持续熵增的不可持续性,蚂蚁大安全部门提出了YoDA(Unified Data Application)项目,并逐步衍生了包含数据上下文、数据研发框架、数据服务框架以及三线一致等在内的多个子项目。整体思路是先结构化理解和治理整个数据智能系统的资产/计算/变更以及状态,然后通过提供跨多引擎和多时态的统一计算/存储开发和衔接抽象,对系统进行逐步底层依赖解耦和上层抽象升级,从而把整个数据智能系统从黑灰盒转换为白盒子,并提供从业务视角出发的逻辑化和一体化的异构融合数据智能系统治理和建设方案。


蚂蚁大安全部门经过一段时间的实践,在YoDA以及基于YoDA的应用等方面,取得了阶段性进展,基本验证了YoDA所倡导的白盒化/逻辑化/一体化的异构融合数据智能系统的建设思路,并在隐私合规、平台整改、成本核算等新近需求实现中显现出越来越多的优势。


1.蚂蚁风险场景的挑战


线上风险场景是典型的数据驱动业务,其研发活动主要包括基于数据和案件的各种策略、模型和特征的探索,以及各种实时或者离线的自动化风险和处置决策等。给定一个线上风险问题类别(例如支付是否有盗用风险):首先需要寻找相关的数据支撑,不管是决策链路直接带过来的数据(称为事件),或者是其他旁路的数据(来源于例如系统日志、数仓、在线数据库、应用服务)


然后基于这些数据生产各类特征,算法上会有进一步的深加工,例如计算各种不同风险标签的概率,并重新以特征方式露出;


最后当决策事件到来的时候,调用预定义好的基于特征之上的策略集合(规则)来给出最终的风险决策(例如判定本笔支付有高风险并进行强校验或者直接阻断)。业界对数据驱动的探索与决策所需要的系统设计已经有了很多好的实践,例如在搜索、营销、推荐等领域。那是不是直接参考相关的实践就足够了呢?要想回答好这个问题,必须首先要理解蚂蚁风险场景,例如说比较典型的交易风控或者欺诈洗钱等场景,相比其他非风险场景的不同特点。下面介绍我们的几个观察。


1.1 强对抗


风险场景最直接的特点是强对抗。这种常年累月的持续对抗带来几个挑战:(1) 全链路多样性,为了尽快获利或者止损,对抗双方都在不停地寻找漏洞并建设新的对抗手段,很难有一劳永逸的银弹,导致在数据、特征、策略、模型、整体链路和方案等各个维度都有不同程度的堆积;(2)计算复杂度持续走高,特别是相比传统的盗用、套现、作弊等相对聚焦于单体作案的风险场景,近年来欺诈、赌博、洗钱等获利更丰,社会危害更大的有组织团伙案件频发,且显现出越来越多的跨风险域“协作”的特点,显著提升了风险对抗博弈所需要的计算复杂度水平(例如更加复杂的算法实现,不同方案链路之间的资产复用和计算协同);(3)沉淀困难,层出不穷的新方案,加上近十年大数据和人工智能领域技术的百花齐放[1],给相关平台和引擎的稳定发展和沉淀带来了挑战。


1.2 资损敏感


大多数蚂蚁风险业务保护的是用户体感强烈(例如欺诈)或者社会危害巨大(例如洗钱)的资金安全。由于资金流出后再追回的难度比较大,团队会倾向于宁可多算三千(特征/策略/模型等),不可放过一个的思路,使得计算规模持续走高;同时,老的风险模式冷却一段时间后可能会被重新激活,导致了相关防控所涉及的数据资产和链路即便在效能评估后收益很低的情况下也不太容易被下线,进一步推高了计算规模;最后,资金损失或者资金行为被阻塞(以规避风险)后有强解释需求,一定程度上阻碍了深度学习的广泛使用,也间接阻碍了我们利用深度学习端到端学习能力来降低整体链路复杂度的努力。

1.3 风险 vs 体验


只强调风险防范(例如每笔支付都要求进行各种验证),会降低用户的体验,最终导致整体支付成功率的大幅下降。一个常见和主要的实践是提升计算性能,在不减少计算量以确保风险识别效果的前提下,尽量提升用户的体验。这个过程常碰到两个挑战:一是如何在低延迟决策场景下(例如20ms)完成尽量多的风险评估,二是相关性能优化要减少对算法效果的影响,或者说整体设计需要在算法、系统、业务之间做综合权衡。这种对客户体验和风险防范矛盾的极致追求也推高了系统的复杂度。
此外,风险场景在异常检测方面也有不少挑战,包括无害异常、缺少反馈、强对抗下的模式多变等,这些都给数据系统带来了各种难题。这些因素叠加在一起,整个数据智能系统的熵呈现出一个几乎单调的增长,带来了诸多问题,参见下个章节的讨论。

2.蚂蚁风险数据的熵痛

熵增带来的最大挑战是无序,而无序导致了一系列痛点。


2.1 黑灰盒子的问题


前面谈到的数据、计算、链路的多样性,加上多年累积下来的方案本身的积累,导致所涉及的不同资产之间的血缘不清晰,语义不严格,给系统理解、系统稳定性、效能治理、数据隐私管控等带来了大量的挑战。一个简单的例子是我们在修改或者删除已有的一个字段、特征、策略或者服务的时候,要确定不会瘫痪已有的但是可能触发概率非常低的一些风险场景链路;又或者在合规场景数据断流的需求下,我们需要量化断流后可能产生的后果以避免断崖式的防控效果下降;又或者我们想下线掉一些对业务贡献比较低的特征和策略以降低成本,但却又没有足够的量化支撑。


这些我们都或多或少踩了不少坑,这里主要原因在于整个系统涉及的系统实例多而且概念/种类/版本杂乱,虽然很多系统内部有很强的可观测性(例如数据库或者某个特征管理平台),但是它们之间的关联/集成并没有明确的规约,导致了很多黑灰色地带。由于我们不了解具体依赖以及其他一些更加细致的特性是如何相互影响的,给很多后续任务造成了困难(图1)。


图1. 黑盒子带来的挑战 


2.2 上下层耦合多


由于业务场景的多样性、对性能的极致要求、对抗方案的持续堆积以及这些年来底层技术栈的更新换代,我们不得不使用了各种各样的底层存储和计算引擎。在具体实现中,业务逻辑和不同底层引擎的客户端代码耦合较为严重,在各种不同部署场合下的适配能力差,导致了很多冗余建设且没办法简单复用。另外一个挑战是在于不同场景下的工作负载也不一样,包括流量、对SLA的要求、以及最终在成本方面的要求,导致了某些已经成熟的重量级引擎并不能简单部署到其他某些场景去。


更糟糕的是,风险场景下想要下线已有链路是一个很谨慎的操作,阻碍了基础设施团队收敛多套引擎的努力。这种业务逻辑依赖于大量各种不同引擎代码的状况,对运维/升级等都造成了很大的负担和风险(图2)。


图2. 大数据存储与计算“日星月异”带来的负担

2.3 鲁布·戈德堡机械问题

实际上大多数纯粹业务视角的逻辑并不复杂,例如我们可能就是希望把几份数据交叉对比一下产生一个新的特征用在防控策略里面。但是由于涉及的底层能力比较杂(例如在线/离线/近线不同时态,表格/图/特征等不同形态),而各个引擎又都是独立发展,有着独立的开发接口/界面,使得集成后的整体链路碎片化散落,被硬代码写在多个地方;同时整体流程衔接和转换缺乏统一实现和管控,质量保障差;再加上我们对性能的要求并不低(特别是规模&延迟),各种优化代码到处嵌入。


这导致了鲁布·戈德堡机械问题(图3),使得简单的一个业务流程问题被不必要地复杂化,降低了迭代的效率和质量,并进一步阻止了整体流程的软协调,以及后续的治理和优化。

图3. 鲁布·戈德堡机械把简单问题复杂化 

2.4 探索与决策的不一致性


策略仿真和模型训练及校验是我们去验证各种风险防控方案的必经之路。实际过程中由于不同链路(仿真/训练等数据探索链路 vs 实时决策链路)存储/计算等的不同需求(性能、规模、成本等)带来了不同的方案,而这些不同方案之前协同不足又导致了防控的效果在不同链路下的一致性缺乏根本性保障,阻碍了大家迭代和创新的推进速度(最典型的困境是我不相信你的探索结果,因为和上线后的数据口径都可能不一致,但是线上探索实验又有很多局限性)


一个例子是某个场景下我们通过SQL和深度学习模型在离线数据基础之上拿到了很好的探索效果,但是真正上线需要把整个计算逻辑搬到在线 - 过程中我们碰到了如下一些挑战:(1)把各种SQL批量计算手工翻译成线上点状计算函数(不一定是SQL表达),(2)不同特征之间的时间对齐不一定能和线下一样,(3)某些特征在在线算的太慢,导致整体决策超时,需要搬到近线。这些在决策链路和探索链路不一致的行为,必然会导致不一样的结果(图4),也就是探索效果在决策链路被大打折扣。


图4. 不一致的行为带来不一致的结果


3.YoDA:如何做熵减?


既然问题出在熵增,我们对解决方案的思考方向也主要是在保障业务需求的前提下,如何有步骤地做熵减,并在此基础上(1)提升治理能力;(2)降本增效(开发/运行);(3)实现新的能力。我们在20年初提出了YoDA项目,开始对此进行了系统化的梳理和应对。下面介绍我们总体的思路以及相关的YoDA子项目,具体的子项目详情我们会在后续的文章中予以更加详细的解读。


3.1 从无序到有序(白盒化)


首先在不改变现状的情况下,如何把现有系统梳理清楚,让大家能把一个黑灰盒子变成白盒子,看清楚看明白。我们的数据系统依赖很多资产,例如策略、模型、特征、数据视图、在线表格、离线表格、图等等。大多数资产实际上都有自己的元数据管理系统,但是由于各个系统没有打通,因此做为用户很难把整个数据链路一下子看透。一个简单自然的想法是把这些不同数据资产的元数据实时汇聚到一起,并且把他们连接起来去理解它们之间的血缘关系。


到目前为止其实和很多资产平台有类似之处,但是在实施的过程中,由于风险资产和计算的多样性/可解释性等,我们又碰到了几个其他的挑战,包括例如:(1)如何精确表征资产之间不同的协作关系,例如A+B=>X, A+C=>X,光看资产之间的血缘只能理解为A+B+C=>X;(2)如何查看历史血缘用来排查问题,特别是在某些变更之后整个血缘已经和问题发生时候不一样了的情况下;(3)如何程序化发挥作用?


为了解决这些问题,我们提出了YoDA数据上下文项目,对数据系统里面的ABC (Application-资产、Behavior-计算、 Change-变更)进行了统一的建模和记录,并在此之上进行了静态和动态信息的打标和绑定(Dynamics-状态),目前覆盖了蚂蚁大安全大多数资产和计算的ABCD管理。


它和传统资产管理平台的核心差异在于:(1)异构:从离线表到HBase,从特征到模型,从宽表到策略,全链路资产接入;(2)资产和计算二部图:尽量准确记录两者之间的生产和消费关系;(3)多版本:方便查找老版本资产的相关血缘等;(4)动态信息管理:目前包括各种动态流量信息以及资产安全隐私等相关打标等都在逐步接入。通过这些核心能力的组合,数据上下文得以支持整个数据系统的白盒化理解、治理、管控、质量预警、标签跟踪、资产推荐、成本核算、性能优化等子应用,并在不断丰富中。


3.2 多态融合(逻辑化)


"We can solve any problem by introducing an extra level of indirection."[2],通过把业务逻辑对计算和存储的需求绑定到统一的一组抽象概念上,我们得以隐藏底层的实现细节(逻辑化),来解决2.2和2.4章节谈到的业务和引擎代辑耦合,以及探索决策不一致的问题:


● YoDA数据研发 

框架提供了统一的计算抽象和语言来支持包含流计算、批计算、图计算等在内的声明式计算逻辑表达,然后通过编译根据实际部署的需求来转换到不同的计算引擎实现之上。同时,开发者也可以结合数据上下文进行逻辑数据资产的导入导出,而无需关注具体的资产访问逻辑(例如hbase如何读写)


● YoDA数据服务 (aka VersaTable) 

围绕风险实时决策场景,提供了声明式的统一的数据存储和服务框架,例如使用什么类型的主存储、需不需要外部缓存/索引支持、如何处理热点、怎么保障高可用等等。和传统存储的核心差异在于它一方面类似于数据研发框架对存储进行了统一抽象,另一方面通过组合多种已有存储以及其他缓存/热点等额外优化方案,并通过声明式语言快速搭建适用于各种大规模低延迟场景下的实时数据/特征服务。同时,它结合YoDA数据研发框架提供相关的特征生产过程;


● YoDA三线一致 

框架提出了三线一致资产的抽象概念并尝试确保各种不同时态场景下(在线/离线/近线)存储和计算的差异性不影响最终计算结果的逻辑一致性,从而保障数据探索和决策效果的一致性。这里的挑战在于不同时态之间数据的一致性(状态和顺序),以及计算逻辑的一致性。另外,由于各个时态环境下的目标、成本以及一致性实现难度的差异性,绝对的一致性并不可取(例如要求在线服务中所有特征的时间戳能够像离线探索场景下一样完全对齐),需要在成本、效果、复杂度之间做好平衡。


YoDA数据研发框架和YoDA数据服务框架对计算和存储分别进行了引擎功能接口的多态融合,而YoDA三线一致框架则对不同时态下的资产进行了语义层面的多态融合。通过这些设计,上层业务开发可以大幅降低甚至忽略对底层技术概念的理解,在实现代码层面也可以让业务逻辑和底层各种存储和计算引擎解耦,从而提升开发效率和质量,并实现了多底盘部署能力。


这里的一个应用例子是图风控,我们的构图逻辑可以部署到Blink和Geaflow等多个不同的流计算引擎上;同时,我们的图特征计算逻辑也可以按需在Geaflow和Geabase等不同时态下(近线/在线)的图引擎上。

3.3 异构融合(一体化)


YoDA除了提供多态融合实现多底盘/多时态能力以外,还同时提供了异构融合的能力来应对2.3节提到的简单流程复杂化的问题,包括对流计算、批计算、图计算、图/表在线查询以及中间的存储读写和串联,以及前面谈到的全链路元数据管理等。


简单来说,YoDA倡导面向对象的开发方式应用到数据业务领域,业务层面可以跨多个引擎去全盘考虑整体结构和流程设计(一体化+逻辑化),而YoDA负责底层的异构拆解、翻译、部署和治理。这个思路在多个YoDA子项目中都有所体现,例如YoDA研发框架提出了数据应用DataApp的概念,把一个业务视角下所涉及的相关数据资产和计算通过类对象的方式放在一起。


采用图风控这个应用作为例子,我们得以把不同的数据产品融合到同一个逻辑大图上,例如图和另外一个基于时间窗口的维度聚合数据产品,这样就可以在业务侧就可以有统一的视图并在此视图之上进行声明式的操作,而不需要去理解运行时这些底层异构数据产品之间应该如何衔接。


更进一步,异构融合消除了原来人为决定的整体数据链路在不同计算和存储之间的边界,使得个性化调整这种边界成为可能,我们认为这是数据驱动的决策链路中系统/算法/业务综合权衡自动化的为数不多的可行路径 - 这块我们正在YoDA几个子项目中进行探索。整体而言,异构融合可以看成是更高阶的多态融合,都是如何构建好的抽象,尽量避免让业务去理解一些没有必要理解的技术侧概念和实现细节,同时给技术侧的后续自主优化提供空间。

3.4 放在一起


YoDA几个子项目关联在一起,我们希望首先结构化理解和治理整个数据系统的ABCD,然后通过提供跨多个存储/计算/时态的统一的开发和衔接抽象,以对系统进行逐步底层依赖解耦(计算、存储)和上层抽象升级(异构时态和形态融合),目标是把整个数据系统从黑灰盒转换为白盒子,并提供从业务视角出发的逻辑化和一体化的异构融合数据智能系统治理和建设方案,为风险类数据驱动的探索与决策场景提供较为全面的数据管理、治理、研发、服务、探索等数据能力。


这几个子项目之间并不是割裂的(图5):数据上下文除了支持原有的数据系统元数据管理和治理之外,更为其他几个YoDA子项目提供服务:例如YoDA数据研发使用YoDA数据上下文的资产作为抽象资产进行访问;YoDA数据服务提供VersaTable的抽象,并注册到到YoDA数据上下文使得YoDA数据研发得以访问;YoDA三线一致通过数据上下文提供的全链路白盒化信息进行一致性检查等。


图5. YODA子项目之间以及与上下游的关系

4.其他思考


4.1 融合计算


前一章节谈到了跨引擎融合的问题,用于帮助从业务视角形成一个整体的结构和流程框架,减少这中间由于多组件/多引擎集成和衔接所带来的效率/质量问题。这个方向本身其实在YoDA之前我们就已经开始探索,但是是不一样的方案[3]。从两者共性的角度来说,底层的一个个面向同质模式的计算和存储引擎已然越来越成熟,而业务侧则一般都不会只依赖其中的一个(特别是在复杂决策场景下),因此这两者之间的距离导致了下一步这些模式之间的融合是一个必然需要去解决的问题(特别是由于多引擎各自为政带来的中间地带的黑盒子问题)


另一方面,随着业务变得更加成熟和复杂,纯粹业务视角的全局视图也有助于提升业务迭代的速度和效率。最后,最近这一两年来关于数据隐私和平台合规方面的要求,也进一步加大了这方面的紧迫性(例如如何自证专数专用)。我们之前的工作在分布式计算领域提出了融合计算的概念,该工作主要还是采用本地过程式编程的方式来进行业务逻辑表达(例如使用Java或者 Python),然后通过本地组件分布式化和分布式组件本地化的方式去解决从本地编程的抽象到分布式实现之间的自动投射 (例如本地Java Method变成分布式Task,本地变量变成分布式Object),从而实现各种计算模式的无缝融合,并在此之上做后续的渐进式融合优化。这个工作由于表达抽象的层次相对较低(相比数据流语言的抽象例如数据集以及数据集上的关系代数等操作),表达能力会很强,但是具体实现到业务语义之间的距离比较远,不太容易自动化推理相关业务逻辑的意图并进行各种优化变换。


即便我们当时还采用了一系列静动态结合的混合数据流优化技术,实际的优化空间都比较局限,核心问题就在于我们没有办法白盒化掌握整个系统。而在YoDA设计之初,在实际分析了几个风险数据场景之后,我们发现声明式融合可能是另外一个选择,且有白盒化和逻辑化的优势。从这个视角,可以认为YoDA是融合计算的2.0版本。注意这里YoDA倡导的逻辑化并不是一体化融合的前提条件(参见融合计算1.0的工作[3]),但是通过在表达能力方面做出一定的牺牲,逻辑化确实能够帮助提升一体化融合的深度和广度。


4.2 抽象升级


在使用各种数据能力支持业务的过程中,我们碰到两个明显的矛盾。一是业务和技术对方案理解上的差别有点大。一个重要原因是数据技术侧细节比较多,相关的技术栈比较杂,很多对外封装的概念也经常不够完善(leaky abstraction[4],例如特征和策略这两个概念的边界就不那么清晰),又或者是技术实现带来的业务本不需要关心的问题(例如不同引擎间的衔接,或者在线/近线/离线计算/存储的各种差异性)。常见的做法是在把这些概念输出给业务的同时,向业务方去解释和请求理解这些不完善的地方(事先或者事后),同时期望配合技术一起去做一些限制和规避以减少不好的事情发生。


另一个矛盾是业务的节奏往往比技术要快,如何匹配两边的节奏同时满足技术的长期沉淀/收敛的目标(特别是在数据相关基础设施领域)是一个挑战。常见的做法是以快速满足业务需求为第一优先级,从业务需求到产品设计到技术实现,一气呵成,缺点在于不可持续,容易累积技术债;反之完全等待技术成熟再支持业务则更加不可取。在这两个矛盾里面,我们发现如果能够优先给出合适的技术抽象,帮助业务去避免了解一些没有必要理解的技术概念(非业务逻辑),就可以很快地完成集成以支持业务场景,并在后续慢慢改善相关的实现。


YoDA在过程中一直在尝试践行这个思路,通过一体化、逻辑化、三线一致等去尽力升级相关抽象,隐藏底下的技术复杂度(包括例如通过三线一致资产的概念去除三线差异性),并给技术团队提供了更大的后续自主优化空间。


5.总结


蚂蚁风险场景下数据智能系统持续熵增带来了很多不可持续的问题。为此蚂蚁大安全团队提出了YoDA项目,通过白盒化/逻辑化/一体化等思路,建设了数据上下文/数据研发/数据服务/三线一致等子项目,对风险场景下的数据智能系统进行逐步底层依赖解耦和上层抽象升级,并取得了一定的阶段性成果。我们期望YoDA的探索和实践能为数据智能系统的后续发展方向给出一些启发与贡献。


参考文献

[1] D. Sculley, Gary Holt, Daniel Golovin, Eugene Davydov, and Todd Phillips. "Hidden Technical Debt in Machine Learning Systems", In 29th Conference on Neural Information Processing Systems, 2015

[2] Butler Lampson. "Hints and Principles for Computer System Design", https://arxiv.org/abs/2011.02455, 2021

[3] Zhenyu Guo. "大数据系统实践:从MapReduce到融合计算", In CCF ADL, 2019

[4] Joel Spolsky. "The Law of Leaky Abstractions", https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/.



延伸阅读:



继续滑动看下一个
蚂蚁技术AntTech
向上滑动看下一个

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

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