一、背景自从Bert打开两阶段模式的魔法盒开关后，在这条路上，会有越来越多的同行者，Bert系列的算法层出不穷，比较注明的有RoBerta，ALBert。Bert系列的算法都属于AutoEncode LM。与之相对应的还要AutoRegressive LM。1.自回归语言模型（Autoregressive LM）定义在ELMO／BERT出来之前，大家通常讲的语言模型其实是根据上文内容预测下一个可能跟随的单词，就是常说的自左向右的语言模型任务，或者反过来也行，就是根据下文预测前面的单词，这种类型的LM被称为自回归语言模型。GPT 就是典型的自回归语言模型。ELMO尽管看上去利用了上文，也利用了下文，但是本质上仍然是自回归LM，这个跟模型具体怎么实现有关系。ELMO是做了两个方向（从左到右以及从右到左两个方向的语言模型），但是是分别有两个方向的自回归LM，然后把LSTM的两个方向的隐节点状态拼接到一起，来体现双向语言模型这个事情的。所以其实是两个自回归语言模型的拼接，本质上仍然是自回归语言模型。优缺点自回归语言模型有优点有缺点，(1)缺点:是只能利用上文或者下文的信息，不能同时利用上文和下文的信息，当然，貌似ELMO这种双向都做，然后拼接看上去能够解决这个问题，因为融合模式过于简单，所以效果其实并不是太好。(2)优点:其实跟下游NLP任务有关，比如生成类NLP任务，比如文本摘要，机器翻译等，在实际生成内容的时候，就是从左向右的，自回归语言模型天然匹配这个过程。而Bert这种DAE模式，在生成类NLP任务中，就面临训练过程和应用过程不一致的问题，导致生成类的NLP任务到目前为止都做不太好。2.自编码语言模型（Autoencoder LM）定义自回归语言模型只能根据上文预测下一个单词，或者反过来，只能根据下文预测前面一个单词。相比而言，Bert通过在输入X中随机Mask掉一部分单词，然后预训练过程的主要任务之一是根据上下文单词来预测这些被Mask掉的单词，如果你对Denoising Autoencoder比较熟悉的话，会看出，这确实是典型的DAE的思路。那些被Mask掉的单词就是在输入侧加入的所谓噪音。类似Bert这种预训练模式，被称为DAE LM。优缺点(1)优点：这种DAE LM的优缺点正好和自回归LM反过来，它能比较自然地融入双向语言模型，同时看到被预测单词的上文和下文，这是好处。(2)缺点:是啥呢？主要在输入侧引入[Mask]标记，导致预训练阶段和Fine-tuning阶段不一致的问题，因为Fine-tuning阶段是看不到[Mask]标记的。DAE吗，就要引入噪音，[Mask] 标记就是引入噪音的手段，这个正常。3.引入xlnetXLNet的出发点就是：能否融合自回归LM和DAE LM两者的优点。就是说如果站在自回归LM的角度，如何引入和双向语言模型等价的效果；如果站在DAE LM的角度看，它本身是融入双向语言模型的，如何抛掉表面的那个[Mask]标记，让预训练和Fine-tuning保持一致。当然，XLNet还讲到了一个Bert被Mask单词之间相互独立的问题，我相信这个不太重要，原因后面会说。当然，我认为这点不重要的事情，纯粹是个人观点，出错难免，看看就完了，不用较真。二、XLNet1.排列语言模型那么，怎么能够在单词Ti的上文中Contenxt_before中揉入下文Context_after的内容呢？你可以想想。XLNet是这么做的，在预训练阶段，引入Permutation Language Model的训练目标。什么意思呢？就是说，比如包含单词Ti的当前输入的句子X，由顺序的几个单词构成，比如x1,x2,x3,x4四个单词顺序构成。我们假设，其中，要预测的单词Ti是x3，位置在Position 3，要想让它能够在上文Context_before中，也就是Position 1或者Position 2的位置看到Position 4的单词x4。可以这么做：假设我们固定住x3所在位置，就是它仍然在Position 3，之后随机排列组合句子中的4个单词，在随机排列组合后的各种可能里，再选择一部分作为模型预训练的输入X。比如随机排列组合后，抽取出x4,x2，x3,x1这一个排列组合作为模型的输入X。于是，x3就能同时看到上文x2，以及下文x4的内容了。这就是XLNet的基本思想，所以说，看了这个就可以理解上面讲的它的初衷了吧：看上去仍然是个自回归的从左到右的语言模型，但是其实通过对句子中单词排列组合，把一部分Ti下文的单词排到Ti的上文位置中，于是，就看到了上文和下文，但是形式上看上去仍然是从左到右在预测后一个单词。但是要注意的是：在预训练的时候并不是先对语料进行排序，这个排序操作是在Attention过程中通过mask来实现的，预训练语料的输入还是按照正常的顺利x1,x2,x3,x4来输入的。（为什么不能用乱序的语料呢？因为在微调期间你的语料不可能是乱序的，使用的话，你的预训练和微调就出现不一致问题了）就算用了排列语言模型，为什么标准的语言模型就不行了呢？论文里面有解释：首先我们要知道的是，标准的语言模型使用的标准的Attention操作，那么为什么标准的Attention会失效呢？怎么理解呢：我们标准的语言模型(Attention)都是预测的下一个字，并不会带上要预测字的位置信息，比如，x1,x2,x3,x4，如果我们要预测t=3也就是x3的时候,我们是根据x1,x2的信息(内容和位置)去预测，并不会带上x3的位置信息。但是排列语言模型不在适应了，排列：x1,x2,x3,x4和x1,x2,x4,x3，那么如还用标准的attention，这两种排列模型预测的t=3时刻的字就没有区别了，实际情况是不一样的，因为我们输入的序列是x1,x2,x3,x4，但是在attention mask之后这两种排列是不一样的。排列：x1,x2,x3,x4在预测t=3时刻，预测的x1,x2,__,__ 是第三个位置。排列：x1,x2,x4,x3在预测t=3时刻，预测的x1,x2,__,__ 是第四个位置。为了解决这个问题，xlnet提出了双流注意力机制。2.双流自注意力机制(Two-Stream Self-Attention )内容流：content stream使用：，内容流失一个标准的Attention,对上下文和Xzt本身编码，例如要预测t时刻的内容，content用的是t之前的(不包括t)的上下文，和t时刻的内容。注意：content stream虽然包含本身单词的意思，但是预测的时候我们并不是根据content去预测的。而是用query流去预测的。查询流：query stream使用：，查询流是一个mask自己的attention，对上下文和Xzt时刻的位置编码，例如要预测t时刻的内容，query用的是t之前的(不包括t)的上下文，和t时刻的位置。注意：query stream不包含本身单词的意思，但是预测的时候是根据query去预测的。而query流的计算要用到content流。具体例子可以参考图片：在pretrain阶段，在输出端对查询流向量预测相应的token，如上图中最后一个公式。在finetune阶段，只需要内容流向量，不再需要查询流向量。3.NSP去掉4.使用transformer-xl5.Partial Prediction(部分预测)参考文献：1.https://arxiv.org/pdf/1906.08237.pdf2.https://yiyibooks.cn/nlp/XLNet/index.html