详解百度ERNIE进化史及典型应用场景

 

上个月,全球规模最大的语义评测比赛 SemEval 2020 结果出炉,百度基于飞桨平台自研的语义理解框架 ERNIE 一举斩获 5 项世界冠军,囊括视觉媒体的关键文本片断挖掘、多语攻击性语言检测和混合语种的情感分析。去年,ERNIE前后完成两版重大升级:ERNIE 1.0 提出知识加强的语义表示模型, ERNIE 2.0 则构建了持续学习语义理解框架,在中英文 16 个任务上超越业界最好模型。本文将为开发者详细解读ERNIE的进化史。git

下载安装命令

## CPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

ERNIE 1.0

ERNIE: Enhanced Representation through Knowledge Integration[1] 是百度在2019年4月的时候,基于BERT模型,作的进一步优化,在中文的NLP任务上获得了state-of-the-art的结果。github

它主要是在mask的机制上作了改进,它的mask不是基本的word piece的mask,而是在pretrainning阶段增长了外部的知识,由三种level的mask组成,分别是basic-level masking(word piece)+ phrase level masking(WWM style) + entity level masking。在这个基础上,借助百度在中文社区的强大能力,中文的ERNIE还使用了各类异质(Heterogeneous)的数据集。此外为了适应多轮的贴吧数据,全部ERNIE引入了DLM (Dialogue Language Model) task。数据库

百度的论文看着写得不错,也很简单,并且改进的思路成为了后来各类改进模型的基础。例如说Masking方式的改进,让BERT出现了WWM的版本,对应的中文版本(Pre-Training with Whole Word Masking for Chinese BERT[2]),以及 facebook的SpanBERT[3]等都是主要基于ERNIE masking方式作的改进。api

01框架

0一、Knowledge Maskingide

「Inituition」: 模型在预测未知词的时候,没有考虑到外部知识。可是若是咱们在mask的时候,加入了外部的知识,模型能够得到更可靠的语言表示。函数

例如:哈利波特是J.K.罗琳写的小说。单独预测 哈[MASK]波特 或者 J.K.[MASK]琳 对于模型都很简单,可是模型不能学到哈利波特和J.K. 罗琳的关系。若是把哈利波特直接MASK掉的话,那模型能够根据做者,就预测到小说这个实体,实现了知识的学习。工具

须要注意的是这些知识的学习是在训练中隐性地学习,而不是直接将外部知识的embedding加入到模型结构中(ERNIE-TsingHua[4]的作法),模型在训练中学习到了更长的语义联系,例如说实体类别,实体关系等,这些都使得模型能够学习到更好的语言表达。布局

首先咱们先看看模型的MASK的策略和BERT的区别。性能

ERNIE的mask的策略是经过三个阶段学习的,在第一个阶段,采用的是BERT的模式,用的是basic-level masking,而后再加入词组的mask(phrase-level masking), 而后再加入实体级别entity-level的mask。以下图:

  • Basic level masking
    在预训练中,第一阶段是先采用基本层级的masking,即随机mask掉中文中的一个字。

  • Phrase level masking
    第二阶段是采用词组级别的masking。咱们mask掉句子中一部分词组,而后让模型预测这些词组,在这个阶段,词组的信息就被encoding到word embedding中了。

  • Entity level masking
    在第三阶段命名实体,如:人名,机构名,商品名等,在这个阶段被mask掉,模型在训练完成后,也就学习到了这些实体的信息。

不一样mask的效果:

02

0二、Heterogeneous Corpus Pre-training

训练集包括了

  • Chinese Wikepedia

  • Baidu Baike

  • Baidu news

  • Baidu Tieba 注意模型进行了繁简体的转化,以及是uncased

03

DLM (Dialogue Language Model) task

对话的数据对语义表示很重要,由于对于相同回答的提问通常都是具备相似语义的,不一样于BERT的输入形式,ERNIE可以使用多轮对话的形式,采用的是三个句子的组合[CLS]S1[SEP]S2[SEP]S3[SEP] 的格式。这种组合能够表示多轮对话,例如QRQ,QRR,QQR。Q:提问,R:回答。为了表示dialog的属性,句子添加了dialog embedding组合,这个和segment embedding很相似。

DLM还增长了任务来判断这个多轮对话是真的仍是假的:

04

0四、NSP+MLM

在贴吧多轮对话数据外都采用的是普通的NSP+MLM预训练任务。NSP任务仍是有的,可是论文中没写,可是git repo中写了用了。

最终模型效果对比BERT:

ERNIE 2.0

ERNIE 2.0: A Continual Pre-Training Framework for Language Understanding[5],百度ERNIE2.0 的出现直接刷新了GLUE Benchmark。

「Inituition」:就像是咱们学习一个新语言的时候,咱们须要不少以前的知识,在这些知识的基础上,咱们能够更快地学习新语言,如此就有了迁移学习的效果。咱们的语言模型若是增长多个任务的话,是否是能够得到更好的效果?事实上,经发现,ERNIE 1.0 加了DLM任务以及其余的模型。如Albert 加了sentence order prediction(SOP)任务以后或者SpanBERT: Improving Pre-training by Representing and Predicting Spans[6]在加上了SBO目标以后 ,模型效果获得了进一步的优化,同时MT-DNN[7]也证实了,在预训练的阶段中加入多个GLUE下游任务(有监督)进行多任务学习,能够获得state-of-the-art的效果。

因而科学家们就在想那一直加task岂不是更强?百度不知足于堆叠任务,而是提出了一个持续学习的框架,利用这个框架,模型能够持续添加任务但又不下降以前任务的精度,从而可以更好更有效地得到词法lexical,句法syntactic,语义semantic上的表达。

ERNIE1.0的基础上,利用了大量的数据,以及先验知识,而后提出了多个任务,用来作预训练,最后根据特定任务finetune。框架的提出是针对life-long learning的,即终生学习,由于咱们的任务叠加,不是一次性进行的(Multi-task learning),而是持续学习(Continual Pre-training),因此必须避免模型在学了新的任务以后,忘记旧的任务,即在旧的任务上loss变高,相反的,模型的表现应该是由于学习了以前的知识,因此可以更好更快的学习到现有的任务。为了实现这个目的,百度提出了一个包含pretraining 和fine-tuning的持续学习框架。

01

0一、Continual Pre-training

  • 任务的构建
    百度把语言模型的任务归类为三大类,模型能够持续学习新的任务。

    • 字层级的任务(word-aware pretraining task)

    • 句结构层级的任务(structure-aware pretraining task)

    • 语义层级的任务(semantic-aware pretraining task)

  • 持续的多任务学习
    对于持续的多任务学习,主要须要攻克两个难点:

    • 如何保证模型不忘记以前的任务?

      常规的持续学习框架采用的是一个任务接一个任务的训练,致使的后果就是模型在最新的任务上获得了好的效果可是在以前的任务上得到很惨的效果(knowledge retention)。

    • 模型如何可以有效地训练?
      为了解决上一个的问题,有人propose新的方案,咱们每次有新的任务进来,咱们都从头开始训练一个新的模型不就行了。虽然这种方案能够解决以前任务被忘记的问题,可是这也带来了效率的问题:每次都要从头新训练一个模型,这样子致使效率很低。

  • 百度提出的方案sequential multi-task learning

     

    聪明的你确定就会想到,为何咱们要从头开始训练一个模型,咱们复用以前学到的模型的参数做为初始化,而后再训练不就好了?是的,可是这样子彷佛训练的效率仍是不高,由于咱们仍是要每一轮中同时训练多个任务,百度的解决方案是,框架自动在训练的过程当中为每一个任务安排训练N轮。

    • 初始化 optimized initialization
      每次有新任务过来,持续学习的框架使用以前学习到的模型参数做为初始化,而后将新的任务和旧的任务一块儿训练。

    • 训练任务安排 task allocating
      对于多个任务,框架将自动的为每一个任务在模型训练的不一样阶段安排N个训练轮次,这样保证了有效率地学习到多任务。如何高效的训练,每一个task 都分配有N个训练iteration。

      One left problem is how to make it trained more efficiently. We solve this problem by allocating each task N training iterations. Our framework needs to automatically assign these N iterations for each task to different stages of training. In this way, we can guarantee the efficiency of our method without forgetting the previously trained knowledge

    • 部分任务的语义信息建模适合递进式:

      好比ERNIE 1.0 突破完形填空

      ERNIE 2.0 突破选择题,句子排序题等

      不断递进更新,就好像前面的任务都是打基础,有点boosting的意味

 

    • 顺序学习容易致使遗忘模式(这个能够复习一下李宏毅的视频),因此只适合学习任务之间比较紧密的任务,就好像你今天学了JAVA,明天学了Spring框架,可是若是后天让你学习有机化学,就先后不可以联系起来,以前的知识就忘得快

    • 适合递进式的语音建模任务

02

0二、Continual Fine-tuning

在模型预训练完成以后,能够根据特定任务进行finetuning,这个和BERT同样。

0三、ERNIE 2.0 Model

为了验证框架的有效性,ERNIE 2.0 用了多种任务,训练了新的ERNIE2.0模型,而后成功刷榜NLU任务的benchmark,GLUE(截止2020.01.04),开源了ERNIE2.0英文版。

0四、Model structure

模型的结构和BERT一致,可是在预训练的阶段,除了正常的position embedding,segment embdding,token embedding还增长了「task embedding」。用来区别训练的任务, 对于N个任务,task的id就是从0~N-1,每一个id都会被映射到不一样的embedding上。模型的输入就是:

可是对于fine-tuning阶段,ERNIE 使用任意值做为初始化均可以。

0五、Pre-training Tasks

ERNIE模型堆叠了大量的预训练目标。就好像咱们学习英语的时候,咱们的卷子上面,有多种不一样的题型。

  • 词法层级的任务(word-aware pretraining task):获取词法知识

    • knowledge masking(1.0)
      ERNIE1.0的任务

    • 大小写预测(Capitalization Prediction Task)
      模型预测一个字不是否是大小写,这个对特定的任务例如NER比较有用。(可是对于中文的话,这个任务比较没有用处,可能能够改成预测某个词是否是缩写)

    • 词频关系(Token-Document Relation Prediction Task)
      预测一个词是否是会屡次出如今文章中,或者说这个词是否是关键词。

  • 语法层级的任务(structure-aware pretraining task) :获取句法的知识

    • 句子排序(Sentence Reordering Task)

      把一篇文章随机分为i = 1到m份,对于每种分法都有i!种组合,因此总共有

       

      种组合,让模型去预测这篇文章是第几种,就是一个多分类的问题。这个问题就可以让模型学到句子之间的顺序关系。就有点相似于Albert的SOP任务的升级版。

    • 句子距离预测(Sentence Distance Task)
      一个三分类的问题:

      0: 表明两个句子相邻

      1: 表明两个句子在同个文章但不相邻

      2: 表明两个句子在不一样的文章中

  • 语义层级的任务(semantic-aware pretraining task) :获取语义关系的知识

    0: 表明了提问和标题强相关(出如今搜索的界面且用户点击了)

    1: 表明了提问和标题弱相关(出如今搜索的界面但用户没点击)

    2: 表明了提问和标题不相关(未出如今搜索的界面)

  • 篇章句间关系任务(Discourse Relation Task)

    判断句子的语义关系例如logical relationship( is a, has a, contract etc.)

  • 信息检索关系任务(IR Relevance Task)

    一个三分类的问题,预测query和网页标题的关系:

    0: 表明了提问和标题强相关(出如今搜索的界面且用户点击了)

    1: 表明了提问和标题弱相关(出如今搜索的界面但用户没点击)

    2: 表明了提问和标题不相关(未出如今搜索的界面)

  • Token level loss:给每一个token一个label

  • Sentence level loss:例如句子重排任务,判断[CLS]的输出是那一类别

 

性能不敏感的场景:直接使用

度小满的风控召回排序提高25%。

度小满的风控识别上:在ERNIE上直接进行微调预测有没有风险对应的结果。传统的缺点:须要海量的数据,而这些数据也很难抓取到的,抓取这些特征以后呢还要进行复杂的文本特征提取,好比说挖掘短信中银行的催收信息,对数据要求的量很高,对数据人工的特征的挖掘也很高。这两项呢形成了大量的成本,现在只需ERNIE微调一下,当时直接在召回的排序上获得25%的提高。这种场景的特色是什么?用户对于实时性的需求不是很强,不须要用户输入一个字段就返回结果。只要拿一天把全部数据跑完,获得结果就能够了,统一的分析就能够了,适合少数据的分析场景。

 

性能敏感场景优化

性能敏感场景优化:模型蒸馏,例如搜索问答Query识别和QP匹配

另外的一个场景是搜索问答query识别和qp匹配,该场景须要很是高的性能优点的,采用的解决方案就是模型蒸馏。输入一个问题,获得答案,本质是文本匹配,实际是输入问题,把数据库中大量的候选答案进行匹配计算得分,把得分最高的返回。可是百度天天不少用户,须要很快的响应速度,数据量大,要求响应速度还快,这时候要求不只模型特别准,并且还要特别快,怎么解决就是模型蒸馏。

Phrase 1: 

判断问题是否可能有答案(文本分类),过滤完是可能有答案的,再与数据库中进行匹配,由于大部分输入框的不必定是个问题,这样过滤掉一部分,排除掉一部分后,在作匹配就能获得很大的提高,提高仍是不够。
第一部分实际上是文本分类,经过小规模的标注特征数据进行微调,获得一个好的模型,同时日志上是有不少没有标注的数据,用ERNIE对这些数据进行很好的标注,用一个更好的模型去标注数据,用这些标注数据训练相对简单的模型,就实现了蒸馏,ERNIE处理速度慢,可是能够用题海战术的方式训练简单的模型。具体步骤:一个很优秀的老师,学一点东西就可以带学生了,可是学生模型不够聪明,海量的题海战术就能够学很好。

Fine-tune:使用少许的人工标注的数据用ERNIE训练

label propagation:使用ERNIE标注海量的挖掘数据,获得带标注的训练数据

train:使用这些数据下去训练一个简单的模型或者采用模型蒸馏的方式,参考TinyBERT

Phrase 2: 

有答案与答案库进行各类各样的匹配(文本匹配)同理,下面问题匹配也是,右边也是query和答案,而后通过embedding,加权求和,全链接,最后计算他们之间的预选类似度,能够是余弦类似度,召回提高7%。

场景:百度视频离线推荐

 

这是一个推荐场景,目标是基于用户浏览的历史视频推荐新的视频。这里使用视频的标题文本做为特征推荐。视频的标题文本是保持不变的,因此能够提早把ERNIE的结果计算保存好。视频之间两两计算类似度的计算量是很是大的,那么怎么减小计算量呢?使用了一个技术叫离线向量化。把ERNIE做为一个特征向量的生成器,离线把每个视频的ERNIE向量计算好,而后存入数据库中。实际计算时,用户看的视频通过ERNIE 获得一个向量,候选集经过另一个ERNIE(共享权重),获得另一个向量,最后经过cos函数计算类似度。这样总体的运算量就从O(N2)下降到O(N)。

 

代码使用

git clone https://github.com/PaddlePaddle/ERNIE
pip install -r requirements.txt
cd models

wget --no-check-certificate https://baidu-nlp.bj.bcebos.com/ERNIE_stable-1.0.1.tar.gz
cd ..
wget --no-check-certificate https://ernie.bj.bcebos.com/task_data_zh.tgz

run.sh

home=YOUR_ERNIE_PATH
export TASK_DATA_PATH=$home/glue_data_processed/
export MODEL_PATH=$home/model/

export TASK_DATA_PATH=YOUR_TASK_DATA_PATH
export MODEL_PATH=YOUR_MODEL_PATH

sh script/zh_task/ernie_base/run_ChnSentiCorp.sh

百度在天然语言处理领域已有二十年的积累与沉淀,具有了最前沿、最全面、最领先的技术布局,不只专一于前瞻技术探索,更致力经过技术应用解决实际问题。而飞桨是目前国内自主研发、开源开放、功能最完备的产业级深度学习平台,集深度学习核心框架、基础模型库、端到端开发套件、工具组件和服务平台于一体,服务于150多万开发者,正与合做伙伴一块儿帮助愈来愈多的行业完成 AI 赋能。

 

本文参考资料

[1 ]ERNIE: Enhanced Representation through Knowledge Integration: 

https://arxiv.org/pdf/1904.09223

 

[2] Pre-Training with Whole Word Masking for Chinese BERT:

https://arxiv.org/pdf/1906.08101

 

[3] facebook的SpanBERT: 

https://arxiv.org/pdf/1907.10529

 

[4] ERNIE-TsingHua:

 https://arxiv.org/pdf/1905.07129.pdf

 

[5] ERNIE 2.0: A Continual Pre-Training Framework for Language Understanding: 

https://arxiv.org/pdf/1907.12412.pdf

 

[6] SpanBERT: Improving Pre-training by Representing and Predicting Spans: 

https://arxiv.org/pdf/1907.10529.pdf

 

[7] MT-DNN: 

https://arxiv.org/pdf/1901.11504.pdf

 

[8] baidu offical video:

http://abcxueyuan.cloud.baidu.com/#/play_video?id=15076&courseId=15076&mediaId=mda-jjegqih8ij5385z4&videoId=2866&sectionId=15081&showCoursePurchaseStatus=false&type=免费课程

 

[9] Life long learning: 

https://www.youtube.com/watch?v=8uo3kJ509hA

 

[10]【NLP】深度剖析知识加强语义表示模型:

ERNIEhttps://mp.weixin.qq.com/s/Jt-ge-2aqHZSxWYKnfX_zg

 

ERNIE项目地址:

https://github.com/PaddlePaddle/ERNIE

 

若是您加入官方QQ群,您将赶上大批志同道合的深度学习同窗。官方QQ群:703252161

 

若是您想详细了解更多飞桨的相关内容,请参阅如下文档。

下载安装命令

## CPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

官网地址:https://www.paddlepaddle.org.cn

 

飞桨开源框架项目地址:

GitHub: https://github.com/PaddlePaddle/Paddle

Gitee:  https://gitee.com/paddlepaddle/Paddle

>> 访问 PaddlePaddle 官网,了解更多相关内容