微博举荐团队:陈雨、韩楠、蔡小娟、高家华
1.我的项目背景
热门微博是新浪微博的重要性能之一,蕴含热门流、热点流、频道流、小视频后举荐、视频社区等场景。
举荐首页 发现页举荐 沉迷视频
weidl机器学习框架为热门微博在线学习提供模型训练和推理服务,举荐全链路中在线推理服务的性能始终是weidl框架优化迭代的重要指标。在线学习零碎依靠于weidl框架。其服务的吞吐量、均匀响应工夫、承接上游QPS、机器资源占用等指标互相制衡,其中weidl框架推理计算的性能至关重要,与举荐服务全链路的整体性能指标及老本密切相关。摸索引擎中计算图运行时算子计算减速的各种个性及优化反对成为本我的项目次要方向。
DeepRec是阿里巴巴团体提供的针对搜寻、举荐、广告场景模型的训练/预测引擎,在分布式、图优化、算子、Runtime等方面对稠密模型进行了深度性能优化,同时提供了稠密场景下丰盛的Embedding相干性能。
本文次要介绍热门微博举荐的整体架构与DeepRec对热门举荐框架性能上的晋升,并具体分析的weidl平台中应用的DeepRec的重要优化点。
2.热门微博举荐零碎与weidl在线学习平台
2.1 热门微博举荐零碎整体架构
热门微博举荐零碎可分为前台业务与weidl在线学习平台两个局部。前台业务为各个业务的接口,负责将举荐后果返回给业务方。在线学习平台集成了样本拼接、模型训练、参数服务器、模型服务等多个模块,为热门举荐的多个业务实现了残缺的举荐流程,可疾速为新业务搭建一套举荐零碎。
2.2 weidl在线学习平台
在线学习平台是整个零碎最外围的局部,次要负责召回、粗排、精排等模块。热门举荐零碎为全链路大规模深度模型的在线学习零碎,其中召回模块有趣味召回、热点召回、策略召回、模型召回等多路召回,别离从千万级物料库中召回局部候选集,通过每路配额配置,将万级物料送入粗排模块。粗排阶段通过物料特色离线生成、用户特色实时拉取的形式,实现高性能的打分服务,通过粗排排序后,将千级候选集送入精排阶段。精排阶段模型最为简单,物料与用户特色实时拉取,多场景多指标交融,最终通过规定零碎的重排,选出一次曝光的博文,举荐给用户。
在线学习平台底层推理计算局部采纳bridge模式,反对多个backend,包含DeepRec、TensorFlow、Torch、TensorRT等,同时反对基于CPU与GPU的模型训练与在线推理。
weidl在线学习平台
热门微博举荐零碎从2018年开始,通过几年的降级,在实时性和规模上都有了实质的晋升。
2.2.1 实时性
实时性包含模型学习到用户行为的速度,模型参数的更新利用到线上模型服务的速度。举荐零碎的更新速度越快,越可能反馈用户最近的用户习惯,越可能给用户进行越有时效性的举荐;模型更容易发现最新风行的数据pattern,越可能让模型反馈找到最新的风行趋势。工程上次要通过以下几个方面,实现举荐零碎的实时性。
a. 样本拼接作为模型训练的终点,一条残缺的样本拼接实现的速度决定了模型学习用户行为速度的下限,目前热门举荐样本拼接窗口为30分钟,即用户在客户端的互动行为在30分钟内必会生成一条样本,送入kafka队列。
b. 模型训练读取样本流kafka,保障kafka无积压,所以该条样本会在毫秒级被模型学到,并通过rpc调用,更新到训练的参数服务器,并将新的模型参数推入kafka队列。
c. 参数同步服务从模型更新的kafka队列中读取数据,将模型最新的参数通过rpc调用,发送给在线服务所用的参数服务器中,此时从用户行为到模型更新实现。
d. 模型在线推理服务直连参数服务器,实时拉取模型最新参数进行打分。除去样本拼接所需的30分钟窗口,其余流程在1分钟内实现。
2.2.2 大规模深度简单模型
热门举荐业务从最后的FM模型,到当初召回阶段以双塔为主,粗排阶段以cold dnn为主,精排阶段以多场景、多指标的简单深度模型为主,模型在特色数量、指标个数、模型构造复杂度上都产生了质的变动,给业务带来了很大的收益。
精排模型从snr模型迭代到mm模型
粗排双塔模型迭代到cold dnn模型
模型复杂度的晋升给工程架构带来了不小的压力,一个multitask模型比一个单指标的dnn模型在算力上是成倍的减少。为了简单模型的落地,热门微博举荐团队摸索了多种开源框架,包含TensorRT, XDL,TFRA等,通过测试与源码剖析,这些框架都在原生Tensorflow根底上做了不同方向的优化,但性能始终无奈满足要求。同时,咱们也通过指令集优化、改良TensorFlow内存治理、算子交融等形式,优化weidl kernel局部性能。
在一直的优化与开源框架的尝试中,发现DeepRec框架在性能、易用性、与weidl的兼容性上都全面胜出,最终,热门举荐框架引擎采纳DeepRec引擎,晋升了训练与在线推理的新能,同时也给业务带来了成果上的晋升。
3.DeepRec及相干模块优化点分析
3.1 OneDNN库减速算子运算
DeepRec集成了最新版本的开源的跨平台深度学习性能减速库oneDNN(oneAPI Deep Neural Network Library),英特尔相干团队进一步优化将oneDNN 原有的线程池对立成DeepRec的Eigen线程池,缩小了线程池切换开销,防止了不同线程池之间竞争而导致的性能降落问题。oneDNN针对支流算子实现了性能优化,包含MatMul、BiasAdd、LeakyReLU等在稠密场景中的常见算子。针对热门微博的线上模型,性能晋升显著。
在DeepRec中英特尔CESG团队针对搜寻广告举荐模型中存在着大量稠密算子如Select、DynamicStitch、Transpose、Tile、SparseSegmentMean、Unique、SparseSegmentSum、SparseFillEmptyRows等一系列稠密算子进行了深度的优化,上面介绍2个罕用稠密算子的优化办法。
3.1.1 Select算子优化
Select算子实现原理是根据条件来做元素的抉择,此时可采纳向量化指令的mask load形式,如图所示,以缩小原先由if条件带来大量判断所导致的工夫开销,而后再通过批量抉择晋升数据读写效率,最终线上测试表明,性能晋升显著。
3.1.2 Transpose算子优化
同样,能够应用向量化的unpack和shuffle指令对transpose算子进行优化,即通过小Block的形式对矩阵进行转置,最终经线上测试表明,性能晋升同样非常显著。
3.2 要害门路优先的调度引擎
DeepRec通过对执行引擎以及底层线程池的从新设计,达到在不同的场景下,包含trianing和inference,能做到更佳执行性能。保障不同线程之间的均衡性,尽量减少线程之间的steal,防止加锁等问题。
Executor的设计须要思考对内存的拜访及其并行实现之间的分割,进行多层次任务调度,缩小缓存缺失和近程内存拜访,充分发挥多核、多节点CPU的并行个性,晋升零碎的运行性能。在线程池层面,设计Cost-aware线程池,联合内存感知以及算子类型等信息,进行针对性优化;在计算图层面,对张量内存的地位进行调度,有利于线程池的调度;在算子生成层面,进行有利于线程池任务调度的算子工作划分。
DeepRec提供的基于要害门路优化的执行引擎,通过动静采集Session Run状况,统计与计算多组指标,并构建CostModel,计算出一个较优的调度策略。该性能中蕴含了基于要害门路的调度策略,依据CostModel patching执行细碎算子的调度策略以及线程池Cost-aware调度策略等。
在graph执行过程中,Collector会监测所有算子执行以及线程池状况,包含算子执行工夫,线程池pending工作饱和度,以及算子的前后依赖关系。这些参数会通过CostModel来计算更佳的调度策略。对于一张graph来说,存在一条或者多条要害门路,即从输出到输入通过的延时最长的逻辑门路。graph执行总的工夫肯定是大于等于要害门路工夫。为了让整个graph执行更快,并发更佳高效 ,在graph执行时该当优先执行要害门路上的节点。
在稠密模型图中,可能会存在大量细碎算子,会带来大量调度开销。有些能够通过算子交融来做优化,算子交融个别通过graph pattern匹配或者手动指定子图来确定须要交融的对象,难以笼罩全副算子。故而在executor层面,通过trace运行时数据来动静进行批量调度执行,这样能够缩小非必要的细碎算子调度开销。
在线程调度层面,目前的线程池调度策略比较简单,如果以后执行线程是inter线程,优先将task调度到以后线程执行,若不是,则调度到一个random线程上。线程的balance齐全由steal机制来保障。在咱们的察看中,发现inter线程之间存在大量的steal,这会导致很多锁以及反复的线程调度等开销。CostModel executor通过采集运行时数据,来确定更佳的线程来执行工作,缩小大量的steal行为。
在简单模型上,应用DeepRec的CostModel调度,可能生成更佳的调度策略,缩小调度开销。在测试的snr模型上均匀耗时稳固优化2ms。
3.3 动静感知的内存/显存分配器
在张量内存治理方面,通常存在两点问题,一个是内存碎片过多,另一个是没有思考模型构造存在多分支的状况下算子并行带来的内存增长。其内存治理非常粗放,大体上都是运行时根据内存申请动静进行内存开释和调配,同时进行一些内存池治理。因为无奈感知下层利用的调配申请特点,这种内存治理存在着内存碎片过多的特点。例如在不分明后续内存申请的状况下,因为后期的屡次内存调配和开释,会导致起初的大内存申请因为内存碎片的问题而须要一块新的内存或者OOM。
深度学习模型的内存调配因为其利用特点存在着显著的规律性,训练时都是以一个个mini-batch的模式训练,每个mini-batch的调配特色大体上保持一致,训练时前向过程始终分配内存,较少开释,而反向过程中会开释前向计算中的长期张量,开释大量内存,所以内存会周期性出现先增长后升高的特色。基于此学习到执行过程中内存调配pattern,从而缩小内存的动态分配以及对内存块做到最佳的复用。同时自适应内存分配器也是graph-aware的,这样使得不同子图之间存在较小的互相烦扰,进步调配效率。自适应内存分配器根本架构如下图所示:
自适应内存分配器在训练过程对于后面的K轮进行一些统计,通过Allocator模块,对内存的调配,包含调配的工夫点、调配的大小,统计好调配的工夫点和大小后,在K轮完结之后会应用启发式的一些算法布局出一个较优的tensor cache planner,planner会创立allocator,并且预调配一些tensor内存块,后续的调配会优先通过此allocator进行调配。
自适应内存分配器根本准则是应用尽量少内存,同时进步内存的复用率。整体来讲,自适应内存分配器解决了在稠密场景中内存调配上存在的一些问题,次要包含,第一,缩小了在稠密场景中,大量内存调配问题,包含小内存和大内存。譬如小内存调配呈现在特色的处理过程中,包含一些特色的拼接,或者在做一些穿插特色,这里会存在大量的小内存的调配。同样在模型训练也存在很多大的内存,包含attention、RNN、或者全连贯层,会有一些大内存的调配。缩小大内存的调配,进而也缩小了minor pagefault数量。第二,对于tensor能做到更好的复用,缩小了总体的内存占用量。
4.DeepRec在业务中获得的收益
4.1 服务性能晋升
热门微博已于9月将weidl的backend全量替换为DeepRec,线上服务与训练都获得了很大的收益,最显著的是精排多任务模型,图计算局部DeepRec比原生TensorFlow耗时升高50%,精排阶段整体耗时升高20%,单机吞吐量晋升30%。
对于双塔和cold dnn模型,图计算局部耗时升高20%,粗排阶段整体耗时升高10%, 单机吞吐量晋升20%,模型训练模块性能晋升20%, 晋升了训练速度并无效的改善了样本积压问题。
4.2 性能晋升所带来的其余收益
举荐引擎模块整体耗时缩小与吞吐量的晋升,缩小了举荐在训练与在线推理上所应用的机器资源,极大的升高了公司老本。
在线推理服务性能晋升,使举荐引擎各个模块能够计算更多的候选物料,粗排阶段能够计算更多的候选物料,晋升物料库总量与扩充召回条数,精排也由1000条扩到2000条,每个阶段候选物料数的减少,都会对整体指标有显著的晋升。
更多对于 DeepRec 训练/预测引擎相干信息: https://github.com/alibaba/Deep