一,模型壓縮技術概述
我們知道,一定程度上,網路越深,引數越多,模型也會越複雜,但其最終效果也越好,而模型壓縮演算法是旨在將一個龐大而複雜的大模型轉化為一個精簡的小模型。
之所以必須做模型壓縮,是因為嵌入式裝置的算力和記憶體有限,經過壓縮後的模型方才能部署到嵌入式裝置上。
模型壓縮問題的定義可以從 3
角度出發:
-
模型壓縮的收益:
- 計算: 減少浮點運算量(
FLOPs
),降低延遲(Latency
) - 儲存: 減少記憶體佔用,提高
GPU/NPU
計算利用率
- 計算: 減少浮點運算量(
-
公式定義模型壓縮問題: \(\underset{Policy_i}{min} {Model\_Size(Policy_i)}\)
-
模型壓縮問題的約束: \(accuracy(Policy_i) >= accuracy\_sla\)
1.1,模型壓縮方法分類
按照壓縮過程對網路結構的破壞程度,《解析卷積神經網路》一書中將模型壓縮技術分為“前端壓縮”和“後端壓縮”兩部分:
- 前端壓縮,是指在不改變原網路結構的壓縮技術,主要包括
知識蒸餾
、輕量級網路(緊湊的模型結構設計)以及濾波器(filter)層面的剪枝(結構化剪枝)
等; - 後端壓縮,是指包括
低秩近似
、未加限制的剪枝(非結構化剪枝/稀疏)、引數量化
以及二值網路等,目標在於儘可能減少模型大小,會對原始網路結構造成極大程度的改造。
總結:前端壓縮幾乎不改變原有網路結構(僅僅只是在原模型基礎上減少了網路的層數或者濾波器個數),後端壓縮對網路結構有不可逆的大幅度改變,造成原有深度學習庫、甚至硬體裝置不相容改變之後的網路。其維護成本很高。
1.2,模型壓縮方法舉例
工業界主流的模型壓縮方法有:知識蒸餾(Knowledge Distillation,KD)輕量化模型架構(也叫緊湊的模型設計)、剪枝(Pruning)、量化(Quantization)。各個模型壓縮方法總結如下:
模型壓縮方法 | 描述 | 涉及的網路層 | 示例 |
---|---|---|---|
知識蒸餾 | 屬於遷移學習的一種,主要思想是將學習能力強的複雜教師模型中的“知識”遷移到簡單的學生模型中。 | 卷積和全連線層 | 經典KD論文,屬於蒸 "logits"方法,將Teacher Network輸出的soft label作為標籤來訓練Student Network。必須重新訓練模型。 |
輕量化模型架構 | 輕量級網路的核心是在儘量保持精度的前提下,從體積和速度兩方面對網路進行輕量化改造。 | 卷積層/卷積模組 | Mobilenet 提出深度可分離卷積; shufflenetv2 論文 提出的四個高效網路設計的實用指導思想; RepVGG 提出重引數化思想。 都需要重新設計 backbone 和和重新訓練模型。 |
剪枝 | 將權重低於閾值的連線都從網路中刪除。 | 卷積層和全連線層 | 韓松2016年Deep Compression屬於開山之作,剪枝步驟:正常訓練,刪除網路中權重低於閾值的連線層,重新訓練。需要重新訓練模型。 |
量化 | 指將神經網路的浮點演算法轉換為定點演算法 | 卷積、全連線、啟用、BN層等 | TensoRT框架中的基於 KL 散度方法的INT8量化策略是主流技術。PTQ 訓練後量化方法不需要重新訓練模型。 |
二,知識蒸餾
知識蒸餾(knowledge distillation),其實也屬於遷移學習(transfer learning)的一種,通俗理解就是訓練一個大模型(teacher 模型)和一個小模型(student 模型),將龐大而複雜的大模型學習到的知識,透過一定技術手段遷移到精簡的小模型上,從而使小模型能夠獲得與大模型相近的效能。也可說讓小模型去擬合大模型,從而讓小模型學到與大模型相似的函式對映。使其保持其快速的計算速度前提下,同時擁有複雜模型的效能,達到模型壓縮的目的。
知識蒸餾的關鍵在於監督特徵的設計,這個領域的開篇之作-Distilling the Knowledge in a Neural Network 使用 Soft Target
所提供的類間相似性作為依據去指導小模型訓練(軟標籤蒸餾 KD
)。後續工作也有使用大模型的中間層特徵圖或 attention map(features KD
方法)作為監督特徵,對小模型進行指導訓練。這個領域的開篇之作-Distilling the Knowledge in a Neural Network,是屬於軟標籤 KD 方法,後面還出現了 features KD 的論文。
以經典的知識蒸餾實驗為例,我們先訓練好一個 teacher
網路,然後將 teacher
的網路的輸出結果 \(q\) 作為 student
網路的目標,訓練 student
網路,使得 student
網路的結果 \(p\) 接近 \(q\) ,因此,student
網路的損失函式為 \(L = CE(y,p)+\alpha CE(q,p)\)。這裡 CE
是交叉熵(Cross Entropy),\(y\) 是真實標籤的 onehot
編碼,\(q\) 是 teacher
網路的輸出結果,\(p\) 是 student
網路的輸出結果。
但是,直接使用 teacher
網路的 softmax 的輸出結果 \(q\),可能不大合適。因為,一個網路訓練好之後,對於正確的答案會有一個很高的置信度而錯誤答案的置信度會很小。例如,在 MNIST 資料中,對於某個 2 的輸入,對於 2 的預測機率會很高,而對於 2 類似的數字,例如 3 和 7 的預測機率為 \(10^-6\) 和 \(10^-9\)。這樣的話,teacher
網路學到資料的相似資訊(例如數字 2 和 3,7 很類似)很難傳達給 student
網路,因為它們的機率值接近0
。因此,論文提出了 softmax-T
(軟標籤計算公式),公式如下所示:
這裡 \(q_i\) 是 \(student\) 網路學習的物件(soft targets),\(z_i\) 是 teacher
模型 softmax
前一層的輸出 logit
。如果將 \(T\) 取 1,上述公式等同於 softmax,根據 logit 輸出各個類別的機率。如果 \(T\) 接近於 0,則最大的值會越近 1,其它值會接近 0,近似於 onehot
編碼。
所以,可以知道 student
模型最終的損失函式由兩部分組成:
- 第一項是由小模型的預測結果與大模型的“軟標籤”所構成的交叉熵(cross entroy);
- 第二項為預測結果與普通類別標籤的交叉熵。
這兩個損失函式的重要程度可透過一定的權重進行調節,在實際應用中,T
的取值會影響最終的結果,一般而言,較大的 T 能夠獲得較高的準確度,T(蒸餾溫度引數) 屬於知識蒸餾模型訓練超引數的一種。T 是一個可調節的超引數、T 值越大、機率分佈越軟(論文中的描述),曲線便越平滑,相當於在遷移學習的過程中新增了擾動,從而使得學生網路在借鑑學習的時候更有效、泛化能力更強,這其實就是一種抑制過擬合的策略。
知識蒸餾演算法整體的框架圖如圖下所示。
圖片來源 https://intellabs.github.io/distiller/knowledge_distillation.html。
三,輕量級模型架構
輕量級網路的核心是在儘量保持精度的前提下,從體積和速度兩方面對網路進行輕量化改造。關於如何手動設計輕量級網路的研究,目前還沒有廣泛通用的準則,只有一些指導思想,和針對不同晶片平臺(不同晶片架構)的一些設計總結,建議大家從經典論文中吸取指導思想和建議,然後自己實際做各個硬體平臺的部署和模型效能測試。
對於卷積神經網路,典型的工作有 Mobilenet
系列網路、ShuffleNet
系列網路、RepVGG
、CSPNet
、VoVNet
等論文。輕量級網路論文解析可閱讀 github 專欄-輕量級網路。
3.1,如何設計高效CNN架構
一些結論
- 分析模型的推理效能得結合具體的推理平臺(常見如:英偉達
GPU
、移動端ARM
CPU
、端側NPU
晶片等);目前已知影響CNN
模型推理效能的因素包括: 運算元計算量FLOPs
(引數量Params
)、卷積block
的記憶體訪問代價(訪存頻寬)、網路並行度等。但相同硬體平臺、相同網路架構條件下,FLOPs
加速比與推理時間加速比成正比。 - 建議對於輕量級網路設計應該考慮直接
metric
(例如速度speed
),而不是間接metric
(例如FLOPs
)。 FLOPs
低不等於latency
低,尤其是在有加速功能的硬體 (GPU
、DSP
與TPU
)上不成立,得結合具硬體架構具體分析。- 不同網路架構的
CNN
模型,即使是FLOPs
相同,但其MAC
也可能差異巨大。 Depthwise
卷積操作對於流水線型CPU
、ARM
等移動裝置更友好,對於平行計算能力強的GPU
和具有加速功能的硬體(專用硬體設計-NPU 晶片)上比較沒有效率。Depthwise
卷積運算元實際上是使用了大量的低FLOPs
、高資料讀寫量的操作。因為這些具有高資料讀寫量的操作,再加上多數時候GPU
晶片算力的瓶頸在於訪存頻寬,使得模型把大量的時間浪費在了從視訊記憶體中讀寫資料上,從而導致GPU
的算力沒有得到“充分利用”。結論來源知乎文章-FLOPs與模型推理速度和論文 G-GhostNet。
一些建議
- 在大多數的硬體上,
channel
數為16
的倍數比較有利高效計算。如海思351x
系列晶片,當輸入通道為4
倍數和輸出通道數為16
倍數時,時間加速比會近似等於FLOPs
加速比,有利於提供NNIE
硬體計算利用率。(來源海思351X
晶片文件和MobileDets
論文) - 低
channel
數的情況下 (如網路的前幾層),在有加速功能的硬體使用普通convolution
通常會比separable convolution
有效率。(來源 MobileDets 論文) - shufflenetv2 論文 提出的四個高效網路設計的實用指導思想: G1同樣大小的通道數可以最小化
MAC
、G2-分組數太多的卷積會增加MAC
、G3-網路碎片化會降低並行度、G4-逐元素的操作不可忽視。 GPU
晶片上 \(3\times 3\) 卷積非常快,其計算密度(理論運算量除以所用時間)可達 \(1\times 1\) 和 \(5\times 5\) 卷積的四倍。(來源 RepVGG 論文)- 從解決梯度資訊冗餘問題入手,提高模型推理效率。比如 CSPNet 網路。
- 從解決
DenseNet
的密集連線帶來的高記憶體訪問成本和能耗問題入手,如 VoVNet 網路,其由OSA
(One-Shot Aggregation
,一次聚合)模組組成。
3.2,輕量級模型部署總結
在閱讀和理解經典的輕量級網路 mobilenet
系列、MobileDets
、shufflenet
系列、cspnet
、vovnet
、repvgg
等論文的基礎上,做了以下總結:
- 低算力裝置-手機移動端
cpu
硬體,考慮mobilenetv1
(深度可分離卷機架構-低FLOPs
)、低FLOPs
和 低MAC
的shuffletnetv2
(channel_shuffle
運算元在推理框架上可能不支援) - 專用
asic
硬體裝置-npu
晶片(地平線x3/x4
等、海思3519
、安霸cv22
等),分類、目標檢測問題考慮cspnet
網路(減少重複梯度資訊)、repvgg2
(即RepOptimizer
:vgg
型直連架構、部署簡單) - 英偉達
gpu
硬體-t4
晶片,考慮repvgg
網路(類vgg
卷積架構-高並行度有利於發揮gpu
算力、單路架構省視訊記憶體/記憶體,問題:INT8 PTQ
掉點嚴重)
MobileNet block
(深度可分離卷積 block
, depthwise separable convolution block
)在有加速功能的硬體(專用硬體設計-NPU
晶片)上比較沒有效率。
這個結論在 CSPNet 和 MobileDets 論文中都有提到。
除非晶片廠商做了定製最佳化來提高深度可分離卷積 block
的計算效率,比如地平線機器人 x3
晶片對深度可分離卷積 block
做了定製最佳化。
下表是 MobileNetv2
和 ResNet50
在一些常見 NPU
晶片平臺上做的效能測試結果。
以上,均是看了輕量級網路論文總結出來的一些不同硬體平臺部署輕量級模型的經驗,實際結果還需要自己手動執行測試。
四,模型剪枝
模型剪枝(model pruning)也叫模型稀疏化(model sparsity)。
深度學習模型中一般存在著大量冗餘的引數,將權重矩陣中相對“不重要”的權值剔除(即置為 0
),可達到降低計算資源消耗和提高實時性的效果,而對應的技術則被稱為模型剪枝。
來源論文 Han et al. Learning both Weights and Connections for Efficient Neural Networks, NIPS 2015。
上圖是典型的三段式剪枝演算法 pipeline
,主要是 3 個步驟:
- 正常訓練模型;
- 模型剪枝;
- 重新訓練模型
以上三個步驟反覆迭代進行,直到模型精度達到目標,則停止訓練。
模型剪枝演算法根據粒度的不同,可以粗分為細粒度剪枝和粗粒度剪枝,如下所示:
- 細粒度剪枝(fine-grained):對連線或者神經元進行剪枝,它是粒度最小的剪枝。
- 向量剪枝(vector-level):它相對於細粒度剪枝粒度更大,屬於對卷積核內部(intra-kernel)的剪枝。
- 核剪枝(kernel-level):去除某個卷積核,它將丟棄對輸入通道中對應計算通道的響應。
- 濾波器剪枝(Filter-level):也叫通道剪枝(
Channel Pruning
),對整個卷積核組進行剪枝,會造成推理過程中輸出特徵通道數的改變,濾波器剪枝的工作是目前研究最多的。
按照剪枝是否規則,剪枝演算法也可分為:
- 非結構化剪枝,其實就是前面的 1,對硬體支援不友好,需要設定特定硬體加速器,典型代表作是韓松
2016
年的論文。 - 結構化剪枝,如 2、3、4,對硬體支援友好,典型代表作如 Learning Efficient Convolutional Networks through Network Slimming 等。
4.1,結構化稀疏與非結構化剪枝比較
與非結構化剪枝相比,結構化剪枝通常通常會犧牲模型的準確率和壓縮比。結構化稀疏對非零權值的位置進行了限制,在剪枝過程中會將一些數值較大的權值剪枝,從而影響模型準確率。 “非規則”的剪枝則契合了神經網路模型中不同大小權值的隨機分佈,這對深度學習模型的準確度至關重要。展開來講就是:
- 非結構化稀疏具有更高的模型壓縮率和準確性,在通用硬體上的加速效果不好。因為其計算特徵上的“不規則”,導致需要特定硬體支援才能實現加速效果。
- 結構化稀疏雖然犧牲了模型壓縮率或準確率,但在通用硬體上的加速效果好,所以其被廣泛應用。因為結構化稀疏使得權值矩陣更規則更加結構化,更利於硬體加速。
綜上所述,深度神經網路的權值稀疏應該在模型有效性和計算高效性之間做權衡。
目前,有一種趨勢是在軟硬體上都支援稀疏張量,因此未來非結構化剪枝可能會變得更流行。
五,模型量化
相比於剪枝操作,引數量化則是一種常用的後端壓縮技術。所謂量化,其實可以等同於低精度(Low precision)運算概念,常規模型精度一般使用 FP32(32 位浮點數,單精度)儲存模型權重引數,低精度則表示使用 INT8
、FP16
等權重數值格式。
模型量化(Model Quantization
,也叫網路量化)過程分為兩部分:將模型的單精度引數(一般 FP32
-32
位浮點引數)轉化為低精度引數(一般 INT8
-8
位定點引數),以及模型推理過程中的浮點運算轉化為定點運算,這個需要推理框架支援。
模型量化技術可以降低模型的儲存空間、記憶體佔用和計算資源需求,從而提高模型的推理速度,也是為了更好的適配移動端/端側 NPU
加速器。簡單總結就是,模型變小了,速度變快了,支援的場景更多了。
最後,現在工業界主流的思路就是模型訓練使用高精度-FP32 引數模型,模型推理使用低精度-INT8 引數模型: 將模型從 FP32 轉換為 INT8(即量化算術過程),以及使用 INT8 進行推理。
5.1,模型量化的方案
在實踐中將浮點模型轉為量化模型的方法有以下三種方法:
data free
:不使用校準集,傳統的方法直接將浮點引數轉化成量化數,使用上非常簡單,但是一般會帶來很大的精度損失,但是高通最新的論文DFQ
不使用校準集也得到了很高的精度。calibration
:基於校準集方案,透過輸入少量真實資料進行統計分析。很多晶片廠商都提供這樣的功能,如tensorRT
、高通、海思、地平線、寒武紀finetune
:基於訓練finetune
的方案,將量化誤差在訓練時模擬建模,調整權重使其更適合量化。好處是能帶來更大的精度提升,缺點是要修改模型訓練程式碼,開發週期較長。
按照量化階段的不同,量化方法分為以下兩種:
- Post-training quantization
PTQ
(訓練後量化、離線量化); - Quantization-aware training
QAT
(訓練時量化,偽量化,線上量化)。
5.2,量化的分類
目前已知的加快推理速度機率較大的量化方法主要有:
- 二值化,其可以用簡單的位運算來同時計算大量的數。對比從 nvdia gpu 到 x86 平臺,1bit 計算分別有 5 到128倍的理論效能提升。且其只會引入一個額外的量化操作,該操作可以享受到 SIMD(單指令多資料流)的加速收益。
- 線性量化(最常見),又可細分為非對稱,對稱和
ristretto
幾種。在nvdia gpu
,x86
、arm
和 部分AI
晶片平臺上,均支援8bit
的計算,效率提升從1
倍到16
倍不等,其中tensor core
甚至支援4bit
計算,這也是非常有潛力的方向。線性量化引入的額外量化/反量化計算都是標準的向量操作,因此也可以使用SIMD
進行加速,帶來的額外計算耗時不大。 - 對數量化,一種比較特殊的量化方法。兩個同底的冪指數進行相乘,那麼等價於其指數相加,降低了計算強度。同時加法也被轉變為索引計算。目前
nvdia gpu
,x86
、arm
三大平臺上沒有實現對數量化的加速庫,但是目前已知海思351X
系列晶片上使用了對數量化。
六,壓縮方法總結
- 按照剪枝是否規則,剪枝演算法可分為:非結構化剪枝和結構化剪枝。前者可以保持高模型壓縮率和準確率,但難加速;後者更利於硬體加速,但犧牲了模型壓縮率或準確率。
- 如果需要一次性端對端訓練得到壓縮與加速後模型,可以考慮基於輕量化網路設計的模型進行模型壓縮與加速。
- 影響神經網路推理速度主要有
4
個因素:計算量FLOPs
、記憶體訪問代價MAC
、計算並行度、硬體平臺架構與特性(算力、GPU 記憶體頻寬)。