在绿色计算的大背景下,算力分配将朝着更加高效和智能的方向持续演进。本文将介绍阿里妈妈展示广告引擎在全局视角下优化算力分配的新探索,让在线引擎像变形金刚一样灵活强悍。
在提倡节能减排,降本增效,追求绿色技术的大趋势下,充分利用好算力资源,尤其是在阿里妈妈展示广告引擎这种使用近百万core机器资源的业务中,显得更为重要。
随着深度学习技术上的大量创新,广告、推荐等在线引擎系统的架构和算法复杂度迅速飙升,对算力的需求出现了爆发式的增长。以阿里展示广告系统为例(参考文章 [1] ),相比于几年前的精排模型,其在线算力的需求暴涨了近 2 个数量级。如此惊人的算力需求增速,一定程度上会带来算力供给触及瓶颈的巨大挑战。阿里展示广告团队从 18 年起就开始布局算力效能技术的研发,目前已经迈入了第4代算力效能体系的阶段:
算力效能 1.0 阶段 (2018):聚焦单点工程优化及模型瘦身优化等技术
算力效能 2.0 阶段 (2019):将 Model Design 和 Engineering Optimization 结合,通过算法-工程 Co-design 方法论的深度实践,带来了显著红利
算力效能 3.0 阶段 (2020):从引擎单模块进一步拓展到系统全链路,用"个性化"算力的思想去重新审视和改造了整个广告引擎系统,为古典在线引擎注入了新的活力,让它变得更加"柔性":充分提升给定算力的性价比,让其在面临任意复杂、动态的业务需求和流量环境时能够自适应地做到算力最优使用。
算力效能 4.0 阶段 (2021):从全局视角,通过精细化度量全链路各模块的算力性价比,优化算力在引擎全链路的算力使用,进一步提升整个引擎将算力转化为业务价值的效率。
结合了算力效能视角的展示广告引擎,我们命名为 Transformers(取自电影变形金刚,寓意系统能够自动调整以适应各种大促活动,把驱动系统运行的算力使用到极致) — 动态算力的出发点就是利用好算力拿到更多业务收益,把算力分配给增量收益大的计算)。
Transformers 引擎的核心理念,就是将算力分配纳入到系统的设计范畴。对于古典广告引擎而言,其使命是确保引擎系统能够准确地实现和运行业务逻辑。对任意一条流量请求,原则上执行的计算逻辑是一致的(这里仅考虑算力差异化视角)。在资源充足时这是合理的策略,但在算力紧张、需要腾挪资源甚至算法策略降级才能在特定的系统资源约束下完成业务逻辑时,这背后就隐藏着巨大的效能空间。以广告系统为例,我们可以选择:1. 开足算力对每条流量做最精细化最复杂的计算,对超出系统算力的部分流量做丢弃操作;2. 对不同价值的流量做差异化的算力规划,确保系统对每条流量都有效服务。哪种策略是最优?这就是 Transformers 引擎的目标:在有限的资源中做"柔性"算力伸缩,确保业务收益最大化。(参考文章 [1] )
去年动态算力完成了从0到1的建设,通过静态最优分配结合基于反馈的动态调控,在展示引擎日常和大促期间都拿到了稳定的业务收益,并且从策略到框架都有好的沉淀,详细内容可以参考文章 [1] 。在业界也出现了跟进研究的团队,且都结合自身的业务场景拿到了切实的业务收益,参考文章 [2] ,集团中也在推动这个方向的进一步发展。但是虽然动态算力去年在业务效果以及柔化系统等方面得到了大家的认可,却也存在一些问题。
整个引擎中包含众多调控点(一个应用模块包含一个或者多个调控点),但各调控点都是孤立调控,只在调控点内部追求局部算力一定时收益最大化。这种没有上下服务配合形成联动调控,实际是存在问题的。具体表现如上游调控点档位过低,导致下游的调控点水位过低,算力空闲。相对应的,下游的调控点档位过低,导致上游的计算结果很多被截断,算力浪费。也即各功能点只关注自己的情况,很难形成合力,在全局上达到好的效果。另外业务引擎部分场景日常RT P99接近上限300ms(影响系统稳定和日常迭代),经常出现上线功能因超时(性能优化和资源扩充都不能及时解决)不得不按照人为经验去做适当的降级来减小RT,因此也需要简便灵活的储备RT的手段。上面的问题都涉及到从全局视角分配算力,因此今年项目组主要工作就是围绕模块联动调控展开,从全局视角去考虑优化算力的分配。
1. 新的探索
如何在现有AllSpark [1] 调控框架的基础上实现联动调控?具体有哪些问题需要解决?
现状,目前单功能点独立调控,每个功能点的算力控制参数不一样。比如定向阶段用的是定向集合,检索阶段用的是token数,粗排和精排截断用的是ad数,策略和创意阶段用的是不同模型,也都不一样。那么如何统一调控参数,使联动调控成为可能。带着这样的问题,我们追根溯源发现,算力的分配本质是计算量的分配,而计算量 = RT * 物理机器资源,在物理机器资源固定的情况下,算力的分配就等价于RT的分配。因此RT调控就是一条能从单点孤立调控过渡到多点联动调控,实现从优化局部算力分配到优化全局算力分配的可行路径。
图1 RT调控的引出
2. 实践
2.1 RT调控实践
要实现全链路的RT调控,我们的思路是先从局部单调控点做起,再扩展到应用模块,最后扩展到引擎全链路。具体的是分三步走:
第一步:实现单个功能点上精准的RT控制
第二步:在单模块多个功能点之间实现RT分配和控制
第三步:引擎实现全链路的RT调控
具体的建设历程如下:
图2 RT调控建设历程
下面针对上面的三步分别展开来介绍:
第一步单功能点的RT调控
通常在单调控点上不同user的RT不一样。RT分布图如下:
图3 海选RT分布图
横坐标是RT,纵坐标是RT对应pv比例,其中绿线右边部分RT高,可认为是毛刺,因此只需要尽可能准确的把这部分user单拉出来进行调整,控制好RT,就能实现这个功能点RT的控制。我们采取的思路是先通过预估流量的RT,将RT接近的user分在一个人群中,通过控制这个人群的档位来实现这个人群平均RT(因为已经对人群分类,该人群中所有的user RT接近)的控制。(注:降档时尽量只影响毛刺RT的user,不误伤其他user。但毛刺user可能是高活user,因此通常大家认为是更容易被降档而影响效果。部分功能点上RT控制确实如此,但对效果影响有限。因为一是比例低,二是之前不控制可能已经超时,不超时一定比超时效果好,下面的线上实验效果可以充分说明这一点。另外效果层面的优化,体现在了全局视角上的RT分配上,即便是高活的user在当前模块也不能超过目标RT,因为其他模块使用RT更高效。)
以召回检索这个功能点为例介绍单机分人群RT机制示意图如下:
图4 分人群RT控制
当一个User进入检索阶段,根据该user携带的标签数以及预估标签数召回的ad预估召回深度(这里认为召回深度跟RT成正比)属于哪个人群,比如红线user3属于crowd1,此时crow1的档位是80,因此直接控制user3的tag数到80档;与此同时crowd1会根据该人群的平均RT,目标RT每10秒钟调整一次,保证该人群的真实RT接近但<=可用RT为8ms。这样每个人群就有自己的档位。另外调控策略在Agent上单机自行运行,实效性更高(不用基于反馈链路收集metric),而且因为是单机上自行调控,也能够适应不同机器不同水位,但始终保持<=8ms。
按照上面的机制,在召回检索功能点实验效果数据如下表:
表1 效果对比
相比于中控调节(不分人群),平均检索深度+10%,sn RT p99-6ms,ctr+0.18%, rpm+0.70%,无动态算力桶ctr-3%, rpm-5%。动态算力中控调节优于无动态算力,而分人群的RT控制又优于中控调节(原因是更精细化的只降高RT或者超时那部分user,减少被误降的user比例和减少超时的比例)。
第二步单模块多功能点RT控制
单模块多功能点的控制是基于现有AllSpark框架,中控Controller负责加载离线处理后的数据计算每个功能点该使用的RT,然后下发给Agent,Agent上每个功能点对应有一个控制器,该控制器基于第一步的机制实现对该功能点的RT控制。
图5 单应用模块RT调控
第三步全链路面向目标RT的自适应调控
此功能是从外部视角看整个广告引擎,不同业务场景对广告引擎的响应时间要求不一样,因此可以每个场景设置自己的响应目标时间。场景响应目标时间变化,整个引擎该场景全链路各模块的可用RT将重新分配。此功能主要是为了应对大促前端对引擎RT(或者局部链路)要求的变化和有的特殊场景日常就已经RT触顶需要进行RT控制而实现。
该功能的核心完全是基于第二步的扩展,但因是整个引擎,链路较长而且涉及跨模块的调控,因此会有包括预调控以及外部服务RT控制等新机制。几个新的概念如下:
1)基于实时反馈的逐层调控和全局预调同时存在,相互配合
基于实时反馈的逐层调控:基于实时反馈调控,这个功能是去年动态算力使用最普遍和成熟的技术,即根据实时收集的metric,看是否满足要求,不满足则下调档位。结合下图说明:当前端目标RT 由300ms下调到160ms,如下图APP1检测到平均响应时间是240ms > 160ms,因此它逐步下调APP2的可用RT。因为这个下调操作导致APP2的超时率变高,因此APP2又逐步下调APP3,APP4和APP5的可用RT。类似如此逐层传递,直到APP1的响应时间<=160ms。
全局预调:基于实时反馈逐层调控收敛时间长,原因是逐层传递,再多次反馈调整。而且调整过程中会出现超时率高的问题。因此需要一种预调机制,当目标RT变化时,整个系统的调控尽可能一次性到位。实际上不同目标RT下,基于历史效果和RT数据是可以计算出合适的RT组合数据,当需要的时候只需要查出来即可。预调虽然快,但基于历史数据,它并不知道线上真实系统的水位情况(预调档位偏高或者偏低),还是需要实时反馈的数据来微调。因此预调档位有过期时间T,当时间超过这个点时,会在预调档位的基础上切换到基于反馈的调整,适应真实的系统状态。
2)内部功能RT控制和外部服务RT控制相互协作
一个应用的响应时间取决于它自身的处理时间和外部服务的响应时间。这两者在RT控制的时候是有区别的。
内部功能RT控制:对应第二步中的分人群RT控制,对于如sn这个应用,它的三个功能点逻辑全在sn本地,可以实现精细化人群划分和RT控制。
外部服务RT控制:对于依赖的外部服务,在进行RT控制时,控制的是最大RT,也即超时时间。主要的考虑是对于服务调用方而言,它无法感知user在被调用服务中的状态,因此无法分人群也没有控制RT的具体抓手,所以需要的只是把升降档这个信息传递给下游服务,具体的调控由下游服务自行处理。而充当这种传递信息的指标超时率要好于平均RT,原因是前者更精准,超时率是最能反映下游服务是否正常的指标(超时率的统计则是依赖超时RT阈值设置)。另外也考虑到如300ms->160ms这种情况,如果不直接调整超时RT阈值进行硬控制(超过阈值就丢掉),而是通过平均RT,很多下游服务的毛刺流量控不住,从而拖慢整个PV的响应时间,导致前端超时。
整体调控示意图如下:
图6 全链路RT调控
比如某场景响应时间由300ms下调到160ms。具体调控分为如下几步:
1)预调先行, Controller中TimePlanner接收到响应目标RT由300ms->160ms后,根据160ms直接查到此时全链路所有功能点的可用RT和在此RT限制时功能点的档位,然后直接下发给引擎各模块。各模块在几秒内生效,系统RT将直接下调到160ms附近。查询整体RT对应的具体功能点RT数据是Controller定期统计分配好的。
2)预调档位会生效一段时间,比如生效20秒之后将失效,交由基于反馈调节根据具体真实的水位情况进行档位调整。
2.2 管控视图升级
管控
相比旧版接入效率更高。在用户体验和安全检查等方面都有优化,如调控策略模板化,支持自定义新模板和复用已有的调控策略,支持档位COPY以及参数类型检查等等。
a)调控策略模板复用
图7 调控策略模版
b)参数类型检查
图8 参数类型检查
视图
新版视图让动态算力的整个调控状态朝可视化的方向迈出了第一步。
a)档位排行,展示实时以及历史档位波动问题。
图9 档位排行榜
b)RT响应控制档位,场景目标RT超过阈值或者前端看引擎超时率超过阈值,引擎会自动重新分配下游链路RT,以满足前端要求。
图10 引擎整体响应时间档位
c)分场景分机房不同链路的档位。(APP代表应用,MOD代表该应用上调控功能点,对应数值表示档位)
图11 链路详细档位
3. 实战表现
3.1 日常
a)召回链路RT精准控制,保障算力不足时系统的稳定性。日常对整个召回链路控制在130ms,稳定运行。核心场景相比关闭动态算力桶,动态算力桶多天稳定cost+3%左右(说明动态算力通过精准RT控制减少超时以及个性化算力分配对效果提升有益),如下图:
图12 效果对比
b)系统异常预警,相比其他手段,更加精细化(功能点粒度)和实效性高(几十秒),而且系统能自适应的调整。过去一年,及时发现数十个问题,包括数据更新异常,容量不足,发布错误,坏机器等。
3.2 大促双十一
a)峰值档位定时生效。11月10号,11:56生效0点档位,极大简化大促预案,并且降低过去多项独立预案11:45推送导致效果损失,减少接近10分钟的严重降级对效果的影响。
b)0点03分打开自动档,随着QPS下降,档位自动回升,水位和效果也及时回升。
水位:
图13 大促峰值附近CPU使用图
效果:
图14 大促峰值附近效果图
c)11.11白天,展示引擎交由动态算力调控,在RT满足要求下,展示广告(alimama_k2)整体水位35+%,AIOS水位排名前列。
图15 大促白天CPU使用图
4. 总结和展望
4.1 总结
好的方面
1)整个引擎所有的RT控制交由动态算力分配管理,RT管理更加灵活(支持分场景配置和实时变更生效不用发布应用)和分配更加合理,为未来追求极致效率,进一步实现全局最优算力分配,建设高效的商业广告引擎打下坚实的基础。
2)在广告引擎这种上下游依赖且模块异质的系统中,针对模块效率评估的方法已经探索出了一条可行路径,目前在完善和落地中。
3)跟阿里云能源与碳管理团队合作 [3] ,进行流量在机房间的调度实验,探索算力与电力的关系,为动态算力未来的应用开辟了新的空间。
不足的方面
1)今年较多的时间投入在全链路的RT控制机制设计和落地上,在这种模块众多且异质,效果又相互依赖相互影响的拓扑上进行最优RT分配策略研究不足,未来需探索更优的策略。
2)调控效果还存在优化空间,针对具体的场景(如大促峰值)需要定制调控策略,在保障系统稳定的前提下,充分利用算力拿到更多的业务收益。
4.2 展望
未来Transformers会继续推进全局RT分配策略优化,并且与机器资源进行联合建模优化,以期实现全局最优算力分配,促进算力的使用由粗犷走向精细,低效走向高效。同时也将继续对算力,容量和效果之间的关系进行研究,用于长期资源管理和容量规划。总之,在算力不足已成为常态且性能优化进入深水区,动态算力尝试建立成本,算力和收益之间的桥梁,并且朝着使系统更加稳定,更加高效和智能的方向持续演进,让在线引擎像变形金刚一样灵活和强悍。
欢迎大家把文章转发给你身边有需要的技术同学,也欢迎在文末留言一起讨论。
5. 参考文章
[2] 美团外卖广告智能算力实践
[3] 阿里巴巴创新研究计划