最近讀了本好書-《深度學習推薦系統(tǒng)》,讀完不覺全身通暢,于是就有了寫這篇文章的想法,把自己的理解和總結分享給大家。 本文將按照從算法到工程的順序,先介紹一下推薦系統(tǒng)整體架構;再聊聊算法模型的演化;然后是推薦系統(tǒng)的一些設計關鍵點;最后,結合自身經(jīng)驗和業(yè)界最新進展,討論一下系統(tǒng)的工程化實踐。 一、推薦系統(tǒng)整體架構說到推薦系統(tǒng),大家應該都不陌生,它幾乎已經(jīng)是任何一個互聯(lián)網(wǎng)系統(tǒng)的標配。在如今信息爆炸的場景下,如何根據(jù)每個人的喜好,快速的把用戶“需要”的信息呈現(xiàn)出來,不僅是提高客戶體驗的需要,也是保證客戶留存率,保證下單率的靈藥。 推薦的呈現(xiàn)形式可能有多種多樣,拿同程藝龍小程序來說,當用戶搜索酒店時,酒店列表的順序就是推薦的體現(xiàn)。推薦的順序,融合了用戶的地理位置、歷史消費習慣、品牌偏好等多種信息,把最具“價值”的酒店擺在靠前的位置。 下圖展現(xiàn)了一個典型的推薦系統(tǒng)的整體架構,也涵蓋了全書所圍繞介紹的主要關鍵點。 圖中將系統(tǒng)整體架構分成“數(shù)據(jù)部分”和“模型部分”,數(shù)據(jù)部分的箭頭代表了數(shù)據(jù)加工處理的過程,從數(shù)據(jù)收集開始,到數(shù)據(jù)匯總、加工、預處理、到最后數(shù)據(jù)落地,通過特征工程形成特征數(shù)據(jù),供算法模型使用。數(shù)據(jù)的內容,對于推薦系統(tǒng)來說,一般可以概括為三部分:用戶信息、物品信息、場景信息。 目前業(yè)界的大數(shù)據(jù)處理框架很多,從最早一代的 Hadoop 技術體系,到后來的實時流處理框架 Storm,再到后來的流批一體化框架,如 Spark、Flink 等,都是在朝“更大吞吐量”、“更高實時性”、“一體化”方向演進。所謂大數(shù)據(jù)架構模式:lambda 也好、kappa 也罷,其實主要是解決如何更好的將流、批兩種處理模式整合在一起,平衡系統(tǒng)的實時性和吞吐量。 模型部分主要講了三件事: 1、 推薦模型的演化及特點; 2、 模型的離線訓練; 3、 模型的在線部署。 其中,關于模型演化及介紹,書中花了兩章的篇幅進行了詳細介紹,從機器學習時代到深度學習時代,是本書的精髓。 模型的離線訓練即包含了訓練框架的選擇,也介紹了模型分布式訓練的原理,還有些訓練方式的奇技淫巧。 模型的在線部署是工業(yè)界討論最多的部分,如何把離線訓練的模型引入系統(tǒng),使其發(fā)揮效能,有很多“關鍵設計”。其中“召回”和“排序”是典型的設計,此外還有冷啟動方案、平衡探索利用等很多注意點。 其實近幾年,模型推理任務還有一些最新的優(yōu)化技術,如“模型量化”、“計算圖優(yōu)化”、“知識蒸餾”等,書中討論的并不是很多,我們將在最后介紹。 接下來,將按照上面的順序,逐一展開討論;讓我們先進入模型的世界吧。 二、傳統(tǒng)推薦模型的演化上圖已經(jīng)將前機器學習時代的主要模型概括的很清楚了,書中將這些模型分為 4 類:協(xié)同過濾算法族、LR 算法族、因子分解機算法族、組合模型。 協(xié)同過濾(CF)可以說是推薦系統(tǒng)算法的鼻祖了,它從用戶購買物品的行為中尋找相似性,構建算法模型。所以它又分兩種:ItemCF 和 UserCF。購買相似的物品的用戶視為“相似”,從而推薦“相似用戶”購買而自己又沒購買的物品,就是 User Based CF;而反之,被多個相似用戶購買的物品視為“相似”,從而推薦“相似物品”給用戶自己的就是 Item Based CF。這兩種方式?jīng)]有優(yōu)劣,視場景而用。UserCF 適用于熱點發(fā)現(xiàn)以及跟蹤熱點趨勢。而 ItemCF 更適用于興趣變化較為穩(wěn)定的應用。 協(xié)同過濾歷史悠久,可解釋性很強,但它也有天然缺陷,如 ItemCF 的熱門物品具有很強的頭部效應,它能與很多物品產(chǎn)生相似性,從而被推薦,這就使得推薦物品缺乏變化。而且,CF 算法僅僅使用了用戶和物品購買信息,無法引入其他特征,使得很多有效信息被遺漏。雖然后續(xù)又衍生出矩陣分解(MF)算法,來解決模型的泛化能力,但始終無法引入其他特征。 邏輯回歸(LR)是經(jīng)典的推薦模型,它著眼于用戶物品購買矩陣,但又不局限于其中,通過引入用戶信息、物品信息及上下文信息,對稀疏矩陣進行預測。其 xw+b ->sigmoid 的數(shù)學形式,不僅使其具有可解釋性強,又是后來深度學習模型神經(jīng)元的典型構成。因此,很長一段時間內,LR 都在工業(yè)界占據(jù)主導地位。 但它的局限性也很明顯:表達能力有限,無法進行自動特征交叉。所有的交叉特征提取,完全看算法工程師的“想象力”和“對業(yè)務的理解力”。所以其表現(xiàn)也很不穩(wěn)定。 因此,很快 FM 的時代來了。FM 為每個特征單獨引入了隱向量,用向量積代表特征組合后的權重。 從 FM 的表達式也可以看出,相比 LR,其只是在線性部分后加了兩兩特征交叉項,如果交叉特征的隱向量維度為 k,n 為特征數(shù)量,其額外增加的計算復雜度為 nk。作為 LR 的改進,F(xiàn)M 不僅繼承了 LR 的所有優(yōu)點,還用“不大”的額外開銷,解決了特征交叉問題。同時 FM 還沒有深度學習模型的復雜性,使其在工程上十分利于部署。 目前,同程藝龍酒店的推薦,很大一部分通道仍然使用的是 FM 模型。輕量、可解釋性強、易于部署,同時還能通過不斷引入新的特征提高其準確性。這些優(yōu)點都使這個奮戰(zhàn)了多年的“老兵”,在深度學習大行其道的今天,仍然有用武之地。 終于說到“上分神器”——GBDT 了。這個神奇的模型通過將一棵棵簡單樹進行組合,通過對“殘差”進行擬合,使其具有非常好的預測準確性和泛化能力。同時它也能對特征進行自動的篩選和組合。 其優(yōu)良的性能使其在前幾年的機器學習比賽中,幾乎是必選的模型。通過不斷的調參和模型融合,就能不斷在比賽中提高分數(shù),拿到不錯成績。XGBoost 和 LightGBM 是實現(xiàn)了 GBDT 模型的兩個經(jīng)典框架。 但如此優(yōu)秀的模型也有其局限性。首先高復雜度必然造成上線的困難和可解釋性的消解。另外,殘差樹的形式,也使得其只能串行化訓練和預測。因此,工業(yè)界在線上實際使用 GBDT 模型進行預測的并不多,而是利用它特征篩選和交叉能力,和其他模型進行組合。 GBDT+LR 就是一個生動的例子,利用 GBDT 特征組合能力,形成多階特征交叉,然后把產(chǎn)生的每棵子樹命中的葉子節(jié)點,形成的 one-hot 向量,作為新的特征,送入到 LR 中。這種組合最妙的地方還在于,兩個模型可以分開訓練,獨立升級演化。 GBDT 作為機器學習時代“最后的倔強”,將“簡單模型”的各項指標都推向了頂峰,特征交叉的方案也基本挖掘到了極致。但互聯(lián)網(wǎng)仍在產(chǎn)出海量的數(shù)據(jù)并對模型提出更高的要求。與此同時,隨著算力的提升和數(shù)據(jù)的積累,深度學習模型也在悄然的崛起。 三、深度學習推薦模型的演化與傳統(tǒng)的機器學習相比,深度學習模型一般有更復雜的網(wǎng)絡結構,更強的表達能力,能夠擬合更復雜的數(shù)據(jù)模式。 書中的這幅圖揭示了推薦領域的深度學習模型演化關系。深度學習模型以多層感知機(MLP)為基礎開始各自的演化。MLP 是典型的神經(jīng)網(wǎng)絡結構,多層的結構很好的解決了特征交叉問題。其實在機器學習時代就有 MLP,但由于其相比 LR、FM 等模型,參數(shù)量更大;在沒有更多數(shù)據(jù)量的情況下,效果反而不如 LR 和 FM 模型,所以,在實際中,往往應用的不多。但這仍然不能掩蓋其在深度學習中的核心地位。 深度學習最開始的實際應用應該說還是 Deep Crossing 和 PNN 系列。Deep Crossing 在實際中大量使用了 Embedding 結構,并使用 stacking 的方式將不同特征拼接起來。而在具體的網(wǎng)絡結構中,使用了經(jīng)典的殘差結構,如下圖: 殘差結構加了一條跳過網(wǎng)絡的路徑,使 X 直接加到網(wǎng)絡后的輸出上,殘差結構很好的解決了隨著模型加深,訓練時梯度消失問題,擬合殘差使得模型的擬合能力更強,訓練難度更低。最經(jīng)典的殘差結構的提出還是微軟的 ResNet,GBDT 某種意義上來說也是針對殘差建模。 介紹深度學習模型,不能不提大名鼎鼎的 Wide&Deep,由谷歌于 2016 年提出。 淺層模型具有較強的記憶能力,訓練速度快,可解釋性強的優(yōu)點;深度模型是處理特征交叉的好手、具有較強的模型容量和泛化能力。那能不能將二者的優(yōu)勢結合起來呢?Wide&Deep 就是這樣一個模型,它包括一個淺層模塊和一個深度神經(jīng)網(wǎng)絡模塊。谷歌團隊最初將其應用在 google 商店 app 推薦中。 但哪些特征需要放在 Deep 端、哪些特征需要放在 Wide 端,需要對業(yè)務場景有深刻的理解。 “記憶”和“泛化”在機器學習領域是一對兒相反的詞,“記憶”代表對訓練數(shù)據(jù)中共現(xiàn)關系的直接運用;“泛化”則代表模型挖掘特征和最終結果的潛在模式的能力。一般來說模型的“記憶能力”是我們機器學習訓練過程中,想極力避免的,“泛化能力”才是我們追求的模型目標。想象一下,一個考生如果只死記硬背,記住了幾道題,練習時可能會得高分,但在考試時遇到自己沒見過的題就懵了,這是我們不希望看到的。但在 Wide&Deep 中,這兩種能力卻得到了綜合運用?!胺夯芰Α庇?Deep 部分承擔,Wide 部分承擔“需要死記硬背”的部分。這就好像,考試前,我們既學會了一些解題模式,又要死記硬背一些典型熱點題目一樣。 谷歌團隊將“已安裝應用”,作為 Wide 部分的特征,Deep 部分輸入則為“全特征”。最后將二者組合起來,形成統(tǒng)一的模型。同程的酒店推薦也有使用 Wide&Deep 模型,目前更多是側重 Deep 部分的特征挖掘。在實際線上生產(chǎn)環(huán)境中,取得了不錯的業(yè)務效果。 Wide&Deep 模型的提出,打開了不同網(wǎng)絡結構融合的新思路。以致后來很多模型都是對 Wide&Deep 模型的 Wide 部分或 Deep 部分進行改造而來。 對 Wide 部分的改進就有 DCN 和 DeepFM,前者是把 Wide 部分換成了交叉網(wǎng)絡,而后者則是使用 FM 來代替原有的 LR 部分。 對 Deep 部分的改進則既有結構上的,也有通過引入新的機制的方式。 注意力機制是一次有意義的突破,DIN、AFM 都是這其中有效的嘗試。注意力機制模擬了人類認識事務的注意力機制,在圖像、語音和推薦領域的呈現(xiàn)形式不盡相同。從數(shù)學形式上看,注意力機制只是將過去的向量加和換成了加權后加和,而且其訓練難度上,也是多了一層注意力的權重,但其意義卻是更符合人類實際的思考模式的。拿 AFM 來說,其 Attention Net 的數(shù)學形式如下: 本質上就是一個單層神經(jīng)網(wǎng)絡 + softmax,最終輸出的 ai,j 就是 FM 各交叉項的權重。這也是符合我們的直覺的:即任意兩個二階交叉項,其重要性也不應該是一樣的。最終效果也證明了這點:引入了 Attention 機制的 AFM,效果大幅提升。 四、推薦系統(tǒng)的一些設計關鍵聊完模型演化,再聊聊模型相關的設計與選型。推薦系統(tǒng)作為一個復雜系統(tǒng),并不只是模型就夠了。有關模型,還有很多設計關鍵點需要關注。 新建一個模型時,需要考慮模型的目標是什么?模型的目標一般由商業(yè)目標和應用場景決定。而模型目標又最終確定了損失函數(shù)和訓練方法。 首先我們需要將大的商業(yè)目標拆解,同時考慮技術架構。比如將系統(tǒng)拆分成“召回”和“排序”兩個階段就是技術上典型的平衡“性能和業(yè)務”的方案。召回階段考慮快速過濾掉大部分不相關商品,同時保留多樣性。有時為了多樣性,還會采取“多路召回”的方式。即通過不同的策略、規(guī)則分別召回一部分候選集,然后把候選集合并混合在一起供后續(xù)使用。召回階段的特點決定了它往往采用簡單的模型、規(guī)則、或 Embedding 技術,以此來保證召回“效率”。而 CTR、CVR 則是進一步對“排序”階段目標的業(yè)務拆分。拿酒店推薦場景來說,用戶必須先點進酒店詳情頁,才有可能進一步到下單頁形成轉化率。因此,CTR、CVR 就是我們模型優(yōu)化的目標,而實現(xiàn)推薦的形式,就是通過列表頁展現(xiàn)的順序來影響用戶的選擇。這種排序推薦的方式,讓我們的訓練方法,不僅可以使用 pointwise 的訓練方法,對單個酒店打分;還可以使用 pairwise 等 LTR 方法,對酒店的順序進行建模訓練。 完成了整體的模型拆解,就開始著眼到單個模型上來。模型的特征挖掘充分嗎?是否需要多模態(tài)特征?像酒店推薦一般會包含“用戶特征”、“酒店特征”、“上下文特征”等。每個特征的選取和處理都是經(jīng)過大量的打磨和 A/B-Test 實驗的結果。 如何解決冷啟動問題?模型的初始化有時是在系統(tǒng)上線前,這時已經(jīng)積累了一定量的數(shù)據(jù),可以充分建模;但有時缺乏的卻是輸入的特征。如新建用戶、新商品。這時有些策略可以幫助我們跨過這個階段。如基于規(guī)則的推薦、或通過“主動學習”主動獲取數(shù)據(jù)等。 推薦的實時性包含模型的實時性和特征的實時性。模型的更新頻率和更新范圍是影響模型實時性的關鍵。更新頻率一般從一周到一天,甚至是在線學習,這些都需要數(shù)據(jù)收集和流處理框架的支持,同時結合好全量和增量更新。更新范圍既可以全部,也可以是模型和 Embedding 向量分開更新。 五、模型的離線訓練與在線部署1、離線訓練在目前互聯(lián)網(wǎng)數(shù)據(jù)規(guī)模越來越大的情況下,模型的訓練場景從單機單卡發(fā)展到單機多卡,再到多機多卡,分布式訓練逐漸成為一個逃不開的選項。目前主流的分布式訓練框架包括 Spark MLlib、Parameter Server、Tensorflow 等。 從并行方式上看,可以分為數(shù)據(jù)并行和模型并行。數(shù)據(jù)并行又可以分為同步并行和異步并行。 Spark MLlib 是典型的同步數(shù)據(jù)并行方式。它通過廣播的方式同步梯度到各個計算節(jié)點,然后每個節(jié)點都拉取一部分訓練數(shù)據(jù),在本地完成一輪梯度計算,再通過 treeAggregate 匯總各個梯度加和求平均,最后同步最新梯度到各節(jié)點完成一輪梯度更新。 可以看出這種并行訓練方式雖然清晰,但訓練過程卻是低效的。每輪迭代先要廣播所有參數(shù),極其耗費帶寬資源;另外,在生成匯總梯度時,都要等待所有節(jié)點完成,訓練速度由最慢的節(jié)點決定。因此,Spark MLlib 并不適合深度學習時代,大規(guī)模神經(jīng)網(wǎng)絡的分布式訓練。 因此,Parameter Server 應運而生,那么 Parameter Server 是怎么解決上述兩個問題的呢?下圖展示了 Ps 的整體架構: Ps 整體上由 Server Group 和 Worker Group 構成,Worker 負責拉取部分數(shù)據(jù),計算局部梯度,并上報 Server;Server 負責維護匯總梯度,計算全局梯度,并更新 Worker??梢钥吹?,Server Group 內多 Server 的結構,每個 Server 通過一致性 hash,維護一定范圍內的參數(shù),避免了單節(jié)點的帶寬瓶頸,也保證了節(jié)點刪擴容的靈活性。而在更新梯度時,不再采取“同步阻塞”的并行方式,而是采取了“異步并行”。即 Worker 在計算完局部梯度并上報更新后,不再等待其他計算節(jié)點,而是繼續(xù)拉取數(shù)據(jù),開始下一輪迭代。當然,速度上的提升,帶來的是模型一致性的喪失,也就是收斂結果的不確定性。這就需要設計者根據(jù)實際模型情況做好平衡。另外,也可以采取“有界延遲”的方式,作為折衷方案。 Tensorflow 采用了多種并行策略。其由 OP 組成的計算關系圖,類似于 Spark 的 DAG(有向無環(huán)圖);有依賴關系的 OP 必須串行執(zhí)行,無依賴關系的 OP,可以分配到多卡上并行執(zhí)行。其分布式策略默認采取了類似 Ps 的數(shù)據(jù)并行的方式,不再贅述。Ring-All Reduce 作為另外一種并行策略,相對 Ps 可以達到更高的帶寬利用率。 2、在線部署模型的在線部署需要面臨的則是另外一番完全不同的場景了。與離線訓練最大的不同是對推理性能的極致追求,面臨的問題和困難也有很多。 首先,在線部署有可能和離線使用的是不同的框架,甚至是不同的語言。那怎么把模型“提交”給在線推理模塊,就有很多考量。PMML 協(xié)議在機器學習時代是幾乎是模型交換的標準。PMML 文件中包含了模型的結構定義和模型參數(shù),像 sklearn 等很多框架都支持直接將模型導出為 PMML 格式。而在部署端,如果編程語言是 Java,則使用 JPMML 則很容易將模型裝載、還原。但到了深度學習時代,模型參數(shù)動輒上百萬,再使用像 PMML 這種以 XML 為組織形式的協(xié)議就不合適了。 如果推理平臺是自研,可以使用自定義導出模型參數(shù)的方式。模型參數(shù)本質上就是大量的 key-value 集合,導出后,可以以任意格式存儲。同程的酒店推薦模型就是采用這種方式,離線訓練端把模型參數(shù)以 key-value 的形式導出后,推送到共享的文件系統(tǒng)中;模型推理平臺自動檢查更新,構建模型并裝載最新的參數(shù),簡單、高效而靈活。 ONNX(Open Neural Network Exchange,開放神經(jīng)網(wǎng)絡交換)格式,是由微軟開源,一套新的用于表示深度學習模型的標準,近幾年逐漸火熱起來,并逐漸被 TensorFlow、PyTorch、Caffe2 等各大框架支持。它定義了可擴展的計算圖模型,以及內置運算符和標準數(shù)據(jù)類型的定義;本質上是以 PB 格式為組織形式的文件,因此更加節(jié)省空間。 然后是線上部署框架的選擇。 Tensorflow Serving 是一個谷歌開源的用于模型推理的高性能庫,可同時提供 RESTful 和 gRPC 接口,用于線上模型推斷。統(tǒng)一的離線框架和在線框架是這種方案的最大優(yōu)點,只需將 Tensorflow 的模型導出為 PB 文件,然后即可導入 Tensorflow Serving 使用。與 TF 良好的兼容性大大簡化了上線步驟;此外,它還提供了模型版本控制和熱更新等功能。Tensorflow Serving 最大的硬傷在于其默認情況下的性能。Python 環(huán)境下程序運行本來的性能就不高,再加上特征預處理過程,如果再不針對硬件進行優(yōu)化,那這種方式上線的模型推斷接口,性能是堪憂的。必須針對性的進行代碼和硬件優(yōu)化。此外,如果訓練環(huán)境不是 Tensorflow,那用 TF-Serving 做線上部署也是比較麻煩的。 自研框架當然也是個不錯的選擇。TE 的酒店推薦框架就是采用自研的方式。當然需要考慮的問題也不少,包括: 1、 與各種離線訓練框架交換模型的格式; 2、 模型的加載與熱更新及版本控制; 3、 如何解構各種模型,并進行高性能的推斷,提供高吞吐量的對外接口; 4、 如何組織、復用大量的特征處理代碼; 5、分布式模型裝載、硬件優(yōu)化等等。 總之自研框架的成本是比較高的,所以一般也只有大型互聯(lián)網(wǎng)公司才會選擇自研。但好處也是明顯的,整個過程更加可控,不必再局限于各種開源框架的限制。百度的 Paddle、騰訊的 TNN 都是業(yè)內比較有名的自研框架。 近幾年,一系列專注于硬件優(yōu)化的模型推理框架也逐漸崛起。Nvidia 推出的 TensorRT 便是其中的典型。根據(jù)其官方文檔介紹,TensorRT 可以針對 GPU 模式,達到 10X 以上的加速。那它是怎么做加速的呢?主要有兩種方式:一種是通用類的模型加速,這個我們后面一起討論;另一種是針對硬件指令級的加速。比如圖像識別中,經(jīng)常使用的一個卷積層 + 一個偏置層 + Relu 激活,本來是三條 cuda 指令,但在特定的顯卡下,TensorRT 可以將其合并成 CBR 層,一條 cuda 指令,從而實現(xiàn)網(wǎng)絡結構簡化和推理加速。 最后,我們來說說通用的模型加速技術,包括:數(shù)學公式優(yōu)化、模型剪枝、模型量化、權值共享和知識蒸餾。 數(shù)學公式優(yōu)化:這類最好理解,就是對模型原有計算形式,做數(shù)學公式上的推導變形,使其更符合 CPU 的計算模式。比如 FM 的交叉項計算公式: 乍一看其計算復雜度為 但可以進行如下變換: 復雜度就變成了 其主要就是利用公式: 實現(xiàn)化簡。 另一個例子是在卷積運算中,Winograd 算法大量被使用。它來自于 CVPR 2016 的一篇 paper:<Fast Algorithms for Convolutional Neural Networks>。核心思想是通過轉換,用多次加法,減少卷積運算中的乘法,而乘法運算是比加法運算慢很多的,以此來提高卷積的計算速度。 模型剪枝:在 2016 ICLR 的 best paper <DEEP COMPRESSION: COMPRESSING DEEP NEURAL NETWORKS WITH PRUNING, TRAINED QUANTIZATION AND HUFFMAN>一文中,Han 等人對模型剪枝、權值共享等做了系統(tǒng)性的綜述。為什么要剪枝呢?訓練好的大型神經(jīng)網(wǎng)絡通常存在參數(shù)冗余,可以對不重要的模型節(jié)點進行剪枝來達到減少模型體積、加快模型運算的目的,同時,控制精度下降。具體做法就是設計一個閾值,將小于這個閾值的參數(shù)連接在網(wǎng)絡中去掉,再重新訓練網(wǎng)絡。通常可能要如此進行多個迭代。上述方法可以說是一種貪心的方法,但它存在一種問題,就是如果刪除了重要節(jié)點,會造成精度不可逆轉的下降。于是,Yiwen Guo 2020 年的這篇論文<Dynamic Network Surgery for efficient DNNs>提出了一個改進方案,見下圖: 也就是增加了“修補”操作,來恢復被誤刪掉的重要連接。從最終效果看,模型剪枝和精度下降都得到了有效控制。 權值共享:卷積網(wǎng)絡中的卷積核最早引用了“權值共享”和“局部感受野”這倆概念。而如果把這種思想引入到模型壓縮領域中是否可行呢?Han 在其論文中就驗證了這一方案:使用 k-means 方法對模型的權值進行聚類,然后使用中心點代替原有權值,以后梯度更新時,就以類別為粒度進行更新。下圖描述了這一方法的過程。 模型量化:模型量化是近兩年較為火熱的一種模型壓縮方式。一般情況下,神經(jīng)網(wǎng)絡中的數(shù)據(jù)是以精度為 32 位的浮點型(FLOAT32)進行表示的,存儲和計算的開銷都很大。模型量化則是研究以更低的精度表示模型,同時控制模型效果損失。目前半精度、INT8、二值化都是流行的方式。量化時,也有僅量化權值和特征、權值都量化兩種方案。 通常來說,INT8 量化用的最多,Tensorflow、TensorRT 等很多框架也都內置支持。原理其實并不復雜,關鍵是如何將 Float32 的值域映射到 INT8 的區(qū)間(-127~127),見下圖: 但浮點型的范圍是很大的,個別的離群點可能會導致 INT8 映射時,將大部分數(shù)據(jù)集中映射在幾個值,從而騰出更大的空間給離群點,這就得不償失了。所以需要控制 FLOAT32 映射的邊界值 T,也就是映射范圍,舍棄掉部分離群點。那如何衡量舍棄哪些以及映射的好壞呢?TensorRT 使用的是 KL 散度,也就是相對熵。相對熵是用來衡量兩個分布的差異的,因此原問題就變成了如何把 FLOAT32 映射到 INT8 的區(qū)域,同時使兩個分布的 KL 散度最小化。 知識蒸餾:知識蒸餾最早要追述到 Hinton 的這篇論文《Distilling the Knowledge in a Neural Network》。知識蒸餾是要用一個訓練好的復雜度較高的 Teacher 網(wǎng)絡,去協(xié)助訓練一個復雜度低的 Student 網(wǎng)絡。一個模型容量更大的 Teacher 網(wǎng)絡,雖然其表達能力很強,但同時也意味著它可能會存在很多冗余,我們要的是模型泛化能力本身,而非模型的參數(shù)結構。所以就需要把 Teacher 模型的預測能力通過“蒸餾”的方式,遷移到一個輕量簡化的 Student 網(wǎng)絡。 這其中的關鍵是軟化后的 Softmax。拿 MINST 手寫數(shù)字識別來說,我們知道輸入到模型中的目標是經(jīng)過 One-hot 的,也就是 0 1 0 0 0 0...這種形式。目的是告訴模型哪個結果是對的,我們希望它概率最大化,從而實現(xiàn)訓練;而其實這種方式丟掉了很多信息,比如數(shù)字 2 和 3 很像,我們怎么把這種信息告訴模型,從而讓它在訓練過程中少走彎路呢?答案就是 Teacher 網(wǎng)絡。作為一個“過來人”,Teacher 網(wǎng)絡通過推斷,當然可以知道 2 和 3 很相似這種信息,然后把結果“軟化”(使 One-hot 結果更加平滑),也一起輸入到 Student 網(wǎng)絡的訓練過程中。這樣,Student 網(wǎng)絡就可以更快的、以更小更簡潔的結構學到老師的精髓。下圖就描述了這一過程: 不知不覺中已經(jīng)寫了這么多,這才發(fā)現(xiàn)推薦領域涉及到的知識點是那么多,而很多內容還沒有展開講。有些是書中提到,有些是自己實際工作中的總結,希望對大家有所幫助。路漫漫其修遠兮,吾將上下而求索。 作者介紹: 房磊,2014 年加入同程藝龍,任架構師,技術委員會委員;先后負責 MAPI 手機網(wǎng)關平臺建設、同程藝龍開放平臺建設、數(shù)據(jù)平臺建設等。擅分布式系統(tǒng)架構設計和 AI 系統(tǒng)設計。20 年參加 Top100 案例北京峰會,獲人工智能專場最佳講師。歡迎關注我的個人微信公眾號:architectAI,進一步交流、私信我~。 |
|
來自: 西一里2l6sluho > 《數(shù)碼電子游戲軟件》