← 全部极客知识库

大模型通识 / 大模型理论基础

3. Transformer:大模型怎样组织这些计算

原文备份 · 第 4 / 20 篇 · 查看极客时间原知识库 ↗

本篇目录 · 14 节

来源:大模型理论基础

你的复习助手收到一段笔记,需要生成一道问题。前两篇已经解释了两个环节:文字怎样变成向量,以及注意力怎样让不同位置交换信息。

但还有几件事没有接起来:注意力输出的那串数字,怎样变成下一层的输入?模型怎样分清“谁帮助谁”?为什么网络要叠很多层?还有,模型介绍里常见的“只有解码器”,是不是意味着它没有负责理解输入的部分?

本篇把这些环节接成一条完整路径。Transformer 是组织神经网络计算的一类架构;注意力是其中的重要部件,但不是全部。

你不需要实现一个 Transformer。读完后,能看懂一张简化结构图,区分各部件的职责,并沿着数据形状走完一次前向计算,就达到了本篇目标。文中的小词表、维数、向量和算例都是教学构造,不对应实际模型配置。

一、先看全图:输入进入的是一组计算块

先以一种用于生成文本的、只有解码器的 Transformer 为例。完整名称是 Decoder-only Transformer。它可以把提示词和已生成内容放在同一条序列里处理。

flowchart TD
    T[文本] --> I[分词得到 Token ID]
    I --> E[查嵌入表得到每个位置的向量]
    E --> B1[第 1 个 Transformer 块]
    B1 --> B2[第 2 个 Transformer 块]
    B2 --> BN[后续 Transformer 块]
    BN --> N[最终归一化:按具体架构设置]
    N --> H[语言模型输出头:计算词表分数]
    H --> P[得到下一 Token 的概率分布]
    P --> S[按生成策略选择 Token]
    POS[位置相关信息] -.按架构加入嵌入或注意力计算.-> B1

位置相关的设计贯穿模型计算;图中的虚线只表示它的作用,不代表所有模型都只在第一块接收位置数据。

这里的 Block,块,指由注意力、前馈网络及辅助连接组成的一组计算。一个块里包含多个子层;看到“32 层模型”时,通常需要结合模型配置判断其计数口径,不能把它理解成只有 32 次简单运算。

各块的结构可以相似,参数通常各不相同。模型在第一块算出的中间表示,被送到第二块继续加工。它不是把同一段问题交给若干独立聊天机器人轮流回答。Hugging Face:Transformer 的基本结构与架构类型

多层的意义在于反复形成和加工表示:某一层汇集来的关系,可以成为下一层继续匹配和组合的信息。不过,不能机械地说“第一层只学词义、第二层只学语法、第三层负责推理”,也不能据此认定层数越多就必然越可靠。结构提供了计算能力,训练决定它怎样被使用。

原始 Transformer 同时包含编码器和解码器;上图先选用较容易串起文本生成过程的一条路线。后面会把几种结构放到同一张地图上。

二、嵌入给出内容表示,位置设计让顺序参与计算

考虑两句话:

小林帮助小周
小周帮助小林

两句话包含的名字与动作相同,关系却反了。如果一个系统只保留“出现了小林、小周、帮助”,而丢掉这些内容的顺序,就难以正确回答“谁帮助了谁”。

Token 嵌入首先提供内容表示。位置相关的设计则让网络能够使用“这是第几个位置”“两处相距多远”等信息。

一种直观做法是,把内容向量与同维度的位置向量相加。例如,我们人为规定:

某 Token 的内容向量:[0.4, -0.2]
位置 1 的位置向量:[0.0,  0.1]
位置 2 的位置向量:[0.3, -0.1]

同一个 Token 放在两个位置,得到:

位置 1:[0.4, -0.2] + [0.0,  0.1] = [0.4, -0.1]
位置 2:[0.4, -0.2] + [0.3, -0.1] = [0.7, -0.3]

结果仍是 2 维,而不是把两个向量接起来变成 4 维。这组数字只演示相加,不是任何实际位置编码公式。

原始 Transformer 使用正弦、余弦构造位置编码,并把它加到嵌入上;也可以使用学习得到的位置表示。《Attention Is All You Need》§3.5

但“位置编码就是在输入上加一个向量”不是通用定义。例如 RoPE,旋转位置嵌入,通过与位置有关的旋转作用于查询和键,使注意力匹配能够反映相对位置关系。这里不必推导旋转矩阵,只需记住:位置信息也可以直接进入注意力计算,而不只是加在初始嵌入上。《RoFormer》原始论文

因果掩码和位置编码也不是同一件事。掩码规定“哪些连接允许存在”,位置设计帮助计算利用“这些位置是什么顺序”。带有因果限制的网络已经具有某种方向结构,但这不等于它就拥有了某种完整的位置编码。

三、进入一个块:信息交换之后,还要继续加工

下面选用一种 Pre-LN,也就是先归一化再进入子层的结构来说明。原始 Transformer 使用的归一化位置与它不同,后续模型也有其他变体;我们不把一张图当成所有模型的精确设计图。《On Layer Normalization in the Transformer Architecture》

把整段序列的当前表示记作 X,一个简化块可以写成:

Y = X + Attention(Norm(X))
Z = Y + FFN(Norm(Y))

Norm 是归一化,Attention 在这里包含多头注意力及输出投影,FFN 是前馈网络。加号表示相同形状的数组逐项相加。Z 再送往下一个块。

先不要急着背这两行。它们包含四个各有用途的设计。

1. 注意力:把其他位置的信息带过来

前一篇已经算过一次加权汇集。把它放进整块之后,其用途是让每个位置能够利用允许访问的其他位置的信息。

例如,笔记写着“间隔复习需要把练习分散到不同时间”,后面提出“请围绕这一方法出题”。后面位置的表示可以通过注意力吸收前面关于方法的说明。

注意力后的输出投影会把多个头组合后的结果变换到块所需的维数,以便与原表示相加。中间某个头的向量宽度,可以与块对外保持的宽度不同。

2. 前馈网络:在每个位置内部组合特征

FFN,Feed-Forward Network,前馈网络,通常是带非线性变换的网络。在经典稠密 Transformer 块中,同一块的 FFN 分别处理每个位置,并在这些位置之间共享参数。

注意力让位置之间交换信息;FFN 则对每个位置已经汇集到的信息进行进一步变换。它不在这一步重新扫描其他位置,但它的输入已经可以包含其他位置的信息。《动手学深度学习》:Transformer 的逐位置前馈网络

用一组不具备实际语言能力的计算,看清“变换”指什么。设某位置的输入是 [a,b],我们手工定义一个两层 FFN:

第一层:把 [a,b] 变成 [a, b, a-b]
非线性:ReLU,把负数改成 0
第二层:把 [h1,h2,h3] 变成 [h1+h3, h2-h3]

当输入为 [1,-2] 时:

第一层结果:[1, -2, 3]
经过 ReLU:[1,  0, 3]
第二层结果:[4, -3]

维数经历了 2 → 3 → 2。内部可以扩大表示空间,输出再回到原来的宽度。若输入换成 [1,2],结果则是 [1,2]。同一套参数处理不同内容,可以得到不同结果。

这个算例只演示 FFN,不包含前面的归一化、注意力和残差连接。实际模型会学习其中的参数;使用什么激活函数、是否采用门控结构,也依架构而异。不能把“前馈”误解为“把信息原样往后递”。

3. 残差连接:保留一条直接相加的路径

两行公式里的 X + ... 和 Y + ... 叫 Residual Connection,残差连接。一个子层不必独自重新生成全部表示;它的输出与输入相加后,再进入后续计算。残差设计有助于深层网络的优化。《Deep Residual Learning for Image Recognition》

例如,若某位置原表示为 [1,2],子层输出为 [0.3,-0.2],相加得到:

[1,2] + [0.3,-0.2] = [1.3,1.8]

如果子层输出恰好为 [0,0],这条相加路径就保留 [1,2]。如果子层输出很大或与输入相反,结果当然仍会明显改变。所以,残差并不保证原始信息毫无损失地永远保存,更不是把“模型记忆”备份到磁盘。

相加还解释了一个结构约束:参与相加的两项必须具有兼容的形状。前馈网络可以在内部把向量变宽,但通常要在输出端回到残差路径使用的宽度。

4. 归一化:处理数值尺度,不检查语义对错

多层计算会不断改变数值。归一化提供一种调整数值尺度的方式,帮助网络训练与运行。以 Layer Normalization,层归一化为例,在常见文本 Transformer 中,它针对每个位置的特征向量计算均值与方差,而不是把整句话所有 Token 混成一个平均值。《Layer Normalization》原始论文

为看清操作,取向量 [1,3]:均值为 2,减去均值得到 [-1,1];这两个偏差的平方平均值为 1,所以标准差为 1,再除以标准差,仍为 [-1,1]。

这是一个简化示意。实际 LayerNorm 会在方差上加一个很小的数,避免除零,并通常带有可学习的缩放与偏移。缩放、偏移之后,也不能再断言输出一定均值为 0、方差为 1。PyTorch:LayerNorm 的计算定义

“归一化”不是把所有数字变成 0 到 1,也不是检查句子是否符合规范。实际模型可能使用其他归一化变体;本篇只用 LayerNorm 建立数值处理的直觉。

四、沿着形状走一遍:Token 数量和向量宽度不要混淆

现在把几个部件放回完整路径。假设我们人为设计一个小模型:

  • 输入是 4 个教学 Token:[我] [用] [卡片] [复习];
  • 块内每个位置保持 4 维表示;
  • FFN 的中间宽度为 8;
  • 用于演示的完整词表只有 8 项。

这里的词表是本篇新设定,不沿用第 01 篇的词表编号。忽略批量维度,只看一条输入,数据形状如下:

经过哪里 形状 怎么读
Token ID 4 个编号 序列有 4 个位置
嵌入及位置处理 4×4 每个位置有 4 个数字
一个块的注意力输出,经输出投影后 4×4 位置数量没有增加
FFN 的中间表示 4×8 每个位置暂时变成 8 维
FFN 输出及残差相加后 4×4 回到块使用的宽度
经过后续同宽度的块 4×4 形状相同,数值与表示内容已经改变
对各位置应用词表输出头 4×8 每个位置给 8 个候选 Token 打分

注意表里出现了两次 4×8,含义完全不同。一次的 8 是 FFN 内部特征数;另一次的 8 是词表大小。形状相同,不代表用途相同。

而且,经过一个块,不意味着多生成了一个 Token。块主要是在加工这 4 个位置的表示;生成新 Token 是输出分数经过选择之后发生的另一个步骤。

最后那串向量怎样变成一个词表选择

语言模型输出头通常用一个学习得到的线性变换,把最终表示转换为词表中各项的分数,常称为 Logits。随后可以通过 Softmax 得到概率分布。《Attention Is All You Need》§3.4

在这个小模型中,4 维表示要变成 8 个分数;采用行向量写法时,输出投影矩阵的形状就是 4×8,不计偏置包含 32 个数。

从已有四 Token 前缀继续生成时,通常取最后一个位置对应的 8 个分数来预测第五个 Token。前面三行的分数并不是要同时再输出三个新词。实现也可以只计算所需位置的词表分数,不必总把整张表都保存下来。

如何选择候选项、为什么同一输入可能产生不同回答,以及停止标记怎样起作用,下一篇再讲。这里先定位一个关键边界:块输出的是特征表示,语言模型输出头给出候选分数,生成策略再作选择。

五、编码器、解码器:名字说的是组织方式

Encoder,编码器与 Decoder,解码器,不是“负责理解的脑区”和“负责说话的脑区”的严格对应。它们描述网络怎样连接、看哪些位置、如何组织输入输出。

结构 典型的信息访问方式 常见用途与例子
Encoder-only,只有编码器 输入各位置可以结合左右两侧的上下文 分类、标注、形成文本表示;BERT 是代表
Decoder-only,只有解码器 一条序列通常按因果限制访问当前位置及之前的位置 根据提示和已生成内容继续生成文本
Encoder–decoder,编码器—解码器 编码器处理源输入;解码器既看已生成前缀,也通过交叉注意力读取编码器输出 翻译、摘要等输入到输出任务;原始 Transformer、T5 是代表

BERT 使用双向上下文形成表示,之后可结合任务输出层处理不同任务。BERT 原始论文 T5 则采用文本到文本的思路,把多种任务写成输入文本到目标文本的转换。T5 原始论文

表格是理解常见设计的入口,不是任务禁令。生成模型也可以输出分类标签,编码器得到的表示也可以服务于更大的生成系统。模型最后适合做什么,还取决于训练目标、数据和输出接口。

为什么只有解码器,也能读懂提示词

假设提示词是:

资料:间隔复习把练习分散到不同时间。
任务:请根据资料出一道题。

当模型开始生成回答时,回答位置位于整段提示之后。因果限制允许它使用此前的资料和任务。它没有独立的编码器,并不意味着这些输入没有被处理:提示词同样经过嵌入、各个块和上下文计算。

与之不同,编码器—解码器会先把资料加工成一组源序列表示,再让生成端通过交叉注意力查询这组表示。这里通常保留的是一组向量,不必把整篇资料压成唯一一个向量。

也不要把“编码器”与分词器混为一谈。分词器把文字转换为 ID;Transformer 编码器处理向量并形成上下文表示。名字里都有“编码”,工作却处在不同层次。

六、能并行计算,为什么回答还要逐步生成

Transformer 的一个重要特点,是在输入已知时,同一层的许多位置计算可以组织成矩阵运算并行完成。它不必像典型循环网络那样,在同一层沿着每个位置逐步传递一个状态。《Attention Is All You Need》§1、§4

但有两种依赖关系仍要区分。

第一,层与层之间有依赖。第二块要使用第一块的结果,并不是所有块都能无条件同时完成。

第二,自回归生成的新内容有依赖。训练时,整段训练文本已经给定,可以用因果掩码同时计算多个位置的预测,再对照各自的下一个 Token 计算损失。生成时,第五个 Token 还没有选出来,第六个 Token 所需的前缀就尚未确定。

所以,“训练中多个位置并行”与“普通自回归生成逐步决定输出”并不矛盾。这里描述的是基本过程;缓存与推理加速会改变具体实现,但不会把这两种概念变成同一件事。

这也纠正另一种误会:网络经过很多块,是一次前向计算内部的深度;回答写了很多 Token,是生成过程的长度。两者不是同一个“思考步数”。普通调用时经过更多位置或更多计算,并不会自动发生参数训练。

七、把这张结构图用于个人项目

对于复习助手,你不需要根据结构图自己训练一个网络,但可以用它判断需求落在哪一层。

如果要为一段笔记输出主题标签,需要的是能完成分类的模型或应用接口;不必因为听说某种架构常用于分类,就忽略现成生成模型也能输出标签。

如果要生成问题与解析,就要确认模型有适合的生成能力。只有一个返回向量的接口,不会因为内部也用了 Transformer,就自动变成聊天接口。

如果要找出与“梯度下降”相关的笔记,最终需要适合检索的文本表示与匹配方式。任意拿一个模型的某层向量做平均,不保证就得到了高质量的检索模型。

这些需求可以共享一些底层原理,但输出头、训练任务和服务接口可能不同。看到模型名里有 Transformer,只能知道一部分结构信息,不能据此判断它能否完成你的整个项目。

八、理解检查

1. 一个输入有 6 个 Token,每个位置是 4 维,FFN 在内部扩大到 10 维后再缩回 4 维。它的输入、中间、输出形状分别是什么?

忽略批量维度,分别是 6×4、6×10、6×4。Token 数仍是 6;中间变宽没有多生成 4 个 Token。

2. 本篇手工 FFN 输入 [2,-1],输出是什么?

第一层得到 [2,-1,3],ReLU 后为 [2,0,3],第二层得到 [5,-3]。这是 FFN 子层的输出;若还要做残差相加,必须另外按结构计算。

3. 残差路径输入为 [2,-1],子层输出为 [-0.5,0.5],相加之后是多少?

得到 [1.5,-0.5]。它不会自动把原输入与子层输出拼成 4 维。

4. 同一个词出现在两个位置,初始 Token 嵌入相同,是否意味着经过整个模型后的表示也必定相同?

不意味着。位置处理、允许访问的上下文及后续计算都可能使两处表示不同。

5. 只有解码器的模型没有独立编码器,因此不能根据输入笔记回答问题。这句话对吗?

不对。笔记作为提示的一部分,同样经过网络处理;后面的回答位置可以利用前面的输入信息。“只有解码器”不等于“没有输入理解能力”。

6. 模型在训练时一次计算了多个位置的预测,是否表示它偷看了各位置的下一 Token?

不能据此认定偷看。正确的因果掩码会阻止未来位置的信息进入当前预测;训练程序再用目标 Token 计算损失。并行计算方式与信息可见范围是两件事。


现在,你已经可以沿着“Token → 表示 → 多个计算块 → 输出头”看懂一条生成路径。注意力、前馈网络、位置处理、残差和归一化各有职责,最后的词表分数也还不是完整回答。

下一篇《回答怎样一个 Token 一个 Token 地生成》,我们就从这组分数出发,解释概率、采样、Temperature、Top-p 和停止条件。

上一篇:注意力机制 · 返回第二部分大纲