知識蒸餾在推薦系統中的應用

導讀:隨着深度學習的快速發展,優秀的模型層出不窮,比如圖像領域的 ResNet、自然語言處理領域的 Bert,這些革命性的新技術使得應用效果快速提升。但是,好的模型性能並非無代價的,你會發現,深度學習模型正在變得越來越複雜,網絡深度越來越深,模型參數量也在變得越來越多。而這會帶來一個現實應用的問題:將這種複雜模型推上線,模型響應速度太慢,當流量大的時候撐不住。

知識蒸餾就是目前一種比較流行的解決此類問題的技術方向。一般知識蒸餾採取 Teacher-Student 模式:將複雜模型作爲 Teacher,Student 模型結構較爲簡單,用 Teacher 來輔助 Student 模型的訓練,Teacher 學習能力強,可以將它學到的暗知識 ( Dark Knowledge ) 遷移給學習能力相對弱的 Student 模型,以此來增強 Student 模型的泛化能力。複雜笨重但是效果好的 Teacher 模型不上線,就單純是個導師角色,真正上戰場擋搶撐流量的是靈活輕巧的 Student 小模型。比如 Bert,因爲太重,很難直接上線跑,目前很多公司都是採取知識蒸餾的方法,學會一個輕巧,但是因爲被 Teacher 教導過,所以效果也很好的 Student 模型部署上線。

01

知識蒸餾典型方法

目前知識蒸餾已經成了獨立研究方向,各種新技術層出不窮。但是如果粗略歸納一下的話,主流的知識蒸餾技術有兩個技術發展主線:Logits 方法及特徵蒸餾方法。

我們先簡單說明下 Logits 方法的思路。在介紹之前,首先得明白什麼是 Logits。我們知道,對於一般的分類問題,比如圖片分類,輸入一張圖片後,經過 DNN 網絡各種非線性變換,在網絡接近最後一層,會得到這張圖片屬於各個類別的大小數值 zi,某個類別的 zi 數值越大,則模型認爲輸入圖片屬於這個類別的可能性就越大。什麼是 Logits? 這些彙總了網絡內部各種信息後,得出的屬於各個類別的彙總分值 zi,就是 Logits,i 代表第 i 個類別,zi 代表屬於第 i 類的可能性。因爲 Logits 並非概率值,所以一般在 Logits 數值上會用 Softmax 函數進行變換,得出的概率值作爲最終分類結果概率。Softmax 一方面把 Logits 數值在各類別之間進行概率歸一,使得各個類別歸屬數值滿足概率分佈;另外一方面,它會放大 Logits 數值之間的差異,使得 Logits 得分兩極分化,Logits 得分高的得到的概率值更偏大一些,而較低的 Logits 數值,得到的概率值則更小。上圖中的公式 qi,就是一個變體的 Softmax 公式,如果把 T 拿掉或令 T=1,則是個標準的 Softmax 公式,zi 就是第 i 個類別的 Logits 數值,qi 是 Logits 數值經過 Softmax 變換後,歸屬於第 i 個類別的概率值。

知道了什麼是 Logits 後,我們來說什麼是 Logits 蒸餾方法。假設我們有一個 Teacher 網絡,一個 Student 網絡,輸入同一個數據給這兩個網絡,Teacher 會得到一個 Logits 向量,代表 Teacher 認爲輸入數據屬於各個類別的可能性;Student 也有一個 Logits 向量,代表了 Student 認爲輸入數據屬於各個類別的可能性。最簡單也是最早的知識蒸餾工作,就是讓 Student 的 Logits 去擬合 Teacher 的 Logits,即 Student 的損失函數爲:

其中,zt 是 Teacher 的 Logits,zs 是 Student 的 Logits。在這裏,Teacher 的 Logits 就是傳給 Student 的暗知識。

Hinton 在論文 Distilling the Knowledge in a Neural Network 中提出了稱爲 Softmax Temperature 的改進方法,並第一次正式提出了"知識蒸餾"的叫法。Softmax Temperature 改造了 Softmax 函數 ( 公式參考上圖 ),引入了溫度 T,這是一個超參數。如果我們把 T 設置成1,就是標準的 Softmax 函數,也就是極端兩極分化版本。如果將 T 設大,則 Softmax 之後的 Logits 數值,各個類別之間的概率分值差距會縮小,也即是強化那些非最大類別的存在感;反之,則會加大類別間概率的兩極分化。Hinton 版本的知識蒸餾,讓 Student 去擬合 Teacher 經過 T 影響後 Softmax 得到的,其實也是讓 Student 去學習 Teacher 的 Logits,無非是加入 T 後可以動態調節 Logits 的分佈。Student 的損失函數由兩項組成,一個子項是 Ground Truth,就是在訓練集上的標準交叉熵損失,讓 Student 去擬合訓練數據,另外一個是蒸餾損失,讓 Student 去擬合 Teacher 的 Logits:

H 是交叉熵損失函數,f(x) 是 Student 模型的映射函數,y 是 Ground Truth Label,zt 是 Teacher 的 Logits,zs 是 Student 的 Logits, ST() 是 Softmax Temperature 函數,λ 用於調節蒸餾 Loss 的影響程度。

一般而言,溫度 T 要設置成大於1的數值,這樣會減小不同類別歸屬概率的兩極分化程度,因爲 Logits 方法中,Teacher 能夠提供給 Student 的額外信息就包含在 Logits 數值裏。如果我們在蒸餾損失部分,將 T 設置成1,採用常規的 Softmax,也就是說兩極分化嚴重時,那麼相對標準的訓練數據,也就是交叉熵損失,兩者等同,Student 從蒸餾損失中就學不到任何額外的信息。

另外一種大的知識蒸餾思路是特徵蒸餾方法,如上圖所示。它不像 Logits 方法那樣,Student 只學習 Teacher 的 Logits 這種結果知識,而是學習 Teacher 網絡結構中的中間層特徵。最早採用這種模式的工作來自於自於論文:"FITNETS:Hints for Thin Deep Nets",它強迫 Student 某些中間層的網絡響應,要去逼近 Teacher 對應的中間層的網絡響應。這種情況下,Teacher 中間特徵層的響應,就是傳遞給 Student 的暗知識。在此之後,出了各種新方法,但是大致思路還是這個思路,本質是 Teacher 將特徵級知識遷移給 Student。因爲介紹各種知識蒸餾方法不是我們的主題,這裏不展開了,我們儘快切入主題。

02

知識蒸餾在推薦系統中的三個應用場景

我們知道,工業界常見推薦系統一般有三個級聯的過程:召回、粗排以及精排。召回環節從海量物品庫裏快速篩選部分用戶可能感興趣的物品,傳給粗排模塊,粗排環節通常採取使用少量特徵的簡單排序模型,對召回物料進行初步排序,並做截斷,進一步將物品集合縮小到合理數量,向後傳遞給精排模塊,精排環節採用利用較多特徵的複雜模型,對少量物品進行精準排序。其中,粗排環節根據具體應用可選可不選。

那麼,在這種串行級聯的推薦體系中,知識蒸餾可以應用在哪個環節呢?假設我們在召回環節採用模型排序 ( FM/FFM/DNN 雙塔等模型 ),那麼知識蒸餾在上述三個環節都可採用,不同環節採用知識蒸餾的目的可能也不太相同。也就是說,精排、粗排以及模型召回環節都可以採用知識蒸餾技術來優化現有推薦系統的性能和效果,這裏的性能指的線上服務響應速度快,效果指的推薦質量好。

1. 精排環節採用知識蒸餾

爲何在精排環節採用知識蒸餾?我們知道,精排環節注重精準排序,所以採用儘量多特徵,複雜模型,以期待獲得優質的個性化推薦結果。但是,這同時也意味着複雜模型的在線服務響應變慢。若承載相同流量,需要增加在線服務並行程度,也就意味着增加機器資源和成本,比如,DNN 排序模型相對 LR / FM 等非深度模型,在線推理速度下降明顯。此時,我們面臨兩難選擇:要麼上簡單模型,但是付出的代價是推薦效果不如複雜模型好;要麼上覆雜模型,雖說效果是提高了,但是要付出額外的機器等資源及成本。有什麼技術方案能夠在兩者之間做個均衡麼?就是說,希望找到一個模型,這個模型既有較好的推薦質量,又能有快速推理能力。我們可以實現這一目標麼?可以的,在精排環節上知識蒸餾模型即可。

上圖展示瞭如何在精排環節應用知識蒸餾:我們在離線訓練的時候,可以訓練一個複雜精排模型作爲 Teacher,一個結構較簡單的 DNN 排序模型作爲 Student。因爲 Student 結構簡單,所以模型表達能力弱,於是,我們可以在 Student 訓練的時候,除了採用常規的 Ground Truth 訓練數據外,Teacher 也輔助 Student 的訓練,將 Teacher 複雜模型學到的一些知識遷移給 Student,增強其模型表達能力,以此加強其推薦效果。在模型上線服務的時候,並不用那個大 Teacher,而是使用小的 Student 作爲線上服務精排模型,進行在線推理。因爲 Student 結構較爲簡單,所以在線推理速度會大大快於複雜模型;而因爲 Teacher 將一些知識遷移給 Student,所以經過知識蒸餾的 Student 推薦質量也比單純 Student 自己訓練質量要高。這就是典型的在精排環節採用知識蒸餾的思路。至於具體蒸餾方法,後文會介紹。當然,你也可以根據前文介紹的經典知識蒸餾方案,自己試着想想應該怎麼做。

對於精排環節來說,我覺得,知識蒸餾比較適合以下兩種技術轉換場景:

一種是排序模型正在從非 DNN 模型初次向 DNN 模型進行模型升級;在超大規模數據場景下,從非 DNN 模型切換到 DNN 模型,切換成本和付出的時間因素可能比你預想得要高,尤其是線上服務環節,切換到 DNN 模型導致大量增加在線服務機器成本,這對於很多公司來說是無法接受的。如果在做模型升級的時候採取知識蒸餾方案,導致的效果是:相對線上的非 DNN 模型,即使上一個蒸餾小模型,效果也可能是有提升的,同時在線服務佔用資源能降下來 ( 相對直接上個複雜 DNN 模型 ),在線服務速度快,所以可以明顯降低模型升級的成本,這樣可以相對容易地切換到 DNN 版本排序模型上來。

第二種情況是:目前儘管線上已經採用了 DNN 排序模型,但是模型還非常簡單,這個也有利用知識蒸餾優化效果的空間;這種情形下,現有在線模型的服務速度可能是足夠快的,因爲在線服務模型還比較簡單,即使換成 Student 小模型,在這方面估計也差不太多。但是,可以期待通過知識蒸餾提升線上模型的推薦質量。我們可以離線訓練一個複雜但是效果明顯優於線上簡單 DNN 排序模塊的模型作爲 Teacher,然後通過知識蒸餾,訓練一個可以代替目前線上模型的 Student 小模型。如果這樣,是有可能在響應速度不降的前提下,模型效果上有所提升的。所以,感覺這種情況也比較適合採用蒸餾模型。

而對於其它情形,比如目前線上已有較爲複雜的 DNN 排序系統的業務或者公司,至於是否要上知識蒸餾,則需要面臨一個權衡:採用知識蒸餾,線上服務模型從複雜模型切換成小模型,肯定可以明顯提高線上 QPS,減少服務資源,效率提升會比較大;但是,有可能推薦質量比線上的大模型會有下降。所以,業務場景是否接受這種指標的臨時下降?這個問題的答案決定了不同的選擇,在有些業務場景下,這是需要好好考慮考慮的。不同業務環境可能會作出不同的選擇。

2. 模型召回以及粗排採用知識蒸餾

在模型召回環節,或者粗排環節,採取知識蒸餾的方案,是非常自然的一個想法拓展,而且非常合算。目前,這塊基本看不到完全公開細節的技術資料,所以本文我重點談談在這塊可能採用的技術,和幾位同學討論出若干可能的方案會列在後面,感興趣的同學可以嘗試一下,在這裏是很容易作出收益的,所以特別值得關注與嘗試,相信這塊用好了,會對完成你的KPI有幫助。

這裏所謂的合算,怎麼理解呢?因爲召回或者粗排環節,作爲精排的前置環節,有自己承擔的獨特職責,需要在準確性和速度方面找到一個平衡點,在保證一定推薦精準性的前提下,對物品進行粗篩,減小精排環節壓力。所以,這兩個環節本身,從其定位來說,並不追求最高的推薦精度,就算模型效果比精排差些,這也完全不成問題,畢竟在這兩個環節,如果準確性不足可以靠返回物品數量多來彌補。而模型小,速度快則是模型召回及粗排的重要目標之一。這就和知識蒸餾本身的特點對上了,所以在這裏用是特別合算的。

那麼,召回或者粗排怎麼用蒸餾呢?如果我們如上圖所示,用複雜的精排模型作爲 Teacher,召回或粗排模型作爲小的 Student,比如 FM 或者雙塔 DNN 模型等,Student 模型模擬精排環節的排序結果,以此來指導召回或粗排 Student 模型的優化過程。這樣,我們可以獲得滿足如下特性的召回或者粗排模型:首先,推薦效果好,因爲 Student 經過複雜精排模型的知識蒸餾,所以效果雖然弱於,但是可以非常接近於精排模型效果;其次,Student 模型結構簡單,所以速度快,滿足這兩個環節對於速度的要求;再次,通過 Student 模型模擬精排模型的排序結果,可以使得前置兩個環節的優化目標和推薦任務的最終優化目標保持一致,在推薦系統中,前兩個環節優化目標保持和精排優化目標一致,其實是很重要的,但是這點往往在實做中容易被忽略,或者因條件所限無法考慮這一因素,比如非模型召回,從機制上是沒辦法考慮這點的。這裏需要注意的一點是:如果召回模型或者粗排模型的優化目標已經是多目標的,對於新增的模型蒸餾來說,可以作爲多目標任務中新加入的一個新目標,當然,也可以只保留單獨的蒸餾模型,完全替換掉之前的多目標模型,貌似這兩種思路應該都是可以的,需要根據具體情況進行斟酌選擇。

由以上分析,可見,召回或粗排環節的知識蒸餾方案,看上去貌似是爲召回和粗排環節量身定製的推薦系統優化技術選項,對於召回或者粗排優化來說,應該是必試的一個技術選項。

下面我們討論下在推薦系統裏,在各個環節採用知識蒸餾的可能的具體方法。精排蒸餾有兩篇公開文獻可供參考,而召回或粗排方面的蒸餾技術,很少見相關公開資料,所以後面列的多數是我和幾位同學討論的方案,除個別方法有實踐結果外,大多方法仍處於設想階段,目前並未落地,所以不能保證有效性,這點還需要注意。

03

精排環節蒸餾方法

目前推薦領域裏,在精排環節採用知識蒸餾,主要採用 Teacher 和 Student 聯合訓練 ( Joint Learning ) 的方法,而目的是通過複雜 Teacher 來輔導小 Student 模型的訓練,將 Student 推上線,增快模型響應速度。

如上圖所示,所謂聯合訓練,指的是在離線訓練 Student 模型的時候,增加複雜 Teacher 模型來輔助 Student,兩者同時進行訓練,是一種訓練過程中的輔導。從網絡結構來說,Teacher 和 Student 模型共享底層特徵 Embedding 層,Teacher 網絡具有層深更深、神經元更多的 MLP 隱層,而 Student 則由較少層深及神經元個數的 MLP 隱層構成,兩者的 MLP 部分參數各自私有。對於所有訓練數據,會同時訓練 Teacher 和 Student 網絡,對於 Teacher 網絡來說,就是常規的訓練過程,以交叉熵作爲 Teacher 的損失函數。而對於 Student 網絡來說,損失函數由兩個部分構成,一個子項是交叉熵,這是常規的損失函數,它促使 Student 網絡去擬合訓練數據;另外一個子項則迫使 Student 輸出的 Logits 去擬合 Teacher 輸出的 Logits,所謂蒸餾,就體現在這個損失函數子項,通過這種手段讓 Teacher 網絡增強 Student 網絡的模型泛化能力。也即:

H 是交叉熵損失函數,f(x) 是 Student 模型的映射函數,y 是 Ground Truth Label,zt 是 Teacher 的 Logits,zs 是 Student 的 Logits,λ 用於調節蒸餾 Loss 的影響程度。

這個模型是阿里媽媽在論文 "Rocket Launching: A Universal and Efficient Framework for Training Well-performing Light Net" 中提出的,其要點有三:其一兩個模型同時訓練;其二,Teacher 和 Student 共享特徵 Embedding;其三,通過 Logits 進行知識蒸餾。對細節部分感興趣的同學可以參考原始文獻。

愛奇藝在排序階段提出了雙 DNN 排序模型,可以看作是在阿里的 rocket launching 模型基礎上的進一步改進。如上圖所示,Student 和 Teacher 共享特徵 Embedding 參數層,Student 模型在損失函數中加入了擬合 Teacher 輸出階段的 Logits 子項,這兩點和 rocket launching 是類似的。主要改進有兩點:首先,爲了進一步增強 student 的泛化能力,要求 student 的隱層 MLP 的激活也要學習 Teacher 對應隱層的響應,這點同樣可以通過在 student 的損失函數中加子項來實現。但是這會帶來一個問題,就是在 MLP 隱層複雜度方面,Student 和 Teacher 是相當的,我們說過,一般知識蒸餾,老師要比學生博學,那麼,在這個結構裏,Teacher 相比 student,模型複雜在哪裏呢?這引出了第二點不同:雙 DNN 排序模型的 Teacher 在特徵 Embedding 層和 MLP 層之間,可以比較靈活加入各種不同方法的特徵組合功能,通過這種方式,體現 Teacher 模型的較強的模型表達和泛化能力。

愛奇藝給出的數據對比說明了,這種模式學會的 Student 模型,線上推理速度是 Teacher 模型的5倍,模型大小也縮小了2倍。Student 模型的推薦效果也比 rocket launching 更接近 Teacher 的效果,這說明改進的兩點對於 Teacher 傳授給 Student 更強的知識起到了積極作用。更多信息可參考:

雙 DNN 排序模型:在線知識蒸餾在愛奇藝推薦的實踐

04

召回/粗排環節蒸餾方法

上面介紹了阿里和愛奇藝在精排方面的兩個知識蒸餾應用工作,目前知識蒸餾應用在推薦領域的公開資料很少,雖說上面兩個工作是應用在精排,目的是加快線上模型推理速度,但是稍微改進一下,也可以應用在召回模型以及粗排模型。

假設我們打算使用上述方案改造召回或者粗排模型,一種直觀的想法是:我們基本可以直接參照 rocket launching 的方案稍作改動即可。對於粗排或者召回模型來說,一般大家會用 DNN 雙塔模型建模,只需要將粗排或召回模型作爲 Student,精排模型作爲 Teacher,兩者聯合訓練,要求 Student 學習 Teacher 的 Logits,同時採取特徵 Embedding 共享。如此這般,就可以讓召回或粗排模型學習精排模型的排序結果。快手曾經在 AICon 分享過在粗排環節採取上面接近 rocket launching 的蒸餾技術方案,並取得了效果。

因雙塔結構將用戶側和物品側特徵分離編碼,所以類似愛奇藝技術方案的要求 Student 隱層學習 Teacher 隱層響應,是很難做到的。粗排尚有可能,設計簡單網絡 DNN 結構的時候不採取雙塔結構即可,召回環節幾無可能,除非把精排模型也改成雙塔結構,可能才能實現這點,但這樣可能會影響精排模型的效果。

但是,問題是:我們有必要這麼興師動衆,爲了訓練召回或粗排的蒸餾模型,去聯合訓練精排模型麼?貌似如果這樣,召回模型對於排序模型耦合得過於緊密了,也有一定的資源浪費。其實我們未必一定要兩者聯合訓練,也可以採取更節省成本的兩階段方法。

1. 召回蒸餾的兩階段方法

在專門的知識蒸餾研究領域裏,蒸餾過程大都採取兩階段的模式,就是說第一階段先訓練好 Teacher 模型,第二階段是訓練 Student 的過程,在 Student 訓練過程中會使用訓練好 Teacher 提供額外的 Logits 等信息,輔助 Student 的訓練。

私以爲,精排環節貌似還是聯合訓練比較好,而召回或粗排環節採取兩階段模式估計更有優勢。爲什麼這麼說呢?你可以這麼想:如果我們的目的是希望訓練一個小的 Student 精排模型,貌似沒有太大的必要採取兩階段訓練過程,因爲無論是聯合訓練也好,還是兩階段訓練也好,反正一大一小兩個模型都需要完整訓練一遍,消耗的資源類似。而如果聯合訓練,則還可以應用特徵 embedding 共享、隱層響應學習等更多可選的技術改進方案。所以貌似沒有太大必要改成兩階段的模式。

但是,如果是召回模型或粗排模型作爲 Student,則情況有所不同。首先,比如隱層響應等技術手段,本來召回或粗排 Student 模型就無法使用 ( 粗排如果不用雙塔,而是簡單 DNN 模型,還是可以的 ),所以聯合訓練相對兩階段訓練增加的好處不明顯。至於 Student 和 Teacher 特徵 Embedding 共享,如果是在兩階段模式下,則可以改爲使用 Teacher 訓練好的特徵 Embedding 初始化 Student 的特徵,這樣貌似損失也不大,所以兩階段模式相對聯合訓練模式,在效果方面並無明顯劣勢。另外,因爲我們希望召回或者粗排模型學習精排模型,而一般而言,我們能夠拿到一個已經訓練好的精排模型,比如最近上線的精排模型,既然這樣,我們可以直接用當前已訓練好的精排模型,讓它把用於召回模型的訓練數據跑一遍,給每個訓練數據打上Logits信息,然後,就可以按照與聯合訓練完全一樣的方式去訓練召回蒸餾模型了,優化目標是 Ground Truth 子目標和 Logits 蒸餾子目標。上圖展示了這一過程。這樣做,明顯我們節省了精排 Teacher 的聯合訓練迭代成本。不過,這種方法是否有效不確定,感興趣的同學可以嘗試一下,不過推論起來應該是能保證效果的。

上面的方法,還是模仿精排蒸餾方式,無非改成了相對節省資源的兩階段模式。這裏我們關心另外一個問題:對於召回蒸餾 Student 模型來說,是否一定要優化那個 Ground Truth 子目標?這可能要分情況看。按理說,蒸餾模型帶上 Ground Truth 優化目標肯定效果要好於不帶這個子目標的模型。如果我們的召回模型或者粗排模型是單目標的,比如就優化點擊,那麼明顯還是應該帶上 Ground Truth 優化目標。但是,事實上,很可能我們手上的召回模型或粗排模型已經是多目標的了,那麼這種情況下,其實蒸餾 Student 模型就沒有太大必要帶 Ground Truth 優化目標,因爲多目標已經各自做了這個事情了。這種情況下,獨立優化蒸餾目標,然後將其作爲多目標的一個新目標加入召回或粗排模型比較合適。

所以,我們下面介紹的方案,就拋掉 Ground Truth 優化目標,單獨優化蒸餾目標。如果根據蒸餾 Student 模型是否需要參考 Teacher 提供的 Logits 信息來對方法進行分類,又可以進一步劃分爲參考 Logits 信息的方案,和不參考 Logits 信息的方案。按理說,參考 Logits 信息效果應該好些,但是,這樣 Student 仍然對 Teacher 有依賴,而不參考 Logits 信息的方案比較獨立,基本不需要精排模型的直接介入,所需信息直接可以在常規的推薦系統 Log 裏拿到,實現起來更具簡單和獨立性。而且,如果精排模型已經是多目標的,可能很難獲得那個 Logits 數值,但是我們能夠拿到精排模塊的排序結果,這意味着 Student 在優化蒸餾目標的時候,就已經朝着多目標進行優化了,是一種在召回或粗排進行非精細化多目標方向優化的一種簡潔手段,所以有額外的好處。如果出於上述目的,此時明顯用非 Logits 方案更從容。綜合而言,從效果考慮,應該考慮引入 Logits,從獨立性和簡潔性角度,可以參考非 Logits 方案。這可能與現實場景相關。

2. Logits 方案

在召回或者精排採用知識蒸餾,此時,精排模型其實身兼二職:主業是做好線上的精準排序,副業是順手可以教導一下召回及粗排模型。所以,其實我們爲了讓 Teacher 能夠教導 Student,在訓練 Student 的時候,並不需要專門訓練一遍 Teacher 精排模型,因爲它就在線上跑着呢。而且我們拋開了 Ground Truth 優化子目標,所以不需要 Teacher 對訓練數據都過一遍,而只需要多做一件事情:線上精排模型在輸出排序結果的時候,對於當前判斷 <User,Item,Context> 實例,除了給出是否點擊等判斷外,只要把對應優化目標的 Logits 數值輸出,並計入 Log 即可。這樣,召回或粗排模型可以直接使用訓練數據中記載的 Logits,來作爲 Student 的訓練數據,訓練蒸餾模型,上圖展示了這一過程。所以,綜合看,這種 Logits 方案,是更節省計算資源的方案。當然,上述都是我的個人推論,實際效果如何,還需要做對比實驗才能說明問題。

3. Without-Logits 方案

另外一類方法可以進一步減少 Student 對 Teacher 的依賴,或適用於無法得到合理 Logits 信息的場合,即 Student 完全不參考 Logits 信息,但是精排作爲 Teacher,怎麼教導 Student 呢?別忘了,精排模型的輸出結果是有序的,這裏面也蘊含了 Teacher 的潛在知識,我們可以利用這個數據。也就是說,我們可以讓 Student 模型完全擬合精排模型的排序結果,以此學習精排的排序偏好。我們知道,對於每次用戶請求,推薦系統經過幾個環節,通過精排輸出 Top K 的 Item 作爲推薦結果,這個推薦結果是有序的,排在越靠前的結果,應該是精排系統認爲用戶越會點擊的物品。

那麼,我們其實可以不用 Logits,粗排或者召回環節的 Student 的學習目標是:像精排模型一樣排序。這時,精排模型仍然是 Teacher,只是傳給召回或粗排模型的知識不再是 Logits,而是一個有序的列表排序結果,我們希望 Student 從這個排序結果裏面獲取額外的知識。如果這樣的話,對於目前的線上推薦系統,不需要做任何額外的工作,因爲排序結果是會記在 Log 裏的 ( 也可以用推薦系統在精排之後,經過 Re-ranker 重排後的排序結果,這樣甚至可以學習到一些去重打散等業務規則 ),只要拿到 Log 裏的信息,我們就可以訓練召回或粗排的 Student 蒸餾模型。

也就是說,對於召回或者粗排模型來說,它看到了若干精排的排序結果列表,精排模型的知識就蘊含在裏面,而這可以作爲 Student 模型的訓練數據來訓練蒸餾模型。很明顯,這是一個典型的 Learning to Rank 問題。我們知道,對於 LTR 問題,常見的優化目標包括三種:Point Wise、Pair Wise 和 List Wise。於是,我們可以按照這三種模式來設計召回模型或粗排模型的蒸餾學習任務。其中,下面文中提到的 Point Wise 方式我們已親試有效,至於 Pair Wise 和 List Wise 蒸餾,仍需實驗才能證明是否有效。

4. Point Wise 蒸餾

在 Point Wise 優化目標下理解召回模型蒸餾,就是說,我們把精排模型的有序輸出結果作爲訓練數據,把學習目標看作一個二分類問題,通過這種方式試圖學習精排模型的排序偏好。這種情況下,分類模型的正負例如何設定呢?我們不能把精排模型輸出結果列表裏用戶行爲過的 Item 作爲正例,因爲這樣你等於在學比如點擊或者互動等用戶行爲模型,而不是在學精排模型的排序偏好。一般而言,可以這麼做:假設精排每次返回 N 個結果,我們取列表前 Top K 的排序靠前的結果,將其指定爲正例,位置K之後的例子,作爲負例。意思是通過排名最高的一部分數據,來學習精排模型的排序偏好。這樣,我們就可以拿這些非標註的排序結果來訓練召回模型。當然,這裏的K是個超參,怎麼定更合理,可能需要實驗來確定。上圖展示了這一做法。

通過這種方式,我們就可以讓召回模型從精排模型的排序列表中學到排序偏好知識,達成知識蒸餾的目標。這種做法,有個可以改進的點:上述切分正負例的方法,並未強調物品排序位置。比如假設 K 值取5,就是排名前5的物品作爲正例,之後的作爲負例。正例中排名 Rank 1 的物品,和排名 Rank 4 的物品,都各自作爲一條正例,沒有差別。但是,我們知道,Rank 1 應該排名比 Rank 4 更高,但模型訓練過程並沒有利用這個信息。我們可以通過對正例引入 Loss Weight 的簡單處理方法來引入這一信息,比如引入一個跟位置相關的 Weight 函數:

其中,Rank Position 是 Item 的排名名次,將其作爲變量引入函數,以此映射函數的數值作爲正例的 Loss Weight,負例 Loss Weight 權重與常規訓練一樣,可認爲缺省 Loss Weight 權重爲1。在具體設計這個函數的時候,指導思想是:希望這個函數能做到,排名越靠前的正例,對應的 Loss Weight 越大。將這個 Loss Weight 引入損失函數中,就可以讓模型更關注排名靠前的物品。比如,我們可以這麼定義函數:

這裏,Position 是排名位置,比如:

Rank Position=1,則 Position=1

Rank Position=4,則 Position=4

通過這種定義,就能使得排名靠前的正例,對應的 Loss Weight 越大,而 a 可以作爲調節權重,來放大或者縮小排名位置的影響。當然,這裏還可以引入其它各種花樣的 Loss Weight 定義方法。

熱門微博嘗試了上述思路 FM 版本的蒸餾召回模型 ( 多目標召回模型基礎上增加蒸餾召回目標 ),線上 AB 測試效果,在時長、點擊、互動等多個指標都有2+%到6+%之間的不同程度的提升作用,目前正在嘗試更多變體模型。

5. Pair Wise 蒸餾

如果我們用 Pair Wise Loss 的方式來看待召回模型優化問題,可以這麼思考:精排的排序結果是有序列表,在列表內隨機任意抽取兩個 Item,都能維持序關係。那麼很明顯,我們可以構造成對的訓練數據,以 Item 爲正例,以排在 Item 後面任意某個 Item 作爲負例,以此方式構造訓練數據來訓練模型。在推薦領域,最常用的 Pair Wise Loss 是 BPR 損失函數,於是我們可以如法炮製,如上圖所示,假設對於排在第三位的 Item 作爲正例,可以抽取排名在其之後的 Item,構造足夠多的成對訓練數據,以此目標來優化召回模型,使得模型可以學會 Item 間的序列關係。

對 <Pos,Neg> 成對的訓練數據,BPR 損失函數希望某個預測系統能夠對正例的得分要高於負例的得分,具體計算方法如上圖所示,因爲是個基礎概念,此處不展開介紹。

6. List Wise 蒸餾

Point Wise Loss 將學習問題簡化爲單 Item 打分問題,Pair Wise Loss 對能夠保持序關係的訓練數據對建模,而 List Wise Loss 則對整個排序列表順序關係建模。List Wise Loss 經常被用在排序問題中,但是有個現實困難是訓練數據不好做,因爲排序列表裏每個 Item 的價值需要人工標註。

我們來考慮下召回蒸餾模型的 List Wise Loss 優化目標怎麼做的問題。既然我們能拿到大量精排給出的有序列表,貌似我們是不缺訓練數據的,但是這裏隱藏着個潛在的問題,問題等會我們再說。我們先說個應用案例,Instagram 的推薦系統在初排階段採用知識蒸餾的方法,使用精排作爲 Teacher 來指導 Student 的優化,Student 的優化目標用的是 NDCG,這是一種非常常用的 List Wise Loss 函數,對 Instagram 推薦系統感興趣的同學可以參考文章:

Instagram 推薦系統:每秒預測 9000 萬個模型是怎麼做到的?

不過遺憾的是,上述文章並未說明是具體怎麼做的,只能靠我們自己來摸索一下。其實細想一下,在這裏用 NDCG 來學習精排輸出的有序列表,這面臨待解決的問題:用 NDCG 是有前提條件的,有序列表中的每個 Item,都需要帶有一個價值分。比如對於搜索排序來說,最相關 Item 是5分,次相關 Item 是4分,類似這種分數,這一般是人工標註上的,而 List Wise Loss 就希望排序系統能夠將列表整體獲得的價值分最大化。上面我們提到存在的問題就是:精排系統只給出了 Item 之間的排序關係,每個 Item 並沒有提供對應的價值分。

那麼,如果想用 NDCG 或者類似的其它 List Wise 損失函數,怎樣才能得到列表內每個 Item 的價值分呢?人工打標註顯然是不現實的。這裏,感覺可以利用一下精排系統輸出的 Logits 信息,假設我們可以設計一個函數:

這個函數以 Logits 分數爲輸入變量,將其映射到比如1分到5分幾檔上,Logits 得分越大,則對應檔次分越高。如果我們能做到這點,就可以使用 List Wise 損失函數來訓練召回或粗排模型了。這個函數定義有各種可能的方法,這裏不展開,各位有興趣的同學可以試試。

如果我們想更簡單點,不用 Logits 分數,那麼有更加簡單粗暴的方法,比如強行將有序列表排在 Top 5 的 Item 設置成5分,排在6到10位置的 Item 賦予4分…..類似這種。這等價於這麼定義 F 函數的:

這個公式充分展示了工業界的簡單暴力算法美學,我相信類似的公式充斥於各大公司的代碼倉庫角落裏。

05

聯合訓練召回、粗排及精排模型的設想

如果我們打算把知識蒸餾這個事情在推薦領域做得更徹底一點,比如在模型召回、粗排以及精排三個環節都用上,那麼其實可以設想一種"一帶三"的模型聯合訓練方法。

如上圖所示,我們可以設計一個很複雜但是效果很好的排序模型作爲 Teacher,然後和召回、粗排、精排三個 Student 聯合訓練,精排 Student 可以使用 Logits 以及隱層特徵響應等各種手段優化,追求效果好前提下的儘可能速度快,召回和粗排 Student 則追求在模型小的前提下追求效果儘可能好。因爲排序 Teacher 比較複雜,所以能夠提供儘可能好的模型效果,通過它來帶動三個環節蒸餾模型的效果,而模型速度快則是蒸餾方法的題中應有之意。

這樣做有不少好處,比如可以一次訓練,多環節收益;再比如可以最大程度上保持推薦系統各個環節的目標一致性等;做起來又不太難,所以看上去是個可行的方案。

最後,歸納下全文,推薦系統在各個環節採取知識蒸餾方法,是可能達到提升推薦質量的同時,提高推薦系統速度的,一舉兩得,比較容易產生效益,所以是值得深入探索及應用的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章