今年阿里双十一提升广告点击率居然用的是这种算法?!
文 | 阿里巴巴定向廣告團隊
源 | 知乎
寫在前面的碎碎念
這篇文章主要是介紹我們在CTR建模領域最新的工作CAN,CAN已經在雙十一前全面在阿里定向廣告落地,在線效果提升非常顯著。一般文章會以事后的視角來寫,這樣思考會更完整,會屏蔽掉中途的一些旁枝末節,會顯得思路更清晰也沒犯啥蠢,不過這篇文章我想試試以順序(流水賬?)的視角來更真實的記錄一下這個工作的誕生過程,具體對方法的描述,以及CAN的精簡思路,大家看論文會體驗更好一些:
https://arxiv.org/abs/2011.05625
過去幾年,我們團隊一直在興趣建模方面投入了非常多的精力,也產出了一些工作。其實我們一直還有另一條堅持的技術主線,表征建模。
第一次沖鋒:在17年開始我就在表征建模上投入了大量的精力,畢竟是做NLP出身的,當然想蹭蹭過去學到的一些小技巧。最開始是想模仿Google做一個真·AI,當時XDL還沒完全交接給工程同學,負責一部分XDL架構和開發的工作。當時想,如果各個業務線都在用XDL,如果我做一個parameter bank用來存放各類ID的embedding。各個業務線的模型訓練任務通過這個parameter bank共享這些embedding參數,并且為它共享梯度,有沒有可能學出一個淘寶體系里最普適的ID representation,最后學出一些我們意想不到的知識?后來這個想法告吹了,因為它背后更新/維護/多個業務線的耦合風險無法說服所有人,同時我當時接到的任務是把圖像用到CTR任務里,這個方案看起來并不是為了完成這個任務目標最直接和現實的方式。到最后這個初始想法演變成了減少我們迭代負擔的model bank,然后這個工作一直也沒公開: )
第二次沖鋒:18年的時候,如何對十億淘寶商品進行表征建模,或者簡單點如何對item id學一個泛化性更強的embedding又開始來撩撥我的思想。想了一個res-embedding的方案,如果說直接學習每個item的embedding很難,那么把相似的item學習一個共享的mid embedding,再去學習每個item特有的信息 res embedding,用它們相加來表達一個item,相似item通過mid embedding共享信息可以緩解稀疏帶來的學習難度,一定程度上提升泛化性。具體在如何找相似的item,以及如何設置mid時,我采用了圖的方法,通過用戶行為把item連接起來,最后這個方案有點類似后來比較火的graph sage。
不過這個方案實際使用時在樣本量幾億規模時非常有效,到幾十億上百億規模時收效甚微,這說明我還是沒找到更好的表征建模方案。
第三次沖鋒:后續陸陸續續做了非常多碎的嘗試,也學習了很多研究思路,包括GNN、Contrastive Learning、Information Bottleneck、Cognitive Rec等等,但是每次嘗試我都發現要寫論文很簡單,很多方法在“小”(甚至幾億規模)數據集上總是有效,但是在我面對的實際業務問題規模上,幾乎都沒什么效果。我甚至開始懷疑我所解的這個業務問題,到底需不需要研究表征建模這個問題,畢竟CV/NLP/語音的原始輸入數據本身就是為表意而存在,天然具備一些連續相關性,而電商業務場景的數據并不是表意的。這到底是水平不夠,還是說問題本身只是一個執念。后來我們做了一個簡單的推演,CTR類模型的核心參數量都在embedding部分,而我們組的大部分工作和模型迭代都在后面的MLP部分,比如DIN/DIEN/MIMN。可是一旦embedding學習方式確定了,如果輸入信息本身學習不夠好,后面的模型空間是有限的。因此我們認為輸入端信息建模應該是有一個比較大的潛在效果空間。然后就成立了一個項目組,搞了一年,沒有完整的產出,成員們壓力極大: (
在第三次沖鋒后期,我們推斷出了一個對輸入端信息做交互建模的方法,算是為我們團隊找到了一個新的迭代路徑,我個人也認為這個方法如果算作特征交互,算是一個新的思路。
回到特征交互
其實我對特征交互方面的工作一直以來態度都比較尷尬。一方面我認為手工交叉特征工程如果又能解決業務問題,又不影響迭代效率,其實挺好的,我們的業務模型里就有部分手工設計的交叉特征。技術都是為了解決問題而存在的,沒有原罪,也沒有原善,有克制的組合特征是能接受的,不能接受的是漫無目,無視迭代負擔,冗余的大規模組合。另一方面,學術界一些比較熟知的工作,FM/NCF/deepFM/PNN/DCN等等(說實話DCN不是很想提,不用看到實驗部分,方法本身都有問題),這些工作以我淺薄的見解,我實在看不太出來和FM有啥區別,到效果上,我們的業務數據里確實都沒效果,因為FM在我們的模型基礎上疊加就沒啥效果。雖然我一直很努力想理解這個在CTR建模領域比興趣建模更為普適的路線到底在研究啥,這些工作一步步思路如何推進的。結果還是看不懂,也就不太想碰。
不過第三次沖鋒,和之前一些同事的嘗試到是找到了一個比較有意思的實事:CTR預估建模問題里,把待預估的商品信息(如item id)和用戶歷史行為序列信息(如item id sequence)做笛卡爾積,形成一個新的id sequence,對其直接做embedding后pooling效果很好,會在DIN和DIEN的基礎上再有比較明顯的提升。
為何笛卡爾積有效
當時細想一下,笛卡爾積有效并不神奇,同時一定能找到參數量更少的模型方案來替代笛卡爾積這種hard的id組合方式。比如用戶行為序列中有一個商品ID為A,待預估商品為B,笛卡爾積形成新的ID A&B,A&B每次在一條樣本里出現,訓練時都會更新獨立屬于自己的embedding。而這個A&B的embedding,我們認為其學習的是A,B兩個ID在一條樣本共現后對Label的co-action信息。
這個co-action信息為什么重要其實很好理解,比如CTR預估問題,要解決的本來就是每條樣本最后預測是否點擊,其實解的問題就是所有輸入信息X條件下點擊的概率 。建模co-action信息就是單獨建模 。具體的,如果A和B分別是待預估的商品ID,和用戶行為序列里的商品ID。如果我們對行為序列做SUM/AVG pooling就等于忽視了ID間的co-action,對序列做DIN/DIEN類似的aggregation,在co-action的視角下可以看做是一個scalar的co-action,沒有方向,且只能對原始行為序列ID的embedding做一個純量的修正。那么每個序列的ID都和預估商品ID做一個笛卡爾積呢,把原始的序列變成一個笛卡爾積ID序列,再給每個ID都學習一個embedding。這個時候co-action就是用向量來建模,且這個新的embedding和原始序列的embedding完全獨立,自由度更大,模型capacity更大。如果原始ID的co-action信息建模本身有用,那么笛卡爾積就是建模co-action最直接的方式。 笛卡爾積+端到端學習的embedding其實很像一個大的memory network,只不過寫入和讀出的索引相同,都是笛卡爾積化后的ID。這樣的模式下這些代表co-action的笛卡爾積ID的embedding在訓練時,具備樣本穿越性。訓練時,任意一個笛卡爾積ID A&B的embedding都是獨立學習的,同時強保證了,在下一條A&B出現的樣本里,這個embedding能把當前學到的co-action信息無損的帶入。而簡單的特征cross方法,比如把 的embedding和 的embedding做外積,這個時候 的co-action為 ,它在訓練時也會被 embedding本身的學習和 等更新,很難保證學習到的co-action信息在下一次出現時,還保留上一次學習的信息。
笛卡爾積不是終局
笛卡爾積其實是非常常用也比較好理解其實現方式的一個方案。不過對用戶行為序列item seq和待預估item做笛卡爾積組合其實有蠻多弊端,即使已經看到了離線的部分提升,我對著急把這樣的方案推進全面生產化不是很感興趣。
1. 這種序列笛卡爾積在訓練端和在線服務端其實成本蠻大的。訓練可能比較好解決,但是在線服務會有比較明顯的瓶頸,因為每一次預估需要生成的ID,和查詢embedding的ID會急劇膨脹,而這些操作是需要CPU計算的,這部分的可優化空間也比較小。算下來成本比一個計算復雜型模型要高不少,至少對于我們,一個熟知如何優化計算復雜型的團隊是這樣。
2. 笛卡爾積意味著強記憶性,是比較hard的方案,對于一些樣本里未出現的ID組合,是直接無法學習的。同時稀疏的組合和稀疏的ID,學習效果也很差,大部分情況下只能選擇過濾。
3. 笛卡爾積的參數膨脹本身就會帶來模型無論從性能還是維護迭代上魯棒性的進一步降低。
下面我們來推演一下在笛卡爾積有效的情況下,我們有沒有機會找到參數量更少的模型方案來替代笛卡爾積這種hard的id組合方式。第一條線索,參數空間視角:前文提到二維笛卡爾積的方式,如果我們局限以對Item ID做co-action建模分析,可以看做是一個全參數空間為 的方法,N為item ID的數量,D是embedding的維度。這個參數空間是非常大的, 在淘寶是十億以上的規模。當然了實際上訓練時不需要那么大的空間,因為并不是所有ID的組合都會在樣本中出現,但是笛卡爾積這個方法的假設參數空間依舊是 。意味著在它有效的狀態下,也是存在大量的參數空間冗余的,再考慮到稀疏出現的笛卡爾積,如出現次數個位數的笛卡爾積embedding無法有效學習。笛卡爾積方法,大部分的假設參數空間都是無效的。第二條線索,學習難度視角: 前文提到,笛卡爾積的方式保障了任意一組co-action組合的學習是獨立且強記憶能實現樣本穿越的。而如直接外積的方式很難建模co-action,因為沒有參數來穩定維持對co-action的建模學習信息。雖然笛卡爾積的方式是有效且看上去對co-action建模最直接的,但是難以忽視的一點是比如在電商場景,商品與商品之間是有聯系的,是有相似性的,任意兩個商品之間的co-action信息也應該有overlap的部分,不應該是完全獨立的。直接外積的方式呢,共享的維度過大,單側ID的信息完全共享,參數空間為 。如果我們能有效利用不同co-action之間有信息可共享,我們就有機會找到把參數空間降低到 的方法,其中 。
CAN:Co-Action Net
最開始我們從memory net的視角想了一種方案,把item id的參數從 擴展到 ,即把embedding變成一個有T個slot的矩陣,這種方案下任意一個ID都有T個slot,每個slot存放維度為D的vector。這時候可以借如attention的思路來建模co-action并保持不同組合co-action學習的部分獨立性。比如在建模co-action時,讓不同的slot對另一個ID的所有slot做attention aggregation,并和aggregation后的結果做外積(element wise乘法):
(向右滑動查看完整公式)
核心的思想是,建模不同的co-action時,采納T個slot中不同的參數,同時更新不同的參數,保持co-action建模一定的參數獨立性。當然這種思路下可以去設計和嘗試的具體模型方案非常多,整個交叉實驗代價還蠻大的。
既然我們的核心目的是讓co-action的建模過程中有相對比較穩定和獨立的參數來維持對建模信息的學習記錄,同時又想讓不同的co-action間有一定的信息共享。不同于memory net的這個思路,我們組的小伙伴提出了一種更簡單的方案:把co-action希望建模的兩個ID,一端信息作為輸入,另一端信息作為MLP的參數,用MLP的輸出來表達co-action信息。
整體模型結構如下圖所示,CAN的部分在左側:
這種方式下,由于MLP的有多層,再加上每一層插入非線性函數,如此, 和不同的ID做co-action,如 ,其輸出co-action有一定信息共享,在參數更新時也會不同,比如MLP的激活函數如果是relu,甚至是稀疏會更新一部分,就做到了我們之前說的通過部分保留參數更新的獨立性,而實現co-action的穩定性。當然了具體的我們的實際方法里這部分激活函數是Tanh,這其實是個實驗結論。做實驗的小兄弟認為:因為我們在第一層輸入時,手動增加了輸入信息的多階計算, ,Tanh會保護訓練時輸出更平滑。不過我沒有完全接受這個觀點,relu或者dice都會更貼近我們最初設計的思路。
最后這個方法我們無論是在我們的業務數據集,還是公開數據集都做了比較完備的實驗。CAN確實性能優異,效果比笛卡爾積更好,同時模型參數量并不會急劇膨脹,因為這種方式需要查詢參數的ID數不變,對在線服務CPU和RT也比較友好。至于增加的GPU計算部分嘛,一個是GPU的算力增長還是比較符合摩爾定律的,增加GPU負擔比較便宜,另一個這部分的計算優化本來就是定向廣告團隊的拿手好戲: )。畢竟到現在都還有人沒辦法相信DIEN的在線服務,可能在線優化這塊真的很難?在工程團隊的給力配合下,我們很快就將這樣的方案全面生產化,給業務帶來了明顯增長。
這個工作是我們團隊在原始輸入信息交互建模上的第一次嘗試,如果真實業務情況笛卡爾積用著比較舒服,也不影響RT和迭代,其實笛卡爾積就是蠻好的方式。CAN是我們希望推進找到模型化的方案替代笛卡爾積建模co-action,背后希望的是找到一條新的路,讓交互信息建模還有進一步的迭代空間。畢竟如果終結于笛卡爾積的方式,我很擔心我們走上step1:手動加特征 step2:無腦增加多階特征 step3:講AutoML做特征搜索的故事 step4:跳槽開始step1的循環。
后臺回復關鍵詞【入群】
加入賣萌屋NLP/IR/Rec與求職討論群
有頂會審稿人、大廠研究員、知乎大V和妹紙
等你來撩哦~
總結
以上是生活随笔為你收集整理的今年阿里双十一提升广告点击率居然用的是这种算法?!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用多模态信息做 prompt,解锁 GP
- 下一篇: 负数的开方到底等于多少?