模型架构 · Attention
学习舱 / 模型架构 / Attention

Attention 与 Transformer

整理中 深度 · 应用 更新 2026-09-22

前置 Tokenizer、采样

Attention 与 Transformer

一句话定位:Transformer 是当代大模型的骨架,注意力(Attention)是骨架里的核心机构——让每个 token 按「相关程度」从序列里各处取用信息。本文拆开这一层看 QKV 怎么打分、多头和因果掩码在干什么,并回答「为什么 Decoder-only 赢下了 LLM 时代」「平方复杂度的瓶颈具体卡在哪」。前置:Tokenizer 与分词——token 是模型的最小计算单元,也是本文的主角;采样:temperature / top-k / top-p——本文输出侧的「打分→采样」流水线在那篇拆过。

先从一个代词的困惑说起

模型读到「小明把球传给小刚,因为他跑得快」——这个「他」指小明;换成「因为他接不住」,就指小刚。前一篇采样已经看清:模型每步给全词表打分,可打分之前,模型得先决定「他」这个词该携带谁的语义——这取决于它怎么「看」前文。

最直接的想法是按距离加权:离得越近的词越重要。但代词的指代对象可能隔着半句话,句子的真正主语也可能在开头——远近规则写不出「该看谁」,而且「看谁」这件事本身随上下文变化,硬编码不了。

要让模型自己学会「该看谁、看多少」,什么样的运算能做到?

答案是注意力:每个 token 拿自己的「查询」去比对序列里各个 token(含自己)的「键」——可以理解为人手一张的标签,匹配度越高就越多取用对方的内容。「看多少」变成可学习的一组权重。把注意力嵌进多层堆叠的网络,就是 Transformer。先看全景:

Transformer 全景:一层内部与 N 层堆叠 token 序列 分词器切好 转成向量进来 一个 Transformer 层(×N 层堆叠) ① 注意力 token 之间换信息 ② FFN 逐位加工消化 ③ 残差通道:原信号直通一层,防走样 ④ 输出打分 全词表 logits 交给采样抽签 层内顺序:①注意力负责「看谁」,②FFN 负责「消化」,每一步都叠着③残差通道 堆几十层:每层做一轮「交换信息 → 加工」,理解逐层加深 下一层的「看」建立在这一层交换过的信息上——低层抓语法、高层抓语义,一层比一层抽象 读法:本文拆的就是①注意力——Transformer 其余部件都围着它转

图:Transformer 全景——token 向量进层,①注意力做 token 间信息交换、②FFN 逐位加工、③残差直通,堆叠 N 层后④输出全词表打分接采样

渐进拆解:打分、缩放、加权

注意力像一场圆桌会议:你手上有一份查询(Query,你当前关心什么),桌上每人别着一块键(Key,我这里有什么信息),听各方按相关程度报分后,按分数抄录各人的值(Value,实际内容)——相关性越高抄得越多,最后的理解是按相关度配比的混合物。Q、K、V 三个名字就是这么来的。

QKV 与缩放点积:一条流水线走完

具体到运算,每个 token 的向量经三个可学习的变换矩阵,派出自己的 Q、K、V 三份表示,然后:

缩放点积注意力:从向量到混合 三份表示 每个 token 派出 Q 查询 / K 键 / V 值 三个可学习矩阵 点积打分 Q · 每个 K 方向越一致分越高 n 个 token 出 n×n 分数阵 ÷√d_k 缩放 维度高→分数方差大 不缩放会一家独大 实测:方差 63.9 → 1.00 softmax 归一 分数变成权重,总和 1 加权求和 V 按权重混合各方内容 新表示 携带着上下文的 token 打分、缩放、归一这一套与采样篇同构:分数过 softmax 变概率式的权重——「该看谁」从此可学习 读法:打分是对「所有 token 两两配对」做的——这个 n×n 结构正是平方复杂度的来源

图:缩放点积注意力流水线——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。一张下三角掩码,把「互看」变成「只看过去」——训练时一个序列里每个位置都在练「预测下一个」,推理时直接续写,同一个结构管两边:

掩码对比:全员互看 vs 只看过去(行=正在写,列=可看) 无掩码:全员互看 因果掩码:只看过去 t1t2t3t4 t1t2t3t4 ✕✕✕ ✕✕ ✕ t1t2t3t4 t1t2t3t4 token2 行 右图高亮行:token2 的权重实测为 0.40 / 0.60 / 0 / 0——白区(未来)权重精确为 0,不是「少看」是「看不见」 双向看得全但没法续写;只看过去才能逐 token 生成——训练与推理共用同一张掩码 读法:左图训练「完形填空」,右图训练「预测下一个」;两种训练目标培育出两类不同的模型(见「边界与取舍」的谱系图)

图:因果掩码对比——左全员互看(双向),右下三角只看过去;白区是「未来」,置负无穷后权重为 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 时代? 三层原因叠加:

  1. 监督信号密度:因果掩码让 n 个 token 的序列产出 n 个「预测下一个」任务——全序列 100% 的位置都在出力;BERT 式的完形填空只训练被盖住的位置(约盖 15%,出自 BERT 论文的掩码设定),同样算力换到的学习信号稀薄得多。
  2. 训练目标与使用方式合一:预训练练的就是「续写」,部署时干的就是续写,中间不需要换姿势——BERT 学会的是「填空」,生成本来就不是它的主场。
  3. 结构简单利于规模化:一个栈、一套掩码,分布式训练与推理基建都围着它优化。

曾是「理解任务之王」的 BERT 与编码器-解码器(读文、写文分两套栈的架构)代表 T5 双双淡出主流——亲历了那个时代的研究者 Yi Tay(UL2 一作)在复盘里给出的核心解释是范式统一:通用多任务模型胜过了任务专属的分类头与单任务微调;真正退场的是 BERT 式纯编码器,编码器-解码器则是被吸收进续写范式、仍有适用场景。2025 年还有论文重新审视这场对决,认为部分结论值得在现代条件下再测——但工程世界的既成事实已经定型。三条谱系各自的练法与归宿:

Transformer 三条谱系:练法不同,命运不同 Encoder-only(代表:BERT) 练法:完形填空(双向互看,盖 15% 猜被盖的) 擅长:理解、分类、检索 境遇:退出生成主战场,转做向量表示与搜索 Encoder-Decoder(代表:T5、翻译模型) 练法:读文用双向、写文用因果,两头各一层栈 擅长:输入输出形态不同的任务 境遇:留在翻译、结构化转换等窄场景 Decoder-only(代表:GPT 系、Qwen、Llama) 练法:因果掩码下续写下一个 token(全员都是考题) 擅长:开放生成,理解任务也不弱 境遇:LLM 时代的主流形态 高亮行赢在三点:每个 token 都是训练信号(密度高)· 预训练即使用方式(无转换)· 单栈结构利于规模化 读法:差别不在「谁更聪明」,在「训练目标是什么、每个 token 提供多少监督」

图:三条谱系对照——练法(掩码与目标)决定擅长与境遇;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 谁在前谁在后?

本节点大纲与自测题(4 个子点 · 2 问)

大纲

  • QKV 与缩放点积注意力
  • 多头机制与因果掩码
  • 残差连接与 LayerNorm 的作用
  • Encoder-only / Decoder-only 分野

自测——答不上来就是缺口

  • 为什么 Decoder-only 赢下了 LLM 时代?
  • attention 平方复杂度的瓶颈具体卡在哪?(引向 long-context)