摘要:BERT由於效果好和適用範圍廣兩大優勢,因此在NLP領域具備里程碑意義。實際項目中主要使用BERT來作文本分類任務,其實就是給文本打標籤。由於原生態BERT預訓練模型動輒幾百兆甚至上千兆的大小,模型訓練速度很是慢,對於BERT模型線上化很是不友好。本篇研究目前比較火的BERT最新派生產品ALBERT來完成BERT線上化服務。ALBERT使用參數減小技術來下降內存消耗從而最終達到提升BERT的訓練速度,而且在主要基準測試中均名列前茅,可謂跑的快,還跑的好。但願對須要將BERT線上化感興趣的小夥伴有些許幫助。
目錄
01 項目背景介紹
02 從BERT到ALBERT
03 萬里第一步:先跑通模型
04 多分類任務實踐
總結
01 項目背景介紹
原生態BERT預訓練模型動輒幾百兆甚至上千兆的大小,訓練速度很是慢,對於模型線上化很是不友好。爲了實現BERT模型線上化問題,其實就是如何又快有好的訓練模型,經調研目前超火的BERT最新派生產品ALBERT項目能很好的解決上述問題。
ALBERT是由論文《ALBERT: A Lite BERT For Self-Supervised Learningof Language Representations》提出來的。一般狀況下增長預訓練模型大小能夠提高模型在下游任務中的性能,可是由於「GPU/TPU內存的限制、更長的訓練時間以及意想不到的模型退化」等問題,做者提出了ALBERT模型。
論文下載地址:
https://arxiv.org/pdf/1909.11942.pdf
通俗的理解ALBERT就是參數數量更少的輕量級BERT模型。ALBERT是BERT最新派生產品,雖然輕量,可是效果並沒打折,在主要基準測試中均名列前茅。
02 從BERT到ALBERT
1. ALBERT出現背景
自從深度學習引爆計算機視覺領域以後,提高模型性能最簡單也最有效的一個方法就是增長網絡深度。下圖中拿圖片分類任務舉例,能夠看出隨着網絡層數不斷增長,模型的效果也會有很大提高:python
一樣的狀況也出如今BERT上,隨着網絡變深變寬使得模型的效果獲得提高:git
可是網絡變深變寬帶來一個顯著的問題:參數爆炸。這裏看下不一樣規模參數的BERT模型參數量的變「胖」之路:github
如何作到,讓BERT不那麼「胖」,可是效果依舊好是目前學術界的研究重點,也是如何將BERT線上化的重點工做之一。這也是ALBERT要作的事情。
2. BERT「胖」在哪裏
想讓BERT變瘦,先要知道「肉」長在哪裏。BERT使用Transformer做爲特徵抽取器,這是BERT參數的來源。以前廣告行業中那些趣事系列4:詳解從配角到C位出道的Transformer很深刻的剖析了Transformer,有興趣的小夥伴能夠回頭看看。
Transformer的參數來源主要有大塊:第一塊是token embedding映射模塊,參數量佔比爲20%,第二塊是attention層和前向反饋層FFN,參數量佔比爲80%。微信
3. ALBERT優化策略
策略1、對embedding參數因式分解(Factorized embedding parameterization)
BERT將詞的one-hot向量映射到高維空間,參數量是O(VXH),ALBERT則採用因式分解的方式先將詞的one-hot向量映射到低維空間(大小爲E),而後再映射回一個高維的空間(大小爲H),這樣使用的參數僅僅是O(VXE+EXH),若是E<<H的時候參數量會減小不少。這裏就必定程度上減小了上面說的BERT第一部分參數token embedding的部分。
能夠經過因式分解減小參數量的緣由是token embedding是上下文獨立的,經過one-hot向量轉化成dense向量。而第二部分的attention和FFN做爲隱藏層是上下文依賴的,包含更多信息。因此經過一個小於H的E作中介將詞的one-hot向量先通過一個低維的embedding矩陣,而後再映射回高維的embedding矩陣是可行的。下圖中紅色方框顯示了因式分解部分:網絡
查看token embedding因式分解效果狀況:整體來看下降了17%的模型參數,可是模型效果僅僅下降了不到1%。性能
圖6 因式分解下降參數量效果
策略2、共享層與層之間的參數(Cross-layer parameter sharing)
經過對Transformer各層參數可視化分析發現各層參數相似,都是在[CLS]token和對角線上分配更多的注意力,因此可使用跨層的參數共享方案。
一般來講,跨層的參數共享對應Transformer編碼器中的結構有兩種方案:一種是attention模塊的參數共享,另外一種是前饋神經網絡層FFN的參數共享。具體的效果以下圖所示:學習
當映射到低維空間E=768時,對比不共享參數和共享FFN層的參數能夠看出,參數減小了近50%,這也是致使模型效果降低的主要緣由。而共享attention層的參數則對模型效果影響較小。
策略3、構建自學習任務-句子連貫性預測
經過改造NSP(Next Sentence Prediction)任務,加強網絡學習句子的連續型來提升預訓練任務。
廣告行業中那些趣事系列3:NLP中的巨星BERT重點講解了BERT模型,其中提到BERT是近幾年NLP領域傑出成果的集大成者,自己的創新主要是隨機屏蔽的語言模型Masked LM和下一句預測Next Sentence Prediction。有興趣的小夥伴能夠倒回去再好好看下。
NSP任務自己是一個二分類任務,目的是預測兩句話是不是連續的語句。NSP實際包含兩個子任務,分別是主題預測和關係一致性預測。NSP任務選擇同一文檔中連續的兩個句子做爲正樣本,選擇不一樣文檔的句子做爲負樣本。由於來自不一樣的文檔,差別性可能很是大。爲了提高模型預測連續型句子的能力,ALBERT提出了新的任務SOP(SenteceOrder Prediction),正樣本獲取方式和NSP相同,負樣本則將正樣本的語句順序顛倒。
SOP和NSP效果展現以下圖所示:
測試
從圖中能夠看出NSP任務沒法預測SOP類任務,可是SOP能夠預測NSP任務。總體來看,SOP任務的模型效果也優於NSP任務。
策略4、去掉dropout
dropout主要是爲了防止過擬合,但實際MLM通常不容易過擬合。去掉dropout還能夠較少中間變量從而有效提高模型訓練過程當中內存的利用率。
優化
其餘策略:網絡寬度和深度對模型效果的影響
1. 網絡深度是否越深越好
對比ALBERT在不一樣深度下的效果能夠發現:隨着層數加深,不一樣NLP任務的模型效果是有必定提高。可是這種狀況並非絕對的,有些任務效果反而會降低。
編碼
2. 網絡寬度是否越寬越好
對比深度爲3的ALBERT-large模型下不一樣網絡寬度的模型效果狀況能夠發現:模型寬度的影響和深度相似,隨着網絡寬度增長,不一樣NLP任務的模型效果是有必定提高。某些任務也會存在效果降低的狀況。
整體來看,ALBERT的實質是使用參數減小技術來下降內存消耗從而最終達到提升BERT的訓練速度,主要優化了如下幾個方面:
03 萬里第一步:先跑通模型
由於實際項目中主要是識別中文,因此主要是使用ALBERT中文版本ALBERT_zh,項目的github地址:https://github.com/brightmart/albert_zh。
記得以前看過一個圖片頗有意思,能很好的描述此刻個人心情:
對於我這種「拿來主義者」來講,再牛逼的模型第一步永遠都是先跑通它,至於優化的先放一放。跑通它不只能提高自信心,最實際的做用就是能快速實現項目上線。由於我須要完成文本分類任務,因此經過上面的github地址下載項目後,在集羣上跳轉到albert_zh目錄下,執行sh run_classifier_lcqmc.sh命令便可跑起來。由於項目沒有句子分類任務,只有個相似的句子關係判斷任務,因此先跑通這個任務,後期再根據這個任務的代碼來改就好了。
run_classifier_lcqmc.sh腳本中整體分紅兩大塊,第一塊是模型運行的準備工做,第二塊就是模型運行。下面是模型的第一塊,其中涉及獲取數據、預訓練模型、設備以及模型相關的參數等等。
第二塊就是負責模型運行,主要就是python運行程序的指令以及須要的相關參數配置。
總結下,這裏重點講了如何運行成功ALBERT_zh自己提供的一個句子關係判斷任務。這個demo是和咱們實際項目中文本分類任務很類似的任務,下面就是經過改造這個腳本以及執行的代碼來完成咱們的實際項目文本分類。
04 多分類任務實踐
項目改造的github地址以下:https://github.com/wilsonlsm006/albert_zh。
將原項目fork下來,這裏我增長了兩個文件run_classifier_multiclass.sh和run_classifier_multiclass.py。這是用來執行文本分類的任務腳本以及代碼。改造的原理其實也比較簡單,這裏大體講解下。
項目原來提供的句子關係判斷任務的數據格式是:id,text_a,text_b,label,任務其實就是來判斷兩句話到底有沒有關係。正樣本舉例以下:
text_a:成龍大哥代言的一刀傳奇好玩麼?
text_b:成龍大哥還代言過其餘傳奇麼?
label:1
負樣本則多是這樣的:
text_a:成龍大哥代言的一刀傳奇好玩麼?
text_b:成都市內哪一個景點最好玩?
label:0
經過上面兩個正負樣本的例子你們應該能瞭解什麼是句子關係判斷任務,其實就是有監督學習的分類任務。咱們實際項目主要經過BERT來作文本分類,識別一句話屬於哪一個標籤,對應到上面的任務其實就是隻有text_a,label。由於任務類型一致,因此修改代碼的策略就是重點分析有text_b的代碼的部分。具體腳本和代碼修改就是上面說的兩個文件,有須要的小夥伴自取。這裏須要注意的是原來的數據文件是tsv格式,我這邊是csv格式,數據輸入有點點不一樣,模型其餘的都沒動。
總結
實際項目中須要將BERT線上化須要使模型又快又好的訓練,因此通過調研使用目前BERT最新的派生產品ALBERT。ALBERT經過因式分解和共享層與層之間的參數減小了模型參數量,提高了參數效率;經過SOP替代NOP,加強了網絡學習句子的連續性的能力,提高了自監督學習任務的能力;經過去掉dropout能夠節省不少臨時變量,有效提高模型訓練過程當中內存的利用率,提高了模型的效率,減小了訓練數據的規模。最後將項目中的句子關係判斷任務改形成咱們實際項目中的文本分類任務用於實際業務需求。能夠說是有理論,幫助小夥伴們理解ALBERT爲啥訓練快了,效果還不錯。也有實踐,若是須要使用ALBERT作文本分類任務,直接用我改造好的腳本和代碼跑起來就行。
喜歡本類型文章的小夥伴能夠關注個人微信公衆號:數據拾光者。有任何干貨我會首先發布在微信公衆號,還會同步在知乎、頭條、簡書、csdn等平臺。也歡迎小夥伴多交流。若是有問題,能夠在微信公衆號隨時Q我哈。