你跟大模型聊了半小时,它忽然能把你十分钟前提过的一个细节拎回来用。你下意识会想:它是把整段对话都「背」住了吗?说白了,不完全是。它更像在每一次开口前,重新扫一眼上下文,决定这一句该盯哪几个字。这个「扫一眼再决定盯哪」的动作,行业里叫注意力机制。
我卡了很久才想通:注意力不是一种更聪明的记忆,而是一种更诚实的取舍。模型算力有限、上下文再长也装不下「处处同等重要」。注意力干的活,是把「重要性」变成一组可学习的权重——该亮的亮,该暗的暗。
它到底在解决什么
更早的神经机器翻译,常见做法是编码器把一整句源语言压成一个固定长度的向量,再交给解码器去生成译文。句子一长,这个向量就变成瓶颈:前半句的细节容易被后半句冲掉,像把一页笔记硬揉成一团塞进口袋。
注意力的人话定义可以这么说:在生成每一个词的时候,模型都被允许回看整段输入,并给每一段输入打一个「此刻有多相关」的分,再按分数加权汇总。它不保证「全记住」,它保证「此刻该看的地方看得更清楚」。
固定压缩对比动态回看
简史:几个绕不开的年份
大约 2013,Graves 在手写生成里用过一种只能向前滑动的对齐思路,常被看作注意力的早期亲戚,但还没成为 NLP 的默认部件。
2014,Bahdanau、Cho、Bengio 那篇《Neural Machine Translation by Jointly Learning to Align and Translate》把注意力正式推上舞台。翻译系统终于可以在产出每个目标词时,动态对齐源句里更相关的位置,而不是死盯一个压缩向量。很多人把这一年当作「注意力走进主流」的起点。
2015,Luong 等人把打分方式摊开试了一遍:点积、一般形式、拼接式,还有局部注意力。名字变多了,核心没变——还是「当前查询」对「候选位置」算相关度。
2017,Vaswani 等人的《Attention Is All You Need》把自注意力推成主角,RNN 不再是序列建模的必选项。标题本身像句玩笑,后面几年的 GPT、BERT 路线却把玩笑做成了基础设施。
2018 前后,预训练语言模型把 Transformer 里的注意力规模化:更大上下文、更多头、更深堆叠。你今天听到的「上下文窗口」「多头注意力」,大多是这条线上长出来的词。
注意力简史:2014 到 2018+
一个我愿意反复讲的类比
把模型想成开卷考试。试卷摊在桌上,字很多。你写某一空时,不会把整张卷子每个字都同等用力看一遍;你会用眼睛当聚光灯,先找题干关键词,再扫相关段落,最后落笔。
注意力干的就是这盏灯: - Query(查询):我现在要填哪一空、缺什么信息。 - Key(键):试卷每一段贴的「标签」,方便被检索。 - Value(值):标签背后真正可抄进答案的内容。
灯照得亮的地方权重大,暗的地方权重小。加权求和之后,得到的是「这一刻的上下文摘要」,不是整本辞典的复印件。
我自己后来多懂的一层是:考试类比里,人还会凭经验跳读;模型的「经验」写在训练出来的参数里——它学的是如何打分,不是某一篇具体文章的标准答案。
注意力像聚光灯
机制:输入到输出可以压成三步
抛开公式符号,流程大致是:
手头有一段已编码的序列(词、子词、图像块都行)。模型为每个位置造出 Q、K、V 三组表示。当前要预测的位置拿出自己的 Q,去和所有位置的 K 比相似度,得到一串分数;分数经 Softmax 变成加起来为 1 的权重;再用这些权重去混合各位置的 V,得到新的表示,送去生成下一个词,或进入下一层。
自注意力(self-attention)说的是:Q、K、V 都来自同一段序列——句子内部的词互相「看」。交叉注意力则是一边来自解码端、一边来自编码端,机器翻译早期的注意力更接近后者。
多头注意力可以想成几盏灯同时开,每盏灯学一种偏好:有的头爱盯句法邻居,有的头爱盯指代,有的头爱盯标点边界。训练结束后你未必能给每个头贴上干净标签,但「多视角并行」这件事本身,是它比单灯更稳的原因之一。
注意力三步走:Query、Keys、打分、加权求和
容易和邻近概念搅在一起的地方
注意力 ≠ 记忆。 记忆更像把东西存进可查找的仓库;注意力是读取时的聚光策略。长对话看起来「记得」,常常是上下文窗口里原文还在,注意力又能重新加权读到。窗口外的内容,灯再亮也照不到。
注意力 ≠ 上下文窗口。 窗口是「最多能放多长」;注意力是「放进来之后怎么读」。窗口变大,注意力的计算量通常按序列长度的平方涨(朴素实现),所以「无限长上下文」会撞上算力与显存墙。
软注意力 ≠ 硬注意力。 现在大模型里主流是软注意力:每个位置都分一点权重,只是多少不同。硬注意力更像直接选一个位置、其余全丢,训练时往往更别扭,线上也少见。
注意力权重 ≠ 可解释的「理由」。 可视化热力图很好看,但高权重不等于人类意义上的因果解释。它更像相关性痕迹,拿来当严谨论证要谨慎。
局限和我踩过的坑
二次复杂度是老问题:序列一长,显存和时延一起涨。于是有各种稀疏注意力、线性近似、滑动窗口,本质都是在「少算一些两两关系」。
还有个反直觉点:注意力很强,并不自动等于「理解很强」。它擅长在给定上下文里做条件读取;若训练数据偏、提示含糊、检索材料错,它也会一本正经地盯错地方,把错材料加权进答案——这跟「幻觉」经常绑在一起出现。
我写这篇时重新核对年份,顺手修了自己以前一个含糊印象:很多人把 2017 当成注意力的发明年。更准确的说法是,2014 让对齐式注意力在翻译里立住,2017 让自注意力成为架构中心。发明与成为默认底座,中间隔了好几年工程与论文的接力。
说到落地,聊天产品里你感知到的「它接得住上文」,往往是窗口里的原文还在,加上注意力按轮次重算权重;中间件再叠一层检索时,检索回来的段落也会进入同一套加权读取。灯照的范围变了,机制本身没有换成另一种魔法。
读完可以带走的一句
下次再听到「模型在注意某处」,不妨把它翻译成:系统正在为当前这一步的预测,重新分配对上下文的阅读预算。灯会动,预算有限,窗口外是黑夜——把这三件事同时记住,后面聊 Transformer、KV Cache、长上下文,会顺很多。