论文
TinyBERT: Distilling BERT for Natural Language Understanding
基于transformer模型的两段式学习框架
general distillation
teacher model: 原始的bert模型(没有进行fine-tuning)
student model: 常规的tinybert 在常规领域的语料
task-specific distillation
首先做数据增强(data augmentation)
teacher model: fine-tuned的bert模型
student model: tinybert 在增强的语料上
三种不同的损失函数去适应bert的各个表示层
- embedding layer的output
类似transformer层的hidden_state
- transformer layer的hidden_state 和attention
hidden_state loss:
MHA(multi-head attention) Loss:
- prediction layer的logit output
论文贡献:
提出一个新的transformer蒸馏方法将bert的编码的语言知识充分的转移到tinybert;
两段式学习框架,既能在预训练,也能在下游任务上,确保tinybert都能学习到bert;
实验,tinybert-4,保留97%能力,使用13.3%的参数,用时是原来的10.6%在GLUE;
tinybert-6实验。
损失函数:
源码:
tinybert
预训练语料获取
python pregenerate_training_data.py --train_corpus train.txt --output_dir outputdir --bert_model …/z_model_info/bert-base-chinese
相关参数解释:
train_corpus: 训练语料的路径位置,注意段落之间使用空白newline隔开;
output_dir: 输出json对应路径;
bert_model: bert模型对应路径,主要获取vocab.txt
epochs_to_generate: 生成多少个json
生成json的结构如下图:
tokens是unicode编码的句子,包含[“CLS”],[“SEP”]
segment_ids代表属于的句子的标签,
is_random_next代表是否是随机选取的句子作为下一句
masked_lm_position代表masked的位置
masked_lm_labels代表原有的标签
生成的规则跟bert的生成规则一致,下一句的是否随机的比例是0.5
masked位置80%采用[“MASK”],10%采用原label,剩下10%的使用随机
预训练阶段蒸馏
python general_distill.py --pregenerated_data $train_file_dir --teacher_model $teacher_model_dir --student_model $student_model_dir --output_dir $output_dir --train_batch_size 16
源码中使用的均方误差作为loss函数,并且1,2的loss都在文中有实现,但是没有看到3中的loss,猜测应该是在第二阶段蒸馏时加入了3的loss,预训练阶段并没有,训练阶段没有特别的,也不赘述;
数据增强
就是扩展数据,没有细致的看,待会补起来
下游任务阶段蒸馏
没有什么特殊的,跟预训练阶段阶段蒸馏类似,因为有具体的任务,所以计算损失函数的时候需要注意,如果是有监督任务,那么就与实际label进行计算;如果是无监督任务,那么就与teacher model的输出进行计算。
补充: 在网上没找到tinybert的中文预训练模型,所以没办法进行下去;因为自己找语料费时且无法保证效果,留着之后在做吧;github的issue上面也说效果不好,所以暂时放弃tinybert,试试albert_zh吧,come on,everyday!