为何诞生
在说transformer是什么,有什么优势之类的之前,先谈一谈它因何而诞生。transformer诞生最重要的原因是早先的语言模型,比如RNN,由于其本身的训练机制导致其并行度不高,特别是遇到一些长句子的情况下。其次,是由于自注意力的产生。自注意力是什么,Attention Is All You Need原文有一个比较不错的解释:
自注意力机制,是一种将序列中不同位置元素做关联学习进而计算序列表征的方法
Transformer完全借助自注意力、MLP以及LayerNorm层完成了语言模型的建模工作,完全摈弃了卷积以及递归模型结构。
缩放点积注意力
transformer的结构没什么可说的,就是encoder+decoder的结构堆叠,这块整体上没有太大创新,创新点在于其encoder和decoder内部使用了自注意力,这个注意力结构的使用使其在目前绝大多数的自然语言处理任务上处于领先地位,这个自注意力即原文所谓的缩放点积注意力(Scaled Dot-Product Attention,下文简称SDPA)。
如图1所示,形式化为:
点积注意力、加和注意力是普遍使用的两种注意力函数,它们理论计算复杂度一致,但是前者由于高度优化的矩阵运算库的存在,使其在实际应用过程中更加高效。值得注意的一点是softmax的输入为什么要除以一个常数,可以参考原文从统计视角给出的解释。
多头自注意力
作者认为,基于单一的SDPA不足以发挥其优势,通过执行多次不同的SDPA可以更好的挖掘句子的语义,所以多头自注意力产生了。多头注意力机制能使模型从多个不同的低维表示空间中提取不同的语义信息,它的基本结构如下:
假设现在需要执行SDPA的次数为h,它的基本做法是:
- 将Q、K和V分别通过h组不同的线性映射层分别将它们映射为、 和 维;
- 对映射完的每一组并行的执行SDPA,产生 维的输出;
- h组SDPA的输出进行concat操作;
- concat的结果进一步做线性映射得到最终输出;
从图4可以看出,多头的SDPA操作是并行执行的;同时,原文中将每个头的线性映射层的维度降为了原先单头的 (单头是512),所以最终的时空开销和单头的基本一致。
位置编码
由于transformer里不再有卷积和递归结构,为了模型能利用序列中不同token的位置信息,需要单独设立一个位置编码embeding,和序列中token的embeding维度一致,因此可以直接做加和操作。