transformer 为什么胜出
RNN 一次只读一步,还总在遗忘。transformer 则一次处理全部,任意距离一步可达。整个领域转向的三个原因,完整版。
有十年时间,机器处理语言靠的是门控 RNN。然后 2017 年 transformer 出现了,几年之内,RNN 就从正经的 NLP 里消失了。这不是赶时髦。三个具体的优势不断累积,直到那套更老的架构再也接不住,而弄懂这三点,就是这一整层的回报。
原因一:并行
这一条是决定性的,而且它关乎硬件,不关乎语言学。
RNN 在第 100 步的隐状态由第 99 步算出来,第 99 步又来自第 98 步,一路往回。这种计算天生就是串行的——上一步没算完,下一步就没法开始。GPU 是一台为同时做几千次运算而造的机器,串行几乎让所有硬件都闲着。拿一篇长文档来训练,就意味着要一个词一个词地等过去。
transformer 的自注意力(self-attention)是同时算出每个位置的表示。注意力运算过程中没有逐步依赖,它就是几次大的矩阵乘法,而矩阵乘法恰恰是 GPU 最拿手的事。一遍并行下来,每个词都和其他所有词互相看过。
实际后果是巨大的。摆脱了串行处理之后,同样的时间和硬件预算下,模型能训练的数据多得多。正是这种效率让互联网规模的语料训练变得可行,而这是一切后续工作的前提。RNN 再怎么调,也走不了这条路;串行就写在它的定义里。
原因二:任意距离都能直接访问
RNN 跨越序列传递信息的方式,是靠隐状态一站一站接力。要让第 1 个词联系上第 200 个词,信号得活着走过 199 跳,而即便是 LSTM 的门控,也只是把它能走多远、多久之后开始衰减往后延了延。长距离依赖一直是 RNN 的软肋。
而在自注意力里,任何位置到任何位置都只要一次运算。第 200 个词去看第 1 个词,代价和去看第 199 个词一模一样。没有接力,也不会随距离衰减。任意两个 token 之间的路径长度都是 1。
这就是 transformer 能处理那些 RNN 常常丢掉的长距离结构的原因——隔着好几段的代词和它的指代对象、函数的定义和远在别处的调用点。自注意力详解里讲了具体机制;结论一句话:距离不再重要。
原因三:注意力本来就是有用的那部分
Bahdanau 注意力那项工作已经表明:seq2seq 模型翻译得好时,出力的是注意力——解码器回头看,把焦点放在正确的输入词上。底下那层 RNN 越来越像是在做管道。
《Attention Is All You Need》把这个想法推到了终点:留下注意力,把 RNN 整个拿掉。用层层堆叠的自注意力取代串行的循环,再加几个配件,让它作为一套独立架构跑得起来。
其中两个配件在这里值得一说,因为它们补的正是去掉 RNN 之后留下的窟窿:
- 位置编码。 注意力本身看不见顺序——它看到的是一堆词,而不是一个序列,因为它没有内建的位置概念。所以位置信息被直接加到 token 的表示上。位置编码讲的是具体做法。
- 多个头。 一次注意力只能捕捉一类关系。并行跑好几路,模型就能同时跟踪好几类——一个头管句法,另一个头管指代。见多头注意力。
结果就是 transformer:没有循环,完全并行,处处可直接访问。
老实说,RNN 哪里做得更好
这次转向不是没有代价的,假装没有会误导人。
自注意力对 n 个 token 要付出 n² 次比较——每个 token 都要和其他所有 token 打一个分。RNN 是随序列长度线性的。序列很长时,transformer 的平方级成本就成了主要开销,这正是注意力为什么贵那一篇的全部主题。RNN 还能自然地处理流式输入,一次一个 token,内存恒定,适合某些实时场景。
正是这些取舍,让 RNN 一脉的想法从未真正消亡,也让状态空间模型用现代技巧重新拾起串行处理。但在「用大数据训练大模型」这件核心任务上,transformer 的并行性是决定性的,整个领域随之转向。
要点回顾
- 并行是决定性因素:自注意力一次处理所有位置,RNN 做不到,而 GPU 对这种差别给的回报极大。
- 直接访问:任意两个 token 一跳可达,而 RNN 是有损的逐步接力。
- 在 seq2seq 里,注意力本来就是有用的那部分;transformer 留下它,去掉了循环。
- 去掉循环之后,需要位置编码和多头注意力来补偿。
- 代价是平方级的注意力,所以 RNN 式的线性处理仍有它的角落——但要谈规模,transformer 赢得干脆。
下一篇: transformer——取代了 RNN、如今支撑着每一个大语言模型的完整架构。