背景
随着高德地图业务的快速开展,除了导航本身的算法业务外,其他中小型业务对算法策略的需求越来越多、越来越快,近两年参与的一些新项目从算法调研到应用上线都在一周级,例如与共享出行相关的各种算法服务,风控、调度、营销等各个体系的业务需求。类似于传统导航中成熟的长周期、高流量、低时延的架构和开发方式已无法满足此类业务初期的快速试错和优化改进诉求,找到合适的为业务赋能的算法服务方式就变得势在必行。
在落地实施的过程中,采用一体化架构。所谓的一体化是指整个算法、工程一体化,涉及数据、系统等全链路打通,实现数据流的系统化流动;算法业务调研兼顾工程服务开发,测试、验证过程自动化、智能化,从而形成业务闭环,推动业务的快速迭代。
项目初期,需要快速试错和策略优化。此时,业务需求的QPS往往不高(<1k),因此,传统的应用开发和部署方式,一方面拖慢了业务节奏,另一方面浪费了大量资源。
在此过程中,我们希望达到的目标就是离线策略调研即服务逻辑开发,离线调研完成即服务化完成,这样就能够显著降低算法调研到策略上线的时间。因为性能(QPS、RT)压力不大,离线用Python进行快速的开发就成为可能。
从长期看,随着业务逐步成熟,算法快速组合、服务调用量和服务性能成为衡量算法服务重要的评价标准,此时合理的优化就应该被向前推进,例如核心算法逻辑高性能化将会变成重要的工作。
因此,算法工程一体化的建设过程也就是满足业务从初创期到成熟期迭代的过程。
系统总体逻辑架构
整个平台类似于上图所示,主要由几个逻辑部分组成:
统一接入网关服务
业务算法透出服务
算法模型及代码管理服务
质量保障体系
注:GBFC为数据服务层,主要用于获取各种算法所需要的数据和特征,让业务算法服务达到无状态的条件,同时也便于数据在各条业务线的共享和共建。
统一接入网关
网关服务目的是将各种算法API进行隔离,提供原子服务和组合服务。业务端需要调用各种算法如价值判断、风险预估、营销推荐时,统一网关对各个业务提供统一算法API,避免各个服务重复调用。算法网关对算法进行统一监控,包括服务性能,接口可用性等,同时对数据进行统一收集,便于数据管理和特征生产,进行实时在线学习,提升用户体验,保障算法效果。
网关服务一方面可以进行一些共用的预处理操作,例如鉴权、路由、限流、降级、熔断、灰度、AB、陪跑等,用于保障服务的可用性和扩展性。同时又能进行服务组合,例如语音识别、图像处理等,使得各个算法服务能够有机的结合在一起,这样使得业务算法层只需要维护原子性服务,即可进行复杂的业务处理。
因此,网关服务必然需要一个灵活、弹性、轻量、无状态的算法业务层的支撑,在技术选型方面,目前火热的Serverless架构刚好能够很好的满足上述需求。
Serverless架构上的业务算法服务
2009 年,伯克利以独特的视角定义了云计算,尤其是最近的四年,这篇文章被大量引用,其中的观点刚好非常契合业务初期的技术场景,比如减少服务化的工作,只关心业务逻辑或算法逻辑,实现快速迭代、按需计算等。2019年,伯克利又进一步提出:
Serverless所提供的接口,简化了云计算的编程,其代表了程序员生产力的又一次变革,一如编程语言从汇编时代演变为高级语言时代。
在目前关于Serverless的探索中,FaaS基本被认为是最佳范例,这与其自身特点有关。FaaS非常轻量级,无状态,运行快,对于纯粹的无状态应用特别合适,虽然在冷启动层面存在一些瓶颈,但这种架构还是解决了很多问题,而业务初期的算法快速实践,刚好与这种架构的特点相契合。
在Serverless架构的基础之上,我们对算法服务按照下图的方式进行了部署。
按照上图所示,算法服务在本地开发完成后,可以直接作为Function进行发布,即之前所说的离线策略调研完成的同时就是服务代码完成。而这个特性也很好的解决了算法同学和业务脱节的问题,很多算法同学无法独立完成整个工程服务开发,需要将代码提交给工程人员进行整合、包装、发布,但这种协作方式在整个业务链条中是不合理的。
一方面算法同学无法独立完成业务支撑,另一方面,工程同学不仅要处理逻辑调用,还需要花时间去了解当前算法实现方式、原理、所需数据、异常情况等各种问题,经常是一个相对简单的算法服务,会议和沟通占据了绝大多数时间,因此引入FaaS不仅简化了这个业务开发流程,同时也让算法部署尽量是原子化,方便业务间组装复用。
我们在实现的路径上,首先完成了Python的运行时环境的构建工作,能够将Python代码及相关模型直接服务化,模型部分支持PMML,TensorFlow等,这样就实现了业务初期所需要的快速迭代,减少试错成本的诉求。
此后会逐步完善基于Golang,Java等运行时环境,选择Golang的原因是对于并行性支持良好,不仅可以实现业务所需要的性能诉求,同时又保留着开发相对简单的特点。
经过算法原子化、函数化后,就赋予了算法同学独立负责线上业务的能力,但也带了几个严肃的问题:服务的稳定性,工程的质量,服务的正确性。如果简单的把这些扔给算法同学,就仅是工作量的转移,并且还可能引起整个业务的宕机风险。因此,质量保障体系建设就变成了重要的一环。
质量保障体系建设
很多人会认为,要做质量保障,就是提交到测试人员进行测试或回归测试,其实不然。前两部分省却的人工成本被转移到测试同学的身上,因为算法同学的工程化能力相对偏弱,是不是就要引入更多的测试同学做验证?
如果抱着这种思维,那么,业务的迭代速度依然无法快速起来。因此就必须考虑:这种质量保障能否完全的自动化呢?答案是肯定的。
在策略的调研过程中一般会经历以下几个步骤:
数据分析
算法设计
数据验证
人工/自动评测
策略迭代重复步骤1-4
在这个过程中,刚好包含了质量保障体系所需要的数据、数据集、测试集及验证集。
算法同学可以通过使用三个集合实现自动化的压测流程,输出QPS、RT、一致率等相关信息,使用数据集,实现稳定性测试;使用测试集,实现了逻辑正确性验证;通过验证集实现了效果测试。
当然,上述只是质量保障的一部分。一般业务快速迭代的过程中,常常需要进行AB验证,或者是全量陪跑验证,在过程实施中通过引流和过程链,我们实现了全量陪跑的过程,对待上线的算法实现了全方位的质量评估。
小结
算法、工程的统一化建设基本实现了业务初期的快速迭代需求。在项目开展的过程中,对工程同学的挑战除了来自于工程化实践外,同时也需要对业务所处的阶段要有清晰的认识。
当前情况下,算法和工程之所以可以独立开展,有一个必要的前提是数据和算法分离,也就是算法服务是无状态、函数化的。正是因为如此,也需要花费不少的时间在特征服务层的建设上。同样,特征服务层的建设也可以遵循相似的逻辑实现共建、共享。
最后需要再次说明的是,算法工程一体化的架构设计能够基本满足业务类算法的诉求。但对于一些对计算量要求巨大的AI项目,频繁的数据获取导致的算力、功耗瓶颈已经明显制约算法创新。业内正在通过将数据存储单元和计算单元融为一体,实现计算存储一体化的硬件架构革新,突破AI算力瓶颈。