EBET易博官网NLP预训练模型(2021版)

  新闻资讯     |      2023-05-26 03:07

  大概是两年前,跟百度的nlp组,参与合作过Ernie在对话系统上的应用。

  问题其实很多,模型训练慢,一个月迭代一次很正常(现在做业务,两周就要有一轮迭代),显卡内存动不动就给爆了。

  一方面是个人技术菜,没利用好。另一方面,线上的lstm模型,已经喂了几百万/千万,各种方式清洗过的质量不错的样本(大力出奇迹),基线其实很高了。

  并且infer非常慢,对话系统对实时性要求又高,只能离线在别的地方用(当时蒸馏这个做法还不流行)。

  但我依然震惊了,因为它只用了人工标注的几万高准样本。而我们之前是花了几个月的时间,各种洗样本。

  所以,我当时写的nlp预训练模型笔记中,称赞bert为集大成者。觉得在预训练这块,像他这样突的突破性进展,短期内是不会有了。(GPT当时做的其实挺不错的,但开源速度太慢了!)158598

  两年过去了,bert的各种魔改依然漫天飞。有很多人做了很棒的尝试,但现在看来,大框架还是没有突破。

  整体框架,各个方向的概括,来龙去脉讲的很清楚,有种看历史书的感觉,也学了不少新知识。

  一共45页,引用就13页,引用的论文的作者一共几千人,就是这几千人一步步推动着预训练走到了现在。

  样本的量级并没有那么重要,因为参数的限制,导致几十万跟几百万的样本对模型带来的提升并不明显。当时提升效果的秘诀是,人工看看模型特征权重,针对性的把样本调整下,特征改改。

  Rnn,LSTM出现后,当时我们组有个大佬,hi的签名是——大力出奇迹。

  虽然当时ResNet这种技术还没出现,神经网络无法做深,基本上就几层。但已有的参数量,已经足够支撑百万/千万级的样本学习了。

  并且根据当年的经验,百万/千万级别的样本,准确率不用很高,最后效果也能很不错。

  很自然,我们当时的工作从调特征的,变成洗样本的。当年洗样本花样老多了,核心思路就是靠各种外部知识,知识词典(当时图谱还不流行),搜索query等。(当然也很无聊)

  还有什么用active learning挖掘高质量样本去标注,但在当时的场景下,效率贼低。

  因为当时nn的特点,几万高准人工标注样本,大概率是比不上人工清洗的几百万准确率一般的样本。

  但BERT出来后世界就变了,几万高准人工标注样本,大概率能跟几百万准确率一般的样本持平,如果样本分布合理,甚至能更好。

  没样本,就靠文法规则快速撸一个基线。最好是跟pm,外包,后端搞一个规则框架。Pm负责监督外包归纳文法规则,后端负责规则框架的实现,算法负责整体框架的设计。

  这样pm得到了效果提升,后端实现了一个技术框架,你等样本标够了入场做模型就好,没有人受伤的世界达成了。

  如果是大公司,那就可以找别的部门/中台,蹭现成的接口呗。当然由于是通用接口,效果大概率不会特别好,至于提针对性优化,那就慢慢等吧。

  于此同时,找外包定规则,标样本,等标注了几万还不错的样本后。上albert做个还不错的基线,耗时要求高就蒸馏一把,耗时要求低那就上线。

  正常情况下,一年拿上百万标样本是很合理的,有钱就标个千万的,反正样本多多益善。至于没钱怎么办?业务部门,百万都拿不出来,那还是先别做算法了。。

  就跟相对论的出现离不开黎曼几何等技术积淀。BERT/GPT的出现,也是基于很多技术沉淀。

  高中毕业的人学相对论,大概率看不懂,但大受震撼。小学毕业的人去学,脑子聪明点,估计第二天就能想到N种方式来推翻相对论。知识的积淀能够帮助你更快的入门新领域,少走弯路。

  Parameter transfer——基于一个intuitive的假设,新的目标task和已经学习的task可以共享parameter,如果两个task差别并不大。先把知识学到共享参数中,再拿目标领域的样本,fine-tuning这些共享参数。这个idea也挺早,2004年就提出来了。

  个人猜测,核心在于样本获取方式的难易度。之前做对话系统的时候,nlp是可以靠引入priori知识来清洗数据。得到准确率还可以的百万/千万级别的样本。这个级别的样本,是能达到浅层神经网络的参数天花板的。在nlp预训练模型无法做深做大的情况下,收益并不明显。

  但这篇论文的说法是——文本很难像图片那样构建一个ImageNet这样大规模的数据集合,因为标注文本是要比标注图片难的多。本人主要经验都在对话的nlu上,open-ended or Non-open-ended的nlg经验很少。这个只能说保留意见吧。

  如何把网络做深,从2012年就开始有人尝试,直到2016年ResNet的出现,给出了一个系统性的解决方案。

  ResNet刚出来的时候,我很不屑一顾,觉得技术实现也不复杂。并且做深了有啥用呢?也就是秀技,没什么实际意义。

  但基于此,再结合self-supervised learning,和谷歌做搜索时爬取的万亿级别的无标注文本数据。

  谷歌搞BERT真的是一个理所应当的事情(当然我老东家百度为啥没搞出来,这我就不知道了),它做搜索爬取的网页数据,大到它当年专门搞了一个hadoop来管理。

  所以,当时的一个思路就是基于RNN/LSTM来做预训练模型,也就是Elmo。但RNN/LSTM身为序列模型,必须要序列训练,无法并行训练加速。

  而互联网累积的unlabel数据实在是太多了,几亿算是开胃菜。所以transformer这种非序列模型的好处就体现出来了。当然,transformer也还是慢,因为数据实在太多。所以这篇综述,专门拿了一章来讨论如何提升efficiency。

  第一,几十亿,甚至上百亿的文本带的知识是很多的,需要一个超大的模型,有足够的参数来容纳这些知识。

  Transformer由于借鉴了ResNet的一些操作,保证了参数增加,效果也能跟随提升(当然现在大家发现有点过参数化)。同时相比于序列模型RNN/LSTM,能支持并行训练。比较好的解决了这两个问题,但BERT/GPT使用Transformer的方式略有不同。

  GPT是generative pre-traing,它是语言模型的套路。也就是我知道上文了,然后maximizing the log-likelihood。所以,它的transformer必然是单向的,把下文mask掉,用上文预测下一个词即可。这种框架,天然适合生成式的下游任务。

  BERT是随机mask词,MLM(masked language modelinng),类似完形填空,给了上下文,预测空着的词是什么,好处是上下文的信息都学习到了。

  nlp可以分成两种任务,自然语言理解(nlu)和自然语言生成(nlg)。

  BERT在nlu是good at。但在nlg问题就大了,因为它是双向的,天然和nlg冲突。

  一个解决方案就是,nlg的时候用GPT,nlu的时候用BERT,于是皆大欢喜。

  XLNET——针对BERT的在nlg上的问题,XLNet 在预训练permutate token的顺序,把尾部一定量的词mask掉,然后再用Autoregressive(上一时刻的输出作为下一时刻的输入)这种方式预测被mask的词。

  这个方向就比较有意思了,transformer这种框架,是否足够好到模拟人类的认知系统了么?答案是否定的。

  sustainable long-term memory——2019年的一篇论了一个实验,发现transformer的feed-forward网络起到了记忆网络的效果。但这个记忆能力始终是有限的,而人类是维护了一个持续多年的long-term memory的。所以,把知识提前编码,要用的时候做替换,有人分别从语料,实体的角度做了一些尝试。以上的方法在开放领域的问答都取得了不错的效果。

  当然,以上的这些尝试,至少从我的观察来看,还没有得到工业界的普遍认可,大家还是各种魔改bert到处用。

  三个方向,多语言,多模态,知识增强的预训练模型。每个方向都可以单独展开写一篇综述。多语言,多模态我接触很少,这里只能简单写一些个人理解。

  基于多语言的预训练模型,跟单语言的区别在于,学习任务的设计,对平行语料的利用,以及生成式预训练模型。

  XLM——MMLM没法利用平行语料,而在翻译任务中,平行语料是非常重要的。intuitively,平行语料也能更有助于cross-lingual知识的学习。所以,提出了一个TLM task,将两个语义匹配的句子合并为一个,并在这两个部分中随机mask。

  ALM——从平行语料中,自动切换序列,然后使用 MLM来学习,让模型基于别的语言的context来做预测。

  小孩子学习的时候,如果文字搭配一些图片,往往能学习的更快,如果能搭配讲解视频,肯定就更快了。

  同理,我们把文字,声音,图片,视频一起学习,期望达到更好的效果,就是多模态。

  这块可挖的坑是真的多,不同模态的组合,就要针对性设计新的task,故事再好好讲讲,一篇论文就出来了。

  但个人感觉吧,语料,计算量,模型框架的不成熟,这个方向短期内做出突破性进展其实挺难的。。但这肯定是未来,因为我们的目标就是让模型越来越像人。

  举个例子,播放xxx,如果xxx是个冷门歌曲,训练样本基本上没见到。那么模型就会困惑这是个电影分类,还是音乐分类呢?

  这个时候通过词典特征,告诉模型xxx是首歌,就能解决这个问题。当然,这两年现在大家都不叫词典了,叫知识图谱。

  ERNIE——举例子,苹果手机评测,bert可能把手给随机mask了,但把苹果手机mask肯定更合理。但这也有个大坑,就是你需要先把实体识别出来,但实体识别是有准确率的,识别不准的反而是noise。

  Comet——针对ERNIE的这个问题,直接将结构化知识转化为序列化文本,让模型自己学习对其。

  以上都是对结构化知识来进行学习,事实上还有一些用非结构化的知识来一起学习。但是!非结构化数据往往特别脏,如果数据预处理准确率只有80,那么收益甚至可能是负向。

  EBET易博官方网站

  方法三,基于transofmer的一些特性,如发现不同层可以share相似的self-attention patterns。所以,可以先训练浅层模型,然后复制以构建深层模型。以及在训练期间删除一些层。

  魔改transformer,来降低它的复杂度。但这些方法大部分是有实现成本的,尝试前建议谨慎调研。

  模型剪枝——预训练模型会不会有一些useless的部分呢?有人尝试过在训练的时候有选择的drop transformer layer。以及有人研究发现transformer的多头有点冗余,只要一小部分就能有不错的效果。

  模型量化——预训练模型经常是16bits或者32bits,最近的实验显示,改成8 bits只对效果有little impact。

  这一块其实蛮有意思的,四个部分。预训练模型学了什么,预训练模型的鲁棒性,structural sparsity/modularity,以及预训练模型的理论分析。

  Representation Probing, 固定预训练模型的参数,训练一个新的线性层基于预训练的隐层。这是最流行的做法,因为做法很通用。通过分析发现,tokens,chunks,pairwise relations这些知识都学到了

  Generation Analysis,使用语言模型来直接评估不同句子和词的概率分布。有人通过预训练模型来recover syntactic tree,发现效果跟人工设计的schema很接近。

  2 更好的正则化,在预训练模型的test error更好的时候,预训练的training error 不一定比随机模型好,这代表更强的泛化能力。

  这个笔记写的是真的累。。内容太多了,论文看了好几天,也写了好几天,快五千字了。有兴趣的同学还是建议自己去看看论文。

  接下来准备写点没那么累的笔记,如召回的离线评估跟在线不一致的问题(偏吐槽),或者热点挖掘。