前言
本文介紹我們在推薦系統領域的大規模參數學習研究. 問題的起源是探究給每一個用戶學習一個 ID 層級的表徵, 而在千萬量級的業務上, 學習如此特徵將會牽涉到超十億規模的參數學習. 對此我們根據推薦算法的特點, 實現了一個無需使用參數服務器, 在普通 Spark 能夠運行的支持大規模參數學習的 FM 算法, 我們稱之為 Elastic Factorization Machines (EFM). 從理論上, EFM 算法能夠支持千億規模的參數訓練. 在實踐中, 限於資源我們實現了一個十億級的 EFM 算法, 並在線上對比 FM 取得 PV 點擊率 5.0% 的提升.
效果說明
[ QQ 動漫某場景的三天 PV 點擊率對比 ]
用戶 ID 層級的表徵學習
推薦系統中, 用戶的表徵是一個非常重要的課題, 表徵的粒度通常影響推薦算法的個性化程度. 當我們只能用性別的男/女來表徵用戶的時候, 算法能夠給出的只是分群熱度推薦. 而當我們能夠刻畫用戶在每一個物品分類的興趣的時候, 算法的便能夠給不同的興趣群體給出不一樣的推薦. 越精細的用戶表徵, 推薦系統的個性化程度越高.
[ 越精細的用戶表徵, 推薦系統就越個性化 ]
而最精細的用戶表徵, 是用戶 ID. 對每一個用戶學習用戶興趣, 能夠做到真正的千人千面. 但在實現上, 學習用戶 ID 層級的表徵通常會遇到計算量的問題, 這裡主要的原因是用戶 ID 層級特徵量級與用戶量直接相關, 以千萬級用戶的業務為例, 如果使用 FM 算法學習用戶 ID 特徵, 對每一個用戶學習維度為 100 維的隱向量, 則整體參數量將會增加到 10億級. 而如果這個業務的物品更新不快, 物品數能控制在數萬規模, 則即便是用 “用戶對物品興趣” 這個用戶表徵也只需要訓練百萬級別的參數.
[ 各級別用戶表徵的特徵量級對比 ]
無參數服務器實現大規模參數學習
業界在大規模參數學習的解決方案是使用參數服務器. 背後的核心是分佈式訓練. 而市面上各個參數服務器在並行策略上也有不一樣的劃分, 包括下面兩種情況:
• 數據並行
o 這種方法是把模型分發到每一個節點做訓練, 但如果模型參數量本來就非常大, 將無法支持.
• 數據並行 + 模型按需並行
o 這種方法的初衷是考慮到並不是每一個訓練數據塊都需要所有的參數, 因此可以統計當前訓練數據所需的參數, 並只向參數服務器請求這些參數. 但因為訓練數據是隨機分佈的, 因而可能一個參數會被多個數據塊請求, 這會導致較大的網絡開銷.
而當我們需要給每一個用戶 ID 訓練表徵的時候, 同一個用戶 ID 的參數, 應當僅被這個用戶創造的樣本所需要, 這個參數對應的梯度也只能從這些樣本產生. 這意味著我們只需要讓訓練數據和模型同時做劃分(分桶), 就能夠讓每個用戶 ID 參數僅被一個數據塊請求. 在這個思想下, 用戶 ID 層級的參數可以分佈式存儲, 從而也不需要一個單點的參數服務器, 可以在普通的 Spark 上實現.
[ 不同類型的大規模參數訓練方案對比 ]
整體的實現步驟如下, 用戶 ID 層級的參數和訓練數據都按照用戶 ID 哈希分桶, 每一個參數塊都被分發到對應的數據塊上做訓練. 與此同時其他特徵也會被分發到每一個訓練數據塊上. 因為除開用戶 ID 層級參數外, 其他參數(例如 Item ID)量級能夠控制在百萬以內, 從而可以分發到各個子結點的內存中. 從參數和訓練數據中我們可以算得每一個參數的梯度, 而用戶 ID 層級參數的梯度也只由這個訓練數據塊中產生, 從而可以做一個一一對應的分發把梯度推送到對應的參數塊. 而其他參數因為量級較小, 可以做一個遞歸合併然後在內存更新.
[ 無參數服務器實現大規模參數訓練方案 ]
實現細節
規模上限
這個實現從理論上能夠支持任意量級的用戶 ID 層級訓練. 但受限於業務資源, 我們最高只測試過十億級別的模型訓練.
算法選擇
按理只要是梯度下降法的優化算法都能夠利用類似的方法去實現. 這裡我們實現了 SGD 和 ADAM 兩種方法, 發現 ADAM 算法作為一個自適應學習率的方法, 效果更好. 這兩個算法的具體原理, 可以參見文獻1.
Spark 大規模參數學習的工程實現
為了訓練億萬級別的模型參數, 我們做了大量的優化工作. 其中部分經驗來自於作者曾經在圖計算上的實踐經驗, 例如在多次迭代之後應當實現使用 checkpoint 功能進行 RDD 斷鏈保證系統魯棒性.
線上模型實現
線上服務在實現上與傳統的 FM 算法相似, 除了用戶 ID 層級外的模型參數都可以存儲在共享內存中. 而每一個用戶的 ID 層級特徵可以寫在 K-V 系統中, 為一個用戶提供服務的時候只需要請求一次就能夠得到對應的參數值. 從而對比起傳統的 FM 算法, EFM 算法只額外多一次 K-V 系統請求的開銷.
異步更新問題
每天例行模型訓練完成之後, EFM 算法在同步模型參數到線上的時候將會遇到異步更新問題. 因為用戶 ID 層級特徵的參數和其他參數分別存儲在不一樣的平臺, 更新耗時有較大差異, 從而導致在更新途中有些用戶的特徵將完全無法和其他特徵的隱向量有匹配.
為了解決這個問題, 我們引入增量學習技術, 每天例行訓練使用前一天的歷史參數做熱啟動, 使得新一天的模型參數與前一天模型的參數在一個類似的向量空間中. 這樣當其他特徵更新了, 線上使用的舊模型將仍可以與其他特徵有相似度匹配.
[ 兩類參數的異步更新會導致部分用戶的參數無法與其他特徵匹配 ]
總結與展望
本文實現了一個支持億級參數訓練的算法, Elastic Factorization Machines (EFM) 算法. 而我們認為可以在 EFM 算法的基礎上做更多的事情, 這裡列舉我們考慮到的點.
• 向量召回
o 可以分別學習出用戶和物品的 Embedding, 做向量相似度的召回.
• Model Ensemble:
o 可以在用戶 Embedding 的基礎上, 用 DNN 做進一步的學習, 增加非線性表達.
參考文獻
[1] https://zhuanlan.zhihu.com/p/22252270
原文發佈於微信公眾號 - 騰訊QQ大數據(qq_bigdata)
閱讀更多 機器不學習 的文章