pytorch中文語言模型bert預訓練程式碼

ACL2020 Best Paper有一篇論文提名獎,Don』t Stop Pretraining: Adapt Language Models to Domains and Tasks》。這篇論文做了很多語言模型預訓練的實驗,系統的分析了語言模型預訓練對子任務的效果提升情況。有幾個主要結論:

  • 在目標領域的數據集上繼續預訓練(DAPT)可以提升效果;目標領域的語料與RoBERTa的原始預訓練語料越不相關,DAPT效果則提升更明顯。

  • 在具體任務的數據集上繼續預訓練(TAPT)可以十分「廉價」地提升效果。

  • 結合二者(先進行DAPT,再進行TAPT)可以進一步提升效果。

  • 如果能獲取更多的、任務相關的無標註數據繼續預訓練(Curated-TAPT),效果則最佳。

  • 如果無法獲取更多的、任務相關的無標註數據,採取一種十分輕量化的簡單數據選擇策略,效果也會提升。

知乎專欄《高能NLP》

//zhuanlan.zhihu.com/p/149210123

雖然在bert上語言模型預訓練在演算法比賽中已經是一個穩定的上分操作。但是上面這篇文章難能可貴的是對這個操作進行了系統分析。大部分中文語言模型都是在tensorflow上訓練的,一個常見例子是中文roberta項目。可以參考

//github.com/brightmart/roberta_zh

使用pytorch進行中文bert語言模型預訓練的例子比較少。在huggingface的Transformers中,有一部分程式碼支援語言模型預訓練(不是很豐富,很多功能都不支援比如wwm)。為了用最少的程式碼成本完成bert語言模型預訓練,本文借鑒了裡面的一些現成程式碼。也嘗試分享一下使用pytorch進行語言模型預訓練的一些經驗。主要有三個常見的中文bert語言模型

  1. bert-base-chinese

  2. roberta-wwm-ext

  3. ernie

1 bert-base-chinese

(//huggingface.co/bert-base-chinese)


這是最常見的中文bert語言模型,基於中文維基百科相關語料進行預訓練。把它作為baseline,在領域內無監督數據進行語言模型預訓練很簡單。只需要使用官方給的例子就好。

//github.com/huggingface/transformers/tree/master/examples/language-modeling

(本文使用的transformers更新到3.0.2)

方法就是

python run_language_modeling.py \    --output_dir=output \    --model_type=bert \    --model_name_or_path=bert-base-chinese \    --do_train \    --train_data_file=$TRAIN_FILE \    --do_eval \    --eval_data_file=$TEST_FILE \    --mlm

其中$TRAIN_FILE 代表領域相關中文語料地址。

2 roberta-wwm-ext

(//github.com/ymcui/Chinese-BERT-wwm)

哈工大訊飛聯合實驗室發布的預訓練語言模型。預訓練的方式是採用roberta類似的方法,比如動態mask,更多的訓練數據等等。在很多任務中,該模型效果要優於bert-base-chinese。

對於中文roberta類的pytorch模型,使用方法如下

import torchfrom transformers import BertTokenizer, BertModeltokenizer = BertTokenizer.from_pretrained("hfl/chinese-roberta-wwm-ext")roberta = BertModel.from_pretrained("hfl/chinese-roberta-wwm-ext")

切記不可使用官方推薦的

tokenizer = AutoTokenizer.from_pretrained("hfl/chinese-roberta-wwm-ext")model = AutoModel.from_pretrained("hfl/chinese-roberta-wwm-ext")

因為中文roberta類的配置文件比如vocab.txt,都是採用bert的方法設計的。英文roberta模型讀取配置文件的格式默認是vocab.json。對於一些英文roberta模型,倒是可以通過AutoModel自動讀取。這就解釋了huggingface的模型庫的中文roberta示例程式碼為什麼跑不通。//huggingface.co/models?

如果要基於上面的程式碼run_language_modeling.py繼續預訓練roberta。還需要做兩個改動。

  • 下載roberta-wwm-ext到本地目錄hflroberta,在config.json中修改「model_type」:”roberta”為”model_type”:”bert”。

  • 對上面的run_language_modeling.py中的AutoModel和AutoTokenizer都進行替換為BertModel和BertTokenizer。

再運行命令

python run_language_modeling_roberta.py \    --output_dir=output \    --model_type=bert \    --model_name_or_path=hflroberta \    --do_train \    --train_data_file=$TRAIN_FILE \    --do_eval \    --eval_data_file=$TEST_FILE \    --mlm

3 ernie

(//github.com/nghuyong/ERNIE-Pytorch)

ernie是百度發布的基於百度知道貼吧等中文語料結合實體預測等任務生成的預訓練模型。這個模型的準確率在某些任務上要優於bert-base-chinese和roberta。如果基於ernie1.0模型做領域數據預訓練的話只需要一步修改。

  • 下載ernie1.0到本地目錄ernie,在config.json中增加欄位”model_type”:”bert”。

python run_language_modeling.py \    --output_dir=output \    --model_type=bert \    --model_name_or_path=ernie \    --do_train \    --train_data_file=$TRAIN_FILE \    --do_eval \    --eval_data_file=$TEST_FILE \    --mlm

最後,huggingface項目中語言模型預訓練用mask方式如下。仍是按照15%的數據隨機mask然後預測自身。如果要做一些高級操作比如whole word masking或者實體預測,可以自行修改transformers.DataCollatorForLanguageModeling。

本文實驗程式碼庫。拿來即用!

//github.com/zhusleep/pytorch_chinese_lm_pretrain

●  [預訓練語言模型專題] RoBERTa: 捍衛BERT的尊嚴
● [預訓練語言模型專題] Transformer-XL 超長上下文注意力模型
●  [預訓練語言模型專題] XLNet:公平一戰!多項任務效果超越BERT
  [預訓練語言模型專題] Huggingface簡介及BERT程式碼淺析
● [預訓練語言模型專題] SpanBERT: 抽取式問答的利器