深度學習筆記之TinyBERT
- 引言
- 回顧:DistilBERT模型
- TinyBERT模型結構
- TinyBERT模型策略
- Transformer層蒸餾
- 嵌入層蒸餾
- 預測層蒸餾
- TinyBERT模型的訓練
- 效果展示
引言
上一節介紹了 DistilBERT \text{DistilBERT} DistilBERT模型,本節將繼續介紹優化性更強的知識蒸餾 BERT \text{BERT} BERT模型—— TinyBERT \text{TinyBERT} TinyBERT模型。
回顧:DistilBERT模型
DistilBERT \text{DistilBERT} DistilBERT模型是一種基于 BERT-base \text{BERT-base} BERT-base的知識蒸餾版本,其模型結構表示如下。單從模型結構的角度觀察,學生模型神經元的維度沒有發生變化 ( 768 ) (768) (768),僅是 Encoder \text{Encoder} Encoder層數減少為 BERT-base \text{BERT-base} BERT-base的一半;并且各層的初始化繼承了一部分 BERT-base \text{BERT-base} BERT-base:從教師模型的 Encoder \text{Encoder} Encoder層中每兩層選擇一層作為學生模型 Encoder \text{Encoder} Encoder層的初始化。
DistilBERT \text{DistilBERT} DistilBERT訓練出的學生模型( param:66M \text{param:66M} param:66M)依然可以達到 BERT-base \text{BERT-base} BERT-base模型幾乎 97 97 97%的準確度。能夠達到這個效果離不開 DistilBERT \text{DistilBERT} DistilBERT的三個核心策略:
- 掩碼語言模型策略 ( Masked?Language?Model ) (\text{Masked Language Model}) (Masked?Language?Model):根據 RoBERTa \text{RoBERTa} RoBERTa中的描述,摒棄掉下句預測 ( Next?Sentence?Prediction,NSP ) (\text{Next Sentence Prediction,NSP}) (Next?Sentence?Prediction,NSP)策略,并使用動態掩碼替代靜態掩碼作為 BERT \text{BERT} BERT模型的訓練策略;
- 蒸餾策略 ( Distillation?loss ) (\text{Distillation loss}) (Distillation?loss):通過使用 Softmax \text{Softmax} Softmax溫度函數將教師模型 BERT-base \text{BERT-base} BERT-base與學生模型 DistilBERT \text{DistilBERT} DistilBERT輸出層的解空間盡可能地相似:
其中
N N N表示教師模型和學生模型的輸出層維度,在
DistilBERT \text{DistilBERT} DistilBERT模型中,兩者的維度相同,均為
768 768 768。
T ( x ) = ( t 1 , t 2 , ? , t N ) S ( x ) = ( s 1 , s 2 , ? , s N ) L c r o s s = ? ∑ i = 1 N t i ? log ? ( s i ) \begin{aligned} & \mathcal T(x) = (t_1,t_2,\cdots,t_N) \\ & \mathcal S(x) = (s_1,s_2,\cdots,s_{N}) \\ & \mathcal L_{cross} = -\sum_{i=1}^{N} t_i * \log (s_i) \end{aligned} ?T(x)=(t1?,t2?,?,tN?)S(x)=(s1?,s2?,?,sN?)Lcross?=?i=1∑N?ti??log(si?)? - 余弦嵌入策略 ( Cosine?Embedding?loss ) (\text{Cosine Embedding loss}) (Cosine?Embedding?loss):通過計算輸出層分布向量之間夾角的余弦值 cos ? [ T ( x ) , S ( x ) ] \cos [\mathcal T(x),\mathcal S(x)] cos[T(x),S(x)],當該值為 1 1 1時,對應的 L c o s i n e \mathcal L_{cosine} Lcosine?達到最小。此時兩向量的方向為同一方向,教師和學生模型輸出的解空間已被對齊:
L c o s i n e = 1 ? cos ? [ T ( x ) , S ( x ) ] \mathcal L_{cosine} = 1 - \cos[\mathcal T(x),\mathcal S(x)] Lcosine?=1?cos[T(x),S(x)]
總結:
在 ALBERT \text{ALBERT} ALBERT模型中介紹過,雖然 ALBERT \text{ALBERT} ALBERT也是 BERT \text{BERT} BERT的簡化版本,但它們的解空間并不相同;
與此相反, DistilBERT \text{DistilBERT} DistilBERT中除了繼承了 BERT \text{BERT} BERT中的掩碼語言模型策略外,剩余的兩條策略均是圍繞牢牢綁定教師模型與學生模型的解空間而設計。
重新觀察學生模型 DistilBERT \text{DistilBERT} DistilBERT,它能夠達到如此精煉的模型結構 ( param:110M?->?66M ) (\text{param:110M -> 66M}) (param:110M?->?66M),但依然保持極高的準確性,沒有出現欠擬合的情況。這至少意味著: DistilBERT \text{DistilBERT} DistilBERT模型中的神經元被利用得更加充分。
在這種情況下,是否可以百尺竿頭更進一步呢 ? TinyBERT ?\text{ TinyBERT} ??TinyBERT模型給了我們一個更精進的答案。
TinyBERT模型結構
相比于 DistilBERT \text{DistilBERT} DistilBERT模型中 Encoder \text{Encoder} Encoder層數減半的嚴肅操作, TinyBERT \text{TinyBERT} TinyBERT模型可以自定義學生模型的層數。并且還可以設置隱藏層單元中神經元的維度,從而使模型更加精簡。那么它是如何實現在如此精簡的模型結構下,不僅沒有欠擬合,而且還能保持優秀的訓練結果呢 ? ? ? 自然是依靠更加嚴苛的策略作為約束。
TinyBERT \text{TinyBERT} TinyBERT模型的教師-學生模型結構表示如下:
其中索引 0 0 0表示嵌入層, 1 1 1表示第一個 Encoder \text{Encoder} Encoder,以此類推。最后 N+1,M+1 \text{N+1,M+1} N+1,M+1分別表示教師、學生模型的預測層。
該蒸餾結構與 DistilBERT \text{DistilBERT} DistilBERT之間沒有太大區別,只不過沒有 DistilBERT \text{DistilBERT} DistilBERT中的初始化操作。教師與學生模型中各層的遷移過程可以表示為如下式子:
n = G ( m ) n = \mathcal G(m) n=G(m)
其表達的含義是:將教師模型中的第 n n n層遷移到學生模型的第 m m m層。例如:
- 0 = G ( 0 ) 0 = \mathcal G(0) 0=G(0)表示將教師模型的嵌入層知識遷移到學生模型的嵌入層;
- N + 1 = G ( M + 1 ) N+1 = \mathcal G(M+1) N+1=G(M+1)表示將教師模型的預測層知識遷移到學生模型的預測層;
- n = G ( m ) n = \mathcal G(m) n=G(m)表示將教師模型的第 n n n個 Encoder \text{Encoder} Encoder層知識遷移到學生模型的第 m m m個 Encoder \text{Encoder} Encoder層。
TinyBERT模型策略
那么 TinyBERT \text{TinyBERT} TinyBERT是如何制定策略的呢 ? ? ? 主要圍繞三個部分制定策略:
- Transformer \text{Transformer} Transformer層 ( Encoder ) (\text{Encoder}) (Encoder)
- 嵌入層 ( Embedding?Layer ) (\text{Embedding Layer}) (Embedding?Layer)
- 預測層 ( Predict?Layer ) (\text{Predict Layer}) (Predict?Layer)
Transformer層蒸餾
在 Transformer \text{Transformer} Transformer層也就是編碼器層,需要使用多頭注意力機制計算注意力矩陣,再使用 FeedForward?Network \text{FeedForward Network} FeedForward?Network進行一個前饋計算,并將最終計算得到的隱藏狀態特征作為該編碼器的輸出。在 TinyBERT \text{TinyBERT} TinyBERT中除了將教師模型中 Encoder \text{Encoder} Encoder內的注意力矩陣遷移到學生模型相應的 Encoder \text{Encoder} Encoder中,也同時將相應的隱藏狀態特征遷移到學生模型中。因而 Transformer \text{Transformer} Transformer層蒸餾包括兩次知識蒸餾:
- 基于注意力的蒸餾
通過最小化對應學生 Encoder \text{Encoder} Encoder和教師 Encoder \text{Encoder} Encoder內注意力矩陣的均方誤差來訓練對應學生 Encoder \text{Encoder} Encoder層:其中
h h h表示注意力機制頭的數量;
A i S \mathcal A_i^{\mathcal S} AiS?表示學生
Encoder \text{Encoder} Encoder內第
i i i個頭的注意力矩陣;
A i T \mathcal A_i^{\mathcal T} AiT?表示教師
Encoder \text{Encoder} Encoder內第
i i i個頭的注意力矩陣;
MSE \text{MSE} MSE表示均方誤差操作。
個人疑問:當學生模型隱藏層維度變化的時候
A i S , A i T \mathcal A_i^{\mathcal S},\mathcal A_i^{\mathcal T} AiS?,AiT?是一樣大的嗎?但書中并沒有解釋。
L a t t n = 1 h ∑ i = 1 h MSE ( A i S , A i T ) \mathcal L_{attn} = \frac{1}{h} \sum_{i=1}^{h} \text{MSE}(\mathcal A_i^{\mathcal S}, \mathcal A_i^{\mathcal T}) Lattn?=h1?i=1∑h?MSE(AiS?,AiT?)
需要注意的是,這里的注意力矩陣 A i S , A i T \mathcal A_i^{\mathcal S},\mathcal A_i^{\mathcal T} AiS?,AiT?使用的是執行 Layer?Norm \text{Layer Norm} Layer?Norm映射前的矩陣,這樣做的目的是保證信息的完整性,并且更快地收斂。
- 基于隱藏狀態的蒸餾
隱藏狀態是當前 Encoder \text{Encoder} Encoder的輸出,我們同樣需要將教師 Encoder \text{Encoder} Encoder的隱藏層知識遷移到學生 Encoder \text{Encoder} Encoder的隱藏層狀態中:
其中
H S \mathcal H_{\mathcal S} HS?表示學生
Encoder \text{Encoder} Encoder內的隱藏層狀態;
H T \mathcal H_{\mathcal T} HT?表示教師
Encoder \text{Encoder} Encoder內的隱藏層狀態。同樣使用均方誤差使
H S \mathcal H_{\mathcal S} HS?向
H T \mathcal H_{\mathcal T} HT?方向擬合。
L h i d n = MSE ( H S , H T ) \mathcal L_{hidn} = \text{MSE}(\mathcal H_{\mathcal S},\mathcal H_{\mathcal T}) Lhidn?=MSE(HS?,HT?)
但需要注意的是:當學生 Encoder \text{Encoder} Encoder隱藏層維度發生變化時, H S \mathcal H_{\mathcal S} HS?和 H T \mathcal H_{\mathcal T} HT?兩者之間的維度之間存在差異,因而需要訓練一個新的權重矩陣 W h \mathcal W_{h} Wh?使兩者處于同一級別的維度空間:
相當于作用在損失函數上的權重矩陣,反向傳播過程中同樣存在梯度更新。
L h i d n = MSE ( H S W h , H T ) \mathcal L_{hidn} = \text{MSE}(\mathcal H_{\mathcal S}\mathcal W_h, \mathcal H_{\mathcal T}) Lhidn?=MSE(HS?Wh?,HT?)
嵌入層蒸餾
關于嵌入層的蒸餾與隱藏狀態的蒸餾相似,當學生模型設置的隱藏層維度與教師模型維度不同時,兩者對應的 Embedding \text{Embedding} Embedding也不同。同樣在損失函數中添加一個新的權重參數 W E \mathcal W_{\mathcal E} WE?,使兩個 Embedding \text{Embedding} Embedding處于同一級別的維度空間:
其中
E S \mathcal E_{\mathcal S} ES?表示學生模型的
Embedding \text{Embedding} Embedding矩陣;
E T \mathcal E_{\mathcal T} ET?表示教師模型的
Embedding \text{Embedding} Embedding矩陣。
MSE \text{MSE} MSE表示均方誤差。
L e m b = MSE ( E S W E , E T ) \mathcal L_{emb} = \text{MSE}(\mathcal E_{\mathcal S} \mathcal W_{\mathcal E} ,\mathcal E_{\mathcal T}) Lemb?=MSE(ES?WE?,ET?)
預測層蒸餾
在預測層蒸餾部分,遷移的是輸出層的知識信息。這里和 DistilBERT \text{DistilBERT} DistilBERT模型關于預測層的損失類似。對于教師模型的輸出 Z T \mathcal Z^{\mathcal T} ZT和學生模型的輸出 Z S \mathcal Z^{\mathcal S} ZS:
- 使用 Softmax \text{Softmax} Softmax溫度函數分別獲取對應的軟目標 P T \mathcal P^{\mathcal T} PT和軟預測 P S \mathcal P^{\mathcal S} PS結果:
同理,
Z T \mathcal Z^{\mathcal T} ZT對應的軟目標結果
P T \mathcal P^{\mathcal T} PT不再贅述。
{ P i S = exp ? ( Z i S / T ) ∑ j exp ? ( Z j S ) / T P S = ( P 1 S , P 2 S , ? , P N S ) \begin{cases} \begin{aligned} \mathcal P_{i}^{\mathcal S} = \frac{\exp(\mathcal Z_i^{\mathcal S} / \mathcal T)}{\sum_{j} \exp(\mathcal Z_j^{\mathcal S}) / \mathcal T} \end{aligned} \\ \quad \\ \mathcal P^{\mathcal S} = (\mathcal P_1^{\mathcal S},\mathcal P_{2}^{\mathcal S},\cdots,\mathcal P_{N}^{\mathcal S}) \end{cases} ? ? ??PiS?=∑j?exp(ZjS?)/Texp(ZiS?/T)??PS=(P1S?,P2S?,?,PNS?)? - 再使用交叉熵損失函數對 P S \mathcal P^{\mathcal S} PS與 P T \mathcal P^{\mathcal T} PT進行描述:
L p r e d = ? P T ? log ? ( P S ) \mathcal L_{pred} = - \mathcal P^{\mathcal T} \cdot \log \left(\mathcal P^{\mathcal S} \right) Lpred?=?PT?log(PS)
最終, TinyBERT \text{TinyBERT} TinyBERT包含所有層的損失函數表示如下:
這里
[ S m , T G ( m ) ] [\mathcal S_{m},\mathcal T_{\mathcal G(m)}] [Sm?,TG(m)?]表示學生模型的第
m m m層與教師模型第
G ( m ) \mathcal G(m) G(m)之間的遷移關系。
L [ S m , T G ( m ) ] = { L e m b ( S 0 , T 0 ) m = 0 L h i d n ( S m , T G ( m ) ) M ≥ m > 0 L p r e d ( S M + 1 , T N + 1 ) m = M + 1 \mathcal L \left[ \mathcal S_{m},\mathcal T_{\mathcal G(m)}\right]= \begin{cases} \mathcal L_{emb}(\mathcal S_0,\mathcal T_0) \quad m = 0 \\ \mathcal L_{hidn}(\mathcal S_m,\mathcal T_{\mathcal G(m)}) \quad M \geq m > 0 \\ \mathcal L_{pred} (\mathcal S_{M+1},\mathcal T_{N+1}) \quad m = M + 1 \end{cases} L[Sm?,TG(m)?]=? ? ??Lemb?(S0?,T0?)m=0Lhidn?(Sm?,TG(m)?)M≥m>0Lpred?(SM+1?,TN+1?)m=M+1?
可以看出:
- TinyBERT \text{TinyBERT} TinyBERT損失函數數量是不確定的。它取決于設計學生模型 ( TinyBERT ) (\text{TinyBERT}) (TinyBERT)的層的數量;
- 相比于 DistilBERT \text{DistilBERT} DistilBERT, TinyBERT \text{TinyBERT} TinyBERT需要為削減隱藏層狀態維度和層數付出相應的代價——設計的策略需要與教師模型關系更加緊密,并精確到注意力矩陣和隱藏層狀態,從而得到一個與教師模型關聯更加緊密的、學生模型的解空間。
TinyBERT模型的訓練
在文章中作者描述的訓練流程表示如下:
在 TinyBERT \text{TinyBERT} TinyBERT模型中,使用兩個階段進行訓練:
- 通用蒸餾:在該階段,使用 BERT-base \text{BERT-base} BERT-base預訓練模型作為教師,并使用 BERT-base \text{BERT-base} BERT-base的訓練集對學生模型 ( TinyBERT ) (\text{TinyBERT}) (TinyBERT)進行蒸餾。并將該模型稱作通用 TinyBERT \text{TinyBERT} TinyBERT模型。
- 特定任務蒸餾:在微調階段,將基于一項具體任務對通用 TinyBERT \text{TinyBERT} TinyBERT模型進行微調 ( fine-tuning ) (\text{fine-tuning}) (fine-tuning)。具體微調過程方式為:
- 使用預訓練 BERT-base \text{BERT-base} BERT-base模型針對具體任務進行微調,并將這個微調后的 BERT-base \text{BERT-base} BERT-base模型作為教師;
- 將上述經過通用蒸餾得到的通用 TinyBERT \text{TinyBERT} TinyBERT模型作為學生,經過蒸餾,得到的 TinyBERT \text{TinyBERT} TinyBERT模型稱作微調的 TinyBERT \text{TinyBERT} TinyBERT模型。
效果展示
論文中關于 TinyBERT \text{TinyBERT} TinyBERT對于各下游任務中,與各模型比較結果如下:
其中, DistilBERT 4 \text{DistilBERT}_4 DistilBERT4?表示學生模型包含 4 4 4層 Encoder \text{Encoder} Encoder,其他同理。可以發現:
- 相比于 DistilBERT 4 \text{DistilBERT}_4 DistilBERT4?, TinyBERT 4 \text{TinyBERT}_4 TinyBERT4?使用不到其 30 30 30%,但準確率卻遠高于 DistilBERT \text{DistilBERT} DistilBERT模型;
- TinyBERT 6 \text{TinyBERT}_6 TinyBERT6?參數數量是 BERT-base \text{BERT-base} BERT-base的 60 60 60%左右,但其準確性基本與 BERT-base \text{BERT-base} BERT-base持平。
Reference \text{Reference} Reference:
論文鏈接
《BERT基礎教程——Transformer大模型實戰》