在微信 AI 背後,技術究竟如何讓一切發生?微信 AI 公眾號推出技術專題系列“微信看一看背後的技術架構詳解”,乾貨滿滿,敬請關注。以下為專題的第一篇《微信看一看推薦排序》。
一、背景
微信公眾平臺作為目前使用者量最大的網際網路原創內容平臺之一,每日新發表的文章可達幾百萬篇。使用者可以透過關注公眾號、朋友圈、聊天轉發等渠道閱讀文章。除了前述幾種方式以外,使用者很難再有其他方式發現更多有趣的文章。因此,看一看個性化推薦應運而生。我們利用使用者在微信內的閱讀、關注、分享等資訊,結合目前最新的深度學習演算法,為使用者推薦最符合興趣的文章。除了文章以外,我們也接入了騰訊影片、企鵝號、豎屏小影片等內容,大大豐富了推薦的內容多樣性。
二、看一看整體架構
看一看的整體架構如圖所示:
和大多數的推薦系統一樣,我們最底層採用了經典的召回、粗排、精排三層結構,各階段處理的候選集數量逐層遞減,主要考慮是需要在實時效能和效果之間做 tradeoff。比較特別的一點是,我們在精排之後接了一層異構內容混排,主要是考慮到不同內容源的點選率、最佳化目標不盡相同,難以放在一起比較。目前,混排側引入了強化學習模型,最佳化長期收益,實現快速實時反饋。
三、基礎資料和召回
資料是推薦系統的天花板所在。簡單來講,推薦系統就是根據使用者的行為,在千萬級別的候選集中挑選最適合使用者的 topN 條結果。對資料判斷得越準確,越細緻,資料的表達能力越強,推薦也越精準。整體上看,資料可以分為使用者資料和內容資料。
透過基礎資料,我們可以從多個緯度去判斷使用者需求,包括使用者的一級類目興趣,二級類目興趣,興趣關鍵詞,topic 分佈等。同時,在 embedding everything 的號召下,我們透過深度網路,對畫像做了多種層面的 embedding。
內容資料泛指所有文件相關的資料。從業務層面看,內容資料分為圖文、影片、新聞、小影片、人工干預等幾個大類,每種業務都是一個獨立的池子,有單獨的資料清洗、質量評估流程,前期甚至有獨立的分類體系。從來源看,內容資料分為公眾平臺文章、企鵝號號文章、外部連結文章、短影片、小影片。從時間上看,內容資料分為實時資料、15 天全量資料、歷史優質資料。
每個文件都有豐富的基礎屬性,包括一級分類、二級分類、tag、實體詞、topic、曝光數、點選數、質量分、色情分、垃圾分。我們還創新的提出了 people rank 演算法,透過每個人的社交影響力,將每個人的社交影響力反饋到文章上,形成文章的權威分、精英分等,能較好的提煉出高質文章。
召回主要負責從百萬級的海量候選集中選出萬級別的候選集給到粗排。召回主要分為興趣畫像、協同、公眾號、社交等幾個大類召回。興趣畫像召回主要有一級/二級類目、topic、地域、關鍵詞等召回;協同召回包括 Item 協同、內容協同、使用者協同等召回;公眾號召回包括關注公眾號、擴充套件公眾號召回。為了增加多樣性,在以上召回之外還有一些試探、冷啟動召回,對使用者興趣進行探索。
四、排序
排序主要分為精排和粗排 2 個階段,二者主要的區別在於候選集的量級不一樣,粗排輸入候選集在 1 萬級別,精排只有 1 千級別。候選集的數量差異決定了粗排在效能上要求會更高,因此在特徵上只能選取粗粒度、區分度較高的少量特徵,而模型側也只能選擇線性模型,或者複雜度較低的深度模型。粗排其他部分的工作和精排比較類似,這裡著重介紹精排。
精排階段需要對粗排候選池中的 ItemList 進行打分,這個分數是針對每個使用者對候選文章點選機率的預測,即 Ctr 預估。看一看業務中每天有海量活躍使用者,這些海量日誌可以用來進行模型訓練以建模喜好。
LR/FM 大規模的 Ctr 預估系統中,Logistic Regression 因簡單、易擴充套件、可解釋的特性成為初期階段使用最為廣泛的一種模型。其 Ctr 預估模型公式為:
我們第一階段的模型採用大規模分散式的 LR,使用自研的分散式訓練平臺 PanguX,透過人工特徵工程提取十億級的特徵用於離線訓練。但 LR 屬於 Memorization 比較強的 model,主要記憶每個特徵的歷史點選率,在 Generalization 上有很大的缺陷,需要大量的人工特徵工程來提高泛化能力。另外,這種線性模型特徵與特徵之間在模型中是獨立的,無法學到在訓練集中未出現過的交叉資訊。因此第二階段我們切換到了 FM(Factorization Machines),該模型可以在很少特徵工程的情況下透過學習特徵的 embedding 表示來學習訓練集中從未見過的組合特徵,FM 的模型公式如下:
雖然理論上講 FM 可以對高階特徵進行組合建模,但是我們一般在使用中受計算複雜度和引數維度的限制都是隻用到了二階特徵。很自然的,對於更高階的特徵組合可以用多層神經網路去解決。
wide&deep
2016 年 Google 提出的 wide&deep 模型拉開了深度學習在 ctr 預估領域大規模應用的序幕,該模型包括兩部分:線性模型
DNN 部分,wide 部分透過 Cross-product transformation 在 Memorization 上增加低階非線性,deep 部分聚焦 Generalization,對特徵的 dense embedding 進行組合,學習更深層的隱藏特徵。在我們的實際應用中, wide 部分增加 cross-product transformation 的組合特徵,deep 部分主要由 embedding 化的離散特徵及連續特徵組成,對離散特徵學習了一個低緯度的 embedding 向量(dense representation),Embedding vectors 隨機初始化後根據最終的 loss 來反向訓練更新。我們把同一個 field 內 embedding 向量進行 sum pooling,不同 field 得到的向量 concat 在一起作為第一個隱藏層的輸入。wide&deep 作為我們進入深度學習領域的第一個模型在看一看精排場景中取得了很大的收益。
DeepFM
wide&deep 模型全量之後相比 FM 這種淺層模型點選率提升明顯,但 wide 部分仍需要大量的人工特徵工程來引入低階組合資訊。我們參考 DeepFM 在網路結構上引入因子分解機部分,透過 FM 的特徵交叉學習淺層組合,dnn 部分挖掘特徵間的深層非線性關聯。標準的 DeepFM 網路結構如下:
我們在引入 FM Layer 時,不同 field 間的交叉不再使用點積操作,而是透過哈達馬積得到一個向量,用於上層的多模組融合。同時,引入 field-wise 的 Wide Layer 以防止共享 embedding 的訓練有偏。對於 Show/Clk/Ctr 等統計特徵,我們放棄了離線單獨統計載入字典的模式,直接在 PanguX 訓練平臺框架層面引入該型別統計資訊,server 針對每個特徵儲存一份實時的全域性 show clk 資訊,並且該資料隨著訓練的進行持續累計和隨時間衰減。最後的模型框架結構如下:
目前該最佳化過的 DeepFM 已經全量應用於看一看精排業務中,取得了非常不錯的效果。
五、多目標
除了前述 ctr 預估,在微信看一看的排序中,我們非常重視多目標的推薦效果最佳化。這裡多目標是指包括了點選目標之外的時長、分享、點贊、評論等其他跟使用者體驗息息相關的推薦指標。單純以 pctr 為目標,會帶來標題黨問題。站在平臺的角度,我們不僅希望在打造一款大眾化的閱讀產品,同時希望提升產品的社交屬性,因此使用者閱讀外的其他互動行為,也是使用者體驗的重要衡量準則。站在內容的角度,被使用者點贊、分享、評論的內容以及停留時長長的內容,往往質量比較高,因此引入這些目標有利於推薦過程中避免標題黨等低質量內容的展現。站在使用者的角度,從閱讀、分享、點贊、評論等多個角度提升使用者綜合體驗,有利於增加產品對使用者的使用黏性。在創作者角度,作者會希望在多元的指標上看到自己微信平臺上的內容作品的反饋效果的提升。
多目標問題業界常見的有方法有兩種:
1.多工聯合建模:
阿里媽媽在廣告的點選率-轉化率預估任務中,提出了對點選率、轉化率進行聯合建模,並將轉化率分解為點選率乘以點選後的轉化率,從而對兩個任務在目標輸出層進行關聯。優點是多個任務之間可以互相利用資訊,點選資料彌補了轉化資料過度稀疏造成的預估不穩定問題,不足之處是模型強依賴於點選-轉化目標在業務遞進關係,不能直接擴充套件到其他複雜場景。
2.各任務獨立建模:
業界一些資訊流推薦產品,對點選、時長、點贊和評論等目標採用獨立訓練模型,線上進行組合的 model combination 方案。優點是各任務完全解耦,加快了模型的迭代速度,也利於對具體任務的特徵獨立最佳化,不足之處是各任務之間無法互借資訊。
3.其他方法:
一些透過修改樣本權重體現多目標重要性的方法,以及一些透過增加正則項在損失函式中體現多目標價值的方法,因為在迭代的靈活性和模型效果上均不具有優勢,此處不再詳述。
看一看的推薦場景和其他推薦產品有相似之處,也有自己獨特的一面。例如,點選目標和閱讀時長、分享、乃至關注公眾號等目標構成業務場景上的遞進關係,這一點是共通的;但在“好看”上線以後,使用者的點贊和評論行為則不必須依賴於點選也可以發生,這些目標和點選目標既有遞進關係,也有平行的關係。
此外,使用者在閱讀中的社互動動行為資料也是微信看一看的特色,共同閱讀一篇文章、觀看一個影片的好友上下文資訊,對使用者行為的引導起到了很大的作用。
看一看中多目標最佳化方法:
1.多目標模型的網路結構:
整體的多目標建模方法論層面,我們也採用了多工聯合建模的方案,各個任務共享底層特徵 embedding 表示,獨享各自的神經網路和目標輸出。
在對多目標之間的聯結方式上,我們在對點選目標和點選後的遞進行為進行全空間建模之外,增加了對非依賴點選行為目標的獨立輸出。以“好看”業務為例,即對圖中的點選(A+B),點選並點贊(B),點贊(B+C)做三路輸出。這樣做的好處是既能受益於點選目標和遞進的 postclick 目標互相借用資訊,又能透過獨立網路將非依賴點選的行為目標完整的考慮進來。
在底層特徵表示方面,我們將特徵種類劃分為三部分進行研究,包括使用者屬性和興趣特徵,內容屬性特徵,和社交關係上下文特徵,我們目前是透過模型自動學習不同目標的預估任務下應該如何配置特徵之間的互動關係的,這一部分的擴充套件性是可以很強的,比如可以加入人工的先驗知識,或者定製化的網路結構進行特徵組選擇。
2.多目標線上融合方式:
多目標預估值的線上融合方式非常重要,是決定看一看產品的綜合使用者體驗的最後一環,我們透過離線、線上兩部實驗獲得最終的權重融合引數。在離線階段,我們透過 grid search 設定多組融合權重方案,觀察每種融合引數對各目標的離線排序 AUC 得分,選擇 AUC trade off 比較平衡的一些權重組合作為候選集,上線進行 ABTEST。線上階段,透過觀察各個實驗的留存率、產品使用時長、使用者行為互動率、以及內容分發量和多樣性等,選擇和產品價值導向最一致的權重組合作為最終的融合方案。
六、重排與多樣性
重排主要負責多路異構推薦結果混合排序,最終決定推薦給使用者的 10 條結果。除了負責策略混排,重排還負責整體的多樣性控制、規則重排、人工干預等。重排這裡是業務的最終出口,我們的最終目標是提升分發量,即 pv+vv。
重排有幾個難點:
資料是異構的,包含多種業務,不同業務資料包含不同的特徵,並且點選率差異也很大; 不同內容的最佳化目標不盡相同,很難做統一的內容排序; 不同內容的點選率不同,比如影片點選率超過 20%,會擠壓低點選率的業務。
我們嘗試了透過 pctr 來統一排序:
看一看中,影片點選率最高,新聞最低。當我們提高影片的展現佔比,整體點選數並不是持續升高,而是會有一個拐點。同樣,不斷降低新聞的佔比,點選數也會迎來拐點。因此,提高高點選率業務,降低低點選率業務,整體的內容點選率會提高,但不會提高整體的點選數。
基於上面的考慮,我們選擇使用強化學習來進行多業務混排。使用者在推薦場景瀏覽可以建模成 ov Progress,Agent 是我們的推薦系統,Action 是我們推薦了什麼內容,Reward 是使用者的反饋資訊,包括點選、負反饋、退出等,每次我們的推薦系統 Agent 採取某個 Action,給使用者推薦了內容,使用者給到我們相應的反饋,透過最最佳化總點選數來獲得最佳效果。
未來有不確定因素,所以要對未來的收益做衰減:
DQN 梯度下降求解 MSE 的 LOSS:
初版 DQN 上線後,對比 baseline 規則,總點選數有大幅提高。為了利用 Session 內短期資訊,我們將 DQN 內的 state 用 RNN 的 hidden 來描述,結構如下:
採用 RNN 結構的強化學習模型上線後效果得到了進一步提升。基於 RL 混排,我們在 reward 的設計上也進行了多輪迭代,如加入時長、負反饋、多樣性。下面重點介紹一下多樣性。
多樣性在推薦系統中是一個重要的最佳化目標,但是相比於 ctr 等指標,學術界、工業界都並沒有一個明確指標來指導多樣性最佳化。為了更好的理解、分析和最佳化多樣性策略,我們設計了 10+中多樣性相關指標,如展示/點選類目數、展示類目熵,使用者主興趣覆蓋率,符合使用者主興趣文章比例等。
第一版的多樣性策略採用啟發式的方法,限制相同類目/Topic/Tag 等個數上限,結合離線平臺/abtest 資料調整引數。這裡最大的問題是個性化策略是全域性的,沒有個性化。
透過 Submodular 的邊際效應遞減特性,對重複度高的類目、關鍵詞進行打壓,同時引入 pctr,體現了一定的個性化,上線取得了不錯的效果,在損失較少的 ctr 的情況下大幅提升了多樣性。
進一步地分析,Submodular 本質上是基於先驗知識的規則,使用者的及時反饋資訊使用的不夠高效,上述公式中仍然存在大量的超引數需要手工調節,迭代效率緩慢。基於上述考慮和之前在強化學習混排中取得的成果,我們想到了使用強化學習來最佳化多樣性,將多樣性作為 reward 加入進來,最後上線取得了 ctr 和多樣性的雙贏。
七、工程挑戰
看一看排序工作在迭代中遇到了好幾個比較大的工程挑戰。
首先是演算法平臺。排序最初上線採用 spark mllib,快速實現了 lr 模型的上線。但是很快就遇到了算力瓶頸,我們先後嘗試了一些開源的演算法平臺,都不能滿足業務的需求,最後選擇基於 ps-lite 自研了大規模分散式深度學習平臺 PanguX。PanguX 平臺支援百億級稀疏特徵實時訓練,支援低頻特徵過濾、特徵動態過期,支援 LR、W&D、DeepFM、RNN、MTL 等常用演算法,已經穩定支援看一看、搜一搜線上業務。
其次是線上 serving 瓶頸,這裡包括記憶體瓶頸和效能瓶頸。記憶體瓶頸方面,當模型特徵膨脹到百億級別,每個特徵對應一個 n 維 embedding,單機無法 load 一個 model,需要對 model 進行拆分,這裡就涉及到比較複雜的工程細節問題,如模型的一致性、版本控制、網路頻寬等問題。我們藉助微信技術架構部在 kv 方面的豐富經驗,實現了一個高效能的特徵 FeatureKV,用於統一儲存模型,解決了 model 的線上儲存問題,單機可支援超過 1kw key/s,同時運營系統支援版本控制、快速回退等功能。模型過渡到深度模型後,預測的耗時大大增加,第一版採用 tf-serving 的模型,雖然取得了不錯的效果,但是耗時接近 1 秒,完全沒辦法全量。最後,藉助於資料平臺團隊的 DeepX 超高效能深度演算法元件和 sage 向量運算庫,將耗時壓縮到極致,最終達到上線要求。
最後是線上特徵抽取的效能和模型可擴充套件性問題。透過 perf 發現,特徵抽取模組中字串拼接和 hash 計算消耗了大量的 cpu 時間,導致 ctr 預測吞吐量一直上不去。痛定思痛,我們對特徵抽取模組進行了完全的重構,完完全全消除字串 copy 和拼接,最佳化 hash 演算法,效能得到了成倍的提升。可擴充套件性方面,因為業務發展太快,前期每做一個新業務,都是 copy 程式碼,先上線後最佳化。後面業務增多,排序目標增多,模型增多,問題就暴露出來。尤其是新演算法在一個業務迭代取得效果想推廣到另一個業務時,需要 copy 大量程式碼,往往需要滯後很久。因此,我們果斷對 ctrsvr 進行重構,將線上預測打分邏輯抽象成特徵抽取、打分演算法、模型儲存等幾個基礎元件,採用配置化的方式進行組裝,大大提升了迭代效率。
八、後記
看一看上線以來,排序側逐步從線性模型過渡到深度模型,並引入了強化學習、多目標學習等方法,對 ctr、時長、多樣性等指標均帶來大幅提升。在逐步迭代的過程中,一個比較大的感悟是,模型演算法要發揮最大效果,一定要在演算法工程架構上精耕細作,充分挖掘效能,提升算力,才能將演算法的緯度和深度優勢發揮到極致。