BANDANA论文解读(facebook推荐系统向量存入NVM)

       对于大规模的推荐系统来说训练的模型和训练的数据都是存储在DRAM(动态存储中)。对于推荐系统来说,数据有着实时更新和大规模的特点。只有训练了大规模的数据之后才会保证模型的准确性。但是随着训练数据的增多和计算量的增大,对存储资源的需求也就更大。但是动态存储器的成本很高(动态存储器是由一个晶体管和一个电容组成的,由于电容会漏电,所以需要隔段时间就进行刷新一次)。为了降低成本本文使用了NVM。

NVM相比较于DRAM的的好处在于:

1.NVM每bit的成本比DRAM低一个数量级。

2. NVM的吞吐率和延迟能满足计算要求,但是NVM的带宽还是比DRAM低很多。通过文中实验可知,(fig2)即使是在高队列深度的情况下(队列深度表示设备发出I/O请求的数量),NVM的读延迟还是比DRAM低30倍以上。

3.NVM一天能支持重写30次,facebook每天更新向量频率10-20次。所以对于NVM来说完全满足这个要求。

       在本文中使用的NVM作为块设备(还有一种是基于字节可寻址的,但是由于在Intel处理器中不支持,同时成本相比较于块设备更加的贵,因此本文用的是块设备)。当NVM提供最大的带宽时NVM块大小至少需要4KB或者是更大。但是对于推荐系统而言一个embedding vector的大小是128B,也就是说一个块设备只能存放32个嵌入向量。那么怎么进行存储块设备中的嵌入向量,才能够增大相应的带宽呢?这就是本文在解决的问题。

本文主要的贡献是:

1.大部分向量使用NVM 作为存储,只有小部分向量用DRAM作为存储。

2.bandana使用超图划分决定哪些向量可以放在一个block中一起进入。

3.使用最近的key-value存储运行轻量级模拟数十个微型缓存决定如何积极的存储预选择,提供一个阈值,访问次数高于这个阈值的话就会被预选择出来。

下面开始讲一下推荐系统中的嵌入向量:

      推荐系统中的嵌入向量主要分为两种:post 和 user。

      在推荐系统中通过user喜欢的页面来表示user的特征。如果一个用户喜欢ID2和ID4的页面的话,就把相应的位置标记为1,也就是我们所说的独热编码。这样会产生一个很稀疏的矩阵(0, 0, 1, 0, 1)

      同理在推荐系统中通过post也通过上面类似的方式生成特征,比如post文章“red car”通过字典(“bicycle, motorcycle, car, blue, red, green”)表示为向量(0, 0, 1, 0, 1, 0)。

      这样通过一组嵌入向量就可以分别表示post和user向量。因为post向量需要更多的处理和排序因此会比user向量需要更长的管道,也就是处理时间。因此可以用相对比较慢并且廉价的存储介质存储user向量,因为在这里影响处理时间的还是post向量而不是user向量,因此user向量存储在哪里并没有太大关系。

工作负载设置:

下表存在8个嵌入向量表,其中vector数量分别有10000000和20000000个,平均访问的请求数(table2中表示被访问的次数很多,表明相关的向量分布在一起了),占总的查找表比例,缺失率(表示第一次请求查找时未在table表中找到)。

table1.characterization of the user embedding tables

下图可以看出table2有向量被访问了10000次以上,table7不存在向量被访问了10000次以上(文中写的是1000,我觉得可能是写错了,因为和下图不符合,欢迎指正)

各表访问次数

design

基线:本文会出现很多次实验是和基线做比较的,这里的基线就是每次NVM4KB块只存一个128向量然后被DRAM读取,然后驱逐旧的single向量。这种情况下NVM 的有效带宽只占总带宽的4%,其余的会被丢弃。但是如果我们每次只用NVM存储一个有用的向量,其他的向量都是随意填充,把NVM的其他位置填充上的话可能会比基线这种只存储一个向量的情况更糟糕,因为会造成很大的读写延迟和驱逐延迟,每次读写进NVM块中,但是并不会被使用。这样情况会减少比基线的情况多90%的有效带宽。那么怎么有效的存储增加带宽呢?

1.通常我们认为相关的向量可能会在较短的时间间隔内被访问,因此可以把两个嵌入向量存储在物理位置相近的位置。那么有两种方法进行嵌入向量是否相关。一种是使用kmeans算法,通过求欧式距离来计算两个向量是否是在一个簇中,如果是一个簇中表示两个向量是相关的可以存储在同一个块中。但是簇的个数k不能设置太大,因为会导致训练时间过长,本文也使用的sub-cluster,也就是用递归的方式在一个簇的内部在分多个子簇,通过实验发现在簇的个数是8192的时候性能最后,运行时间可以接受,再比8192大的话运行时间呈现指数级增长。但是使用kmeans算法虽然简单,但是Facebook的嵌入向量是频繁更新的,如果使用kmeans的话会导致一个更新vector进来就要更新一次对应的欧式距离也就是重新训练。因此本文尝试不使用欧式距离,而是依赖每个向量过去访问,因为每个向量的身份会保持不变,即使他们的值会更新。

假设是无限大小DRAM的,本文使用超图划分计算最小扇出来衡量在每次访问时进入块的数量。这个越小也就表示相关的数据存储在一个块的数量也多。这样也就增加了相应的带宽。Qj表示一个用户所有的访问的队列,p表示特征向量中用于排序的特定列,根据这列参数来决定哪些嵌入向量放入同一个块中。计算最小扇出公式如下:

最小扇出计算

其中:

扇出公式

 

但是 DRAM大小是有限的,使用超图划分之后的嵌入向量表,相比较于原始的嵌入向量表,会发现有效带宽的有明显改善的。如图所示,简单地将一个块中的所有32个向量分配给高速缓存将触发32个驱逐可能更有用的向量,这些向量在逐出队列中排名更高,降低了高速缓存命中率并显着降低了有效带宽。

有限DRAM大小情况下有效带宽增加

 所以怎么驱逐向量,使得命中率提高,有效带宽增加呢?本文是进行一个预选择,把访问次数达到某一个特定阈值t的向量存在队列中,这样保证了命中率,因为频繁被访问的很有可能会被再次访问,这样防止了访问次数少的向量驱逐了访问次数多的向量。本文使用模型的方式通过少量样本找到不同cache size情况下的最佳阈值,节省了时间,同时效果和使用完全的样本进行预测阈值的结果相同。小的cache size应该使用大的t做阈值,大的cache size应该使用小的t做阈值。

阈值

这就是本文主要的思想,bandana的重点是怎么物理放置和存储嵌入向量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章