我的BERT!改改字典,让BERT安全提速不掉分(已开源)
文 | 蘇劍林
編 | 小軼
背景
當前,大部分中文預訓練模型都是以字為基本單位的,也就是說中文語句會被拆分為一個個字。中文也有一些多粒度的語言模型,比如創(chuàng)新工場的ZEN和字節(jié)跳動的AMBERT,但這類模型的基本單位還是字,只不過想辦法融合了詞信息。目前以詞為單位的中文預訓練模型很少,據(jù)筆者所了解到就只有騰訊UER開源了一個以詞為顆粒度的BERT模型,但實測效果并不好。
那么,純粹以詞為單位的中文預訓練模型效果究竟如何呢?有沒有它的存在價值呢?最近,我們預訓練并開源了以詞為單位的中文BERT模型,稱之為WoBERT(Word-based BERT,我的BERT!)。實驗顯示,基于詞的WoBERT在不少任務(wù)上有它獨特的優(yōu)勢,比如速度明顯的提升,同時效果基本不降甚至也有提升。在此對我們的工作做一個總結(jié)。
開源地址:
https://github.com/ZhuiyiTechnology/WoBERT
字還是詞?
究竟是“字”好還是“詞”好?這是中文NLP一個很讓人抓狂的問題,也有一些工作去系統(tǒng)地研究這個問題。比較新的是香儂科技在ACL2019上發(fā)表的《Is Word Segmentation Necessary for Deep Learning of Chinese Representations?》,里邊得到了字幾乎總是優(yōu)于詞的結(jié)論。前面也說了,現(xiàn)在中文預訓練模型確實也基本上都是以字為單位的。所以,看上去這個問題已經(jīng)解決了?就是字更好?
事情遠沒有這么簡單。就拿香儂科技的這篇論文來說,它的實驗結(jié)果是沒有錯,但卻是沒有代表性的。為什么這樣說呢?因為在該文的實驗設(shè)置下,模型的embedding層皆從隨機初始化狀態(tài)開始訓練。這樣一來,對于同樣的任務(wù),以詞為單位的模型Embedding層參數(shù)更多,自然就更容易過擬合,效果容易變差,這不用做實驗都能猜個大概。問題是,我們用基于詞的模型的時候,通常并不是隨機初始化的,往往都是用預訓練好的詞向量的(下游任務(wù)看情況選擇是否微調(diào)詞向量),這才是分詞的NLP模型的典型場景,但論文里邊卻沒有比較這個場景,所以論文的結(jié)果并沒有什么說服力。
事實上,“過擬合”現(xiàn)象具有兩面性,我們要防止過擬合,但過擬合也正好說明了模型擁有比較強的擬合能力,而如果我們想辦法抑制過擬合,那么就能夠在同樣復雜度下得到更強的模型,或者在同樣效果下得到更低復雜度的模型。而緩解過擬合問題的一個重要手段就是更充分的預訓練,所以不引入預訓練的比較對以詞為單位的模型來說是不公平的,而我們的WoBERT正是證實了以詞為單位的預訓練模型的可取性。
詞的好處
一般認為,以字為單位的好處是:
參數(shù)更少,不容易過擬合;
不依賴于分詞算法,避免邊界切分錯誤;
沒那么嚴重的稀疏性,基本上不會出現(xiàn)未登錄詞。
至于以詞為單位的理由是:
序列變短,處理速度更快;
在文本生成任務(wù)上,能緩解Exposure Bias問題;
詞義的不確定性更低,降低建模復雜度。
對于詞的好處,大家可能會有些疑惑。比如第2點,詞能緩解Exposure Bias,這是因為理論上來說,序列越短Exposure Bias問題就越不明顯(詞模型單步預測出一個n字詞,相當于字的模型預測了n步,這n步都遞歸依賴,所以字的模型Exposure Bias問題更嚴重)。至于第3點,雖然有多義詞的存在,但是多數(shù)詞的含義還是比較確定的,至少比字義更加明確,這樣一來可能只需要一個Embedding層就能把詞義建模好,而不是像字模型那樣,要通用多層模型才能把字組合成詞。
看起來不相伯仲,但事實上以字為單位的好處,并非就是以詞為單位的缺點了。只要多一些技巧,以詞為單位也能一定程度上避免這幾個問題。比如:
以詞為單位的參數(shù)確實增多了,但是可以通過預訓練來緩解過擬合,所以這個問題不會很嚴重;
依賴分詞算法是個問題,如果我們只保留最常見的一部分詞,那么不管哪個分詞工具分出來的結(jié)果都是差不多的,差異性不大;
至于邊界切分錯誤,這個難以避免,但是需要準確的邊界的,只是序列標注類任務(wù)而已,文本分類、文本生成其實都不需要準確的邊界,因此不能就此否定詞模型;
如果我們把大部分字也加入到詞表中,也不會出現(xiàn)未登錄詞。
所以,其實用詞的好處是相當多的,除了需要非常精確邊界的序列標注類型的任務(wù)外,多數(shù)NLP任務(wù)以詞為單位都不會有什么問題。因此,我們就去做了以詞為單位的BERT模型了。
Tokenizer
往BERT里邊加入中文詞,首先得讓Tokenizer能分出詞來。只需要把詞加入到字典vocab.txt里邊就行了嗎?并不是。BERT自帶的Tokenizer會強行把中文字符用空格隔開,因此就算你把詞加入到字典中,也不會分出中文詞來。此外,BERT做英文word piece的分詞的時候,使用的是最大匹配法,這對中文分詞來說精度也不夠。
為了分出詞來,我們修改了一下BERT的Tokenizer,加入了一個“前分詞(pre_tokenize)”操作。這樣我們就可以分出中文詞來,具體操作如下:
把中文詞加入到vocab.txt;
輸入一個句子s,用pre_tokenize先分一次詞,得到;
遍歷各個,如果在詞表中則保留,否則將用BERT自帶的tokenize函數(shù)再分一次;
將每個的tokenize結(jié)果有序拼接起來,作為最后的tokenize結(jié)果。
在bert4keras>=0.8.8版本中,實現(xiàn)上述改動只需要在構(gòu)建Tokenizer的時候傳入一行參數(shù),例如:
tokenizer = Tokenizer(dict_path,do_lower_case=True,pre_tokenize=lambda s: jieba.cut(s, HMM=False) )其中pre_tokenize為外部傳入的分詞函數(shù),如果不傳入則默認為None。簡單起見,WoBERT使用了結(jié)巴分詞,刪除了BERT自帶詞表的冗余部分(比如帶##的中文詞),然后加入了20000個額外的中文詞(結(jié)巴分詞自帶的詞表詞頻最高的兩萬個),最終WoBERT的vocab.txt規(guī)模是33586。
模型細節(jié)
目前開源的WoBERT是Base版本,在哈工大開源的RoBERTa-wwm-ext基礎(chǔ)上進行繼續(xù)預訓練,預訓練任務(wù)為MLM。初始化階段,將每個詞用BERT自帶的Tokenizer切分為字,然后用字embedding的平均作為詞embedding的初始化。
到這里,WoBERT的技術(shù)要點基本上都說清楚了,剩下的就是開始訓練了。我們用單張24G的RTX訓練了100萬步(大概訓練了10天),序列長度為512,學習率為5e-6,batch_size為16,累積梯度16步,相當于batch_size=256訓練了6萬步左右。訓練語料大概是30多G的通用型語料。訓練代碼已經(jīng)在文章開頭的鏈接中開源了。
此外,我們還提供了WoNEZHA,這是基于華為開源的NEZHA進行再預訓練的,訓練細節(jié)跟WoBERT基本一樣。NEZHA的模型結(jié)構(gòu)跟BERT相似,不同的是它使用了相對位置編碼,而BERT用的是絕對位置編碼,因此理論上NEZHA能處理的文本長度是無上限的。這里提供以詞為單位的WoNEZHA,就是讓大家多一個選擇。
模型效果
最后,說一下WoBERT的效果。簡單來說,在我們的評測里邊,WoBERT相比于BERT,在不需要精確邊界的NLP任務(wù)上基本都沒有變差的,有些還會有一定的提升,而速度上則有明顯提升,所以一句話就是“提速不掉點”。
比如中文榜單上的兩個分類任務(wù):
我們內(nèi)部還測了不少任務(wù),結(jié)果都是類似的,表明這些NLU任務(wù)上WoBERT和BERT基本上都差不多的。但是速度上,WoBERT就比BERT有明顯優(yōu)勢了,下表是兩個模型在處理不同字數(shù)的文本時的速度比較:
我們還測了WoBERT+UniLM的方式Seq2Seq任務(wù)(CSL/LCSTS標題生成),結(jié)果是比以字為單位的模型有明顯提升:
這說明以詞為單位來做文本生成其實是更有優(yōu)勢的。要是生成更長的文本,這個優(yōu)勢還能進一步放大。
當然,我們也不否認,用WoBERT去做NER等序列標注任務(wù)時,可能會有明顯的掉點,比如做人民日報的NER,掉了3%左右,可能讓人意外的是,經(jīng)過bad case分析,我們發(fā)現(xiàn)掉點的原因并不是因為切分錯誤,而是因為稀疏性(平均來說每個詞的樣本更少,所以訓練得沒那么充分)。
不管怎么說,我們把我們的工作開源出來,給大家在使用預訓練模型的時候,多一個嘗試的選擇吧。
文章小結(jié)
在這篇文章里,我們開源了以詞為單位的中文BERT模型(WoBERT),并討論了以詞為單位的優(yōu)缺點,最后通過實驗表明,以詞為單位的預訓練模型在不少NLP任務(wù)(尤其是文本生成)上有它獨特的價值,一方面它有速度上的優(yōu)勢,一方面效果上能媲美以字為單位的BERT,歡迎大家測試。
文末福利
后臺回復關(guān)鍵詞【入群】
加入賣萌屋NLP/IR/Rec與求職討論群
有頂會審稿人、大廠研究員、知乎大V和妹紙
等你來撩哦~
總結(jié)
以上是生活随笔為你收集整理的我的BERT!改改字典,让BERT安全提速不掉分(已开源)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 拒绝无脑试错:写给萌新的“科学炼丹”入门
- 下一篇: 图灵奖得主Jeff Ullman:机器学