ERNIE 2.0 是基於持續學習的語義理解預訓練框架,使用多任務學習增量式構建預訓練任務。ERNIE 2.0 中,新構建的預訓練任務類型能夠無縫的加入訓練框架,持續的進行語義理解學習。 經過新增的實體預測、句子因果關係判斷、文章句子結構重建等語義任務,ERNIE 2.0 語義理解預訓練模型從訓練數據中獲取了詞法、句法、語義等多個維度的天然語言信息,極大地加強了通用語義表示能力。html
咱們對 ERNIE 2.0 模型和現有 SOTA 預訓練模型在 9 箇中文數據集、以及英文數據集合 GLUE 上進行效果比較。結果代表:ERNIE 2.0 模型在英語任務上幾乎全面優於 BERT 和 XLNet,在 7 個 GLUE 任務上取得了最好的結果;中文任務上,ERNIE 2.0 模型在全部 9 箇中文 NLP 任務上全面優於 BERT。node
針對 ERNIE 2.0 模型,咱們構建了多個預訓練任務,試圖從 3 個層面去更好的理解訓練語料中蘊含的信息:python
同時,針對不一樣的 pre-training 任務,ERNIE 2.0 引入了 Task Embedding 來精細化地建模不一樣類型的任務。不一樣的任務用從 0 到 N 的 ID 表示,每一個 ID 表明了不一樣的預訓練任務。git
Knowledge Masking Taskgithub
Capitalization Prediction Taskweb
Token-Document Relation Prediction Task算法
Sentence Reordering Taskshell
Sentence Distance Taskjson
Discourse Relation Taskapi
IR Relevance Task
ERNIE 1.0 經過建模海量數據中的詞、實體及實體關係,學習真實世界的語義知識。相較於 BERT 學習原始語言信號,ERNIE 直接對先驗語義知識單元進行建模,加強了模型語義表示能力。
這裏咱們舉個例子:
Learnt by BERT :哈 [mask] 濱是 [mask] 龍江的省會,[mask] 際冰 [mask] 文化名城。
Learnt by ERNIE:[mask] [mask] [mask] 是黑龍江的省會,國際 [mask] [mask] 文化名城。
在 BERT 模型中,咱們經過『哈』與『濱』的局部共現,便可判斷出『爾』字,模型沒有學習與『哈爾濱』相關的任何知識。而 ERNIE 經過學習詞與實體的表達,使模型可以建模出『哈爾濱』與『黑龍江』的關係,學到『哈爾濱』是 『黑龍江』的省會以及『哈爾濱』是個冰雪城市。
訓練數據方面,除百科類、資訊類中文語料外,ERNIE 還引入了論壇對話類數據,利用 DLM(Dialogue Language Model)建模 Query-Response 對話結構,將對話 Pair 對做爲輸入,引入 Dialogue Embedding 標識對話的角色,利用 Dialogue Response Loss 學習對話的隱式關係,進一步提高模型的語義表示能力。
任務 | ERNIE 1.0 模型 | ERNIE 2.0 英文模型 | ERNIE 2.0 中文模型 |
---|---|---|---|
Word-aware | ✅ Knowledge Masking | ✅ Knowledge Masking ✅ Capitalization Prediction ✅ Token-Document Relation Prediction |
✅ Knowledge Masking |
Structure-aware | ✅ Sentence Reordering | ✅ Sentence Reordering ✅ Sentence Distance |
|
Semantic-aware | ✅ Next Sentence Prediction | ✅ Discourse Relation | ✅ Discourse Relation ✅ IR Relevance |
咱們在 9 個任務上驗證 ERNIE 2.0 中文模型的效果。這些任務包括:天然語言推斷任務 XNLI;閱讀理解任務 DRCD、DuReader、CMRC2018;命名實體識別任務 MSRA-NER (SIGHAN2006);情感分析任務 ChnSentiCorp;語義類似度任務 BQ Corpus、LCQMC;問答任務 NLPCC2016-DBQA 。任務的詳情和效果會在以下章節中介紹。
數據集 | XNLI | |
---|---|---|
評估 指標 |
acc | |
dev | test | |
BERT Base | 78.1 | 77.2 |
ERNIE 1.0 Base | 79.9 (+1.8) | 78.4 (+1.2) |
ERNIE 2.0 Base | 81.2 (+3.1) | 79.7 (+2.5) |
ERNIE 2.0 Large | 82.6 (+4.5) | 81.0 (+3.8) |
XNLI 是由 Facebook 和紐約大學的研究者聯合構建的天然語言推斷數據集,包括 15 種語言的數據。咱們用其中的中文數據來評估模型的語言理解能力。[連接: https://github.com/facebookresearch/XNLI]
數據集 | DuReader | CMRC2018 | DRCD | |||||
---|---|---|---|---|---|---|---|---|
評估 指標 |
em | f1-score | em | f1-score | em | f1-score | ||
dev | dev | dev | test | dev | test | |||
BERT Base | 59.5 | 73.1 | 66.3 | 85.9 | 85.7 | 84.9 | 91.6 | 90.9 |
ERNIE 1.0 Base | 57.9 (-1.6) | 72.1 (-1.0) | 65.1 (-1.2) | 85.1 (-0.8) | 84.6 (-1.1) | 84.0 (-0.9) | 90.9 (-0.7) | 90.5 (-0.4) |
ERNIE 2.0 Base | 61.3 (+1.8) | 74.9 (+1.8) | 69.1 (+2.8) | 88.6 (+2.7) | 88.5 (+2.8) | 88.0 (+3.1) | 93.8 (+2.2) | 93.4 (+2.5) |
ERNIE 2.0 Large | 64.2 (+4.7) | 77.3 (+4.2) | 71.5 (+5.2) | 89.9 (+4.0) | 89.7 (+4.0) | 89.0 (+4.1) | 94.7 (+3.1) | 94.2 (+3.3) |
* 實驗所用的 DuReader 抽取類、單文檔子集爲內部數據集。
* 實驗時將 DRCD 繁體數據轉換成簡體,繁簡轉換工具:https://github.com/skydark/nstools/tree/master/zhtools
* ERNIE 1.0 的預訓練數據長度爲 128,其餘模型使用 512 長度的數據訓練,這致使 ERNIE 1.0 BASE 在長文本任務上性能較差, 爲此咱們發佈了 ERNIE 1.0 Base (max-len-512) 模型 (2019-07-29)
DuReader 是百度在天然語言處理國際頂會 ACL 2018 發佈的機器閱讀理解數據集,全部的問題、原文都來源於百度搜索引擎數據和百度知道問答社區,答案是由人工整理的。實驗是在 DuReader 的單文檔、抽取類的子集上進行的,訓練集包含15763個文檔和問題,驗證集包含1628個文檔和問題,目標是從篇章中抽取出連續片斷做爲答案。[連接: https://arxiv.org/pdf/1711.05073.pdf]
CMRC2018 是中文信息學會舉辦的評測,評測的任務是抽取類閱讀理解。[連接: https://github.com/ymcui/cmrc2018]
DRCD 是臺達研究院發佈的繁體中文閱讀理解數據集,目標是從篇章中抽取出連續片斷做爲答案。咱們在實驗時先將其轉換成簡體中文。[連接: https://github.com/DRCKnowledgeTeam/DRCD]
數據集 | MSRA-NER(SIGHAN2006) | |
---|---|---|
評估 指標 |
f1-score | |
dev | test | |
BERT Base | 94.0 | 92.6 |
ERNIE 1.0 Base | 95.0 (+1.0) | 93.8 (+1.2) |
ERNIE 2.0 Base | 95.2 (+1.2) | 93.8 (+1.2) |
ERNIE 2.0 Large | 96.3 (+2.3) | 95.0 (+2.4) |
MSRA-NER (SIGHAN2006) 數據集由微軟亞研院發佈,其目標是識別文本中具備特定意義的實體,包括人名、地名、機構名。
數據集 | ChnSentiCorp | |
---|---|---|
評估 指標 |
acc | |
dev | test | |
BERT Base | 94.6 | 94.3 |
ERNIE 1.0 Base | 95.2 (+0.6) | 95.4 (+1.1) |
ERNIE 2.0 Base | 95.7 (+1.1) | 95.5 (+1.2) |
ERNIE 2.0 Large | 96.1 (+1.5) | 95.8 (+1.5) |
ChnSentiCorp 是一箇中文情感分析數據集,包含酒店、筆記本電腦和書籍的網購評論。
數據集 | NLPCC2016-DBQA | |||
---|---|---|---|---|
評估 指標 |
mrr | f1-score | ||
dev | test | dev | test | |
BERT Base | 94.7 | 94.6 | 80.7 | 80.8 |
ERNIE 1.0 Base | 95.0 (+0.3) | 95.1 (+0.5) | 82.3 (+1.6) | 82.7 (+1.9) |
ERNIE 2.0 Base | 95.7 (+1.0) | 95.7 (+1.1) | 84.7 (+4.0) | 85.3 (+4.5) |
ERNIE 2.0 Large | 95.9 (+1.2) | 95.8 (+1.2) | 85.3 (+4.6) | 85.8 (+5.0) |
NLPCC2016-DBQA 是由國際天然語言處理和中文計算會議 NLPCC 於 2016 年舉辦的評測任務,其目標是從候選中找到合適的文檔做爲問題的答案。[連接: http://tcci.ccf.org.cn/conference/2016/dldoc/evagline2.pdf]
數據集 | LCQMC | BQ Corpus | ||
---|---|---|---|---|
評估 指標 |
acc | acc | ||
dev | test | dev | test | |
BERT Base | 88.8 | 87.0 | 85.9 | 84.8 |
ERNIE 1.0 Base | 89.7 (+0.9) | 87.4 (+0.4) | 86.1 (+0.2) | 84.8 |
ERNIE 2.0 Base | 90.9 (+2.1) | 87.9 (+0.9) | 86.4 (+0.5) | 85.0 (+0.2) |
ERNIE 2.0 Large | 90.9 (+2.1) | 87.9 (+0.9) | 86.5 (+0.6) | 85.2 (+0.4) |
* LCQMC 、BQ Corpus 數據集須要向做者申請,LCQMC 申請地址:http://icrc.hitsz.edu.cn/info/1037/1146.htm, BQ Corpus 申請地址:http://icrc.hitsz.edu.cn/Article/show/175.html
LCQMC 是在天然語言處理國際頂會 COLING 2018 發佈的語義匹配數據集,其目標是判斷兩個問題的語義是否相同。[連接: http://aclweb.org/anthology/C18-1166]
BQ Corpus 是在天然語言處理國際頂會 EMNLP 2018 發佈的語義匹配數據集,該數據集針對銀行領域,其目標是判斷兩個問題的語義是否相同。[連接: https://www.aclweb.org/anthology/D18-1536]
ERNIE 2.0 的英文效果驗證在 GLUE 上進行。GLUE 評測的官方地址爲 https://gluebenchmark.com/ ,該評測涵蓋了不一樣類型任務的 10 個數據集,其中包含 11 個測試集,涉及到 Accuracy, F1-score, Spearman Corr,. Pearson Corr,. Matthew Corr., 5 類指標。GLUE 排行榜使用每一個數據集的平均分做爲整體得分,並以此爲依據將不一樣算法進行排名。
數據集 | CoLA | SST-2 | MRPC | STS-B | QQP | MNLI-m | QNLI | RTE |
---|---|---|---|---|---|---|---|---|
評測指標 | matthews corr. | acc | acc | pearson corr. | acc | acc | acc | acc |
BERT Large | 60.6 | 93.2 | 88.0 | 90.0 | 91.3 | 86.6 | 92.3 | 70.4 |
XLNet Large | 63.6 | 95.6 | 89.2 | 91.8 | 91.8 | 89.8 | 93.9 | 83.8 |
ERNIE 2.0 Large | 65.4 (+4.8,+1.8) |
96.0 (+2.8,+0.4) |
89.7 (+1.7,+0.5) |
92.3 (+2.3,+0.5) |
92.5 (+1.2,+0.7) |
89.1 (+2.5,-0.7) |
94.3 (+2.0,+0.4) |
85.2 (+14.8,+1.4) |
咱們使用單模型的驗證集結果,來與 BERT/XLNet 進行比較。
數據集 | - | CoLA | SST-2 | MRPC | STS-B | QQP | MNLI-m | MNLI-mm | QNLI | RTE | WNLI | AX |
---|---|---|---|---|---|---|---|---|---|---|---|---|
評測指標 | score | matthews corr. | acc | f1-score/acc | spearman/pearson corr. | f1-score/acc | acc | acc | acc | acc | acc | matthews corr. |
BERT Base | 78.3 | 52.1 | 93.5 | 88.9/84.8 | 85.8/87.1 | 71.2/89.2 | 84.6 | 83.4 | 90.5 | 66.4 | 65.1 | 34.2 |
ERNIE 2.0 Base | 80.6 (+2.3) |
55.2 (+3.1) |
95.0 (+1.5) |
89.9/86.1 (+1.0/+1.3) |
86.5/87.6 (+0.7/+0.5) |
73.2/89.8 (+2.0/+0.6) |
86.1 (+1.5) |
85.5 (+2.1) |
92.9 (+2.4) |
74.8 (+8.4) |
65.1 | 37.4 (+3.2) |
BERT Large | 80.5 | 60.5 | 94.9 | 89.3/85.4 | 86.5/87.6 | 72.1/89.3 | 86.7 | 85.9 | 92.7 | 70.1 | 65.1 | 39.6 |
ERNIE 2.0 Large | 83.6 (+3.1) |
63.5 (+3.0) |
95.6 (+0.7) |
90.2/87.4 (+0.9/+2.0) |
90.6/91.2 (+4.1/+3.6) |
73.8/90.1 (+1.7/+0.8) |
88.7 (+2.0) |
88.8 (+2.9) |
94.6 (+1.9) |
80.2 (+10.1) |
67.8 (+2.7) |
48.0 (+8.4) |
因爲 XLNet 暫未公佈 GLUE 測試集上的單模型結果,因此咱們只與 BERT 進行單模型比較。上表爲ERNIE 2.0 單模型在 GLUE 測試集的表現結果。
爲了提高ERNIE模型在實際工業應用中的落地能力,咱們推出ERNIE-tiny模型。
ERNIE-tiny做爲小型化ERNIE,採用瞭如下4點技術,保證了在實際真實數據中將近4.3倍的預測提速。
淺:12層的ERNIE Base模型直接壓縮爲3層,線性提速4倍,但效果也會有較大幅度的降低;
胖:模型變淺帶來的損失可經過hidden size的增大來彌補。因爲fluid inference框架對於通用矩陣運算(gemm)的最後一維(hidden size)參數的不一樣取值會有深度的優化,由於將hidden size從768提高至1024並不會帶來速度線性的增長;
短:ERNIE Tiny是首個開源的中文subword粒度的預訓練模型。這裏的短是指經過subword粒度替換字(char)粒度,可以明顯地縮短輸入文本的長度,而輸入文本長度是和預測速度有線性相關。統計代表,在XNLI dev集上採用subword字典切分出來的序列長度比字表平均縮短40%;
萃:爲了進一步提高模型的效果,ERNIE Tiny扮演學生角色,利用模型蒸餾的方式在Transformer層和Prediction層去學習教師模型ERNIE模型對應層的分佈或輸出,這種方式可以縮近ERNIE Tiny和ERNIE的效果差別。
ERNIE Tiny輕量級模型在公開數據集的效果以下所示,任務均值相對於ERNIE Base只降低了2.37%,但相對於「SOTA Before BERT」提高了8%。在延遲測試中,ERNIE Tiny可以帶來4.3倍的速度提高 (測試環境爲:GPU P4,Paddle Inference C++ API,XNLI Dev集,最大maxlen=128,測試結果10次均值)
model | XNLI(acc) | LCQCM(acc) | CHNSENTICORP(acc) | NLPCC-DBQA(mrr/f1) | Average | Latency |
---|---|---|---|---|---|---|
SOTA-before-ERNIE | 68.3 | 83.4 | 92.2 | 72.01/- | 78.98 | - |
ERNIE2.0-base | 79.7 | 87.9 | 95.5 | 95.7/85.3 | 89.70 | 633ms(1x) |
ERNIE-tiny-subword | 75.1 | 86.1 | 95.2 | 92.9/78.6 | 87.33 | 146ms(4.3x) |
ModuleNotFoundError: No module named 'propeller'
本項目依賴於 Paddle 1.6,* 因爲Paddle 1.6版本相比以前版本有較大API改動,使用Paddle 1.6之前版本運行本代碼庫會致使序列標註等任務報錯 *,請參考安裝指南進行安裝。
【重要】安裝後,須要及時的將 CUDA、cuDNN、NCCL2 等動態庫路徑加入到環境變量 LD_LIBRARY_PATH 之中,不然訓練過程當中會報相關的庫錯誤。具體的paddlepaddle配置細節請查閱這裏
若是您想了解更多的 Paddle 的相關信息,例如針對實際問題建模、搭建本身網絡等,這裏有更多的來自官方的文檔供您參考:
ERNIE的其餘依賴列在requirements.txt
文件中,使用如下命令安裝
pip install -r requirements.txt
Model | Description |
---|---|
ERNIE 1.0 中文 Base 模型 | 包含預訓練模型參數 |
ERNIE 1.0 中文 Base 模型 | 包含預訓練模型參數、詞典 vocab.txt、模型配置 ernie_config.json |
ERNIE 1.0 中文 Base 模型(max_len=512) | 包含預訓練模型參數、詞典 vocab.txt、模型配置 ernie_config.json |
ERNIE 2.0 英文 Base 模型 | 包含預訓練模型參數、詞典 vocab.txt、模型配置 ernie_config.json |
ERNIE 2.0 英文 Large 模型 | 包含預訓練模型參數、詞典 vocab.txt、模型配置 ernie_config.json |
ERNIE tiny 中文模型 | 包含預訓練模型參數、詞典 vocab.txt、模型配置 ernie_config.json 以及切詞詞表 |
因爲數據集協議問題,在這裏沒法直接提供英文數據集。GLUE 的數據下載方式請參考GLUE 主頁以及 GLUE 提供的數據下載代碼。
假設全部數據集下載放置的路徑爲$GLUE_DATA
,將數據下載完畢後,執行 sh ./script/en_glue/preprocess/cvt.sh $GLUE_DATA
,將完成全部數據的格式轉換,默認轉換後的數據會輸出到文件夾./glue_data_processed/
。
在實驗中咱們發現,不一樣的任務對應的 batch size 會影響任務的最終效果,所以在這裏列出了具體實驗中咱們使用的具體配置,在具體的實驗運行時,請注意本地 GPU 卡數。
在下表的 Batch Size 一欄,"(base)" 指 ERNIE BASE 模型 Fine-tuning 時使用的參數,未特殊標明則表示 ERNIE Large 和 ERNIE Base 使用一樣的 batch size。
任務 | Batch Size | GPU卡數 |
---|---|---|
CoLA | 32 / 64 (base) | 1 |
SST-2 | 64 / 256 (base) | 8 |
STS-B | 128 | 8 |
QQP | 256 | 8 |
MNLI | 256 / 512 (base) | 8 |
QNLI | 256 | 8 |
RTE | 16 / 4 (base) | 1 |
MRPC | 16 / 32 (base) | 2 |
WNLI | 8 | 1 |
XNLI | 65536 (tokens) | 8 |
CMRC2018 | 64 | 8 (large) / 4 (base) |
DRCD | 64 | 8 (large) / 4 (base) |
MSRA-NER(SIGHAN 2006) | 16 | 1 |
ChnSentiCorp | 24 | 1 |
LCQMC | 32 | 1 |
BQ Corpus | 64 | 1 |
NLPCC2016-DBQA | 64 | 8 |
* MNLI 和 QNLI 的任務中,使用了 32 GB 顯存的 V100。除此以外的顯卡皆爲22 GB 的 P40。
使用finetune_launch.py
腳原本啓動多進程訓練 。多進程訓練能夠提高充分利用多核CPU/多卡GPU 的能力來加速finetune過程。 finetune_launch.py
須要放在原來finetune腳本前面, 同時指定每一個節點的進程數--nproc_per_node
, 以及每一個節點上的gpu卡號--selected_gpus
, 通常數量與進程數, CUDA_VISIBLE_DEVICES
相同且從0開始編號 (參考script/zh_task/ernie_base/run_xnli.sh
)
只需在訓練腳本中加入--use_fp16 true
便可啓用fp16混合精度訓練(確保您的硬件支持Tensor Core技術)。ERNIE會將計算Op轉換成fp16精度,同時仍然使用fp32精度存儲參數。ERNIE使用動態loss scale來避免梯度消失。在XNLI任務上能夠觀察到大約60%加速。
分類或者回歸任務的邏輯都封裝在 run_classifier.py
文件中。爲了方便的復現上述的實驗效果,該項目將每一個任務與其對應的超參封裝到了任務對應的 shell 文件中。
下面提供了中英文情感分析 ChnSentiCorp
,SST-2
,和 LCQMC
的運行示例。在運行前,請經過 模型&數據 一節提供的連接預先下載好對應的預訓練模型。
以 ChnSentiCorp
情感分類數據集做爲單句分類任務示例,假設下載數據並解壓後的路徑爲 /home/task_data/
,則在該目錄中應該存在文件夾chnsenticorp
,其訓練數據路徑爲/home/task_data/chnsenticorp/train.tsv
,該數據格式爲包含2個字段的tsv文件,2個字段分別爲: text_a label
, 示例數據以下:
label text_a ... 0 噹噹網名不符實,定貨多日不見送貨,詢問客服只會推託,只會要求用戶再下訂單。如此服務留不住顧客的。去別的網站買書服務更好。 0 XP的驅動很差找!個人17號提的貨,如今就降價了100元,並且還送殺毒軟件! 1 <薦書> 推薦全部喜歡<紅樓>的紅迷們必定要收藏這本書,要知道當年我據說這本書的時候花很長時間去圖書館找和借都沒能如願,因此此次一看到噹噹有,立刻買了,紅迷們也要記得備貨哦! ...
假設下載的模型路徑爲 /home/model/
,則該目錄中應該有名爲 params
的文件夾。在執行任務前,須要提早設置環境變量:
export TASK_DATA_PATH=/home/task_data/ export MODEL_PATH=/home/model/
執行 sh script/zh_task/ernie_base/run_ChnSentiCorp.sh
便可開始 finetune,執行結束後會輸出以下所示的在驗證集和測試集上的測試結果:
[dev evaluation] ave loss: 0.303819, acc:0.943333, data_num: 1200, elapsed time: 16.280898 s, file: /home/task_data/chnsenticorp/dev.tsv, epoch: 9, steps: 4001 [dev evaluation] ave loss: 0.228482, acc:0.958333, data_num: 1200, elapsed time: 16.023091 s, file: /home/task_data/chnsenticorp/test.tsv, epoch: 9, steps: 4001
再以一個英文的數據集 SST-2
爲例,文件的格式和中文文件的格式相似。假設通過 模型&數據 章節中轉換完數據以後,獲得的路徑爲 /home/glue_data_processed/
,其訓練數據路徑爲 /home/glue_data_processed/SST-2/train.tsv
,該文件一樣要有2列,分別爲 text_a label
,示例數據如:
label text_a 0 hide new secretions from the parental units 0 contains no wit , only labored gags 1 that loves its characters and communicates something rather beautiful about human nature 0 remains utterly satisfied to remain the same throughout 0 on the worst revenge-of-the-nerds clichés the filmmakers could dredge up 0 that 's far too tragic to merit such superficial treatment 1 demonstrates that the director of such hollywood blockbusters as patriot games can still turn out a small , personal film with an emotional wallop . 1 of saucy
一樣在運行前設置環境變量:
export TASK_DATA_PATH=/home/glue_data_processed/ export MODEL_PATH=/home/model/
執行 sh script/en_glue/ernie_large/SST-2/task.sh
,能夠觀測到相似以下內容的日誌:
epoch: 3, progress: 22456/67349, step: 3500, ave loss: 0.015862, ave acc: 0.984375, speed: 1.328810 steps/s [dev evaluation] ave loss: 0.174793, acc:0.957569, data_num: 872, elapsed time: 15.314256 s file: ./data/dev.tsv, epoch: 3, steps: 3500 testing ./data/test.tsv, save to output/test_out.tsv
以 LCQMC
語義類似度任務做爲句對分類任務示例,數據格式爲包含 3 個字段的 tsv 文件,3 個字段分別爲: text_a text_b label
,示例數據以下:
text_a text_b label 開初婚未育證實怎麼弄? 初婚未育狀況證實怎麼開? 1 誰知道她是網絡美女嗎? 愛情這杯酒誰喝都會醉是什麼歌 0 這腰帶是什麼牌子 護腰帶什麼牌子好 0
執行 sh script/zh_task/ernie_base/run_lcqmc.sh
便可開始 fine-tuning,執行結束後會輸出以下所示的在驗證集和測試集上的測試結果:
[dev evaluation] ave loss: 0.299115, acc:0.900704, data_num: 8802, elapsed time: 32.327663 s, file: ./task_data/lcqmc/dev.tsv, epoch: 2, steps: 22387 [dev evaluation] ave loss: 0.374148, acc:0.878080, data_num: 12500, elapsed time: 39.780520 s, file: ./task_data/lcqmc/test.tsv, epoch: 2, steps: 22387
以 MSRA-NER(SIGHAN2006)
做爲示例,數據格式爲包含 2 個字段的 tsv 文件,2 個字段分別爲: text_a label
, 示例數據以下:
text_a label 在 這 裏 恕 弟 不 恭 之 罪 , 敢 在 尊 前 一 諍 : 前 人 論 書 , 每 曰 「 字 字 有 來 歷 , 筆 筆 有 出 處 」 , 細 讀 公 字 , 何 嘗 跳 出 前 人 藩 籬 , 自 隸 變 而 後 , 直 至 明 季 , 兄 有 何 新 出 ? O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O 相 比 之 下 , 青 島 海 牛 隊 和 廣 州 鬆 日 隊 的 雨 中 之 戰 雖 然 也 是 0 ∶ 0 , 但 乏 善 可 陳 。 O O O O O B-ORG I-ORG I-ORG I-ORG I-ORG O B-ORG I-ORG I-ORG I-ORG I-ORG O O O O O O O O O O O O O O O O O O O 理 由 多 多 , 最 無 奈 的 卻 是 : 5 月 恰 逢 雙 重 考 試 , 她 攻 讀 的 博 士 學 位 論 文 要 通 考 ; 她 任 教 的 兩 所 學 校 , 也 要 在 這 段 時 日 大 考 。 O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O
執行 sh script/zh_task/ernie_base/run_msra_ner.sh
便可開始 finetune,執行結束後會輸出以下所示的在驗證集和測試集上的測試結果:
[dev evaluation] f1: 0.951949, precision: 0.944636, recall: 0.959376, elapsed time: 19.156693 s [test evaluation] f1: 0.937390, precision: 0.925988, recall: 0.949077, elapsed time: 36.565929 s
以 DRCD
做爲示例,首先將數據轉換成 SQUAD 格式:
{ "version": "1.3", "data": [ { "paragraphs": [ { "id": "1001-11", "context": "廣州是京廣鐵路、廣深鐵路、廣茂鐵路、廣梅汕鐵路的終點站。2009年底,武廣客運專線投入運營,多單元列車覆蓋980千米的路程,最高時速可達350千米/小時。2011年1月7日,廣珠城際鐵路投入運營,平均時速可達200千米/小時。廣州鐵路、長途汽車和渡輪直達香港,廣九直通車從廣州東站開出,直達香港九龍紅磡站,總長度約182千米,車程在兩小時內。繁忙的長途汽車每一年會從城市中的不一樣載客點把旅客接載至香港。在珠江靠市中心的北航道有渡輪線路,用於近江居民直接渡江而無需乘坐公交或步行過橋。南沙碼頭和蓮花山碼頭間天天都有高速雙體船往返,渡輪也開往香港中國客運碼頭和港澳碼頭。", "qas": [ { "question": "廣珠城際鐵路平均每小時能夠走多遠?", "id": "1001-11-1", "answers": [ { "text": "200千米", "answer_start": 104, "id": "1" } ] } ] } ], "id": "1001", "title": "廣州" } ] }
執行 sh script/zh_task/ernie_base/run_drcd.sh
便可開始 finetune,執行結束後會輸出以下所示的在驗證集和測試集上的測試結果:
[dev evaluation] em: 88.450624, f1: 93.749887, avg: 91.100255, question_num: 3524 [test evaluation] em: 88.061838, f1: 93.520152, avg: 90.790995, question_num: 3493
ERNIE tiny 模型採用了subword粒度輸入,須要在數據前處理中加入切詞(segmentation)並使用sentence piece進行tokenization. segmentation 以及 tokenization 須要使用的模型包含在了 ERNIE tiny 的預訓練模型文件中,分別是 ./subword/dict.wordseg.pickle
和 ./subword/spm_cased_simp_sampled.model
.
目前./example/
下的代碼針對 ERNIE tiny 的前處理進行了適配只需在腳本中經過 --sentence_piece_model
引入tokenization 模型,再經過 --word_dict
引入 segmentation 模型以後便可進行 ERNIE tiny 的 Fine-tune。 對於命名實體識別類型的任務,爲了跟輸入標註對齊,ERNIE tiny 仍然採用中文單字粒度進行做爲輸入。所以使用 ./example/finetune_ner.py
時只須要打開 --use_sentence_piece_vocab
便可。 具體的使用方法能夠參考下節.
Propeller 是基於PaddlePaddle構建的一鍵式訓練API,對於具有必定機器學習應用經驗的開發者可使用Propeller得到定製化開發體驗。 您能夠經過export PYTHONPATH=./:$PYTHONPATH
的方式引入Propeller. Propeller基礎教程能夠參考./example/propeller_xnli_demo.ipynb
. 您只需定義好本身的模型以及 Dataset, 剩下的工做,如多卡並行,模型存儲等等,都交給Propeller來處理吧。 ./example/ 裏放了使用Propeller進行分類任務、排序任務和命名實體識別任務的finetune流程,能夠做爲您修改的模板。
模板中使用的demo數據能夠從這裏下載,解壓完成後放到 ${TASK_DATA_PATH} 中。 以分類任務爲例,用下面腳本便可啓動finetune,在訓練的過程當中框架會自動把準確率最好的模型保存在 ./output/best/inference
下面。利用 infernce_model 進行在線預測的方案請參考: 在線預測
python3 ./example/finetune_classifier.py \ --data_dir ${TASK_DATA_PATH}/chnsenticorp/ \ --warm_start_from ${MODEL_PATH}/params \ --vocab_file ${MODEL_PATH}/vocab.txt \ --max_seqlen 128 \ --run_config '{ "model_dir": "output", "max_steps": '$((10 * 9600 / 32))', "save_steps": 100, "log_steps": 10, "max_ckpt": 1, "skip_steps": 0, "eval_steps": 100 }' \ --hparam ${MODEL_PATH}/ernie_config.json \ --hparam '{ # model definition "sent_type_vocab_size": None, # default term in official config "use_task_id": False, "task_id": 0, }' \ --hparam '{ # learn "warmup_proportion": 0.1, "weight_decay": 0.01, "use_fp16": 0, "learning_rate": 0.00005, "num_label": 2, "batch_size": 32 }'
finetune完成後,在上述腳本中加入--do_predict 參數後便可啓動開始預測:
cat input_file | python3 ./example/finetune_classifier.py --do_predict ... > output_score
基於百科類、資訊類、論壇對話類數據構造具備上下文關係的句子對數據,利用百度內部詞法分析工具對句對數據進行字、詞、實體等不一樣粒度的切分,而後基於 tokenization.py
中的 CharTokenizer 對切分後的數據進行 token 化處理,獲得明文的 token 序列及切分邊界,而後將明文數據根據詞典 config/vocab.txt
映射爲 id 數據,在訓練過程當中,根據切分邊界對連續的 token 進行隨機 mask 操做;
咱們給出了 id 化後的部分訓練數據:data/demo_train_set.gz
、和測試數據:data/demo_valid_set.gz
,每行數據爲1個訓練樣本,示例以下:
1 1048 492 1333 1361 1051 326 2508 5 1803 1827 98 164 133 2777 2696 983 121 4 19 9 634 551 844 85 14 2476 1895 33 13 983 121 23 7 1093 24 46 660 12043 2 1263 6 328 33 121 126 398 276 315 5 63 44 35 25 12043 2;0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1;0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55;-1 0 0 0 0 1 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 1 0 1 0 0 0 0 1 0 0 0 0 -1 0 0 0 1 0 0 1 0 1 0 0 1 0 1 0 -1;0
每一個樣本由5個 ';
' 分隔的字段組成,數據格式: token_ids; sentence_type_ids; position_ids; seg_labels; next_sentence_label
;其中 seg_labels
表示分詞邊界信息: 0表示詞首、1表示非詞首、-1爲佔位符, 其對應的詞爲 CLS
或者 SEP
;
預訓練任務的啓動腳本是 script/zh_task/pretrain.sh
, 在開始預訓練以前須要把 CUDA、cuDNN、NCCL2 等動態庫路徑加入到環境變量 LD_LIBRARY_PATH 之中;而後執行 sh script/zh_task/pretrain.sh
就能夠基於 demo 數據和默認參數配置開始預訓練;
預訓練任務進行的過程當中會輸出當前學習率、訓練數據所通過的輪數、當前迭代的總步數、訓練偏差、訓練速度等信息,根據 --validation_steps ${N} 的配置,每間隔 N 步輸出模型在驗證集的各類指標:
current learning_rate:0.000001 epoch: 1, progress: 1/1, step: 30, loss: 10.540648, ppl: 19106.925781, next_sent_acc: 0.625000, speed: 0.849662 steps/s, file: ./data/demo_train_set.gz, mask_type: mask_word feed_queue size 70 current learning_rate:0.000001 epoch: 1, progress: 1/1, step: 40, loss: 10.529287, ppl: 18056.654297, next_sent_acc: 0.531250, speed: 0.849549 steps/s, file: ./data/demo_train_set.gz, mask_type: mask_word feed_queue size 70 current learning_rate:0.000001 epoch: 1, progress: 1/1, step: 50, loss: 10.360563, ppl: 16398.287109, next_sent_acc: 0.625000, speed: 0.843776 steps/s, file: ./data/demo_train_set.gz, mask_type: mask_word
若是用自定義的真實數據進行訓練,請參照script/zh_task/pretrain.sh
腳本對參數作相應修改。
通過預訓練的 ERNIE 模型可以直接用於文本語義表示。模型預測的句子 embedding 能夠很方便地應用於語義近鄰搜索(ANN), 或者下游任務feature-based finetune 任務中。爲了更方便地將 ERNIE 用做特徵抽取器,咱們提供了一個ERNIE server來完成這項工做。 ERNIE server 依賴propeller, 您能夠經過export PYTHONPATH=./:$PYTHONPATH
的方式引入Propeller. 請從 這裏 下載中文 ERNIE1.0-base 模型的 inference_model, 隨後您能夠經過下面的指令啓動ERNIE server服務
python3 ernie/service/encoder_server.py -m ./ernie1.0_base_inference_model/ -p 8888 -v --encode_layer pooler
經過 --encode_layer
能夠指定特徵抽取的位置,pooler
表明選取 ERNIE pooler fc 的輸出做爲特徵。
您能夠經過下面的方式請求ERNIE server服務,目前客戶端支持python3調用:
from ernie.service.client import ErnieClient client = ErnieClient('./config/vocab.txt', host='localhost', port=8888) ret = client(['誰有狂三這張高清的', '英雄聯盟什麼英雄最好']) # 單句輸入 # output: # array([[-1. , -1. , 0.9937699 , ..., -0.99991065, # -0.9999997 , -0.9999985 ], # [-1. , -1. , -0.05038145, ..., -0.9912302 , # -0.9999436 , -0.9739356 ]], dtype=float32) ret = client(['誰有狂三這張高清的', '這張高清圖,誰有'], ['英雄聯盟什麼英雄最好', '英雄聯盟最好英雄是什麼']) # 句對輸入 # output: # array([[-1. , -0.99528974, -0.99174845, ..., -0.9781673 , # -1. , -1. ], # [-1. , -1. , -0.8699475 , ..., -0.997155 , # -1. , -0.99999994]], dtype=float32)
ERNIE提供了經過數據蒸餾從而達到模型壓縮、加速的開發套件,具體開發流程請參考 這裏
完成finetune以後只需幾步操做便可生成inference_model, PaddlePaddle能夠在生產環境中加載生成的預測模型並進行高效地預測。
運行infer_classifyer.py
腳本時經過指定 --save_inference_model_path
即可生成 inference_model 到指定位置。
若是您採用 propeller
完成finetune,則 BestInferenceExporter
會在finetune過程當中根據預測指標,挑最好的模型生成 inference_model .
隨後您可使用ERNIE fast inference C++ API將模型的前向預測代碼聯編到您的生產環境中。或者您可使用咱們爲您構建好的python預測引擎來完成一個簡單的服務。執行以下指令,即可以開啓一個propeller server:
python -m propeller.tools.start_server -m /path/to/saved/model -p 8888
您能夠在python腳本很方便地調用propeller server:
from propeller.service.client import InferenceClient client = InferenceClient('tcp://localhost:8888') sentence_id = np.array([[[20], [1560], [1175], [8], [42]]], dtype=np.int64) position_id = np.array([[[0], [1], [2], [3], [4]]], dtype=np.int64) token_type_id = np.array([[[0], [0], [0], [1], [1]]], dtype=np.int64) input_mask = np.array([[1., 1., 1., 1., 1.]], dtype=np.float32) result = client(sentence_id, token_type_id, position_id, input_mask)
client
的請求參數類型是numpy array,對應了save_inference_model時指定的輸入tensor. 若是是使用infer_classifyer.py
生成的inference_model則請求參數有四個:(sentence_id, position_id, token_type_id, input_mask)。 若是是propeller
生成的inference_model, client的請求參數對應您eval_dataset
的元素類型。目前InferenceClient
只支持在python3環境下使用。
能夠經過 ernie_encoder.py
抽取出輸入句子的 Embedding 表示和句子中每一個 token 的 Embedding 表示,數據格式和 Fine-tuning 任務 一節中介紹的各類類型 Fine-tuning 任務的訓練數據格式一致;以獲取 LCQMC dev 數據集中的句子 Embedding 和 token embedding 爲例,示例腳本以下:
export FLAGS_sync_nccl_allreduce=1 export CUDA_VISIBLE_DEVICES=0 python -u ernie_encoder.py \ --use_cuda true \ --batch_size 32 \ --output_dir "./test" \ --init_pretraining_params ${MODEL_PATH}/params \ --data_set ${TASK_DATA_PATH}/lcqmc/dev.tsv \ --vocab_path ${MODEL_PATH}/vocab.txt \ --max_seq_len 128 \ --ernie_config_path ${MODEL_PATH}/ernie_config.json
上述腳本運行結束後,會在當前路徑的 test 目錄下分別生成 cls_emb.npy
文件存儲句子 embeddings 和 top_layer_emb.npy
文件存儲 token embeddings; 實際使用時,參照示例腳本修改數據路徑、embeddings 文件存儲路徑等配置便可運行;
咱們以分類任務爲例,給出了分類任務進行批量預測的腳本, 使用示例以下:
python -u infer_classifyer.py \ --ernie_config_path ${MODEL_PATH}/ernie_config.json \ --init_checkpoint "./checkpoints/step_100" \ --save_inference_model_path ./saved_model \ --predict_set ${TASK_DATA_PATH}/xnli/test.tsv \ --vocab_path ${MODEL_PATH}/vocab.txt \ --num_labels 3
實際使用時,須要經過 init_checkpoint
指定預測用的模型,經過 predict_set
指定待預測的數據文件,經過 num_labels
配置分類的類別數目;
Note: predict_set 的數據格式是由 text_a、text_b(可選) 組成的 1 列 / 2 列 tsv 文件。
單獨一張顯卡分配到的數據量。
在 LD_LIBRARY_PATH 中添加 cudnn 庫的路徑,如 export LD_LIBRARY_PATH=/home/work/cudnn/cudnn_v[your cudnn version]/cuda/lib64
須要先下載 NCCL,而後在 LD_LIBRARY_PATH 中添加 NCCL 庫的路徑,如export LD_LIBRARY_PATH=/home/work/nccl/lib
ModuleNotFoundError: No module named 'propeller'
您能夠經過export PYTHONPATH=./:$PYTHONPATH
的方式引入Propeller.
項目地址: https://github.com/PaddlePaddle/ERNIE/blob/develop/README.zh.md
>> 訪問 PaddlePaddle 官網,瞭解更多相關內容。