Attention 与 Transformer
一句话定位:Transformer 是当代大模型的骨架,注意力(Attention)是骨架里的核心机构——让每个 token 按「相关程度」从序列里各处取用信息。本文拆开这一层看 QKV 怎么打分、多头和因果掩码在干什么,并回答「为什么 Decoder-only 赢下了 LLM 时代」「平方复杂度的瓶颈具体卡在哪」。前置:Tokenizer 与分词——token 是模型的最小计算单元,也是本文的主角;采样:temperature / top-k / top-p——本文输出侧的「打分→采样」流水线在那篇拆过。
先从一个代词的困惑说起
模型读到「小明把球传给小刚,因为他跑得快」——这个「他」指小明;换成「因为他接不住」,就指小刚。前一篇采样已经看清:模型每步给全词表打分,可打分之前,模型得先决定「他」这个词该携带谁的语义——这取决于它怎么「看」前文。
最直接的想法是按距离加权:离得越近的词越重要。但代词的指代对象可能隔着半句话,句子的真正主语也可能在开头——远近规则写不出「该看谁」,而且「看谁」这件事本身随上下文变化,硬编码不了。
要让模型自己学会「该看谁、看多少」,什么样的运算能做到?
答案是注意力:每个 token 拿自己的「查询」去比对序列里各个 token(含自己)的「键」——可以理解为人手一张的标签,匹配度越高就越多取用对方的内容。「看多少」变成可学习的一组权重。把注意力嵌进多层堆叠的网络,就是 Transformer。先看全景:
图:Transformer 全景——token 向量进层,①注意力做 token 间信息交换、②FFN 逐位加工、③残差直通,堆叠 N 层后④输出全词表打分接采样
渐进拆解:打分、缩放、加权
注意力像一场圆桌会议:你手上有一份查询(Query,你当前关心什么),桌上每人别着一块键(Key,我这里有什么信息),听各方按相关程度报分后,按分数抄录各人的值(Value,实际内容)——相关性越高抄得越多,最后的理解是按相关度配比的混合物。Q、K、V 三个名字就是这么来的。
QKV 与缩放点积:一条流水线走完
具体到运算,每个 token 的向量经三个可学习的变换矩阵,派出自己的 Q、K、V 三份表示,然后:
图:缩放点积注意力流水线——Q 与各 K 点积打分、除以 √d_k 防一家独大、softmax 变权重、按权重混合 V;n 个 token 两两打分即 n×n 分数阵
为什么要除以 √d_k? 点积是把几十上百个分量乘积加起来:维度越高,加数越多,打分的方差越大——分差被系统性放大,softmax 一过就成了「一家独大」的近乎独热(one-hot,一家独占全部权重)的选择,其他候选拿到的梯度(训练更新信号)几乎断流。缩放除以键向量维度的平方根,把打分方差拉回与维度无关的水位。
这不是玄学,可实测验证:未缩放时方差贴合理论值 d_k、标准差贴合 √d_k,除以 √d_k 后方差回到 1——具体数字见上图 ÷√d_k 一格与动手一节的可复跑代码。饱和程度同样可测(同法实测、序列长 16):不缩放时 64 维的最大权重平均已到 0.84,512 维更是高达 0.94——注意力近乎退化成「只看一个人」;除以 √d_k 后回落到 0.25(缩放后与维度无关),权重分布重新铺开。
多头与 GQA:换视角,压缓存
多头换视角,不按头数翻倍计算。 一组 QKV 只会一种「看法」,容易单偏。多头机制(Multi-Head)把向量维度切成几份,每份独立做一遍完整注意力——像审一份合同,法务看条款、财务看数字、技术看实现,各审各的最后拼合。关键在「切」:把 3584 维(Qwen2-7B 的隐层宽度,即每层向量的总维度)切成 28 个 128 维的头,28 个头打分的总计算量与 3584 维单头一次注意力相同——换的是视角,不是翻倍的开销。
GQA 压缓存。 推理时每个已生成 token 的键、值都要存下来供后续复用,这份存档叫键值缓存。现代模型对它下手:把查询头分组,每组共享一组键值头(GQA,分组查询注意力,2023 年提出),缓存体积随组数成倍缩小。Qwen2-7B 的官方配置即 28 个查询头分 4 组共享,缓存压到全量的 1/7(28/4 从配置直接算得),质量几乎不掉。这也是长上下文篇里「键值显存墙」的第一道缓解手段。
因果掩码:考试不能偷看后面
生成模型逐 token 往下写,写第 5 个词时第 6 个词还不存在——注意力天然是「全员互看」,必须用掩码把「未来位置」的分数置成负无穷,softmax 后权重精确为 0。一张下三角掩码,把「互看」变成「只看过去」——训练时一个序列里每个位置都在练「预测下一个」,推理时直接续写,同一个结构管两边:
图:因果掩码对比——左全员互看(双向),右下三角只看过去;白区是「未来」,置负无穷后权重为 0,生成由此成为可能
残差与 Norm:传送带和质检
注意力与 FFN(前馈网络——每层里逐位过的两层全连接)都不做「一锤子买卖」:每层的输入还留一条直通通道(残差连接,源自 2015 年的 ResNet 论文),层的加工结果以「原样 + 增量」的方式传下去——网络再深,信号也不会在层层加工中走样失联。Norm 层则是每步加工前的质检,把数值拉回稳定区间防训练发散。这一对组合是大模型能堆到几十层、上百层而不崩的前提。
大白话:注意力就是每个 token 开一场圆桌会议——用查询对遍所有人的标签打分,按分抄内容;多头是几个部门各开各的会;掩码规定不许偷看后文;残差是「原稿复印一份再改」,Norm 是改稿前把格式对齐。堆几十层,炼出「每个 token 都带着全上下文语境」的表示;最后一个位置去给全词表打分(logits),交给采样抽签——正好接回采样篇的四级流水线。
技术定义:Transformer(2017 年论文《Attention Is All You Need》)以自注意力为核心构件的神经网络架构。缩放点积注意力的完整式子:softmax(QKᵀ/√d_k)V——Q、K、V 分别是输入经三个可学习矩阵变换出的查询、键、值矩阵,d_k 是键向量维度;点积 QKᵀ 给出 n×n 两两相关分数,除以 √d_k 控制方差(使分数方差与维度无关),softmax 把每行分数归一化成总和为 1 的权重,最后按权重对 V 加权求和。
多头注意力将上述过程在隐层宽度(即前文的 3584 那类总维度)的若干等分切片上并行执行后拼接。
动手:亲手量一次「缩放」与「掩码」
下面的实验不依赖任何深度学习库,纯 Python 就能跑——量出「除以 √d_k 前后,打分方差差多少」:
import math, random
random.seed(42) # 固定种子,结果可复现
def gauss(): # 标准正态随机数(Box-Muller)
u1, u2 = random.random(), random.random()
return math.sqrt(-2*math.log(u1+1e-12))*math.cos(2*math.pi*u2)
d_k = 64 # 每头键向量的常见维度量级
N = 50000
dots = []
for _ in range(N): # 模拟 5 万次「查询×键」打分
q = [gauss() for _ in range(d_k)]
k = [gauss() for _ in range(d_k)]
dots.append(sum(a*b for a, b in zip(q, k))) # 点积打分
m = sum(dots)/N
var = sum((x-m)**2 for x in dots)/N
print(f"未缩放:方差 {var:.1f},标准差 {math.sqrt(var):.2f}")
print(f"除以 sqrt({d_k})={math.sqrt(d_k):.0f} 后:方差 {var/d_k:.2f}")
实测输出:未缩放方差 63.9、标准差 8.00(恰为 √d_k);除以 8 后方差 1.00。这就是「缩放」两个字的全部含义——不是玄学调参,是把打分的统计水位钉在与维度无关的位置。
再把掩码验一遍(打分矩阵与正文图同源):
import math
S = [[0.9, 0.8, 0.1, 0.2], [0.7, 1.1, 0.4, 0.3],
[0.2, 0.5, 1.3, 0.9], [0.1, 0.3, 0.6, 1.5]] # 4 token 的打分矩阵
for i in range(4): # 行 = 正在写的 token
row = [S[i][j] if j <= i else -math.inf # 上三角=未来,置负无穷
for j in range(4)]
m = max(row); e = [math.exp(x - m) for x in row]
w = [x / sum(e) for x in e] # 逐行 softmax 归一
print(f"token{i+1}:", [round(v, 3) for v in w])
实测输出:token1 只有自己(1.0);token2 是 0.401 / 0.599 / 0 / 0——后两列精确为 0;token4 才看得到全部四个位置。「不许偷看后面」是数学保证,不是修辞。
边界与取舍:赢家的代价
为什么 Decoder-only 赢下了 LLM 时代? 三层原因叠加:
- 监督信号密度:因果掩码让 n 个 token 的序列产出 n 个「预测下一个」任务——全序列 100% 的位置都在出力;BERT 式的完形填空只训练被盖住的位置(约盖 15%,出自 BERT 论文的掩码设定),同样算力换到的学习信号稀薄得多。
- 训练目标与使用方式合一:预训练练的就是「续写」,部署时干的就是续写,中间不需要换姿势——BERT 学会的是「填空」,生成本来就不是它的主场。
- 结构简单利于规模化:一个栈、一套掩码,分布式训练与推理基建都围着它优化。
曾是「理解任务之王」的 BERT 与编码器-解码器(读文、写文分两套栈的架构)代表 T5 双双淡出主流——亲历了那个时代的研究者 Yi Tay(UL2 一作)在复盘里给出的核心解释是范式统一:通用多任务模型胜过了任务专属的分类头与单任务微调;真正退场的是 BERT 式纯编码器,编码器-解码器则是被吸收进续写范式、仍有适用场景。2025 年还有论文重新审视这场对决,认为部分结论值得在现代条件下再测——但工程世界的既成事实已经定型。三条谱系各自的练法与归宿:
图:三条谱系对照——练法(掩码与目标)决定擅长与境遇;Decoder-only 以信号密度、训练即使用、结构简单三条胜出
平方复杂度的瓶颈具体卡在哪?
注意力要对 n 个 token 两两打分,计算量随 n² 增长:1000 token 是 100 万对,10 万 token 是 100 亿对,100 万 token 直接上万亿对——序列拉长十倍,打分开销涨一百倍。瓶颈在训练与推理两侧各卡一道:
- 训练侧:n×n 分数阵本身要占显存,是长序列训练的第一道墙。
- 推理侧:键值缓存随长度线性增长,且每生成一个 token 都要读完整个缓存——按 Qwen2-7B 官方配置推算:28 层 × 4 组键值头 × 每头 128 维 × K 与 V 两份 × 2 字节(bfloat16 半精度)≈ 56 KiB/token,13 万 token 上下文仅缓存就要 7.0 GiB 量级。
工程上有各种缓解,但「两两配对」是写在这个运算结构里的,缓解手段都是换一种方式「少看」。沿着这条线往下打,就是长上下文篇的稀疏注意力路线。
Transformer 不是万能骨架。 流式场景(日志、传感器)天然是「来了就处理」,RNN 式的常数增量成本反而更贴;超局部模式(波形、边缘检测)卷积一次算一片更省。Transformer 赢在「长程关联 + 可并行 + 可规模化」的组合拳,不是绝对速度。选架构先问数据形状,再问规模需求。
坏味道预警:把「注意力=人脑注意」当真。 模型里的注意力只是加权平均运算,「关注」是借词——它没有主观焦点,也不保证可解释(权重高不等于因果依赖)。拿注意力权重图做产品决策之前,先想想这张图真的支持你要下的结论吗。
自测
合上文章先自己答,再展开对照:
为什么 Decoder-only 赢下了 LLM 时代?
三层原因:①监督信号密度高——因果掩码下 n 个 token 产出 n 个「预测下一个」的训练信号,而 BERT 式完形填空只训练被遮盖的位置(约 15%),同等算力换到的信号稀薄;②训练目标与使用方式合一——预训练练续写、部署用续写,没有目标转换;③结构简单利于规模化——一个栈一套掩码,训练与推理基建都围着它长,编码器-解码器的灵活性没跑赢这点工程动量。注意这说的是工程既成事实:2025 年仍有论文重审这场对决,部分结论有再测空间。
attention 平方复杂度的瓶颈具体卡在哪?
卡在「两两配对」这个结构上:n 个 token 要出 n×n 打分阵,计算量随 n² 增长——10 万 token 是 100 亿对打分;训练时这个分数阵还占显存,是长序列训练第一道墙。推理时瓶颈换位置:键值缓存随长度线性增长(按 Qwen2-7B 配置推算约 56 KiB/token),且每生成一个 token 都要读全量缓存。所以长上下文的成本是「训练平方增长 + 推理线性增长但每步全读」双重叠加——缓解思路都是少看(稀疏化)、少存(键值压缩),见长上下文专篇。
参考与延伸
- Vaswani 等《Attention Is All You Need》(2017):Transformer 与缩放点积注意力的原始出处 — arxiv.org/abs/1706.03762
- Ainslie 等《GQA: Training Generalized Multi-Query Transformer Models》(2023):查询头共享键值头的分组方案 — arxiv.org/abs/2305.13245
- He 等《Deep Residual Learning for Image Recognition》(2015):残差连接的源头 — arxiv.org/abs/1512.03385
- Zhang & Sennrich《Root Mean Square Layer Normalization》(2019):RMSNorm — arxiv.org/abs/1910.07467
- Sebastian Raschka《Understanding Encoder and Decoder LLMs》:编码器与解码器两种架构的通俗对照 — magazine.sebastianraschka.com
- Devlin 等《BERT: Pre-training of Deep Bidirectional Transformers》(2018):完形填空式预训练与 15% 掩码率的出处 — arxiv.org/abs/1810.04805
- Yi Tay《What happened to BERT & T5?》:亲历者复盘编码器系为何退场 — yitay.net
- 《Encoder-Decoder or Decoder-Only?》(2025):在现代条件下重审两派 Scaling 对比的翻案论文 — arxiv.org/abs/2510.26622
- Qwen2-7B 官方配置:28 查询头 / 4 键值头 / RMSNorm 的一手实证 — huggingface.co/Qwen/Qwen2-7B
下一站:位置编码:RoPE——注意力本身不认识「先后顺序」,谁告诉它 token 谁在前谁在后?