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的重點是怎麼物理放置和存儲嵌入向量。

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