点击率预测模型Embedding层的学习和训练
導讀: 本文將簡要介紹推薦模型的發展歷史,現狀,和下一步的研究趨勢。并重點介紹針對embedding數據的模型訓練及優化。主要包含以下幾大部分內容:
- CTR預測模型(CTR Models)
- 連續值處理(Continuous Feature)
- 交叉特征建模(Interaction Modelling)
- 大Embedding模型訓練(Distributed Training)
- 總結和展望
--
01 CTR預測模型(CTR Models)
1. 推薦模型的發展
首先簡要介紹下推薦模型的發展。以06年為起點,在06年時,更多的是以協同過濾(Collaborative Filtering)的方法來做推薦,還包括最近鄰方法(Nearest neighbor),矩陣分解(Matrix factorization - MF)的方法,以及主題模型(Topic models)的方法。
10年以后,很多公司開始在業務中引入使用廣義線性模型(Generalized Linear Model)這一系列的模型,包括邏輯回歸(Logistic regression)、低秩模型如因子分解機FM(Factorization Machines)、基于域信息的因子分解機FFM (Field-aware Factorization Machine),以及一些learning to rank 的方法,如BPR, RankSVM,lambda Rank等。
15年以后,CNN在視覺任務取得了一些突破性的進展,深度學習模型在業界得到了很大的關注,很多模型被提出。例如大家熟知的FNN、PNN、DIN、谷歌提出的wide&deep,以及華為的deepFM等等。
18年以后,研究開始傾向于向強化學習這一類推薦模型發展。18年之前已經有像多臂老虎機這種方法在使用,但是AlphaGo擊敗圍棋世界冠軍這次事件引起了業界極大關注,推薦任務的研究也開始轉向基于強化學習的推薦模型
整體的發展趨勢就是模型逐漸從人工經驗向自動化,深度模型的歸一化,越來越聚焦到某一類模型,期望引入自適應模型來解決業務問題。
2. 推薦系統中的核心問題
點擊率預測模型是推薦系統中的核心問題。舉個例子,如上圖所示是一個網頁,網頁上有一些內容,也有一些位置留給廣告,廣告對于一個網站是比較大的收入來源。展示什么廣告給用戶,就需要預測用戶在特定頁面點擊廣告的概率,點擊率預測就是執行這樣一個任務。預測的準確與否決定了整個推薦系統或者說廣告系統的收益以及用戶體驗。
在2021年IJCAI上面有這樣一篇Survey論文,是上海交通大學張偉楠老師和華為諾亞實驗實的聯合工作,將深度學習時代的點擊率預測模型分為了三類:
- 第一類就是基于組合特征挖掘的模型;
- 第二類針對用戶行為的模型;
- 第三類是自動架構搜索的模型。
① 用戶行為挖掘
這塊從論文來看做的比較早的是阿里的一些工作,包括阿里媽媽團隊在2017-2018做的基于dnn的Deep interest network-DIN,是用dnn里面的pooling,將用戶的歷史行為做了一些建模。這樣可以把用戶的歷史興趣體現在模型中,從而得到更好的預測效果。2019年,阿里媽媽團隊又在DIN的基礎上增加了一個RNN模塊,推出DIEN模型。DIN只是把用戶行為做pooling,把過去歷史行為都等同來看,而沒有去關注行為之間過去歷史之間的序列關系。所以DIEN 模型在user modeling加了一個RNN模型,從而可以擬合序列關系。同年,阿里另一個團隊推出了BST模型,將transformer用在了用戶行為 modeling模塊里面,目前有很多公司也在用,包括去年快手發布的萬億參數模型,也是用到了transformer來擬合用戶的長期行為。
② 組合特征挖掘
另一類是組合特征挖掘類模型。我個人認為可以分為三類,第一類就是像wide&deep模型,谷歌最先提出,他們在模型里面加入了顯示的交叉,也就是特征之間笛卡爾相乘之后構建出來新特征,加入到線性部分,這樣模型會記住這些特征,當下次組合特征出現的時候,會直接把它的權重取出來做預測。第二類模型是DeepFM這類的模型,可以稱為雙塔模型、雙塔結構,像DCN,xDeepFM以及后邊的很多模型,都屬于這類模型,這類模型是在dnn之外以及線性之外,加了基于分解的模塊,用來建模兩個特征之間的組合關系。兩個特征的組合關系,是用一個向量的乘法或者是一些復雜的結構來擬合的,建模完這個關系之后,會直接把輸出喂到最終輸出中,而不會去神經網絡。與之相反的是第三類如PNN這種網絡,也會利用分解模式構建特征之間的組合關系,但是它構建完組合關系之后,會再把輸出喂入到模型MLP中,讓MLP來再度擬和這些特征之間的關系。
3. 結構創新帶來的收益越來越小,如何突破?
如上圖中展示的一些實驗結果,是華為諾亞實驗室20-21年的一個工作成果,已經公開發表(FuxiCTR: An Open Bench mark for Click-Through Rate Prediction[J]. arXiv preprint arXiv: 2009.05794, 2020.)。論文對15年至今比較有代表性的深度學習點擊率預測模型進行復現,在幾個公開數據集上進行調參、再調優。實驗結果顯示,模型創新,結構創新帶來的收益越來越小。比如圖中DeepFM和AFN+,公開數據集結果顯示結果差距不大。當然并不是說這些年模型沒有發展,業界使用模型做實驗時,很多時候都是用自己私有的數據集,數據集會有不同的特點,模型在這樣的私有數據集會有收益,并且會針對數據集專門改造模型。還有就是比如17年的時候很多模型調參的trick沒有發現,現在將這些trick帶入到17年的模型進行訓練,補足了以前模型的短板,所以看不到大的差異。相對于模型創新,如何結合數據設計模型以及如何找到一些針對推薦搜索等場景比較通用的調參策略,是一個不錯的突破點。
4. 如何更高效的利用數據?
在此基于組合特征建模和用戶行為建模提供兩個方向。這幾個工作也是近兩年發表在KDD和SIGIR上的一些工作。
首先是組合特征建模方向,很多深度模型建模的時候,使用顯示特征作為輸入,這樣一是會帶來人工的特征工程,二是因為特征的稀疏,直接使用可能學習不好。而像阿里的CAN模型,并沒有使用顯示的特征,而是將顯示的交互特征(組合特征)喂入模型, 帶來的提升也是很明顯的。怎么設計特征或者說怎么選擇哪些特征做顯示的喂入,哪些做隱式的交叉也是一個研究方向。另外,很多這種基于交叉基于分解的建模方式都是將所有的特征中間都去做交叉建模,但并不是所有特征都適合這種交叉。哪些可以交叉,哪些交叉后會帶來負向的效果,這需要模型去自動選擇或者人工去不斷嘗試。
上圖展示了華為諾亞方舟實驗室在2020年發表的AutoFIS模型,該模型針對交叉特征加了一組參數,用來自動去學哪些特征重要,哪些特征不重要。通過第一階段的搜索,篩選出重要特征,把不重要的去掉,再重新輸入到模型,這樣做效果有明顯提升。
第二個方向是用戶行為建模。怎么更高效利用數據呢,其實很多工作也提到了,那就是用更長周期的行為數據;但是利用更長周期的行為數據,會帶來兩個問題,第一個問題就是數據序列會很長,建模時它的參數量會很大,而且不容易訓練,另一個問題是可能只是一小部分的用戶行為序列很長,其他大多數用戶行為序列很稀疏,從而造成模型訓練困難。
針對這些問題,阿里以及上海交通大學張偉楠老師分別發表了類似的工作:SIM和UBR。這兩個工作想法類似:在行為數據中加入檢索模塊。如上圖所示,用戶的行為進來之后,通過一個行為建模的模塊,比如RNN或者是transformer,就會得到一個用戶的embedding,再和其他的特征一起注入到模型去做預測。這里的檢索基于一個target,即預測目標,去對用戶的行為做了一個篩選或者加權?;谶@樣的操作,模型會有很明顯的提升。此外,針對如何更高效利用數據,本報告會介紹華為諾亞方舟實驗室最近兩個工作,如何去處理連續特征和更好的建模組合特征。
5. 如何處理大Embedding?
推薦模型的研究,還有一個方向就是怎樣去處理大embedding。分兩個方面來看,一方面就是怎樣把embedding變小,也就是將embedding壓縮;另一方面就是怎么用更新的分布式架構去更高效更低成本的去訓練大embedding。
壓縮方法的話也有幾個分類,這里簡單提幾個比較有趣的工作,第一個就是twitter在Recsys 2021發表的Double hash的方法。這種方法首先把特征分成了高頻和低頻,因為高頻特征相對比例比較小,給每一個高頻特征分配一個獨立的embedding,它所占的空間也不是很大。對于低頻特征,使用Double hash方法進行壓縮,該hash方法是為了盡可能地減少沖突。第二個工作是百度在SIGMOD2021發表的一篇基于int16訓練Embedding參數。直接基于低比特參數進行訓練模型十分挑戰。第三個工作比較偏探索,是Google發表在KDD2021上的DHE模型,去掉了Embedding Table。
如上圖所示,這個模型里面左側是傳統的embedding的處理方法,對一個特征進行編碼,得到一個ID,然后用ID去一個大的Embedding table里面查表,得到它對應的Embedding。這種做法需要存一個大的Embedding,假設特征是億級別的,那這個table可能是數百GB,維護這樣一個Embedding table和訓練模型是比較困難的。谷歌的DHE基于原始輸入,用了1024個hash函數對數據做了一個硬編碼,但函數怎么設計,沒有提到,只是給了一個簡要的指導,基于它硬編碼之后的1024維輸出,會再通過一個多層的網絡去恢復出來一個Embedding,也就是說他認為1024維的hash函數進行編碼加上多層神經網絡即可恢復出Embedding table的參數。其在矩陣分解的一些模型上做了實驗,實驗效果顯示精度沒有損失太多。
另外一個方向的就是新的大Embedding分布式訓練架構。這里的話我們最熟知的,用的最多的可能就是基于GPU這種Horovod去數據同步。騰訊發表于SIGIR2020的DES通過模型結合硬件設計了一個分布式的方案。英偉達提出基于cude直接寫了一個HugeCTR,當然還有很多其他工作,后面的第四部分會介紹華為諾亞方舟實驗室的ScaleFreeCTR模型,簡單介紹一下這幾種訓練方式的一些不同。
--
02 連續值處理(Continuous Feature)
下面介紹華為的AutoDis,這個工作已經在KDD2021發表。熟悉深度模型的同學可能很清楚,我們的模型基本是服從Embedding+MLP。已有工作更多的是聚焦在怎么去設計網絡的架構,在特征組合部分去設計架構,目的是為了更好的去捕捉顯式或者隱式的交叉,但是特征的embedding,尤其是針對連續特征的embedding的研究是比較少的。 下面對現有的相關工作做了一些總結。
如上圖是一種對離散特征的處理方法,它就是做了one-hot的編碼,然后去做Embedding lookup。對于連續特征的處理方法,調研發現主要分為三類,第一類就是不使用Embedding,把原始值做一些變化,或者是歸一化后輸入到模型。第二類是Field Embedding,是給每個域一個Embedding。第三類是把連續特征離散化,之后把它當成離散特征來處理。
第一種方法,No Embedding。這里介紹幾個模型的用法,第一個是wide&Deep,在它的介紹里面,使用的是原始值,另外一個是谷歌的YouTubeNet,它會對原始值做平方開根號這些變換。另一個是facebook DLRM模型,對連續值的處理方式是把所有的連續值輸入到一個神經網絡,然后通過神經網絡把它壓縮到一個embedding維度大小的一個向量上,然后將Embedding和其他離散特征Embedding Concat起來,再做后面根據它的模型去做不同的計算。京東的DMT模型,他們的網絡是使用了歸一化的輸出,這種方法表示能力比較弱,因為它這里其實沒有對原始的延續特征做一個很好的表示。
第二種處理連續值的方法是Field Embedding,每個域有一個Embedding。某個域的Embedding是該域的一個連續值,乘上它的域的Embedding。這類方法的問題是表示能力比較弱,然后不同值之間是一個線性的關系。
第三類的方法就是離散化。離散化可以有很多方法,比方說等頻、等距和取log,或者基于樹的模型去做一個預訓練。但這類方法有兩個問題:首先,就是它是兩階段的,離散化的過程不能端到端優化;另外,有一些邊界的問題,如下圖所示的例子,一個年齡特征,假設我們按40,41來分,40以下的我們稱之為青年,41以上的成為中年,其實40和41,它們是很接近的年齡,但是因為我們的離散化的方法,把它分到兩個不同的桶里面,可能學到的Embedding是差異比較大的Embedding。
針對這些問題,華為提出了一個連續值Embedding的方法AutoDis,它分為三個模塊,第一個模塊是Meta-embedding,就是假設有若干個桶,每個桶有個Field Embedding,這個embedding是可以去學習的,還有一個模塊叫做Automatic Discretization,這個模塊就是將原始值映射到一個H維的向量上。這里函數是去學習連續值分配到H個桶上的概率,然后基于分配概率和Meta-embedding,就會得到最終的連續值的embedding。
為了驗證這個模型是不是有效,這里在兩個公開數據集以及一個私有的數據集上做了實驗,比較了像前面提到的幾種不同的embedding方法,可以看到當使用這種離散化的方法時,它的效果相對于這種沒有embedding或者Field Embedding,會有比較明顯的提升。
AutoDis方法相對于離散化的方法,會有進一步的提升,這篇文章也在不同的模型嘗試加入AutoDis模塊,看看AutoDis對普通模型是否有效果,這里可以看到(上圖右邊部分)它其實都有一些提升。文中還嘗試了將該模型在華為內部一個業務上去落地上線。基線組的連續特征被專門做了精細化的設計,通過很多的調參去選擇出來一個離散化的策略,實驗組使用的是原始的連續值,然后在模型里面加入了一個AutoDis,看線上效果,在點擊率及eCPM這兩個指標上都是有一個百分位的提升。
--
03 交叉特征建模(Interaction Modelling)
這一部分介紹華為諾亞方舟實驗室的第二個工作 - 交叉特征建模。這個工作目前還沒有發表,但是我們已經放在了Arxiv上。
如上圖所示,這里將組合特征建模方法分為了三類,即Naive、Memorized和Factorized。
第一類像FNN模型,即不建模,每個特征有一個embedding,所有的特征embedding后concat拼接輸入網絡,后面網絡自己去學,想學到什么就是什么。
第二類像wide&deep模型,這里統稱為基于記憶的方法,就是去顯示的構造組合特征,特征做交叉做笛卡爾積,然后把新構造的特征輸入模型。模型就會記住這個特征,這個信號就比較強。
第三類方法就是基于分解的方法,例如IPNN模型,對不同的域之間的交叉關系,通過乘法的方式去做建模,得到的乘法結果會和原始embedding一起喂入到后面的MLP,然后來再次去做一個組合。不同的特征之間是不是都應該組合,或者說怎么去組合,如果我們去試的話,需要去做很多實驗,能不能自動判斷特征是不是要組合,以及它們之間應該用哪種組合這種關系去學到呢,這個就是我們這個工作的一個動機。
基于這個目標,我們提出Optlnter。如上左圖,最上面有一個分類器,然后中間是一個Feature Interaction層,再下面是一個embedding層,這一層一方面會為每個特征用原始方法去構建出來它的embedding輸出(Origin Embedding table),還有一個的話就是通過一個Cross-product transformation模塊,將交叉特征的embedding學到。Cross-product transformation??斓募毠澱归_如上右圖所示,可以看到這個圖里面藍色的模塊是一個選擇模塊,通過選擇模塊,最終輸出這兩個域的一個交叉的embedding。選擇模塊的輸入有三個:第一個是使用分解方式去構建的一個embedding,基于這兩個特征的一個embedding做一個乘法,然后得到的一個輸出;然后第二個輸入的話就是拿小白的方法 - 根據業務選擇的特征直接輸入,不做特征交叉,即我們認為兩個特征之間關系不強,不去構建它,用了一個空的embedding。然后第三個輸入,是通過交叉或者笛卡爾去構建出來特征,為這個特征分配一個獨立的embedding。有這樣三個輸入,進入選擇模塊,選擇模塊會最終選出來一個embedding。選擇模塊是一個類似于softmax函數(如上圖右圖中公式),這個函數里面有一些參數是可以去學習的,最終會學出來一個結構的參數?;谶@個框架,訓練也是分為兩個階段,第一個階段就是搜索,第二個階段是Retrain。搜索的話,這塊具體細節不進行展開了,其實是要學一個?參數。這個參數,是一個結構的參數,針對每個特征,它們之間是使用小白的、記憶的,還是使用基于分解的方式去建模,通過訓練會得到一個最優的?參數,然后到了retrain階段的話,我們會根據最優的?參數去重構我們的網絡,然后基于重構的網絡的,將模型重新訓練。
對于以上方法,在多個數據集進行了實驗,包括三個公開的數據集,這三個數據集是CTR預測比較常用的數據集,并且在私有的數據集進行了實驗;如上圖所示,是幾個數據集的實驗結果。這里分別比較了LR這種不去構建任何特征交叉的方法、分解的方法以及記憶的方法。
--
04 大Embedding模型訓練(Distributed Training)
第四部分也是介紹華為的一個工作 - 大Embedding模型的分布式訓練,這個工作發表于SIGIR2021。
如上圖所示,推薦模型一般都包含兩部分,一部分是參數embedding,一部分是MLP。兩部分在數據和存儲上有不同的特點。embedding參數量很大,計算量相對比較少。一般GPU的顯存是明顯不夠去存embedding的,像上文提到的模型有幾百個G,一張顯卡如V100有32個G,還會去存很多運行態參數等數據,用它存embedding顯然是不切實際的。第二部分MLP,它的參數量相對來說比較少,但計算量會相對比較大。訓練MLP的話,使用CPU它的效率相對于GPU來說是低很多的。這里簡單介紹了下推薦模型的一個訓練的特點。
這里再簡要提一下,為什么Embedding會大。這是因為推薦里面有很多的高維稀疏輸入,什么是高緯稀疏呢,比如上圖的例子,樣本有三個域的特征,星期、性別和城市,因為它是離散的特征,所以它這里面只有某個位置會有值。這個例子中特征的維度都是比較低的,其實像用戶或者是一些交叉特征,它的維度是會很高的,特征的量也是很大的,在推薦里面因為用了embedding,就是將高維稀疏的輸入映射到了一個低維稠密的一個向量上,當我們稀疏的特征變得很大,大到幾十億甚至是幾百億上千億規模之后,它的embedding的table也會變得很大。如上圖右下部分,是快手去年發布的一個模型,比谷歌的一個超大模型還要大,這是因為它這里面embedding table里面有很多的特征,每個特征都有個embedding,導致規模會很大。
簡要介紹下已有的幾種并行訓練的方法:
第一類是數據并行,例如基于all-reduce的Horovod,這種方式在每個GPU卡中存一份完整的模型副本,需要把模型都能存得下,我們模型如果變得大,GPU顯存不足以存下完整模型,即使模型可以存得下,比方說有十幾G幾十G,基于這樣一個大小的模型,它在做通信的時候,它的通信的時延很可能比它計算帶來的時間的減少還要來得多,也就是說你增加節點不一定帶來性能的一個提升。
第二類是NVIDIA提出的,之前他們的方案還是一個多卡切分的方案,但現在已經支持了一個CPU的embedding的一個存儲,他們這個方法把embedding切成多份,然后在每個卡的顯存里面存一部分,MLP在每個節點都存一個完整的模型。embeding通過一個all to all的通信, MLP通過all-reduce通信,這個方案有一個問題就是當它的模型很大時需要的GPU卡很多,從而它的成本也會很高。
第三類方法是使用CPU的內存來存embedding,然后用GPU來存MLP。CPU負責存儲,MLP來負責前項以及反向的梯度的計算。對于這種方法,如果我們采用同步訓練的話,它有一個問題就是因為embedding是存在CPU側的,需要從CPU去傳輸到GPU,梯度需要從GPU回傳到CPU,他們之間通信的時延是很高的。
針對這些問題華為就提出了自己的一個分布式訓練的框架,叫做ScalefreeCTR,這個框架分成三個部分,第一個部分是有一個Host manager,它是用來負責embedding單元以及緩存的一個維護,另一個模塊的話是dataloader,負責將數據從硬盤讀到內存,以及做一些去重之類的操作,第三個部分是GPU worker,它負責從緩存里面去把對應的embedding取到,然后去做一個前向計算以及反向的訓練,然后再將梯度更新到緩存的embedding中。這里由host-manager來負責embedding參數的下發,GPU緩存的維護,以及embedding參數的更新,因為有了緩存,所以我們可以做到數據讀取,參數下發以及模型訓練的三階段的流水,盡可能的提升了資源的利用效率,從而提升了最終的吞吐。
如上所示是比較細節的圖,這里可以看到embedding完整的存在了CPU側。如果有多個節點的話,每個節點負責一部分embedding的存儲,然后換Host-manager,它就負責綠色的緩存和embedding之間的交互,host-manager會根據當前的數據去做下一批的數據提前的下發,也就是說當下面的GPUworker完成了上一個batch訓練之后,可以直接從緩存里面取到它下一個batch需要用到的參數,因而GPU相對來說利用率是比較高的,GPU之間的通信使用all-reduce的MLP的通信。
--
05 總結和展望
最后做個簡單的總結,從做算法以及訓練方法的角度有以下三個比較有意思的方向:
怎樣去結合數據設計更好的模型,讓模型更有針對性。 如何進一步提升訓練效率,包括怎樣去利用更多的數據,以及增快模型迭代效率。 怎樣去增強數據處理、選擇、模型調優的自動化的程度,從而解放業務或者算法同學,讓他們更多地去關注模型數據、算法和策略。
今天的分享就到這里,謝謝大家。
本文首發于微信公眾號“DataFunTalk”,歡迎轉載分享,轉載請留言或評論。
總結
以上是生活随笔為你收集整理的点击率预测模型Embedding层的学习和训练的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Numpy API 速查表
- 下一篇: 最小二乘擬合matlab,存在已知协方差