深度学习模型轻量化(下)
深度學(xué)習(xí)模型輕量化(下)
2.4 蒸餾
2.4.1 蒸餾流程
蒸餾本質(zhì)是student對teacher的擬合,從teacher中汲取養(yǎng)分,學(xué)到知識,不僅僅可以用到模型壓縮和加速中。蒸餾常見流程如下圖所示
-
老師和學(xué)生可以是不同的網(wǎng)絡(luò)結(jié)構(gòu),比如BERT蒸餾到BiLSTM網(wǎng)絡(luò)。但一般相似網(wǎng)絡(luò)結(jié)構(gòu),蒸餾效果會更好。
-
總體loss為 soft_label_loss + hard_label_loss。soft_label_loss可以用KL散度或MSE擬合
-
soft label為teacher模型的要擬合的對象。可以是模型預(yù)測輸出,也可以是embeddings, 或者h(yuǎn)idden layer和attention分布。
針對軟標(biāo)簽的定義,蒸餾的方案也是百花齊放,下面分享兩篇個人認(rèn)為非常經(jīng)典的文章。
2.4.2 distillBERT
DistillBERT: A distilled version of BERT: smaller,
faster, cheaper and lighter
DistillBERT由大名鼎鼎的HuggingFace出品。主要創(chuàng)新點為:
-
Teacher 12層,student 6層,每兩層去掉一層。比如student第二層對應(yīng)teacher第三層
-
Loss= 5.0 * Lce+2.0 * Lmlm+1.0 * Lcos
·
Lce: soft_label 的KL散度
·
Lmlm: mask LM hard_label
的交叉熵
·
Lcos:hidden state 的余弦相似度
DistilBERT 比 BERT 快 60%,體積比 BERT 小 60%。在glue任務(wù)上,保留了 95% 以上的性能。在performance損失很小的情況下,帶來了較大的模型壓縮和加速效果。
2.4.3 TinyBERT
TinyBERT: Distilling BERT for Natural Language
Understanding
總體結(jié)構(gòu)
重點來看下 TinyBERT,它是由華為出品,非常值得深入研究。TinyBERT 對 embedding 層,transformer層(包括hidden layer和attention)和 prediction 層均進(jìn)行了擬合。如下圖所示。
TinyBERT蒸餾過程
其中Embeddings采用MSE, Prediction采用KL散度, Transformer層的hidden layer和attention,均采用MSE。loss如下
其中m為層數(shù)。
效果分析
表2: glue任務(wù)上的performance。在glue任務(wù)上,可達(dá)到bert-base的96%,幾乎無損失。表3: tinyBERT模型大小和推理速度。縮小7.5倍,加速9.4倍。壓縮和加速效果十分明顯。
消融分析
表6:分析embedding、prediction、attention、hidden layer軟標(biāo)簽作用,其中attention和hidden layer作用最大。這個也很好理解,transformer層本來就是整個BERT中最關(guān)鍵的部分。
表7:分析老師學(xué)生不同層對應(yīng)方法的效果,uniform為隔層對應(yīng),top為全部對應(yīng)老師頂部幾層,bottom為全部對應(yīng)老師底部幾層。Uniform效果明顯好很多。這個也很好理解,淺層可以捕捉低階特征,深層可以捕捉高階特征。全是低階或者高階顯然不合適,我們要盡量葷素搭配。
3 框架層加速
3.1 手機(jī)端AI能力
目前移動端AI框架也比較多,包括谷歌的tf-lite,騰訊的NCNN,阿里的MNN,百度的PaddleLite,
小米的MACE等。他們都不同程度的進(jìn)行了模型壓縮和加速的支持。特別是端上推理的加速。這個可以參考“手機(jī)端AI性能排名“。
3.2 端側(cè)AI框架加速優(yōu)化方法
個人總結(jié)的主要方法如下,可能有遺漏哈,各位看官請輕拍:
- 基于基本的C++編譯器優(yōu)化。
a. 打開編譯器的優(yōu)化選項,選擇O2等加速選項。
b. 小函數(shù)內(nèi)聯(lián),概率大分支優(yōu)先,避免除法,查表空間換時間,函數(shù)參數(shù)不超過4個等。
-
利用C,而不是C++,C++有不少冗余的東西。
-
緩存優(yōu)化
a. 小塊內(nèi)存反復(fù)使用,提升cache命中率,盡量減少內(nèi)存申請。比如上一層計算完后,接著用作下一層計算。
b. 連續(xù)訪問,內(nèi)存連續(xù)訪問有利于一次同時取數(shù),相近位置cache命中概率更高。比如縱向訪問數(shù)組時,可以考慮轉(zhuǎn)置后變?yōu)闄M向訪問。
c. 對齊訪問,比如224224的尺寸,補(bǔ)齊為256224,從而提高緩存命中率。
d. 緩存預(yù)取,CPU計算的時候,preload后面的數(shù)據(jù)到cache中。
- 多線程。
a. 為循環(huán)分配線程。
b. 動態(tài)調(diào)度,某個子循環(huán)過慢的時候,調(diào)度一部分循環(huán)到其他線程中。
- 稀疏化
a. 稀疏索引和存儲方案,采用eigen的sparseMatrix方案。
- 內(nèi)存復(fù)用和提前申請
a. 掃描整個網(wǎng)絡(luò),計算每層網(wǎng)絡(luò)內(nèi)存復(fù)用的情況下,最低的內(nèi)存消耗。推理剛開始的時候就提前申請好。避免推理過程中反復(fù)申請和釋放內(nèi)存,避免推理過程中因為內(nèi)存不足而失敗,復(fù)用提升內(nèi)存訪問效率和cache命中率。
-
ARM NEON指令的使用,和ARM的深度融合。NEON可以單指令多取值(SIMD),感興趣可針對學(xué)習(xí),這一塊水也很深。
-
手工匯編,畢竟機(jī)器編譯出來的代碼還是有不少冗余的。可以針對運(yùn)行頻次特別高的代碼進(jìn)行手工匯編優(yōu)化。當(dāng)然如果你匯編功底驚天地泣鬼神的強(qiáng),也可以全方位手工匯編。
-
算子支持:比如支持GPU加速,支持定點化等。有時候需要重新開發(fā)端側(cè)的算子。
4 硬件層加速
硬件層加速比較硬核,小編就連半瓢水都達(dá)不到了,為了保證整個方案的全面性,還是硬著頭皮東施效顰下。目前AI芯片廠家也是百花齊放,誰都想插一腳,不少互聯(lián)網(wǎng)公司也來趕集,如下圖所示。
AI 芯片目前三種方案。GPU目前被英偉達(dá)和AMD牢牢把控。ASIC目前最火,TPU、NPU等屬于ASIC范疇。
5 總結(jié)
本文對深度學(xué)習(xí)模型壓縮和加速的幾類常用的方法進(jìn)行了介紹。
參考文獻(xiàn)
-
ALBERT: A Lite BERT for Self-supervised Learning of
Language Representations -
MobileNets: Efficient Convolutional Neural Networks for
Mobile Vision Applications -
Are Sixteen Heads Really Better than One?
-
DistillBERT: A distilled version of BERT: smaller, faster,
cheaper and lighter -
TinyBERT: Distilling BERT for Natural Language
Understanding -
手機(jī)端AI性能排名
總結(jié)
以上是生活随笔為你收集整理的深度学习模型轻量化(下)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 智能驾驶开发的几个问题
- 下一篇: MAML-Tracker: 目标跟踪分析