MPNet with PaddleNLP
MPNet: Masked and Permuted Pre-training for Language Understanding - Microsoft Research
摘要: BERT 采用掩码语言建模(MLM)进行预训练,是最成功的预训练模型之一。由于 BERT 忽略了预测标记之间的依赖关系,XLNet 引入了置换语言建模(PLM)进行预训练来解决这个问题。然而,XLNet 没有利用句子的完整位置信息,因此会受到预训练和微调之间的位置差异的影响。在本文中,我们提出了 MPNet,这是一种新的预训练方法,它继承了 BERT 和 XLNet 的优点并避免了它们的局限性。MPNet 通过置换语言建模(相对于 BERT 中的 MLM)利用预测标记之间的依赖性,并以辅助位置信息作为输入,使模型能够看到完整的句子,从而减少位置差异(相对于 XLNet 中的 PLM)。我们在大规模数据集(超过160GB 的文本语料库)上预训练了 MPNet 模型,并对各种下游任务(GLUE、SQuAD 等)进行微调。实验结果表明,在相同的模型设置下,MPNet 大大优于 MLM 和 PLM,并且与之前最先进的预训练方法(例如 BERT、XLNet、RoBERTa)相比,在这些任务上取得了更好的结果。原始代码和预训练模型可从 https://github.com/microsoft/MPNet 下载得到。
本项目是 MPNet 在 Paddle 2.x 上的开源实现。
快速开始
下游任务微调
1、GLUE
以 QQP 数据集为例,运行其他 glue 数据集,请参考train.sh文件。(超参数遵循原论文的仓库的README)
(1)模型微调:
unset CUDA_VISIBLE_DEVICES
python -m paddle.distributed.launch --gpus "0" run_glue.py \
--model_type mpnet \
--model_name_or_path mpnet-base \
--task_name qqp \
--max_seq_length 128 \
--per_device_train_batch_size 32 \
--learning_rate 1e-5 \
--lr_scheduler_type linear \
--weight_decay 0.1 \
--warmup_steps 5666 \
--max_steps 113272 \
--logging_steps 500 \
--save_steps 2000 \
--seed 42 \
--output_dir qqp/ \
--do_train \
--do_eval \
--device gpu
其中参数释义如下:
model_type指示了模型类型,当前支持 BERT、ELECTRA、ERNIE、CONVBERT、MPNET 模型。model_name_or_path模型名称或者路径,其中 mpnet 模型当前仅支持 mpnet-base 几种规格。task_name表示 Fine-tuning 的任务,当前支持 CoLA、SST-2、MRPC、STS-B、QQP、MNLI、QNLI、RTE 和 WNLI。max_seq_length表示最大句子长度,超过该长度将被截断。per_device_train_batch_size表示每次迭代每张卡上的样本数目。learning_rate表示基础学习率大小,将于 learning rate scheduler 产生的值相乘作为当前学习率。lr_scheduler_typescheduler 类型,可选 linear 和 cosine。weight_decay权重衰减比例。warmup_stepswarmup 步数。max_steps表示最大训练步数。logging_steps表示日志打印间隔。save_steps表示模型保存及评估间隔。output_dir表示模型保存路径。do_train表示是否需要训练。do_eval表示是否需要评测。device表示使用的设备类型。默认为 GPU,可以配置为 CPU、GPU、XPU。若希望使用多 GPU 训练,将其设置为 GPU,同时环境变量 CUDA_VISIBLE_DEVICES 配置要使用的 GPU id。
(2)模型预测:
cd glue
python run_predict.py --task_name qqp --ckpt_path qqp/best-qqp_ft_model_106000.pdparams
(3)压缩 template 文件夹为 zip 文件,然后提交到GLUE 排行榜:
GLUE 开发集结果:
| task | cola | sst-2 | mrpc | sts-b | qqp | mnli | qnli | rte | avg |
|---|---|---|---|---|---|---|---|---|---|
| metric | mcc | acc | acc/f1 | pearson/spearman | acc/f1 | acc(m/mm) | acc | acc | |
| Paper | 65.0 | 95.5 | 91.8/空 | 91.1/空 | 91.9/空 | 88.5/空 | 93.3 | 85.8 | 87.9 |
| Mine | 64.4 | 95.4 | 90.4/93.1 | 91.6/91.3 | 91.9/89.0 | 87.7/88.2 | 93.6 | 86.6 | 87.7 |
GLUE 测试集结果对比:
| task | cola | sst-2 | mrpc | sts-b | qqp | mnli-m | qnli | rte | avg |
|---|---|---|---|---|---|---|---|---|---|
| metric | mcc | acc | acc/f1 | pearson/spearman | acc/f1 | acc(m/mm) | acc | acc | |
| Paper | 64.0 | 96.0 | 89.1/空 | 90.7/空 | 89.9/空 | 88.5/空 | 93.1 | 81.0 | 86.5 |
| Mine | 60.5 | 95.9 | 91.6/88.9 | 90.8/90.3 | 89.7/72.5 | 87.6/86.6 | 93.3 | 82.4 | 86.5 |
2、SQuAD v1.1
使用 Paddle 提供的预训练模型运行 SQuAD v1.1数据集的 Fine-tuning
unset CUDA_VISIBLE_DEVICES
python -m paddle.distributed.launch --gpus "0" run_squad.py \
--model_type mpnet \
--model_name_or_path mpnet-base \
--max_seq_length 512 \
--per_device_train_batch_size 16 \
--learning_rate 2e-5 \
--num_train_epochs 4 \
--lr_scheduler_type linear \
--logging_steps 25 \
--save_steps 25 \
--warmup_ratio 0.1 \
--weight_decay 0.1 \
--output_dir squad1.1/ \
--device gpu \
--do_train \
--do_eval \
--seed 42
训练过程中模型会自动对结果进行评估,其中最好的结果如下所示:
{
"exact": 86.84957426679281,
"f1": 92.82031917884066,
"total": 10570,
"HasAns_exact": 86.84957426679281,
"HasAns_f1": 92.82031917884066,
"HasAns_total": 10570
}
3、SQuAD v2.0
对于 SQuAD v2.0,按如下方式启动 Fine-tuning:
unset CUDA_VISIBLE_DEVICES
cd squad
python -m paddle.distributed.launch --gpus "0" run_squad.py \
--model_type mpnet \
--model_name_or_path mpnet-base \
--max_seq_length 512 \
--per_device_train_batch_size 16 \
--learning_rate 2e-5 \
--num_train_epochs 4 \
--lr_scheduler_type linear \
--logging_steps 200 \
--save_steps 200 \
--warmup_ratio 0.1 \
--weight_decay 0.1 \
--output_dir squad2/ \
--device gpu \
--do_train \
--do_eval \
--seed 42 \
--version_2_with_negative
version_2_with_negative: 使用 squad2.0数据集和评价指标的标志。
训练过程中模型会自动对结果进行评估,其中最好的结果如下所示:
{
"exact": 82.27912069401162,
"f1": 85.2774124891565,
"total": 11873,
"HasAns_exact": 80.34750337381917,
"HasAns_f1": 86.35268530427743,
"HasAns_total": 5928,
"NoAns_exact": 84.20521446593776,
"NoAns_f1": 84.20521446593776,
"NoAns_total": 5945,
"best_exact": 82.86869367472417,
"best_exact_thresh": -2.450321674346924,
"best_f1": 85.67634263296013,
"best_f1_thresh": -2.450321674346924
}
Tips:
Reference
@article{song2020mpnet,
title={MPNet: Masked and Permuted Pre-training for Language Understanding},
author={Song, Kaitao and Tan, Xu and Qin, Tao and Lu, Jianfeng and Liu, Tie-Yan},
journal={arXiv preprint arXiv:2004.09297},
year={2020}
}