继续创作,加快生长!这是我参加「日新计划 · 10 月更文应战」的第1天,点击检查活动概况

导读:

本文将以下三个方面打开介绍:

  • DeepRec布景(咱们为什么要做DeepRec)
  • DeepRec功用(规划动机和完结)
  • DeepRec社区(最新发布的2206版别首要功用)

DeepRec布景介绍

咱们为什么需求稀少模型引擎?TensorFlow现在的社区版别是能够支撑稀少场景的,可是在以下三个方面存在一些功用上的短板:

  • 提高模型作用的稀少练习功用;
  • 提高模型迭代功率的练习功用;
  • 稀少模型的布置。

因而咱们提出了DeepRec,其功用定位在稀少场景做深度的优化。

DeepRec所做的作业首要在四大方面:稀少功用、练习功用、Serving、以及布置& ODL。

DeepRec在阿里巴巴内部的运用首要在引荐(猜你喜欢)、查找(主搜)、广告(直通车和定向)等几个中心场景。咱们也给云上的一些客户供给了部分稀少场景的处理办法,为其模型作用和迭代功率的提高带来了很大帮助。

DeepRec功用介绍

DeepRec的功用首要分为以下五大方面:稀少功用Embedding,练习结构(异步、同步),Runtime(Executor、PRMalloc),图优化(结构化模型,SmartStage),serving布置相关功用。

1. Embedding

Embedding部分将介绍以下5个子功用:

1.1 动态弹性特征(EV)

上图的左边是TensorFlow支撑稀少功用的首要办法。用户首先界说固定的shape的Tensor,稀少的特征经过Hash+Mod的办法map到刚刚界说的Tensor上。这个逻辑上有4个问题:

  • 稀少特征的抵触,Hash+Mod的办法容易引进特征抵触,这会导致有用特征的消失,从而影响作用;
  • 存储部分会导致内存的糟蹋,有部分内存空间不会被运用到;
  • 固定的shape,一旦Variable的shape固定了,未来无法更改;
  • 低效的IO,假如用户用这种办法界说Variable,有必要经过全量的办法导出,假如Variable的维度很大,那么不管导出仍是加载都是非常耗时的,但咱们在稀少的场景其实改变的部分是很少的。

在这种情况下,DeepRec界说的EmbeddingVariable规划的原理是:将静态的Variable转化为动态的相似HashTable的存储,每来一个key,新创建一个Embedding,这样就天然地处理了特征抵触的问题。经过这样的规划,当特征特别的多的时分,EmbeddingVariable无序的扩张,内存消耗也会变得很大,因而DeepRec引进了以下两个功用:特征准入和特征淘汰。它们都能有用的防止特征扩展到很大的维度。在查找和引荐这样的稀少场景,有些长尾特征被模型练习的次数非常少。因而特征准入能经过CounterFilter或者BloomFilter的办法对特征进入EmbeddingVariable设置一个门槛;在模型导出Checkpoint的时分也会有特征淘汰的功用,时刻上比较老的特征也会被淘汰。这在阿里内部某个引荐事务AUC提高5‰,在云上某引荐事务AUC提高5‰,pvctr也有提高4%。

1.2根据特征频率的动态弹性维度特征(FAE)

通常情况下同一个特征对应的EmbeddingVariable会被设置为同一个维度,假如EmbeddingVariable被设置一个较高的维度,低频的特征内容容易导致过拟合,而且会消耗大量的内存。相反的假如维度设置的过低,高频的特征内容则有或许因为表达的才能缺乏而影响模型的作用。FAE的功用则供给了关于同一个特征里,根据不同特征冷热来配置不同的维度。这样让模型主动进行练习时榜首个是模型的作用能得到确保,第二个也能处理练习对资源的运用。这是关于FAE功用的起点的介绍。这个功用的运用现在是让用户传入一个维度和核算的算法,FAE主动根据完结的算法来产生不同的EmbeddingVariable;后面DeepRec计划在体系内部自适应的发现去分配特征的维度,从而提高用户的易用性。

1.3自适应EmbeddingVariable

这个功用和第二个功用有些相似,都是以界说高低频的联系作为起点。当时面说到的EV特别大时,咱们会看到内存占用特别高。在Adaptive Embedding Variable中咱们用两个Variable来表达,如右图展现。咱们会界说其间一个Variable为静态的,低频的特征会尽或许映射到这个Variable上;别的一个则界说为动态弹性维度特征,用于高频部分的特征。Variable的内部支撑低频和高频特征动态的转换,这样的长处是极大降低了体系对内存的运用。例如某个特征练习后榜首维或许有接近10亿,而重要的特征只有20%-30%,经过这种自适应的办法后,能够不需求那么大的维度,从而极大的降低了对内存的运用。咱们在实践运用发现对模型的精度影响是很小的。

1.4 Multi-Hash Variable

这个功用是为了处理特征抵触的问题。咱们本来是经过一个Hash+Mod的办法处理特征抵触,现在用两个或多个Hash+Mod去得到Embedding,而且随后对得到的Embedding做Reduction,这样的好处是能用更少的内存来处理特征抵触的问题。

1.5 Embedding多级混合存储

这一功用的起点同样也是发现EV在特征个数多的时分,内存开支非常大,练习的时分worker占用的内存或许到达了几十上百G。咱们发现,特征实践上遵循典型的幂律分布。考虑到这个特征点,咱们将热门特征放到CPU这样更宝贵的资源,而相对长尾低频的特征则放到相对廉价的资源中。如右图,有DRAM、PMEM、SSD三种结构,PMEM是英特尔供给的速度介于DRAM和SSD之间,但容量很大。咱们现在支撑DRAM-PMEM、DRAM-SSD、PMEM-SSD的混合,也在事务上取得了作用。云上有个事务 本来用200+多CPU分布式练习,现在运用多级存储后改成了单机GPU练习。

以上是对Embedding一切功用的介绍。咱们做这些功用的动机是因为TensorFlow的几个问题(首要是特征抵触),咱们处理的方案是动态弹性特征和Multi-Hash特征,针对动态弹性特征内存开支较大的问题,咱们又开发了特征准入和特征淘汰的功用;针对特征频次,咱们开发了3组功用:动态弹性维度和自适应动态弹性特征是从维度的方向处理的问题,多级混合存储则是从软硬件的方向处理的问题。

2.  练习结构

第二个要介绍的功用是练习结构,分为异步和同步两个方历来介绍。

2.1异步练习结构StarServer

在超大规模使命情况下,上千个worker,原生TensorFlow存在的问题是:线程调度非常低效,关键途径开支凸显,别的小包通讯非常频频,这些都成为了分布式通讯的瓶颈。

StarServer在图的线程调度、内存的优化方面做得很好,将结构中Send/Recv修正为了Push/Pull语义,PS在执行的时分运用了lockless的办法,极大地提高了执行的功率。咱们比照原生结构有数倍的功用提高,而且在内部3Kworker左右的数量能到达线性的扩展。

2.2同步练习结构HybridBackend,

这是咱们为同步练习开发的方案,它支撑数据并行和模型并行混合分布式练习。数据读取经过数据并行来完结,模型并行能支撑大参数量练习,终究运用数据并行做稠密核算。咱们针对不同EmbeddingLookup的特征,做了多路Lookup兼并的优化,分组优化,还使用了GPU Direct RDMA的长处,根据网络拓扑的感知,规划整个同步的结构。

3.  Runtime

第三个大方面的功用是Runtime,首要介绍PRMalloc和Executor优化。

3.1 PRMalloc

首先是内存分配,内存分配在TensorFlow和DeepRec中都是无处不在的,咱们首先在稀少练习中发现,大块内存分配造成了大量的minorpagefault,此外在多线程的分配中也存在并发分配的问题。咱们在DeepRec中针对稀少练习前向反向的特色,规划了针对深度学习的内存分配方案,称为PRMalloc。它提高了内存运用率和体系的功用。在图中能够看到首要的一块是MemoryPlanner,它的作用是在模型练习的前k轮的minibatch先核算当时练习的特色,每次需求分配多少Tensor,将这些行为记录经过bin的buffer记录下来,而且做相应的优化。在k步后,咱们将其运用,从而极大削减上述的问题。咱们在DeepRec的运用中发现,这能大大削减minorpagefault的呈现,削减了内存的运用,练习速度也得到了1.6倍的加快。

3.2 Executor优化

TensorFlow原生的Executor的完结非常简单,首先对DAG做拓扑排序,随后将Node插入到执行行列中,经过Task使用Executor调度。这样的完结没有结合事务考虑,ThreadPool默许运用了Eigen线程池,若线程负载不均匀,会产生大量的线程间抢占Steal,带来极大开支。咱们在DeepRec中界说调度更均匀,同时界说了关键途径使得在调度的时分有一定的优先级顺序,来执行Op。终究DeepRec也供给了多种包含根据Task,SimpleGraph的调度战略。

4. 图优化相关的功用

4.1结构化特征

这是从事务启示的一个功用。咱们发现在查找场景下,不管是练习仍是推理,样本往往是1个user对应多个item,多个label的特色。本来的处理办法会视为多个样本,这样user的存储是冗余的,咱们为了节约这部分开支,自界说了存储格式来做这部分优化。假如这些样本在一个minibatch中是同一个user,部分user网络和item网络会分别核算,终究在做相应的逻辑核算,这样能节约核算开支。所以咱们分别从存储和核算端做了结构化的优化。

4.2 SmartStage

咱们看到稀少模型的练习通常包含样本的读取,EmbeddingLookup,还有MLP的网络核算。样本的读取和Embedding查找往往不是核算密集型的,并不能有用使用核算资源。原生结构供给的prefetch接口虽然能一定程度上完结异步操作,可是咱们在EmbeddingLookup过程中规划部分复杂的子图,这些不能经过TensorFlow的prefetch完结流水线。TensorFlow供给的流水线功用,实践运用中需求用户显示的指定stage边界,一方面会提高运用难度,另一方面因为stage的精度不够,无法精确到op级别。关于High Level的API用户无法手动插入,会导致许多脚步并行化。下图是SmartStage的具体操作,它会将Op主动的归类到不同的Stage,使得并发的流水线能得到功用的提高。咱们在ModelZoo里模型的测验作用最大加快比能到达1.1-1.3。

5. Serving

5.1模型增量导出及加载

一开始在介绍Embedding的时分其间一个重要的点是低效的IO,假如将前面说到动态弹性功用运用后,咱们天然能做增量的导出。只要在图中加入从前拜访的稀少ID,那么在增量导出的时分就能准确的导出这部分咱们需求的ID。咱们做这个功用有两个起点:首先,模型练习时咱们原有的办法,在每个step导出全量的模型导出,在程序中止restore时分也是restore checkpoint,最差的时分或许丢失两个checkpoint区间一切的成果,有了增量导出,咱们关于dense部分会全量导出,sparse部分是增量导出,这在实践场景10分钟的增量导出能很大程度节约restore带来的丢失;别的,增量导出的场景是在线serving,假如每次都全量加载,那么关于稀少场景,模型非常大,每次加载都需求消耗很长时刻,假如要做在线学习会很困难,所以增量导出也会用到ODL场景。

5.2 ODL

最左边是样本处理,上下两部分是离线和在线的练习,右边是serving。这里边运用了许多PAI的组件来完结Pipeline的结构。

DeepRec 社区

社区方面,咱们在6月份发布了新版别2206,首要包含以下新功用: