1. 工作简介
基于 ERNIE 预训练模型成果上达到业界当先,然而因为模型比拟大,预测性能可能无奈满足上线需要。
间接应用 ERNIE-Tiny 系列轻量模型 fine-tune,成果可能不够现实。如果采纳 数据蒸馏 策略,又须要提供海量未标注数据,可能并不具备客观条件。
因而,本专题采纳支流的常识蒸馏的计划来压缩模型,在满足用户预测性能、预测成果的需要同时,不依赖海量未标注数据,晋升开发效率。
文心提供多种不同大小的基于字粒度的 ERNIE-Tiny 学生模型,满足不同用户的需要。
注:常识蒸馏(KD)是将简单模型(teacher)中的 dark
knowledge 迁徙到简略模型(student)中去,teacher 具备弱小的能力和体现,而 student 则更为紧凑。通过常识蒸馏,心愿 student 能尽可能迫近亦或是超过 teacher,从而用更少的复杂度来取得相似的预测成果。
1.1 模型蒸馏原理
常识蒸馏是一种模型压缩常见办法,指的是在 teacher-student 框架中,将简单、学习能力强的网络 (teacher) 学到的 特色示意 “ 常识 ” 蒸馏进去,传递给参数量小、学习能力弱的网络(student)。
在训练过程中,往往以最优化训练集的 准确率作为训练指标 ,但 实在指标其实应该是最优化模型的泛化能力 。显然如果能间接以晋升模型的泛化能力为指标进行训练是最好的,但这须要正确的对于泛化能力的信息,而这些信息通常不可用。如果咱们应用由 大型模型产生的所有类概率作为训练小模型的指标,就能够让小模型失去不输大模型的性能。这种把大模型的常识迁徙到小模型的形式就是蒸馏。
基本原理可参考 Hinton 经典论文:https://arxiv.org/abs/1503.02531
1.2 ERNIE-Tiny 模型蒸馏
- 模型蒸馏原理可参考论文 ERNIE-Tiny : A Progressive Distillation Framework for Pretrained Transformer Compression 2021。不同于原论文的实现,为了和开发套件中的通用蒸馏学生模型保持一致,咱们将蒸馏 loss 替换为 Attention 矩阵的 KQ loss 和 VV loss,原理可参考论文 MiniLM: Deep Self-Attention Distillation for Task-Agnostic Compression of Pre-Trained Transformers 2020 和 MiniLMv2: Multi-Head Self-Attention Relation Distillation for Compressing Pretrained Transformers 2021。试验表明通用蒸馏阶段和工作蒸馏阶段的蒸馏 loss 不匹配时,学生模型的成果会受到影响。
BERT 等预训练语言模型 (PLM) 采纳了一种训练范式,首先在个别数据中预训练模型,而后在特定工作数据上微调模型,最近获得了巨大成功。然而,PLM 因其宏大的参数而臭名远扬,并且难以部署在现实生活中的应用程序中。常识蒸馏通过在一组数据上将常识从大老师转移到小得多的学生来解决这个问题。咱们认为抉择三个要害组成部分,即老师、训练数据和学习指标,对于蒸馏的有效性至关重要。因而,咱们提出了一个四阶段渐进式蒸馏框架 ERNIE-Tiny 来压缩 PLM,它将三个组件从个别级别逐步变动到特定工作级别。具体来说,第一阶段,General Distillation,在预训练的老师、个别数据和潜在蒸馏损失的领导下进行蒸馏。而后,General-Enhanced Distillation 将老师模型从预训练老师转变为微调老师。之后,Task-Adaptive Distillation 将训练数据从个别数据转移到特定于工作的数据。最初,Task-Specific Distillation 在最初阶段减少了两个额定的损失,即 Soft-Label 和 Hard-Label 损失。实证后果证实了咱们的框架的有效性和所带来的泛化增益。试验表明 4 层 ERNIE-Tiny 在 GLUE 基准测试的根底上放弃其 12 层老师 BERT 的 98.0% 以上的性能,超过最先进的 (SOTA) 1.0% 的 GLUE 分数雷同数量的参数。此外,ERNIE-Tiny 在五个中文 NLP 工作上实现了新的压缩 SOTA,比 BERT 根底的精度高 0.4%,参数缩小 7.5 倍,推理速度放慢 9.4 倍。
预训练的语言模型(例如,BERT (Devlin et al., 2018) 及其变体)在各种 NLP 工作中获得了显着的胜利。然而,这些模型通常蕴含数亿个参数,因为提早和容量限度,这给事实利用中的微调和在线服务带来了挑战。在这项工作中,咱们提出了一种简略无效的办法来压缩基于大型 Transformer (Vaswani et al., 2017) 的预训练模型,称为深度自注意力蒸馏。小模型(学生)通过深度模拟大模型(老师)的自注意力模块进行训练,该模块在 Transformer 网络中起着至关重要的作用。具体来说,咱们倡议提炼出老师最初一个 Transformer 层的自注意力模块,这对学生来说既无效又灵便。此外,除了现有作品中应用的注意力散布(即查问和键的缩放点积)之外,咱们还引入了自我留神模块中值之间的缩放点积作为新的深度自我留神常识. 此外,咱们表明,引入老师助理(Mirzadeh 等人,2019 年)也有助于提炼大型预训练 Transformer 模型。试验结果表明,咱们的单语模型在不同参数大小的学生模型中优于最先进的基线。特地是,它应用 50% 的 Transformer 参数和老师模型的计算在 SQuAD 2.0 和几个 GLUE 基准测试工作上放弃了 99% 以上的准确率。咱们还在将深度自注意力蒸馏利用于多语言预训练模型方面取得了竞争性后果。
咱们仅应用自注意力关系蒸馏来对预训练的 Transformer 进行工作不可知的压缩,从而在 MiniLM (Wang et al., 2020) 中推广深度自注意力蒸馏。特地是,咱们将多头自注意力关系定义为每个自注意力模块内的查问、键和值向量对之间的缩放点积。而后咱们利用上述关系常识来训练学生模型。除了简略对立的准则外,更无利的是,学生的注意力头数没有限度,而之前的大多数工作都必须保障老师和学生之间的头数雷同。此外,细粒度的自注意力关系偏向于充分利用 Transformer 学习到的交互常识。此外,咱们彻底查看了老师模型的层抉择策略,而不是像 MiniLM 中那样仅仅依赖最初一层。咱们对压缩单语和多语预训练模型进行了宽泛的试验。试验结果表明,咱们从根底规模和大型老师(BERT、RoBERTa 和 XLM-R)中提取的模型优于最先进的模型。
-
二阶段蒸馏:
- 通用蒸馏(General Distillation,GD):在预训练阶段训练,应用大规模无监督的数据,帮忙学生网络学习到尚未微调的老师网络中的常识,有利于进步泛化能力。为不便用户应用,咱们提供了多种尺寸的通用蒸馏学生模型,可用的通用蒸馏学生模型可参考文档:通用模型 – ERNIE3.0 Tiny。
- 工作蒸馏(Task-specific Distillation,TD):应用具体任务的数据,学习到更多任务相干的具体常识。
- 如果已提供的通用蒸馏学生模型尺寸合乎需要,用户能够次要关注接下来的工作蒸馏过程。
1.3 工作蒸馏步骤
- FT 阶段:基于 ERNIE 3.0 Large 蒸馏模型 fine-tune 失去老师模型,留神这里用到的老师模型和 ERNIE 3.0 Large 是两个不同的模型;
- GED 阶段(可选):应用 fine-tuned 老师模型和通用数据持续用通用蒸馏的形式蒸馏学生模型,进一步晋升学生模型的成果;
a. 热启动 fine-tuned 的老师模型和通用学生模型。其中,通用的学生模型由文心平台提供,从 bos 上下载。
- TD1 阶段:蒸馏中间层
a. 只对 学生模型的最初一层进行蒸馏 , 将学生模型 transformer 的 attention 层的 k - q 矩阵和 v - v 矩阵与老师模型的对应矩阵做 KLloss,可参考:MiniLMV2。
b. 热启动 fine-tuned 的老师模型和 GED 阶段失去的学生模型。其中,通用的学生模型由文心平台提供,从 bos 上下载,下载链接所在文档:通用模型 ERNIE3.0 Tiny,或参考预置的下载脚本:
c. 反向流传阶段只更新学生模型参数,老师模型参数不更新;
- TD2 阶段:蒸馏预测层,产出最终的学生模型。
a. 热启动 fine-tuned 的老师模型和 TD1 阶段训练的学生模型;
b. loss 包含两局部:1)pred_loss:软标签,学生模型的预测层输入与老师模型的预测层输入的穿插熵;2)
student_ce_loss:硬标签,学生模型的预测层输入与实在 label 的穿插熵;c. pred_loss 与 student_ce_loss 之和作为最终 loss,进行反向流传;
d. 反向流传阶段只更新学生模型参数,老师模型参数不更新;
注:对于 GED 阶段应用的通用数据:开发套件中的通用数据是由开源我的项目 https://github.com/brightmart/nlp_chinese_corpus 中的中文维基百科语料(wiki2019zh)通过预处理失去。该数据只用于 demo 展现,理论应用时替换为业务无标注数据成果晋升更显著。
2. 常见问题
问题 1:怎么批改学生模型的层数?下面提供了多种不同的学生模型,但每个学生模型的层数、hidden size 等都是固定的,如果想更改,须要在哪些地方更改?
文心提供了三种不同构造的预训练学生模型,如果批改层数、hidden size 等,会导致预训练学生模型参数无奈加载,在此状况下,蒸馏进去的学生模型成果无奈保障,倡议用户还是应用文心提供的预训练模型,不更改模型构造;如果用户认为更改学生模型的构造十分有必要,须要对文心做以下改变:
- 批改 TD1 阶段 json 配置文件的 pre_train_model 配置项,删除预训练学生模型的加载,只保留微调后的老师模型
"pre_train_model": [
# 热启动 fine-tune 的 teacher 模型
{
"name": "finetuned_teacher_model",
"params_path": "./output/cls_ernie_3.0_large_ft/save_checkpoints/checkpoints_step_6000"
}
]
- 将 json 文件中的 ”student_embedding” 替换为自定义的学生模型
"student_embedding": {"config_path": "../../models_hub/ernie_3.0_tiny_ch_dir/ernie_config.json"},
- 再次强调,上述批改后,因为无奈加载预训练学生模型,蒸馏进去的学生模型成果无奈保障。(用户训练数据量到百万样本以上能够思考尝试一下)
3. 数据蒸馏工作
3.1 简介
在 ERNIE 弱小的语义理解能力背地,是须要同样弱小的算力能力撑持起如此大规模模型的训练和预测。很多工业利用场景对性能要求较高,若不能无效压缩则无奈理论利用。
因而,咱们基于数据蒸馏技术构建了数据蒸馏零碎。其原理是通过数据作为桥梁,将 ERNIE 模型的常识迁徙至小模型,以达到损失很小的成果却能达到上千倍的预测速度晋升的成果。
目录构造
数据蒸馏工作位于 wenxin_appzoo/tasks/data_distillation
├── data
│ ├── dev_data
│ ├── dict
│ ├── download_data.sh
│ ├── predict_data
│ ├── test_data
│ └── train_data
├── distill
│ └── chnsenticorp
│ ├── student
│ └── teacher
├── examples
│ ├── cls_bow_ch.json
│ ├── cls_cnn_ch.json
│ ├── cls_ernie_fc_ch_infer.json
│ └── cls_ernie_fc_ch.json
├── inference
│ ├── custom_inference.py
│ ├── __init__.py
├── model
│ ├── base_cls.py
│ ├── bow_classification.py
│ ├── cnn_classification.py
│ ├── ernie_classification.py
│ ├── __init__.py
├── run_distill.sh
├── run_infer.py
├── run_trainer.py
└── trainer
├── custom_dynamic_trainer.py
├── __init__.py
3.2 数据筹备
目前采纳三种数据加强策略策略,对于不必的工作能够特定的比例混合。三种数据加强策略包含:
(1)增加噪声:对原始样本中的词,以肯定的概率(如 0.1)替换为”UNK”标签
(2)同词性词替换:对原始样本中的所有词,以肯定的概率(如 0.1)替换为本数据集中随机一个同词性的词
(3)N-sampling:从原始样本中,随机选取地位截取长度为 m 的片段作为新的样本,其中片段的长度 m 为 0 到原始样本长度之间的随机值
数据加强策略可参考数据加强,咱们已筹备好了采纳上述 3 种加强策略制作的 chnsenticorp 的加强数据。
3.3 离线蒸馏
- 应用预置的 ERNIE 2.0 base 模型
cd wenxin_appzoo/models_hub
bash download_ernie_2.0_base_ch.sh
- 下载预置的原始数据以及加强数据。
cd wenxin_appzoo/tasks/data_distillation/distill
bash download_data.sh
- 运行以下命令,开始数据蒸馏
cd wenxin_appzoo/tasks/data_distillation
bash run_distill.sh
3.3.1 蒸馏过程阐明
- run_distill.sh 脚本会进行前述的三步:
在工作数据上 Fine-tune;
加载 Fine-tune 好的模型对加强数据进行打分;
应用 Student 模型进行训练。脚本采纳 hard-label 蒸馏,在第二步中将会间接预测出 ERNIE 标注的 label。
- run_distill.sh 脚本波及老师和学生模型的 json 文件,其中:
./examples/cls_ernie_fc_ch.json 负责老师模型的 finetune,
./examples/cls_ernie_fc_ch_infer.json 负责老师模型的预测。./examples/cls_cnn_ch.json,负责学生模型的训练。
- 当时结构好的加强数据放在./distill/chnsenticorp/student/unsup_train_aug
- 在脚本的第二步中,应用 ./examples/cls_ernie_fc_ch_infer.json 进行预测:脚本从规范输出获取明文输出,并将打分输入到规范输入。用这种形式对数据加强后的无监督训练意料进行标注。最终的标注后果放在 ./distill/chnsenticorp/student/train/part.1 文件中。标注后果蕴含两列, 第一列为明文,第二列为标注 label。
- 在第三步开始 student 模型的训练,其训练数据放在 distill/chnsenticorp/student/train/ 中,part.0 为原监督数据 part.1 为 ERNIE 标注数据。
- 注:如果用户曾经领有了无监督数据,则能够将无监督数据放入 distill/chnsenticorp/student/unsup_train_aug 即可。