Skip to content

Latest commit

 

History

History
 
 

ernie-3.0

ERNIE 3.0 轻量级模型

目录

模型介绍

本次开源的模型是在文心大模型ERNIE 3.0 基础上通过在线蒸馏技术得到的轻量级模型,模型结构与 ERNIE 2.0 保持一致,相比 ERNIE 2.0 具有更强的中文效果。

相关技术详解可参考文章《解析全球最大中文单体模型鹏城-百度·文心技术细节》

在线蒸馏技术

在线蒸馏技术在模型学习的过程中周期性地将知识信号传递给若干个学生模型同时训练,从而在蒸馏阶段一次性产出多种尺寸的学生模型。相对传统蒸馏技术,该技术极大节省了因大模型额外蒸馏计算以及多个学生的重复知识传递带来的算力消耗。

这种新颖的蒸馏方式利用了文心大模型的规模优势,在蒸馏完成后保证了学生模型的效果和尺寸丰富性,方便不同性能需求的应用场景使用。此外,由于文心大模型的模型尺寸与学生模型差距巨大,模型蒸馏难度极大甚至容易失效。为此,通过引入了助教模型进行蒸馏的技术,利用助教作为知识传递的桥梁以缩短学生模型和大模型表达空间相距过大的问题,从而促进蒸馏效率的提升。

更多技术细节可以参考论文:

image

模型效果

本项目开源 ERNIE 3.0 BaseERNIE 3.0 MediumERNIE 3.0 MiniERNIE 3.0 MicroERNIE 3.0 Nano 五个模型:

下面是 PaddleNLP 中轻量级中文模型的效果-时延图。横坐标表示在 IFLYTEK 数据集 (最大序列长度设置为 128) 上测试的延迟(latency,单位:ms),纵坐标是 CLUE 10 个任务上的平均精度(包含文本分类、文本匹配、自然语言推理、代词消歧、阅读理解等任务),其中 CMRC2018 阅读理解任务的评价指标是 Exact Match(EM),其他任务的评价指标均是 Accuracy。图中越靠左上的模型,精度和性能水平越高。

图中模型名下方标注了模型的参数量,测试环境见性能测试

batch_size=32 时,CPU 下的效果-时延图(线程数 1 和 8):

batch_size=1 时,CPU 下的效果-时延图(线程数 1 和 8):

batch_size=32 和 1,预测精度为 FP16 时,GPU 下的效果-时延图:

从图上可看出,ERNIE 3.0 系列轻量级模型在精度和性能上的综合表现已全面领先于 UER-py、Huawei-Noah 以及 HFL 的中文模型。且当 batch_size=1、预测精度为 FP16 时,在 GPU 上宽且浅的模型的推理性能更有优势。

在 CLUE 验证集上评测指标如下表所示:

Arch Model AVG AFQMC TNEWS IFLYTEK CMNLI OCNLI CLUEWSC2020 CSL CMRC2018 CHID C3
24L1024H ERNIE 1.0-Large-cw 79.03 75.97 59.65 62.91 85.09 81.73 93.09 84.53 74.22/91.88 88.57 84.54
ERNIE 2.0-Large-zh 76.90 76.23 59.33 61.91 83.85 79.93 89.82 83.23 70.95/90.31 86.78 78.12
RoBERTa-wwm-ext-large 76.61 76.00 59.33 62.02 83.88 78.81 90.79 83.67 70.58/89.82 85.72 75.26
20L1024H ERNIE 3.0-Xbase-zh 78.39 76.16 59.55 61.87 84.40 81.73 88.82 83.60 75.99/93.00 86.78 84.98
12L768H ERNIE 3.0-Base-zh 76.05 75.93 58.26 61.56 83.02 80.10 86.18 82.63 70.71/90.41 84.26 77.88
ERNIE 1.0-Base-zh-cw 76.47 76.07 57.86 59.91 83.41 79.58 89.91 83.42 72.88/90.78 84.68 76.98
ERNIE-Gram-zh 75.72 75.28 57.88 60.87 82.90 79.08 88.82 82.83 71.82/90.38 84.04 73.69
Langboat/Mengzi-BERT-Base 74.69 75.35 57.76 61.64 82.41 77.93 88.16 82.20 67.04/88.35 83.74 70.70
ERNIE 2.0-Base-zh 74.32 75.65 58.25 61.64 82.62 78.71 81.91 82.33 66.08/87.46 82.78 73.19
ERNIE 1.0-Base-zh 74.17 74.84 58.91 62.25 81.68 76.58 85.20 82.77 67.32/87.83 82.47 69.68
RoBERTa-wwm-ext 74.11 74.60 58.08 61.23 81.11 76.92 88.49 80.77 68.39/88.50 83.43 68.03
BERT-Base-Chinese 72.57 74.63 57.13 61.29 80.97 75.22 81.91 81.90 65.30/86.53 82.01 65.38
UER/Chinese-RoBERTa-Base 71.78 72.89 57.62 61.14 80.01 75.56 81.58 80.80 63.87/84.95 81.52 62.76
8L512H UER/Chinese-RoBERTa-Medium 67.06 70.64 56.10 58.29 77.35 71.90 68.09 78.63 57.63/78.91 75.13 56.84
6L768H ERNIE 3.0-Medium-zh 72.49 73.37 57.00 60.67 80.64 76.88 79.28 81.60 65.83/87.30 79.91 69.73
HLF/RBT6, Chinese 70.06 73.45 56.82 59.64 79.36 73.32 76.64 80.67 62.72/84.77 78.17 59.85
TinyBERT6, Chinese 69.62 72.22 55.70 54.48 79.12 74.07 77.63 80.17 63.03/83.75 77.64 62.11
RoFormerV2 Small 68.52 72.47 56.53 60.72 76.37 72.95 75.00 81.07 62.97/83.64 67.66 59.41
UER/Chinese-RoBERTa-L6-H768 67.09 70.13 56.54 60.48 77.49 72.00 72.04 77.33 53.74/75.52 76.73 54.40
6L384H ERNIE 3.0-Mini-zh 66.90 71.85 55.24 54.48 77.19 73.08 71.05 79.30 58.53/81.97 69.71 58.60
4L768H HFL/RBT4, Chinese 67.42 72.41 56.50 58.95 77.34 70.78 71.05 78.23 59.30/81.93 73.18 56.45
4L512H UER/Chinese-RoBERTa-Small 63.25 69.21 55.41 57.552 73.64 69.80 66.78 74.83 46.75/69.69 67.59 50.92
4L384H ERNIE 3.0-Micro-zh 64.21 71.15 55.05 53.83 74.81 70.41 69.08 76.50 53.77/77.82 62.26 55.53
4L312H ERNIE 3.0-Nano-zh 62.97 70.51 54.57 48.36 74.97 70.61 68.75 75.93 52.00/76.35 58.91 55.11
TinyBERT4, Chinese 60.82 69.07 54.02 39.71 73.94 69.59 70.07 75.07 46.04/69.34 58.53 52.18
4L256H UER/Chinese-RoBERTa-Mini 53.40 69.32 54.22 41.63 69.40 67.36 65.13 70.07 5.96/17.13 51.19 39.68
3L1024H HFL/RBTL3, Chinese 66.63 71.11 56.14 59.56 76.41 71.29 69.74 76.93 58.50/80.90 71.03 55.56
3L768H HFL/RBT3, Chinese 65.72 70.95 55.53 59.18 76.20 70.71 67.11 76.63 55.73/78.63 70.26 54.93
2L128H UER/Chinese-RoBERTa-Tiny 44.45 69.02 51.47 20.28 59.95 57.73 63.82 67.43 3.08/14.33 23.57 28.12

以下是本项目目录结构及说明:

.
├── run_seq_cls.py               # 分类任务的微调脚本
├── run_token_cls.py             # 序列标注任务的微调脚本
├── run_qa.py                    # 阅读理解任务的微调脚本
├── compress_seq_cls.py          # 分类任务的压缩脚本
├── compress_token_cls.py        # 序列标注任务的压缩脚本
├── compress_qa.py               # 阅读理解任务的压缩脚本
├── config.yml                   # 压缩配置文件
├── infer.py                     # 支持 CLUE 分类、CLUE CMRC2018、MSRA_NER 任务的预测脚本
├── deploy                       # 部署目录
│ └── python
│   └── ernie_predictor.py
│   └── infer_cpu.py
│   └── infer_gpu.py
│   └── README.md
│ └── serving
│   └── seq_cls_rpc_client.py
│   └── seq_cls_service.py
│   └── seq_cls_config.yml
│   └── token_cls_rpc_client.py
│   └── token_cls_service.py
│   └── token_cls_config.yml
│   └── README.md
│ └── paddle2onnx
│   └── ernie_predictor.py
│   └── infer.py
│   └── README.md
└── README.md                    # 文档,本文件

微调

ERNIE 3.0 发布的预训练模型还不能直接在下游任务上直接使用,需要使用具体任务上的数据对预训练模型进行微调。

使用 PaddleNLP 只需要一行代码可以拿到 ERNIE 3.0 系列模型,之后可以在自己的下游数据下进行微调,从而获得具体任务上效果更好的模型。

from paddlenlp.transformers import *

tokenizer = AutoTokenizer.from_pretrained("ernie-3.0-medium-zh")

# 用于分类任务
seq_cls_model = AutoModelForSequenceClassification.from_pretrained("ernie-3.0-medium-zh")

# 用于序列标注任务
token_cls_model = AutoModelForTokenClassification.from_pretrained("ernie-3.0-medium-zh")

# 用于阅读理解任务
qa_model = AutoModelForQuestionAnswering.from_pretrained("ernie-3.0-medium-zh")

本项目提供了针对分类(包含文本分类、文本匹配、自然语言推理、代词消歧等任务)、序列标注、阅读理解三大场景下微调的示例脚本,可分别参考 run_seq_cls.pyrun_token_cls.pyrun_qa.py 三个脚本,启动方式如下:

# 分类任务
# 该脚本共支持 CLUE 中 7 个分类任务,超参不全相同,因此分类任务中的超参配置利用 config.yml 配置
python run_seq_cls.py  \
    --task_name tnews \
    --model_name_or_path ernie-3.0-medium-zh \
    --do_train

# 序列标注任务
python run_token_cls.py \
    --task_name msra_ner  \
    --model_name_or_path ernie-3.0-medium-zh \
    --do_train \
    --num_train_epochs 3 \
    --learning_rate 0.00005 \
    --save_steps 100 \
    --batch_size 32 \
    --max_seq_length 128 \
    --remove_unused_columns False

# 阅读理解任务
python run_qa.py \
    --model_name_or_path ernie-3.0-medium-zh \
    --do_train \
    --learning_rate 0.00003 \
    --num_train_epochs 8 \
    --batch_size 24 \
    --max_seq_length 512

模型压缩

尽管 ERNIE 3.0 已提供了效果不错的 6 层、4 层轻量级模型可以微调后直接使用,但如果有模型部署上线的需求,则需要进一步压缩模型体积,可以使用这里提供的一套模型压缩方案及 API 对上一步微调后的模型进行压缩。

环境依赖

使用裁剪功能需要安装 paddleslim 包

pip install paddleslim

模型压缩 API 使用

本项目使用压缩 API 对任务数据上微调后的模型进行裁剪和量化。用户在传入模型,以及相关的压缩超参数(可选,提供默认选项)后,只需要调用一行 compress() 即可一键启动裁剪和量化,并自动保存压缩后的模型进行后续部署。

核心调用方法如下,如需跑通完整的例子可参考本目录下完整样例脚本:

trainer = Trainer(
    model=model,
    args=compression_args,
    data_collator=data_collator,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    criterion=criterion)

trainer.compress()

使用压缩 API 基于 Trainer 需要先初始化一个 Trainer 实例,然后调用 compress() 启动压缩。

假设上述代码位于脚本 compress.py 中,可这样调用:

python compress.py \
    --dataset   "clue cluewsc2020"   \
    --model_name_or_path best_models/CLUEWSC2020 \
    --output_dir ./compress_models  \
    --per_device_train_batch_size 32 \
    --per_device_eval_batch_size 32 \
    --width_mult_list 0.75 \
    --batch_size_list 4 8 16 \
    --batch_num_list 1 \

可以通过传入命令行参数来控制模型压缩的一些超参数,压缩 API 可以传入的超参数可参考文档

本项目提供了压缩 API 在分类(包含文本分类、文本匹配、自然语言推理、代词消歧等任务)、序列标注、阅读理解三大场景下的使用样例,可以分别参考 compress_seq_cls.pycompress_token_cls.pycompress_qa.py,启动方式如下:

# 分类任务
# 该脚本共支持 CLUE 中 7 个分类任务,超参不全相同,因此分类任务中的超参配置利用 config.yml 配置
python compress_seq_cls.py \
    --dataset "clue tnews"  \
    --model_name_or_path best_models/TNEWS  \
    --output_dir ./

# 序列标注任务
python compress_token_cls.py \
    --dataset "msra_ner"  \
    --model_name_or_path best_models/MSRA_NER \
    --output_dir ./ \
    --max_seq_length 128 \
    --per_device_train_batch_size 32 \
    --per_device_eval_batch_size 32 \
    --learning_rate 0.00005 \
    --remove_unused_columns False \
    --num_train_epochs 3

# 阅读理解任务
python compress_qa.py \
    --dataset "clue cmrc2018" \
    --model_name_or_path best_models/CMRC2018  \
    --output_dir ./ \
    --max_answer_length 50 \
    --max_seq_length 512 \
    --learning_rate 0.00003 \
    --num_train_epochs 8 \
    --per_device_train_batch_size 24 \
    --per_device_eval_batch_size 24 \

一行代码验证上面模型压缩后模型的精度:

# 原模型
python infer.py --task_name tnews --model_path best_models/TNEWS/compress/inference/infer --use_trt
# 裁剪后
python infer.py --task_name tnews --model_path best_models/TNEWS/compress/0.75/float --use_trt
# 量化后
python infer.py --task_name tnews --model_path best_models/TNEWS/compress/0.75/hist16/int8 --use_trt --precision int8

其中 --model_path 参数需要传入静态图模型的路径和前缀名。

压缩效果

精度测试

本案例中我们对 ERNIE 3.0-Medium 模型在三类任务上微调后的模型使用压缩 API 进行压缩。压缩后精度如下:

Model AVG AFQMC TNEWS IFLYTEK CMNLI OCNLI CLUEWSC2020 CSL CMRC2018 MSRA_NER
ERNIE 3.0-Medium 74.87 75.35 57.45 60.18 81.16 77.19 80.59 81.93 66.95/87.15 92.65/93.43/93.04
ERNIE 3.0-Medium+FP16 74.87 75.32 57.45 60.22 81.16 77.22 80.59 81.90 66.95/87.16 92.65/93.45/93.05
ERNIE 3.0-Medium+裁剪+FP32 74.70 75.14 57.31 60.29 81.25 77.46 79.93 81.70 65.92/86.43 93.10/93.43/93.27
ERNIE 3.0-Medium+裁剪+FP16 74.71 75.21 57.27 60.29 81.24 77.56 79.93 81.73 65.89/86.44 93.10/93.43/93.27
ERNIE 3.0-Medium+裁剪+量化+INT8 74.44 75.02 57.26 60.37 81.03 77.25 77.96 81.67 66.17/86.55 93.17/93.23/93.20
ERNIE 3.0-Medium+量化+INT8 74.10 74.67 56.99 59.91 81.03 75.05 78.62 81.60 66.32/86.82 93.10/92.90/92.70

评价指标说明: 其中 CLUE 分类任务(AFQMC 语义相似度、TNEWS 文本分类、IFLYTEK 长文本分类、CMNLI 自然语言推理、OCNLI 自然语言推理、CLUEWSC2020 代词消歧、CSL 论文关键词识别)的评价指标是 Accuracy,阅读理解任务 CLUE CMRC2018 的评价指标是 EM (Exact Match) / F1-Score,计算平均值时取 EM,序列标注任务 MSRA_NER 的评价指标是 Precision/Recall/F1-Score,计算平均值时取 F1-Score。

由表可知,ERNIE 3.0-Medium 模型经过裁剪和量化后,精度平均下降 0.46,其中裁剪后下降了 0.17,单独量化精度平均下降 0.77。

性能测试

性能测试的配置如下:

  1. 数据集:TNEWS(文本分类)、MSRA_NER(序列标注)、CLUE CMRC2018(阅读理解)

  2. 计算卡:T4、CUDA11.2、CuDNN8.2

  3. CPU 信息:Intel(R) Xeon(R) Gold 6271C CPU

  4. PaddlePaddle 版本:2.3

  5. PaddleNLP 版本:2.3

  6. 性能数据单位是 QPS。QPS 测试方法:固定 batch size 为 32,测试运行时间 total_time,计算 QPS = total_samples / total_time

  7. 精度数据单位:文本分类是 Accuracy,序列标注是 F1-Score,阅读理解是 EM (Exact Match)

CPU 性能

测试环境及说明如上,测试 CPU 性能时,线程数设置为12。

TNEWS 性能 TNEWS 精度 MSRA_NER 性能 MSRA_NER 精度 CMRC2018 性能 CMRC2018 精度
ERNIE 3.0-Medium+FP32 311.95(1.0X) 57.45 90.91(1.0x) 93.04 33.74(1.0x) 66.95
ERNIE 3.0-Medium+INT8 600.35(1.9x) 56.57(-0.88) 141.00(1.6x) 92.64(-0.40) 56.51(1.7x) 66.23(-0.72)
ERNIE 3.0-Medium+裁剪+FP32 408.65(1.3x) 57.31(-0.14) 122.13(1.3x) 93.27(+0.23) 48.47(1.4x) 65.55(-1.40)
ERNIE 3.0-Medium+裁剪+INT8 704.42(2.3x) 56.69(-0.76) 215.58(2.4x) 92.39(-0.65) 75.23(2.2x) 63.47(-3.48)

三类任务(分类、序列标注、阅读理解)经过相同压缩过程后,加速比达到 2.3 左右。

GPU 性能
TNEWS 性能 TNEWS 精度 MSRA_NER 性能 MSRA_NER 精度 CMRC2018 性能 CMRC2018 精度
ERNIE 3.0-Medium+FP32 1123.85(1.0x) 57.45 366.75(1.0x) 93.04 146.84(1.0x) 66.95
ERNIE 3.0-Medium+FP16 2672.41(2.4x) 57.45(0.00) 840.11(2.3x) 93.05(0.01) 303.43(2.1x) 66.95(0.00)
ERNIE 3.0-Medium+INT8 3226.26(2.9x) 56.99(-0.46) 889.33(2.4x) 92.70(-0.34) 348.84(2.4x) 66.32(-0.63
ERNIE 3.0-Medium+裁剪+FP32 1424.01(1.3x) 57.31(-0.14) 454.27(1.2x) 93.27(+0.23) 183.77(1.3x) 65.92(-1.03)
ERNIE 3.0-Medium+裁剪+FP16 3577.62(3.2x) 57.27(-0.18) 1138.77(3.1x) 93.27(+0.23) 445.71(3.0x) 65.89(-1.06)
ERNIE 3.0-Medium+裁剪+INT8 3635.48(3.2x) 57.26(-0.19) 1105.26(3.0x) 93.20(+0.16) 444.27(3.0x) 66.17(-0.78)

三类任务(分类、序列标注、阅读理解)经过裁剪 + 量化后加速比均达到 3 倍左右,所有任务上平均精度损失可控制在 0.5 以内(0.46)。

使用 FasterTokenizer 加速

FasterTokenizer 是飞桨提供的速度领先的文本处理算子库,集成了 Google 于 2021 年底发布的 LinMaxMatch 算法,该算法引入 Aho-Corasick 将 WordPiece 的时间复杂度从 O(N2) 优化到 O(N),已在 Google 搜索业务中大规模上线。FasterTokenizer 速度显著领先,且呈现 batch_size 越大,优势越突出。例如,设置 batch_size = 64 时,FasterTokenizer 切词速度比 HuggingFace 快 28 倍。

在 ERNIE 3.0 轻量级模型裁剪、量化基础上,当设置切词线程数为 4 时,使用 FasterTokenizer 在 NVIDIA Tesla T4 环境下在 IFLYTEK (长文本分类数据集,最大序列长度为 128)数据集上性能提升了 2.39 倍,相比 BERT-Base 性能提升了 7.09 倍,在 Intel(R) Xeon(R) Gold 6271C CPU @ 2.60GHz、线程数为 8 的情况下性能提升了 1.27 倍,相比 BERT-Base 性能提升了 5.13 倍。加速效果如下图所示:

使用 FasterTokenizer 的方式非常简单,在安装 faster_tokenizer 包之后,仅需在 tokenizer 实例化时直接传入 use_faster=True 即可。目前已在 Linux 系统下支持 BERT、ERNIE、TinyBERT 等模型。

安装 faster_tokenizer 包的命令:

pip install faster_tokenizer

如需设置切词线程数,需要运行前先设置环境变量 OMP_NUM_THREADS

# 设置切词线程数为 4
export OMP_NUM_THREADS=4

调用 from_pretrained 时只需轻松传入一个参数 use_faster=True

from paddlenlp.transformers import AutoTokenizer
AutoTokenizer.from_pretrained("ernie-3.0-medium-zh", use_faster=True)

部署

我们为 ERNIE 3.0 提供了多种部署方案,可以满足不同场景下的部署需求,请根据实际情况进行选择。

image

Python 部署

Python部署请参考:Python 部署指南

服务化部署

Paddle2ONNX 部署

ONNX 导出及 ONNXRuntime 部署请参考:ONNX 导出及 ONNXRuntime 部署指南

Paddle Lite 移动端部署

即将支持,敬请期待

Notebook教程

参考文献

  • Sun Y, Wang S, Feng S, et al. ERNIE 3.0: Large-scale Knowledge Enhanced Pre-training for Language Understanding and Generation[J]. arXiv preprint arXiv:2107.02137, 2021.

  • Su W, Chen X, Feng S, et al. ERNIE-Tiny: A Progressive Distillation Framework for Pretrained Transformer Compression[J]. arXiv preprint arXiv:2106.02241, 2021.

  • Wang S, Sun Y, Xiang Y, et al. ERNIE 3.0 Titan: Exploring Larger-scale Knowledge Enhanced Pre-training for Language Understanding and Generation[J]. arXiv preprint arXiv:2112.12731, 2021.