去年春节期间,支付宝推出的“集五福”活动风靡一时。活动中,每张福卡背面都附有刮刮卡,上面包含来自蚂蚁金服、阿里巴巴及其合作伙伴提供的多种权益。活动主要集中在春节前几天,因此具有很强的时效性。如何高效地匹配权益和目标受众,处理系统冷启动问题,优化转化率和提升用户体验,成为了在线学习系统需要解决的问题。
过去,构建这样的系统需要多个复杂的模块。我们需要收集日志、聚合数据、拼接和采样样本,还要对接模型训练和验证等机器学习模块,并实时加载模型,以及配备其他相关设施。这些模块的连接大大增加了系统的复杂性。
由于涉及的系统较多,我们的系统遇到了一些问题。例如,在大促期间,为了保证关键链路的稳定性,某些数据处理链路可能会被降级,但下游团队对此并不知情。另一个常见的问题是流批逻辑不一致,需要离线特征来训练基准模型,同时在线计算的特征用于实时更新模型。这种差异对业务效果产生了显著影响。
总结下来,我们面临的主要挑战可以归纳为三类:
理想的系统应具备“稳、快、简”的特性。首先,从数据角度出发,需要确保数据和计算的一致性,实现端到端的SLA,这是保障业务稳定的基础。其次,需要优化系统效率,将多个系统的连接简化为系统内部的连接,将作业调度转换为任务调度,提高系统效率并减少网络带宽的使用。此外,统一的系统可以极大地简化开发和运维工作。
在线机器学习系统需要展示数据处理、模型训练和模型服务的能力。这些能力要求计算引擎框架具有灵活的调用机制、敏捷的资源管理及完善的容错机制。底层系统通常采用不同的编程语言实现,因此需要多语言接口。综合考虑底层需求和现有框架特点,最终我们选择了Ray作为融合计算的基础框架。
Ray是由伯克利大学RiseLab实验室发起,并由蚂蚁金服共同参与的一个开源分布式计算框架,旨在使分布式系统的开发和使用更加简便。Ray作为一个计算框架,能够帮助我们实现“稳、快、简”的目标。Ray具有灵活的调度机制,能够在一秒内处理数百万次任务调度,并根据计算需求动态分配资源。
Ray提供了三个基本的分布式原语:分布式任务、对象和服务,与常用的面向过程的编程语言中的函数、变量和类相对应。通过简单的修改,可以在Ray系统中实现这些概念之间的转换。
例如,一个简单的函数可以通过添加“@remote”修饰符转换为分布式任务。任务通过“.remote”调用执行,返回值是一个变量,可以参与其他计算。同样,一个类也可以通过添加“@remote”修饰符转换为服务,类中的方法可以转换为分布式任务。
Ray的调度机制旨在提高系统效率,依赖于计算和数据的组织方式。例如,计算Add(a, b)时,该函数会在本地自动注册并提供给本地调度器。全局调度器与第二个节点的本地调度器协作,将A备份到第二个节点执行Add操作。根据A和B的数据量,Ray可以进一步优化调度和控制。
Ray提供了多语言API接口。在蚂蚁金服内部,流式计算常用Java,而机器学习建模常用Python。Ray的灵活性允许我们重用Java编写的流处理算子,同时保留Python进行机器学习建模的便捷性。
在线机器学习的核心需求是连接流计算和模型训练。Ray的多语言接口和灵活调度机制使得这一连接变得简便。数据处理的最后一个节点是流计算的输入,Worker节点生成数据,作为模型训练的输入。Ray可以通过调度机制将这两个计算调度到同一节点,实现数据共享,从而打通两种计算模式。
在多阶段分布式计算中,DAG(有向无环图)的概念最初是为了提高计算效率而提出的。但在机器学习任务中,我们经常需要设计新模型或调试超参数。在Ray系统中,计算过程中可以动态生成新的节点,从而动态调整DAG,以便适应新的需求。
在线系统与离线系统的主要区别在于在线系统对时效性的要求更高。如果离线系统中的任务失败,可以通过重启机器解决,但在线系统不能简单地通过重启机器来恢复数据。因此,完善的容错机制至关重要。在模型训练中,可以利用Ray的Actor机制拉起模型训练的Worker和Server节点。如果Worker或Server节点不健康,可以通过Actor的容错特性恢复数据和计算,从而实现容错训练。
我们追求系统的时效性和稳定性之间的平衡。具体来说,系统波动性包括数据实时性和强一致性保障;模型波动性要求模型能够拟合实时数据流,同时避免在线学习过程中因数据噪声导致的效果退化;机制波动性则涉及赛马机制和快速回滚策略。
除了使用Ray实现融合计算带来的好处,我们还进行了许多模块建设,如TF融合、稳定性保障、样本回流、延迟样本修正、数据共享、流批一体、端到端强一致性、模型增量导出。这些措施在支付宝的多个场景中得到了应用,取得了显著的效果:
从2023年8月开始建设,2024年2月开始上线第一个场景,至今在支付线和财富线都取得了不错的效果。未来,我们将继续推广到蚂蚁金服的其他业务线上。
基于融合计算的机器学习,实现了融合计算和机器学习的有机结合,优化了资源共享。通过这些探索,我们初步验证了融合计算框架的有效性。融合计算旨在通过数据共享实现计算模式的兼容,其本质是开放。只要我们能够方便地实现各计算模式之间的数据互通,并保障数据的实时性和端到端一致性,就能在复杂的场景中实现多种计算模式的组合。