一、模型蒸餾
1.1 蒸餾簡介
知識蒸餾是指透過教師模型指導學生模型訓練,透過蒸餾的方式讓學生模型學習到教師模型的知識,最終使學生模型達到或媲美教師模型的準確度。
在模型壓縮中,教師模型是一個預訓練好的複雜的模型,而學生模型是一個規模較小的模型。如分類任務中,由訓練好的教師模型在相同的資料下,透過將教師模型對樣本的預測值作為學生模型的預測目標,指導學生模型學習,這個預測值一般指教師網路輸出的類機率。教師模型的引數規模大,能夠表達更好的泛化能力,學生模型的引數規模比較小,如果用通常的方法直接訓練,往往達不到教師模型的泛化能力,所以透過教師模型的指導,讓學生模型學習教師模型的泛化能力,以達到或媲美教師模型的精準度。
1.2 知識種類
- 輸出特徵知識:教師模型輸出的相關內容,對於分類模型,輸出特徵知識可以是logits或者軟目標,輸出特徵知識是以目標為導向,讓學生模型學習教師模型提供的答案,以學習教師模型對目標的泛化能力;
- 中間特徵知識:指教師模型的中間層上輸出的相關資訊,如果將輸出特徵知識比做是問題的答案,那麼中間特徵知識可以看做問題的求解過程,將中間特徵知識作為學習目標,可以讓學生模型學習與教師模型類似的求解過程,也可以使用隔層、逐層和逐塊等不同粒度大小,將教師模型的中間特徵知識遷移給學生模型;
- 關係特徵知識:指教師模型不同層和不同樣本資料之間的關係知識,關係特徵知識中,學生模型所學習的內容,不侷限模型的某一層,而是對模型多層的資訊進行模仿,關係特徵知識可以比做求解問題的方法;
- 結構特徵知識:結構特徵知識是教師模型的完整知識體系,不僅包括上面提到的各種特徵知識,還包括教師模型的區域特徵分佈等知識,結構特徵知識透過多種知識的互補,促使學生模型達到與教師模型一樣豐富的預測能力。
1.3 蒸餾分類
- 離線蒸餾:可以理解為知識淵博的老師給學生傳授知識。早期的知識蒸餾方法都屬於離線蒸餾,將一個預訓練好的教師模型的知識遷移到學生網路,通常包括兩個階段。第一階段在蒸餾前,教師網路在訓練集上進行訓練;第二階段,教師模型透過logits層資訊或者中間資訊提取知識引導學生網路進行訓練。優點是實現起來比較簡單,形式上通常是單向的知識遷移,即從教師網路到學生模型。缺點是教師網路通常比較龐大,模型複雜,需要大量的訓練時間,需要注意教師網路和學生網路之間的差異,當差異過大時,學生網路可能很難學習好這些知識。
- 線上蒸餾:可以理解為教師和學生一起學習。離線蒸餾方法雖然簡單有效,但也存在上述一些問題,為了克服離線蒸餾的侷限性,提出了線上蒸餾,以進一步改善學生模型的效能。線上蒸餾中,教師模型和學生模型同時更新,並且整個知識蒸餾框架是端到端可訓練的,教師模型可以不是預訓練模型,在沒有現成的大教師網路模型的時候,可以考慮使用線上蒸餾。
- 自蒸餾:學生學習自己的知識。在自蒸餾中,教師和學生模型使用相同的網路,自蒸餾可以看作線上蒸餾的一種特殊情況,因為教師網路和學生網路使用的是相同的模型。自蒸餾分為兩類,第一類是使用不同樣本資訊進行相互蒸餾,其他樣本的軟標籤,可以避免網路過擬合,甚至能透過最小化不同樣本間的預測分佈來提高網路效能。另一類是單個網路的網路層間進行自蒸餾,通常的做法是使用深層網路的特徵,去指導淺層網路的學習。
1.4 蒸餾架構
學生網路一般是:
1.教師網路的簡化版本,具有較少的層和每層中較少的通道。
2.教師網路的量化版本,其中網路結構被保留。
3.具有高效基本操作的小型網路。
4.具有最佳化的整體網路結構的小型網路。
5.與教師相同的網路。
1.5 蒸餾演算法
為了改進在更復雜的環境中傳遞知識的過程,已經出現許多不同的知識蒸餾演算法。
- 對抗蒸餾:對抗網路中的鑑別器用來估計樣本來自訓練資料分佈的機率,而生成器試圖使用生成的資料樣本來欺騙鑑別器。受此啟發,已經出現許多基於對抗的知識蒸餾方法,以使教師模型和學生模型能夠更好的理解真實的資料分佈。
- 多教師蒸餾:不同的教師框架可以為學生網路提供不同的有用的知識。在訓練學生網路期間,多個教師網路可以單獨地,也可以整體地用於蒸餾。為了傳遞來自多個教師的知識,最簡單的方法是使用來自所有教師的平均響應作為監督訊號。
- 交叉模式蒸餾:在訓練或測試期間,某些資料或標籤可能不可用。因此在不同的模型之間傳遞知識是很重要的。然而當模型存在差異時,跨模型知識蒸餾是一項具有挑戰性的研究。
- 基於圖形的蒸餾:用圖作為教師知識的載體,用圖來控制教師知識的資訊傳遞。大多數知識蒸餾演算法集中於將單個的例項知識從教師傳遞給學生,而基於圖形的知識蒸餾,使用圖來探索資料的內在關係,可以傳遞資料的資訊結構知識,然而如何恰當的構造圖,來建模資料的知識結構,仍然具有挑戰性。
- 無資料蒸餾:為了克服由隱私、合法性、安全性和保密性問題等原因引起的不可用資料的問題,出現了一些無資料知識蒸餾的方法。無資料蒸餾中的合成資料通常是從預訓練教師模型的特徵表示中生成的。儘管無資料蒸餾在資料不可用的情況下顯示出巨大的潛力,但是如何生成高質量的多樣化訓練資料,以提高模型的泛化能力,仍是一個很大的挑戰。
- 量化蒸餾:一個大的高精度的教師網路將知識傳遞給一個小的低精度的學生網路。為了確保小的學生網路精確的模仿大的教師網路,首先在特徵圖上量化教師網路,然後將知識從量化的教師轉移到量化的學生模型。
- 其他知識蒸餾演算法:基於注意力的蒸餾、終身蒸餾,NAS蒸餾等。
1.6 蒸餾流程
1.訓練教師模型。
2.在高溫T下,教師網路產生soft lables,學生網路產生soft prediction,同時在T=1下學生網路產生hard prediction。
3.用步驟二生成的soft lables和soft prediction計算 distillation loss,用hard prediction和hard labley計算student loss,用這兩個損失同時訓練學生網路。
4.設定T=1,用學生網路做線上推理。
二、模型剪枝
2.1 剪枝簡介
過引數化主要是指在訓階段,在數學上需要進行大量的微分求解,去捕捉資料中的微小的變化資訊,一旦完成迭代式的訓練之後,網路模型在推理的時候不需要這麼多引數,而剪枝演算法正是基於過引數化的理論基礎提出來的。剪枝演算法核心思想就是減少網路模型中的引數量和計算量,同時儘量保證模型的效能不受影響。
2.2 剪枝步驟
對模型剪枝有三種常見做法:
1.訓練一個模型->對模型進行剪枝->對剪枝後的模型進行微調(最常見);
2.在模型訓練過程中進行剪枝->對剪枝後的模型進行微調;
3.進行剪枝->從頭訓練剪枝後的模型。
剪枝可以進行細粒度剪枝、向量剪枝、核剪枝、濾波器剪枝等不同的剪枝演算法。其中很重要的一點是在剪枝之後,對網路模型進行評估,看是否符合要求。剪枝之前需要確定需要剪枝的層,設定一個剪枝閾值或者比例,在具體實現上,透過修改程式碼,加入一個與引數矩陣尺寸一致的mask矩陣,mask矩陣中只有0和1,它的實際作用是微調網路。
微調是恢復被剪枝操作影響的模型表達能力的必要步驟,結構化剪枝會對原始模型的結構進行調整,因此剪枝後的模型雖然保留了原始模型的引數,但是由於模型結構的改變,模型的表達能力會受到一定程度的影響。具體實現上,在計算的時候先乘以該mask矩陣,mask為1的值將繼續訓練,並透過反向傳播調整梯度,而mask為0的部分因為輸出始終為0,則不對後面產生影響。
2.3 剪枝分類
2.3.1 結構化剪枝與非結構化剪枝。非結構化剪枝粒度最小,結構化剪枝中的層級、通道級、濾波器級剪枝粒度依次增大。
- 非架構化剪枝主要是對一些獨立的權重或者神經元或者神經元的連線進行剪枝,就是隨機剪枝,是粒度最小的剪枝。難點是何如確定要剪枝哪些東西,最簡單的方法是定義一個閾值,低於這個閾值的權重被減去,高於的被保留。但是有三個主要缺點:1.閾值與稀疏性沒有直接聯絡;2.不同的層應該具有不同的靈敏度;3.這樣設定閾值可能會剪掉太多資訊,無法恢復原來的精度。還有一種方法是使用一個拼接函式來遮蔽權重,權重值沒有劇烈的變化,而且修剪過程可以與再訓練過程融合。非結構化剪枝的優點是剪枝演算法簡單,模型壓縮比高。缺點是精度不可控,剪枝後權重矩陣稀疏,沒有專用硬體,難以實現壓縮和加速效果。
- 結構化剪枝 結構化剪枝是有規律、有順序的。對神經網路,或者計算圖進行剪枝,幾個比較經典的就是對layer進行剪枝,對channel進行剪枝、對Filter進行剪枝,剪枝粒度依次增大。優點是大部分演算法保留原始卷積結構,不需要專用硬體就可以實現。缺點是剪枝演算法比較複雜。
2.3.2 靜態剪枝與動態剪枝。靜態剪枝在推理之前離線執行所有剪枝步驟,而動態剪枝在執行時執行。
- 靜態剪枝在訓練後和推理前進行剪枝。在推理過程中,不需要對網路進行額外的剪枝。靜態剪枝透過包括三個部分:1.剪枝引數的選擇;2.剪枝的方法;3.選擇性微調或再訓練,提高修剪後的網路的效能,以達到與修剪前網路相當的精度,但可能需要大量的計算時間和能耗。靜態剪枝儲存成本低,適用於資源有限的邊緣裝置,但是也存在三個主要問題:1.通道的刪除是永久性刪除,對於一些較為複雜的輸入資料,可能無法達到很好的精度,因為有些通道已經被永久性的剪掉了;2.需要精心設計要剪枝的部分,不然容易造成計算資源的浪費;3.神經元的重要性並不是靜態的,而且神經元的重要性很大程度上依賴於輸入資料,靜態的剪枝很容易降低模型的推理效能。
- 動態剪枝:網路中有一些奇怪的權重,它們在某些迭代中作用不大,但在其他的迭代卻很重要。動態剪枝就是透過動態的恢復權重來得到更好的網路效能。動態剪枝在執行時才決定哪些層、通道、過濾器不會參與進一步的活動。動態剪枝可以透過改變輸入資料,來克服靜態剪枝的限制,從而潛在的減少計算量、寬頻和功耗,而且動態剪枝通常不會執行微調或重新訓練。與靜態剪枝相比動態剪枝能夠顯著提高卷積神經網路的表達能力,從而在預測精度方面取得更好的效能。同樣動態剪枝也存在一些問題:1.之前有方法透過強化學習來實現動態剪枝,但在訓練過程中要消耗非常多的運算資源;2.很多動態剪枝的方法都是透過強化學習的方式來實現的,但是“閥門的開關“是不可微的,也就是說,梯度下降法在這裡是用不了的;3.儲存成本高,不適用於資源有限的邊緣裝置。
2.3.3 硬剪枝與軟剪枝。都是對filter進行剪枝,是結構化剪枝中粒度最大的剪枝。
- 硬剪枝在每個epoch之後會將卷積核直接剪掉,被剪掉的卷積核在下一個epoch中不會出現。這類的剪枝演算法通常從模型本身的引數出發,尋找或設計出合適的統計量,來表明連線的重要性。透過對重要性的排序等演算法,永久刪除部分不重要的連線,保留下來的模型即為剪枝模型。但也存在一些問題:1.模型效能降低;2.依賴預先訓練的模型。
- 軟剪枝在剪枝後進行訓練時,上一個epoch中被剪掉的卷積核在當前epoch訓練時仍參與迭代,只是將其引數設定為0,因此那些卷積核不會被直接丟棄。在每輪訓練中根據不同的資料,對完整模型進行最佳化和訓練。在每輪之後,為每個加權層計算所有濾波器的L2範數,並將其作為濾波器選擇的標準。然後透過將相應的濾波器權重設定為0來修剪所選擇的濾波器,隨後進行下一輪訓練。最後原始的深度神經網路模型被修剪成一個緊湊而有效的模型。軟剪枝一般有四個步驟:1.濾波器選擇(使用L2正規化來評估每個濾波器的重要性,具有較小L2正規化的濾波器的卷積結果會導致相對較低的啟用值,從而對網路模型的最終預測結果有較小的影響。所以這種具有較小L2正規化的濾波器將更容易被剪枝掉);2.濾波器剪枝(將所選濾波器的值設定為0,這可以暫時消除它們對網路輸出的影響,然而在接下來的訓練階段這些濾波器仍然可以被更新,保持模型的高效能。在濾波器剪枝的步驟中,可以同時修剪所有加權層。此外,要對所有加權層使用相同的剪枝率);3.重建(在剪枝步驟之後,再訓練一輪來重構修剪後的濾波器,修剪濾波器透過反向傳播被更新為非零。這樣經過軟剪枝的模型可以具有與原始模型相當的效能);4.獲得緊湊模型(重複以上三個步驟,黨模型收斂後可以得到一個包含許多0濾波器的稀疏模型,一個0濾波器對應一個特徵圖,對應於那些0濾波器的特徵圖,在推理過程中將總是0,移除這些濾波器以及相應的特徵圖不會有任何影響)。
三、模型量化
3.1 量化簡介
數字精度(如32位浮點數、16位浮點數或8位浮點數或8位整數),所能表示的範圍不同。不同的數字精度會影響模型大小和推理時間,範圍越大,精度越高,模型越大,推理時間越長。
卷積神經網路特點:引數量大,計算量大,記憶體佔用多,精度高。
模型量化就是把高位寬(float32)表示的權值或者啟用值用較低位寬來近似表示(int8,int4....)在數值上的體現就是將連續的值離散化。模型量化,降低精度以減少模型尺寸,會存在一定的損失,但有時候需要快速的做輸出,並不一定要那麼精確。模型量化特點:壓縮引數,提升速度,降低記憶體佔用,可接受的精度損失。
量化有兩種,一種是在訓練當中進行降低,一種是預訓練完成後再降低。一般第二種用的多。在huggingface裡面,模型量化分兩種,第一種是GGML,為了在CPU上更快更好的訓練模型,對CPU推出一種模型量化方式。第二種GPTQ對GPU推出一種量化方式。
3.2 量化優點
1.減小模型大小
2.降低訪存,執行神經網路時大部分時間都用於訪存(如取指,訪存,寫回的時間較長),但在執行神經網路在gpu上的時間很少,量化能降低訪存時間。
3.加快速度,gpu在Pascal架構下支援dp4a指令,可以一次完成4個8位元整型的乘加,Xilinx的DSP框架也會對整型運算加速。
3.3 量化分類
- 按量化的均勻性:均勻量化(線性量化,每個量化位寬相等)、非均勻量化(非線性量化,量化位寬不等);
- 按量化的範圍:對稱量化(最大最小值範圍正負對稱)、非對稱量化(最大最小值範圍不對稱);
- 按bit範圍:8bit、4bit、2bit、1bit...。
- 按量化的引數粒度:per-axis/per-channel(權重的每個通道使用單獨的量化引數)、per-tensor/per-layer(對於卷積或全連線層有每層獨立的量化引數);
- 按量化位寬:全部採用統一位寬、混合精度(如有的8bit,有的4bit)。
- 按量化方式:PTQ(post training quantization,後訓練量化,將已經訓練完的模型直接量化,然後進行推理)、QAT(quantization aware training,量化感知訓練,將訓練完的模型引數載入到量化後的模型然後再訓練微調,訓練好之後再用於推理)。
3.4 量化方法
早期量化,將input和weight進行量化,再卷積得到輸出結果。輸出結果在反向傳播傳到量化部分時,因為量化是一個不可微分的操作,需要使用直通估計器解決。但是每一層的output受量化的weight和input的影響產生誤差,這個output作為下一層的input也被量化從浮點域轉換到定點域,繼續影響下一層的機率分佈。如此下去導致整個網路的輸出和原先浮點輸出相比差距極大。但是反向傳播引數更新的時候,依然在浮點權重上更新,對於複雜網路最佳化難度極大。
Google在2018年在CVPR上提出一種新正規化,訓練時將input和weight的float值量化為int值,再反量化為float值,再卷積得到輸出結果,這樣會引入量化誤差,在訓練時會自動調優這個量化誤差,訓練效果會很好。推理時將input和weight的float值量化到int,再卷積得到結果output,注意需要對output進行移位定點運算,再與下一層進行計算。
BN摺疊量化,BN層摺疊到卷積層,摺疊進去之後也可以量化。
ReLU摺疊量化,也可以摺疊,直接進行量化。
Add量化,與訓練程式碼無關,所以可以直接在推理框架裡量化。
Concat量化等。