百度推薦排序技術(shù)的思考與實踐
一、背景
首先來介紹一下百度綜合信息流推薦的業(yè)務(wù)背景、數(shù)據(jù)背景,以及基本的算法策略。
1、百度綜合信息流推薦
百度的綜合信息流包括手百 APP 中搜索框的列表頁以及沉浸頁的形態(tài),有著非常多的產(chǎn)品類型。從上圖中可以看到,有類似于抖音的沉浸態(tài)的推薦,也有單列的推薦,以及類似于小紅書筆記的雙列推薦。交互形態(tài)也是多種多樣的,可以在落地頁上進行評論、點贊、收藏,也可以點進作者頁中查看作者的相關(guān)信息并進行交互,當(dāng)然也可以有負向的 feedback 等等。
2、數(shù)據(jù)背景
從建模的角度上看,主要面對三方面的挑戰(zhàn):
- 大規(guī)模。每天的展現(xiàn)量級超過了百億級別,因此模型需要有天級別百億的吞吐能力。每天的 DAU 過億,這也決定了整個模型需要有高吞吐、高可擴展性的設(shè)計。對于排序模型來說,在線每秒鐘有數(shù)億次的計算,因此模型設(shè)計時不僅要考慮效果,同時也要考慮性能,需要做到很好的性能和效果的折中。用戶交互形態(tài)以及場景的多樣化,還要求模型可以預(yù)估多類型任務(wù)。
- 高要求。整個系統(tǒng)的響應(yīng)時間要求非常高,端到端都是毫秒級的計算,超過了預(yù)定的時間,就會返回失敗。這也造成了另一個問題,就是復(fù)雜結(jié)構(gòu)上線困難。
- 馬太效應(yīng)強。從數(shù)據(jù)樣本角度上來看,馬太效應(yīng)非常強,少量的頭部活躍用戶貢獻了大多數(shù)的分發(fā)量,頭部的熱門資源也覆蓋到了大多數(shù)的展現(xiàn)量。無論是用戶側(cè)還是資源側(cè),馬太效應(yīng)都是非常強的。因此,系統(tǒng)設(shè)計時就需要弱化馬太效應(yīng),使得推薦更加公平。
3、基本算法策略
在整個工業(yè)界的推廣搜場景上,特征設(shè)計通常都是采用離散化的設(shè)計,需要保證兩方面的效果,一方面是記憶,另一方面是泛化。特征都是通過哈希的方式做成 one hot 的離散化。對于頭部用戶需要有精細刻畫,準(zhǔn)確記憶。而對于占比更大的稀疏長尾,則需要很好地泛化。另外,對于用戶的點擊以及消費決策序列,session 是非常重要的。
模型設(shè)計需要平衡很大的頭部,使整個數(shù)據(jù)呈現(xiàn)出 Beta distribution 的分布,需要平衡頭部的準(zhǔn)確以及長尾的泛化。由于特征設(shè)計已經(jīng)做了這方面的考量,模型的設(shè)計也需要同時兼顧泛化以及準(zhǔn)確。百度整個的推薦漏斗對性能要求是非常極致的,所以要考慮到架構(gòu)跟策略的聯(lián)合設(shè)計,需要考慮性能與效果的折中,另外也需要考慮平衡模型的高吞吐性以及精度。
架構(gòu)的設(shè)計也要從性能和效果這兩個維度來綜合考量。一個模型算不動所有數(shù)千萬的資源庫,所以必須要做分層的設(shè)計,核心思想是分治法。當(dāng)然各層之間是有關(guān)聯(lián)的,所以會做多階段的聯(lián)訓(xùn),來提升多階段漏斗之間的效率。另外,還有彈性計算法,保證在資源幾乎不變的情況下,上線非常復(fù)雜的模型。
上圖中右側(cè)的漢諾塔項目,在粗排這一層非常巧妙地實現(xiàn)了用戶與資源的分離建模。還有 CTR3.0 聯(lián)合訓(xùn)練,實現(xiàn)了多層多階段的聯(lián)訓(xùn),比如精排,是整個系統(tǒng)中最復(fù)雜、最精致的模型,精度是相當(dāng)高的,重排是在精排之上做 list wise 的建模,精排跟重排的關(guān)系是很緊密的,我們提出的基于這兩個模型聯(lián)訓(xùn)的方式,取得了非常好的線上效果。
接下來,將分別從特征、算法和架構(gòu)三個角度進一步展開介紹。
二、特征
1、用戶-系統(tǒng)交互決策過程
特征描述了用戶與系統(tǒng)之間的交互決策過程。
下圖中展示了用戶-資源-場景-狀態(tài)時空關(guān)系交互矩陣圖。
首先將所有信號切分為用戶、資源、場景和狀態(tài)這四個維度,因為本質(zhì)上是要建模用戶與資源之間的關(guān)系。在每個維度上,可以做各種各樣的畫像數(shù)據(jù)。
用戶維度上,最基礎(chǔ)的年齡、性別、興趣點畫像。在此基礎(chǔ)上還會有一些細粒度的特征,比如相似用戶,以及用戶歷史上對不同資源類型的偏好行為等。session 特征,主要是長短期行為序列。業(yè)界有很多做序列的模型,在此不作贅述。但無論做何種類型的序列模型,都缺少不了特征層面的離散 session 特征。在百度的搜索廣告上,從 10 多年前就已經(jīng)引入了這一種細粒度的序列特征,對用戶在不同的時間窗口上,對不同資源類型的點擊行為、消費行為等等都細致地刻畫了多組序列特征。
資源維度上,也會有 ID 類特征來記錄資源本身的情況,主導(dǎo)的是記憶。還有明文畫像特征來實現(xiàn)基礎(chǔ)的泛化能力。除了粗粒度的特征以外,也會有更為細致的資源特征,比如 Embedding 畫像特征,是基于多模態(tài)等預(yù)訓(xùn)練模型產(chǎn)出的,更細致地建模離散 embedding 空間中資源之間的關(guān)系。還有統(tǒng)計畫像類的特征,描述資源各種情況下的后驗如何。以及 lookalike 特征,通過用戶來反向表征資源進而提升精度。
在場景維度上,有單列、沉浸式、雙列等不同的場景特征。
用戶在不同的狀態(tài)下,對于 feed 信息的消費也是不同的。比如刷新狀態(tài)是如何的,是從什么樣的網(wǎng)絡(luò)過來的,以及落地頁上的交互形態(tài)是怎樣的,都會影響到用戶未來的決策,所以也會從狀態(tài)維度來描述特征。
通過用戶、資源、狀態(tài)、場景四個維度,全面刻畫用戶與系統(tǒng)交互的決策過程。很多時候也會做多個維度之間的組合。
2、離散特征設(shè)計原理
接下來介紹離散特征設(shè)計原理。
優(yōu)質(zhì)的特征通常具有三個特點:區(qū)分度高、覆蓋率高、魯棒性強。
- 區(qū)分度高:加入特征后,后驗有著很大差異。比如加入 a 特征的樣本,后驗點擊率跟沒有命中 a 特征的后驗點擊率差距是非常大的。
- 覆蓋率高:如果加入的特征在整個樣本中的覆蓋率只有萬分之幾、十萬分之幾,那么即使特征很有區(qū)分度,但大概率也是沒有效果的。
- 魯棒性強:特征本身的分布要是相對穩(wěn)定的,不能隨著時間發(fā)生非常劇烈的變化。
除了上述三個標(biāo)準(zhǔn),還可以做單特征的 AUC 判斷。比如只用某一特征來訓(xùn)練模型,看特征跟目標(biāo)之間的關(guān)系。也可以去掉某特征,看少了特征之后的 AUC 變化情況。
基于上述設(shè)計原則,我們來重點討論三類重要特征:即交叉、偏置和序列特征。
- 交叉特征方面,業(yè)界有數(shù)百篇的相關(guān)工作,實踐中發(fā)現(xiàn)無論任何類型的隱式特征交叉都無法完全替代顯示特征交叉,也不可能把所有的交叉特征全部刪掉,只用隱式表征來做。顯示特征交叉能夠刻畫出隱式特征交叉所無法表達的相關(guān)信息。當(dāng)然如果做得更深,可以用 AutoML 來進行自動搜索可能的特征組合空間。因此在實踐中,以顯式特征交叉為主,隱式特征交叉為輔的方式來做特征之間的 cross。
- 偏置類特征指的是,用戶的點擊不等于用戶滿意,因為資源的展示有各種各樣的偏置,比如最普遍的就是 position bias,展現(xiàn)在頭部的資源天然更容易被點擊。還有 system bias,系統(tǒng)優(yōu)先展現(xiàn)出認為最優(yōu)的,但不一定是真的最優(yōu),比如新發(fā)布的資源,可能會因為缺少后驗信息而處于劣勢。
對于偏置特征有一個很經(jīng)典的結(jié)構(gòu),就是谷歌提出的 Wide&Deep 結(jié)構(gòu),Wide 側(cè)通常會放各種偏置的特征,線上直接可以裁剪掉,通過這種偏序排序的方式來達到無偏估計的效果。 - 最后是序列特征,是非常重要的一類用戶個性化特征。業(yè)界現(xiàn)在主流的都是做超長序列的建模,具體的實驗中會發(fā)現(xiàn),通常長序列的存儲開銷是非常大的。前文中提到我們要達到性能與效果的折中。長序列可以通過離線預(yù)計算好,短序列可以在線實時計算,所以我們往往會結(jié)合兩種方式。通過門控網(wǎng)絡(luò)來決策用戶當(dāng)前更偏向于短序列還是長序列的方式,來 balance 長期興趣以及短期興趣。同時需要注意,隨著序列拉長其邊際收益是遞減的。
3、推薦漏斗最優(yōu)化的特征體系
整個推薦漏斗是分層設(shè)計的,每一層都做了過濾與截斷。如何在過濾截斷的分層設(shè)計中達到效率最高呢?前面也提到會做模型的聯(lián)合訓(xùn)練。另外,特征設(shè)計的維度上也可以做相關(guān)的設(shè)計。這里也存在一些問題:
- 首先,為了提升漏斗通過率,召回和粗排直接擬合精排打分或者精排序,會導(dǎo)致馬太效應(yīng)進一步加強,此時,召回/粗排模型并非用戶行為驅(qū)動學(xué)習(xí)過程,而是擬合漏斗。這不是我們希望看到的結(jié)果。正確的做法是推薦漏斗各層模型解耦合設(shè)計,而不是直接擬合下層的漏斗。
- 第二是粗排方面,理論上與召回靠得更近,本質(zhì)上相當(dāng)于是統(tǒng)一召回的出口。所以粗排這一層,可以引入更多召回的信號,例如協(xié)同推薦的人群投票信號,圖索引的路徑等等,以便粗排能夠與召回隊列聯(lián)合優(yōu)化,使得進入精排的資源的召回效率能夠最優(yōu)化。
- 第三是計算復(fù)用,在降低計算量的同時又能夠提升模型的魯棒性。此處要注意的是,常有級聯(lián)類的模型,第二級模型使用第一級模型的打分作為特征,這種做法的風(fēng)險很大,因為模型最終的預(yù)估值是不穩(wěn)定的分布,如果直接使用第一級模型的預(yù)估值當(dāng)做特征,會使得下層模型有非常嚴重的耦合,造成系統(tǒng)的不穩(wěn)定。
三、算法
接下來介紹核心算法的設(shè)計。
1、系統(tǒng)視角下的排序模型
首先來看推薦排序模型。一般認為,精排是推薦系統(tǒng)中精度最高的模型。業(yè)界有一種觀點認為粗排附屬于精排,對著精排學(xué)就可以了,但具體實踐中發(fā)現(xiàn)粗排并不能直接對著精排來學(xué),可能會帶來很多問題。
從上圖可以看出,粗排與精排的定位不同。一般來說,粗排的訓(xùn)練樣本與精排一樣,也是展現(xiàn)樣本。每次召回候選供粗排打分的結(jié)果有數(shù)萬條之多,這里面 99% 以上的資源是沒有被展現(xiàn)的,而模型僅使用最終展現(xiàn)的十幾條資源來做訓(xùn)練,這就打破了獨立同分布的假設(shè),在離線模型分布差異極大。這種情況在召回是最為嚴重的,因為召回的候選集都是數(shù)百萬、數(shù)千萬甚至數(shù)億,最終返回的結(jié)果大多數(shù)也都是沒有被展現(xiàn)的,粗排一樣相對也比較嚴重,因為候選集通常也在數(shù)萬級別。而精排就相對好很多,通過了召回與粗排兩層漏斗后,資源的基礎(chǔ)質(zhì)量是有保證的,它主要做優(yōu)中選優(yōu)的工作。因此,精排在離線分布不一致問題不是那么嚴重,不需要過多地考慮樣本選擇偏差(SSB)的問題,同時由于候選集合小,可以做重計算,精排重點在于特征交叉,序列建模等。
但是粗排這一層,并不能直接對著精排學(xué),也不能直接做類似于精排的重計算,因為其計算量是精排的數(shù)十倍,如果直接用精排的設(shè)計思路,線上的機器是完全不可承受的,所以粗排需要高度的技巧平衡性能與效果,它是一個輕量級模塊。粗排迭代的重點與精排不同,主要解決樣本選擇偏差,召回隊列優(yōu)化等問題。由于粗排與召回關(guān)系緊密,更關(guān)注的是返回精排的數(shù)千資源的平均質(zhì)量,而不是精確的排序關(guān)系。精排則是與重排關(guān)系更緊密,更關(guān)注的是單點的 AUC 精度。
因此在粗排的設(shè)計上,更多的是做樣本的選擇與生成,和泛化特征與網(wǎng)絡(luò)的設(shè)計。而精排的設(shè)計可以做復(fù)雜的多階交叉特征、超長序列建模等等。
2、超大規(guī)模離散 DNN 的泛化
前面介紹的是宏觀層面的,下面來看一下微觀層面。
具體到模型的訓(xùn)練過程,目前業(yè)界主流的是使用超大規(guī)模的離散 DNN,泛化問題會是比較嚴重的。因為超大規(guī)模離散 DNN,通過 embedding 層,主要做的是記憶的功能。參見上圖,整個 embedding 空間是非常龐大的矩陣,通常都是千億或者萬億行,1000 列。所以模型訓(xùn)練都是全分布式,數(shù)十乃至上百臺 GPU 做分布式訓(xùn)練。
理論上,對于這么大的矩陣,并不會直接做暴力計算,而是采用類似矩陣分解的操作。當(dāng)然這個矩陣分解和標(biāo)準(zhǔn)的 SVD 矩陣分解并不一樣,這里的矩陣分解是先學(xué)到低維的表征,通過 slot 之間的 parameter 的 share 來降低計算跟存儲量,也就是分解成兩個矩陣的 learning 的過程。首先是特征、表征矩陣,會學(xué)習(xí)特征跟低維嵌入的關(guān)系,這個嵌入很低,通常會選擇十維左右的嵌入。另外一個是嵌入和神經(jīng)元矩陣,每個槽位之間的權(quán)重是共享的。通過這種方式既降低了存儲量,又能夠提升效果。
低維的嵌入學(xué)習(xí)是離線 DNN 優(yōu)化泛化能力的關(guān)鍵,它等價于做稀疏矩陣分解,因此,整個模型泛化能力提升的關(guān)鍵就在于如何使得參數(shù)規(guī)模與樣本數(shù)能夠更好地匹配。
從多個方面來進行優(yōu)化:
- 首先是從嵌入維度方面,因為不同特征的展現(xiàn)量差異是很大的,有些特征的展現(xiàn)量非常高,比如頭部的資源、頭部的用戶,可以使用更長的嵌入維度,這就是常見的動態(tài)嵌入維度的思想,即展現(xiàn)越充分嵌入維度越長。當(dāng)然如果要做得更 fancy,可以用 autoML 等方式做強化學(xué)習(xí),自動搜索最優(yōu)嵌入長度。
- 第二個方面是創(chuàng)建閾值,由于不同資源展現(xiàn)量不同,因此,何時為特征創(chuàng)建嵌入表征也是需要考量的。
3、過擬合問題
業(yè)界通常是采用兩階段訓(xùn)練抗過擬合的方式。整個模型由兩層組成,一個是很大的離散矩陣層,另一個是很小的稠密參數(shù)層。離散矩陣層是非常容易過擬合的,所以業(yè)界實踐通常都是采用 One Pass Training,即 online learning,所有的數(shù)據(jù)都過一遍,并不會像學(xué)術(shù)界一樣的做 batch training。
另外,業(yè)界通常會利用時序 Validation Set 來解決稀疏層的 overfitting 問題。把整個訓(xùn)練數(shù)據(jù)集按時間維度切分成很多個 Delta,T0,T1,T2,T3 不同的 Delta。每次訓(xùn)練是用前幾小時訓(xùn)練好的離散參數(shù)層固定住,再用下一個 Delta 的數(shù)據(jù) finetune dense 網(wǎng)絡(luò)。也就是通過固定稀疏層、重訓(xùn)其它參數(shù)的方式來緩解模型的過擬和問題。
這種做法也會帶來另外一個問題,因為訓(xùn)練是切分開的,并且每次都需要固定 T0 時刻的離散參數(shù),再用 t+1 時刻重訓(xùn) join 階段,這樣會拖累整個訓(xùn)練速度,帶來擴展性方面的挑戰(zhàn)。所以近年來都是采用單階段訓(xùn)練,即將離散表征層與稠密網(wǎng)絡(luò)層在一個 Delta 中同時更新。而單階段訓(xùn)練也存在一個問題,因為整個模型除了 embedding 特征之外,還有很多連續(xù)值特征,這些連續(xù)值特征會統(tǒng)計每個離散特征的展現(xiàn)點擊情況,因此,可能帶來數(shù)據(jù)穿越的風(fēng)險。所以在具體實踐時,第一步會先除掉統(tǒng)計量的特征,第二步使得稠密網(wǎng)絡(luò)與離散表征一起訓(xùn)練,使用單階段的方式訓(xùn)練。另外整個嵌入的長度,都是自動可伸縮的方式。通過這一系列方法,可以使得模型訓(xùn)練提速 30% 左右。實踐表明,該方法過擬合程度很輕微,訓(xùn)練跟測試的 AUC 的差距也都是 1/ 1000 或者更低的程度。
四、架構(gòu)
接下來介紹架構(gòu)設(shè)計上的思考和經(jīng)驗。
1、系統(tǒng)分層設(shè)計原理
系統(tǒng)設(shè)計的核心原則是分治法。召回需要有多個通道,核心的目標(biāo)是要提升召回率,以及召回資源的豐富程度。同時召回也要考慮探索跟利用的問題,是推薦效果的基礎(chǔ)保證。粗排做第一層的過濾,主要做輕量級點預(yù)估,承上啟下。精排通常是做重計算,也是做點預(yù)估,跟重排之間的關(guān)系非常緊密,通常會使用非常復(fù)雜的結(jié)構(gòu),也是業(yè)界研究的重點。重排是最后一層,重排是具體面對用戶的,決定了最終的展現(xiàn)序列,基于精排的結(jié)果考慮上下文然后來做復(fù)雜的序列預(yù)估,即 list wise 的排序。重排序需要考慮很多業(yè)務(wù)的約束,里面有很多規(guī)則,包括打散、LCN、退場等等,是規(guī)則與模型雙重驅(qū)動的模塊。
推薦系統(tǒng)各層的目標(biāo)基本一致,但是各層側(cè)重不太一樣。召回和粗排側(cè)重的是泛化以及召回率,精排側(cè)重的是單點 AUC 的精度,重排側(cè)重的是整體序列最優(yōu)。從數(shù)據(jù)上來看,越靠近召回粗排,越泛化,越靠近精排重排,越要求精度。越靠近召回源,性能受限越嚴重,因為候選資源越多計算量越大。粗排只需要對齊精排是一個誤區(qū),粗排需要考慮與精排的一致性,但是并不能只對齊精排。如果粗排什么都不做,只是做對齊精排,會帶來非常嚴重的馬太效應(yīng)。因為精排不是 ground truth,用戶的行為才是,需要學(xué)習(xí)好用戶行為,而不是學(xué)習(xí)精排,這是很重要的一點提示。
2、多階段模型聯(lián)合訓(xùn)練
精排跟重排之間的關(guān)系是非常緊密的,早年重排是直接用精排的打分來做訓(xùn)練的,一方面耦合很嚴重,另一方面直接使用精排打分來做訓(xùn)練,很容易產(chǎn)生線上的波動。
百度鳳巢 CTR 3.0 精排跟重排聯(lián)合訓(xùn)練項目,就非常巧妙地利用模型同時訓(xùn)練避免打分耦合的問題。該項目將精排子網(wǎng)絡(luò)的隱層及內(nèi)部打分,都作為重排子網(wǎng)絡(luò)的特征,然后,將精排與重排子網(wǎng)絡(luò)拆開,分別部署于各自模塊。一方面可以很好地復(fù)用中間結(jié)果,不會出現(xiàn)打分耦合帶來的波動問題,同時對于重排的精度又會有百分位的提升。這也是當(dāng)年百度最高獎的子項目之一。
另外,注意該項目并不是 ESSM,ESSM 是 CTCVR 建模,是多目標(biāo)建模,而 CTR3.0 聯(lián)合訓(xùn)練主要解決打分耦合和重排模型精度的問題。
此外,要對召回和粗排做解耦合,因為新隊列加入進來,對于新隊列可能會不太公平。因此,提出了隨機掩碼的方式,即隨機 mask 掉一部分特征,使得耦合度不會那么強。
3、稀疏路由網(wǎng)絡(luò)
最后再來看一下部署在線上的過程。模型參數(shù)規(guī)模都是千億到萬億量級,目標(biāo)也非常多,直接進行線上部署開銷是非常大的,不能只考慮效果,不考慮性能。有一種比較好的方式就是彈性計算,類似于 Sparse MOE 的思想。
粗排接入了非常多的隊列,有數(shù)十個甚至數(shù)百個隊列。這些隊列對線上的價值(LTV)是不一樣的,由流量價值層來計算不同召回隊列對線上點擊時長的價值。其核心思想是召回隊列整體的貢獻度越大,越可以享受更復(fù)雜的計算。從而使得有限的算力能夠服務(wù)于更高價值的流量。所以我們也沒有采用傳統(tǒng)的蒸餾的方式,而是采用類似 Sparse MOE 的思想來做彈性計算,即策略跟架構(gòu) co-design 的設(shè)計,使得不同的召回隊列能夠使用最適合的資源網(wǎng)絡(luò)進行計算。
五、未來計劃
眾所周知,現(xiàn)在已經(jīng)進入 LLM 大模型時代。百度對下一代基于 LLM 大語言模型的推薦系統(tǒng)的探索將會從三個方面來展開。
第一方面是希望模型從基礎(chǔ)的預(yù)測升級到能夠做決策。比如經(jīng)典的冷啟資源高效率探索,沉浸式序列推薦反饋,以及從搜索到推薦的決策鏈等等重要的問題,都可以借助大模型來進行決策。
第二方面是從判別到生成,現(xiàn)在整個模型都是判別式的,未來會探索生成式推薦的方式,比如自動生成推薦理由,對長尾數(shù)據(jù)基于 prompt 來做數(shù)據(jù)自動增強,以及生成式的檢索模型。
第三方面是從黑盒到白盒,傳統(tǒng)做推薦系統(tǒng),大家常說神經(jīng)網(wǎng)絡(luò)是煉丹術(shù),是黑盒的,是否有可能向白盒化方向探索,也是未來的重要工作之一。比如基于因果,探究用戶行為狀態(tài)遷移背后的原因,推薦公平性方面做更好的無偏估計,以及 Multi Task Machine Learning 的場景上能夠做更好的場景自適應(yīng)。