多头自注意力学习 时间复杂度是关于序列长度的 o(n^2)的,这就意味着使用vanilla ttransformers 去快速处理长序列变得非常棘手。
在过去的两年里,NLP社区已经开发出了一套真正的方法来对付这种有问题的复杂性,但是在这篇文章中,我们将集中讨论一些有前景的方法。
原博客可以查看incorporating long term context
这里我没有按照原博客来写,这里主要是一个简答的概括,每个模型都有对应的论文解读。可以点进去查看。(尚未更新完,持续更新)
关于Transformer可以看以前的博客transformer - Google Brain
- Sparse Transformers Open AI
- Adaptive Span Transformers Face book AI research
- Transformer-XL Google Brain
- Compressive Transformers DeepMind
- Reformer UC Berkeley & Google Research
- Routing Transformer
- Sinkhorn Transformer
- Linformer
- Efficient Attention: Attention with Linear Complexities
- Transformers are RNNs
- ETC
- Longformer
dense 多头注意力机制的时间和空间复杂度
多头注意力机制 在处理序列长度方面 不够灵活,主要是由2个原因导致的。
- 第一时间复杂度太大, 计算注意力矩阵的时间复杂度与序列长度的平方 成比例,时间复杂度为 O ( h d n 2 ) O(hd n^2) O(hdn2) ,其中h是the number of head (多少个头), d是key 和 query 的维度, n是序列长度。
- 第二空间复杂度太大,dot-product自注意力机制的空间复杂度也是随着序列长度的平方而增大。计算注意力矩阵的空间复杂度为 O ( h d n + h n ) O(hdn+hn) O(hdn+hn), 第一项是存储key和query所需的内存,第二项是每个头产生的注意力值占用的空间。
让我们代入一些具体的数字从BERT-Base中看一下,哪些因素占主导。
- BERT-Base使用序列长度512、hidden size768和12个head,也就是每个头的维度为64(768 / 12)。
- 在这种情况下, 需要393216 floats (~ 1.5 mb)(12head * 64size* 512seqlen)来存储键和值, 而存储所有attention值所需的内存为 3145728 floats(12 * 512 * 512)或~ 12 mb——近10倍的内存存储key仅512标记上下文大小。
由于在训练期间必须缓存激活以允许梯度计算(如果采用存储梯度checkpoint的话需要重新计算激活函数),因此每个实例仅仅存储 bert 12层的attention 矩阵就需要~150MB的内存。 当序列长度为1024时,就是~600MB, 当长度为2048时,单是注意力矩阵 每个example 就需要2.4GB 的内存。这意味着更小的批处理规模和更差的训练时间的并行性,进一步阻碍我们训练利用长上下文长度的模型的能力。
改进模型总结
下面截图来自于知乎一个问答的答案:transformer 魔改
感觉很好直接截图贴过来了 另外还可以参考 那些悄悄拍了拍Transformer的奔涌的后浪们
参考:
transformer 魔改