主题
第 3 章 · Transformer 原理解析
写在前面
这可能是整本指南中晦涩程度最高的一章,我们会尽量不写数学公式,用通俗的语言解释 Transformer 的原理,但仍旧需要你具备一定的抽象思维能力才能较好的理解。
如果你只是想学习如何使用 SillyTavern、如何编写提示词, 你大可直接跳过本章节,转而去阅读你需要的部分。
如果你愿意静下心来,仔细阅读,陪我们走完这一趟精彩的旅程,相信你一定会有所收获。
章节概要
- 模型眼里只有数字——分词(Tokenization)+ 嵌入(Embedding)把汉字变成向量
- 位置编码:attention 本身无视顺序,靠"位置签名"找回先后
- Attention 的本质:让每个 token 从其它 token 那里按相关度借一点意义;Q/K/V 只是它的算法实现,不是它的本质
- Multi-Head:多个 attention 头并行工作,自动分工出不同的关注模式
- Transformer Block 的真正主角是 FFN——它是一张以"模式"为键、"语义修改"为值的键值表,模型的世界知识几乎全在这里
- 残差 + LayerNorm 是让深堆叠成为可能的隐形支柱
- 输出端:最后一个位置的向量经过 LM Head 变成一个覆盖整个词表的概率分布
- 三大变体:Encoder-Decoder(翻译)/ Encoder-only(BERT, 理解)/ Decoder-only(GPT 全家,生成)
上一章我们把 Transformer 当成了一个黑盒,记住了它对世界做出的三条结构性承诺—— 训练可以并行、任意两个词之间的距离都是 1、模型规模越大效果越好。 我们也记住了那个赌博式的标题:Attention Is All You Need。
但这台机器具体是怎么做到这三件事的? 那个被押上整张赌桌的 attention,又到底是在做什么?
是时候打开盖子了。
这一章会沿着一句话从输入到输出的完整路径走一遍—— 从最开始的一串汉字,到中间的层层向量,再到最末端的一组概率, 这台机器内部的每一个主要部件都会依次登场: 分词、嵌入、位置编码、注意力、前馈网络、归一化、输出。
为了方便理解,本章我们使用一个简单的中文句子作为示例:
小李昨天买了一只小猫,今天它就把家里的沙发抓
句子在「抓」字之后戛然而止。 这恰恰是一个 LLM 每时每刻都在面对的情境—— 一段话已经写到这里,下一个字会是什么?
这句话会被拆成 token、变成向量、过完 attention、走完所有层, 最后让模型站在「抓」之后吐出一组概率, 告诉你下一个 token 最可能是什么。
一、模型眼里没有文字,只有数字
打开 Transformer 之前,必须先纠正一个普遍误解。
前两章里一直在说"词"、"句子"、"上下文", 那种叙述方式很容易让人产生一种错觉, 仿佛模型能像人类一样真的"读懂"中文或英文。
但事实是——模型从头到尾都没见过一个汉字、一个字母。 它眼里的世界,长这样:
[15, 8429, 1097, 423, 6]
整整一句话,对它来说就是一串整数。
那么,「小李昨天买了一只小猫」, 是怎么从汉字变成这样一串数字的?
答案分两步——分词 (Tokenization) 和 嵌入 (Embedding)。
第一步:分词,把一句话切成 token
第一件事是把你输入的句子切成一段段小片段,每段叫一个 token。
请注意:token 不等于"词",也不等于"字"。 它是模型词表里的一个最小单位, 可能是一个完整的中文词、可能是一个汉字、可能是英文的一个词根、甚至可能是一个标点。
举个例子,「小李昨天买了一只小猫」用 OpenAI 的中文分词器切,大致是这样:
[小, 李, 昨天, 买, 了, 一只, 小, 猫]
注意「昨天」、「一只」被当成一个整体(因为它们出现得非常频繁), 而「小猫」被切成了「小」和「猫」两个 token(因为它没那么常见)。 模型的词表是从海量文本里"统计学出来的",每个分词器有自己的切法。
切完之后,每个 token 在模型的词表里有一个编号(叫 token ID)。 词表通常有几万到几十万个条目,所以每个 token ID 是一个像 15 或 8429 这样的整数。
一个常被忽略的事实
你给模型输入的"一句话",模型看到的并不是字,而是一串整数。 后面所有事情——理解、注意、生成——都是在这串整数上做的。
这件事的一个副作用:模型对它没在训练时见过的 token 组合特别敏感。 比如你用一种很罕见的字符、emoji、或者新造的网络黑话, 分词器可能会把它切成一长串它没见过的奇怪片段,导致模型表现失常。
第二步:嵌入,把整数变成向量
光有 token ID 还不够。 对模型来说,ID 是 15 还是 8429 没有任何含义——它只是一个序号。 模型需要的是能表达语义的数字。
这一步叫 embedding(嵌入)。
模型内部有一张超大的查询表, 表里每个 token ID 对应一串数字(比如 768 个), 这串数字就是这个 token 的语义向量。
[token ID = 8429("猫")] → [0.12, -0.85, 0.33, ..., 0.07](768 个数字)
这正是第 1 章讲到的那个词向量—— 也就是当年让计算机第一次摸到"语义"边缘的发明。 意思相近的 token,它们的这串数字也长得相近: "猫"和"狗"两个向量的距离很近, "猫"和"苹果"两个向量的距离就很远。
那 768 个数字到底是什么意思?
没人知道,也不需要知道。
这 768 个维度是模型自己在训练中学出来的, 某个维度可能恰好对应"动物性"、另一个可能对应"具体性"、 但大多数维度是几十种属性的混合, 人类无法直接解读,只能从它们的几何关系(哪些向量挨得近)反推。
从这一刻开始,模型始终都在操作这一串串数字。 所谓"模型理解了 X",背后无非是—— 模型把 X 这个 token 的向量,转成了某一个新向量。 所谓"模型把注意力转向了 Y",背后无非是—— 模型在加权混合的时候,给 Y 那个向量分配了高权重。
这也是对于 LLM 原理最通俗的理解—— 所有看起来神奇的结果,本质都是在数字上做加减乘除和混合。 没有秘密,只有规模。
二、位置编码:给"一袋词"装上顺序
把句子转成了向量之后,下一个问题是——顺序。
请想象一下:
- 「小李把书还给图书管理员」
- 「图书管理员把书还给小李」
这两句话用的 token 几乎一模一样, 但意思完全相反。 顺序决定意义。
但是——本章后面会讲到的 attention 机制,有一个先天缺陷: 它本身完全无视顺序。
attention 的原理就是把句子里所有 token 打散来处理,就像你把一幅拼图拆开成一片一片,全收进袋子里,它们的顺序都会被打乱。 对它来说,「小李把书还给图书管理员」和「图书管理员把书还给小李」 是完全一样的输入。
这显然不行。怎么办?
用一个"位置签名"解决
研究者想了一个朴素的办法—— 给每个位置盖一个唯一的"位置签名",把它加到那个位置的 embedding 上。
具体说:
- 第 1 个位置加上一个特定的数字序列 P₁
- 第 2 个位置加上 P₂
- 第 3 个位置加上 P₃
- ……
P₁、P₂、P₃ 这些"签名"是事先用一个数学公式(论文里用了一组 sin 和 cos 函数)生成的, 每个位置的签名独一无二,而且位置越接近的签名越像。
回到被分词器切好的例句:
[小, 李, 昨天, 买, 了, 一只, 小, 猫]
当 attention 看到「小」这个 token 时, 它实际收到的向量是「小」的语义向量 + 它所在位置的签名。
第 1 个位置的「小」和第 7 个位置的「小」, 对模型来说就是不同的输入——签名不一样。
位置编码的两种流派
原论文用的是正弦位置编码(Sinusoidal)——固定的数学公式,不参与训练。
后来主流模型(GPT、Llama、Claude)改用了**旋转位置编码(RoPE)**或它的变体, 直觉上一致——都是给每个位置一个独特签名, 只是数学形式不同、对长距离外推更友好。
时至今日,各种"百万 token 上下文"模型的背后, 就是各种位置编码的精巧改进。
走到这一步,模型手里拿着的,是一串既带语义、又带位置的向量。 "小李"知道自己是"小李", 也知道自己站在第 1 个位置, 而不是第 7 个。
万事俱备。接下来,它要做这一整套机器里最关键、也最容易被神化的那一步—— 让所有这些向量,互相对话。
这就是 attention。
三、Attention 到底在做什么
如果你之前听说过 attention,多半会同时听到三个神秘的字母:Q、K、V—— 分别是 Query(查询)、Key(键)、Value(值)的缩写, 是原论文里用来描述这套机制的标准记号。
但请把这套缩写先放在一边—— 它只是一种算法上的实现,不是 attention 的本质。 真正的本质要朴素得多:让每个词,从其它所有词那里借一点意义。
把这件事说清楚最快的方式,是回到主例句。 等直觉建立起来,再回头看 Q/K/V 是怎么对应进去的,就会一切自然。
一个具体的问题:「它」指什么?
小李昨天买了一只小猫,今天它就把家里的沙发抓
请你读到中间那个「它」时,停一下。
你的脑子里立刻就知道「它」指小猫,不是小李,也不是昨天、今天。 你是怎么知道的?
你回头扫了一眼「它」之前出现过的每个词, 对每一个 token, 都心算了一下「这个会不会是"它"的指代对象」:
| 候选 | 你心里给它的分数 |
|---|---|
| 小李 | 0.05(是个人,但中文「它」通常不指人类) |
| 昨天 | 0.01(时间词,不可能) |
| 买了 | 0.01(动词,不可能) |
| 一只 | 0.02(量词) |
| 小猫 | 0.70(动物 + 名词 + 刚被量词「一只」修饰过) |
| 今天 | 0.02 |
| ……(其余) | 接近 0 |
这张表里每一行的分数——就是你的"注意力权重"。 你最后理解的「它」= 这些权重 × 对应词的意义,加权混合的结果。 其中「小猫」占了 70% 的比重,所以你的大脑里「它」≈ 小猫。
Attention 机制做的就是这件事,只不过它对句子里的每一个 token 都做一遍。
Q/K/V:搜索引擎的隐喻
现在正式介绍 Q、K、V 三个字母。
这三个字母分别代表 Query(查询)、Key(键)、Value(值)。 它们最准确的类比是——搜索引擎。
想象你在 Google 上搜东西。整个过程涉及三个角色:
| 字母 | 全称 | 在搜索引擎里对应 | 在 attention 里对应 |
|---|---|---|---|
| Q | Query | 你在搜索框里输入的关键词 | 当前 token "想找什么" |
| K | Key | 互联网上每个网页的标签/索引 | 每个 token 胸前贴着的"我擅长提供什么" |
| V | Value | 网页的实际内容 | 每个 token 实际承载的语义信息 |
回到刚才那个例子。 当 attention 处理到「它」这个 token 时:
第一步——「它」举起一张 Query 牌子, 牌子上的意思(用人话翻译)是:「我是一个代词,我需要找一个之前出现过的、可以被指代的具体事物」。 这块牌子不是字,是一串数字(768 维向量)。
第二步——之前出现过的每个 token 都举起自己的 Key 牌子:
- 「小李」的 Key 说:"我是一个人,男性"
- 「小猫」的 Key 说:"我是一只动物,名词,刚被'一只'修饰过"
- 「昨天」的 Key 说:"我是一个时间词"
- 「今天」的 Key 说:"我是一个时间词"
- ……
模型把「它」的 Query 牌子和之前每一个 Key 牌子都做一次比对(数学上是点积), 得到一组相似度分数。 和 Query 越匹配的 Key,分数越高。 「小猫」的 Key 最契合,分数最高;「小李」次之(虽然中文「它」通常不指人,但同样是名词、是具体物体);其他几乎为 0。
第三步——把这组分数用 softmax 归一化成概率(加起来等于 1), 就得到了前面那张表里的"注意力权重"。
第四步——拿这些权重去加权混合每个 token 的 Value 向量。 每个 token 都有一个 Value 牌子,写着它实际能提供的"语义内容"。 「它」最终拿到的"新理解"= 0.05 × 小李的 Value + 0.01 × 昨天的 Value + ... + 0.70 × 小猫的 Value + ...
加权混合的结果是一个新向量, 这个新向量就是"它"在这个上下文中的全新表达—— 现在它的语义里 70% 都已经是"小猫"了。
这一切和搜索引擎的关键不同
到这里你可能会问:「这不就是个搜索引擎吗?」
不完全是。Attention 和搜索引擎有一个关键差异:
搜索引擎挑出最相关的 1 个(或 10 个)结果。Attention 把所有结果按权重混合成 1 个综合答案。
也就是说—— attention 不做"二选一",它做的是"按比例融合"。 即使「小李」只占 5% 的权重,那 5% 也真的会被混进去; 「它」最终的表达里多多少少都带着每一个上下文 token 的影子, 只是有的多有的少。
这正是 attention 比搜索引擎"软"的地方—— 它从不二选一,它永远是概率加权。 也正是因为这一点,模型能处理人类语言里大量的歧义、暗示、隐喻、双关。
一个延伸思考
回头看上面那个例子,如果把句子改成——
那只猫看着窗外的鸟,它一动不动。
「它」这次到底是猫还是鸟? 中文里两个解读都说得通——但「一动不动」对猫更合理一些(鸟动的概率稍大一些)。
Attention 给出的不是"猫"或"鸟"的二选一, 而是一个权重分布——大概 70% 是猫、25% 是鸟、5% 其他。 最终的「它」就是这个加权混合。
这就是为什么 LLM 写出来的文字常常保留了原文的暧昧性—— 因为它从根本上就是按概率混合,不是按规则选择。
Multi-Head:同时从不同角度看
到这一步,attention 的核心已经讲完了。 但论文里还有一个重要的设计叫 Multi-Head Attention(多头注意力)。
什么意思?
刚才描述的 attention 流程(Q-K 配对、加权混合 V), 就叫一个"头"(head)。
但模型实际上并行地运行很多个独立的头—— 原论文是 8 个,GPT-3 是 96 个,2026 年的前沿模型动辄上百个(例如 DeepSeek-V4-Pro 拥有 128 个注意力头)。
每个头都有自己独立的一套 Q、K、V 牌子, 所以每个头会学到一种不同的关注模式:
- 一个头可能专门关注指代关系(「它」配「小猫」)
- 另一个头可能关注语法依赖(动词配主语)
- 另一个头可能关注词义类型(同类名词互相关注)
- 还有的头可能关注位置距离(每个词只关注附近的词)
不需要人工告诉它每个头去关注什么—— 头之间分工是训练时自动浮现的。
最后,所有头的输出会被拼接起来再过一遍变换, 得到这一层 attention 的最终结果。
Self-Attention 是什么意思?
你可能在别处看过 "Self-Attention"(自注意力)这个词。
"Self" 的意思是——Q、K、V 都来自同一个序列。 也就是说,句子里的 token 都在互相关注(包括关注自己)。
与之相对的有 "Cross-Attention",是 Q 来自一个序列、K 和 V 来自另一个序列—— 原版翻译 Transformer 里就用了 cross-attention 让翻译输出去关注源语句。 现代纯生成的 LLM(GPT 系)基本只用 self-attention。
到这里,attention 这台机器你已经全部见过了。 但 Transformer 不只是 attention—— attention 算完之后,每个 token 拿到的"新理解"还要再经过几个加工步骤。
四、Transformer Block:一层之内的完整剧目
attention 解决了"让每个词从其它词那里借意义"的问题。 但仅靠 attention,模型其实还做不了任何事—— 借来的意义需要被加工、模型自己学过的世界知识需要被调用、 算到一半的数字需要被稳住, 否则向量越算越乱,整台机器再深一层就会散架。
所以原论文里在 attention 周围又加了三样东西: 前馈网络(FFN)、残差连接、LayerNorm。 这三样和 attention 一起,按一个固定顺序串起来—— 就构成了一个完整的 Transformer Block(Transformer 层)。
attention 的角色 §三 已经讲过了,下面把新加的这三样逐个拆开。 它们的重要程度并不对等: 其中一样(FFN)是真正干活的主角, 另外两样(残差、LayerNorm)是让深堆叠成为可能的基础设施。
真正的主角是 FFN——模型的"大脑皮层"
attention 算完之后,每个 token 拿到的是一个带着上下文重量的新向量。 以那个反复出现的「它」为例—— 它现在的内部已经混合了大约 70% 的"小猫"、5% 的"小李",其余则散落在各种零碎的上下文权重里。
但仅仅"知道上下文"还不够。 模型还得用上自己学过的所有世界知识,去给这个混合向量做进一步加工—— 判断"小猫抓沙发"是不是一件合理的事、推断接下来最可能发生什么、 回忆起它在训练时见过的几百万句类似句子……
这一步交给 FFN(Feed-Forward Network,前馈网络)。
FFN 长什么样:一升一降的两层网络
FFN 本身的结构出人意料地朴素——只有两层全连接夹一个非线性激活:
输入向量 (768 维)
│
│ W₁ ——把向量"升维"到一个很宽的中间层
▼
中间层 (3072 维,通常是输入的 4 倍宽)
│
│ ReLU / GeLU ——非线性激活,决定哪些维度"通电"
▼
被激活过的中间层 (只剩一部分维度是非零的)
│
│ W₂ ——把激活信号"降维"回原来的尺寸
▼
输出向量 (768 维)整个 FFN 只做了三件事:升维 → 激活 → 降维。 但关键的两个细节决定了它不简单:
- 中间层宽 4 倍——给了 FFN 一个非常大的"工作空间"
- 中间夹着非线性激活——没有这层非线性,两个全连接叠起来在数学上等价于一个全连接,等于什么都没做
这两层在干什么?把它读成一张"问答表"
要看懂 FFN 的原理,最直观的方式是把这两层各自重新解读一遍——
第一层 W₁(升维) 其实是在对输入向量同时问几千个问题:
"你像不像'第三人称代词在指代上文出现过的名词'?" "你像不像'某人养了宠物'?" "你像不像'小动物正要做出某个破坏性动作'?" ……
中间层有 3072 维,就相当于同时问 3072 个不同的问题。 和某个问题越像,那个维度上的数值就越大;完全不像,那个维度就接近 0 甚至是负数。
非线性激活(ReLU / GeLU) 就是这道"像 / 不像"的开关—— ReLU 把所有负数直接砍成 0;GeLU 是个更平滑的版本,作用类似。 弱信号被关掉,只有强匹配能继续往下传。 经过这一刀,3072 维中间层里只有一小部分维度仍然亮着,其余全是 0。
第二层 W₂(降维) 干的事是反过来的—— 它根据"哪些问题被点亮了",从一张事先学好的大表里取出对应的'答案向量',把它们加起来写回到 token 的语义空间。
「代词指代上文名词」那一格被点亮 → 把"它 → 小猫"这条线索叠加上去 「养宠物 + 宠物做事」被点亮 → 把"接下来该出现一个动作"的语义叠加上去 「猫常见的破坏性动作」被点亮 → 把"抓 / 咬 / 挠 / 后接'坏'或'破'"的语义叠加上去
合起来看,这两层做的事就一句话:
第一层判断这个 token 匹配上了哪些模式,第二层根据匹配上的模式追加相应的语义修改。
如果你愿意把它再压缩一句,那就是—— FFN 本质上是一张以"模式"为键、以"语义修改"为值的大型键值表, 查询方式就是上面这条"先升维问问题、激活后再降维取答案"的固定流程。
FFN 和 attention 的分工
回到那个反复出现的「它」—— attention 已经替它从前文里收集到了"我和小猫高度相关"的上下文信号, FFN 接过这个信号,要做的事是:
- 在自己存着的几千条"模式 → 语义"规则里翻一翻
- 找到几条最匹配的:「代词指代上文名词」「人和宠物的常见动作搭配」「'今天'+'就'暗示动作刚发生」……
- 把这些规则对应的语义修改叠加回「它」的向量
到下一层 attention 开始之前,「它」就不再只是"和小猫相关", 而是被加上了"指代上文名词、参与一段叙事、和宠物动作有关"的更明确的语义标签。
如果说 attention 是"群聊"——每个 token 之间互通信息, 那 FFN 就是"独处 + 查记忆"——每个 token 关上门,对自己的状态做一遍知识检索和加工。 群聊一轮、查一次记忆,正是 Transformer 学习的核心节奏。
一个常被低估的事实:参数量几乎全在 FFN 里
明白了 FFN 的结构,就能理解一件容易被忽略的事——
模型里真正占参数量的,不是听起来更玄的 attention,而是这两层 FFN。 原因很直接:FFN 中间层宽 4 倍, 所以 W₁、W₂ 这两块矩阵各自的参数量都比 attention 里同尺寸的矩阵大 4 倍上下。 全模型加总,FFN 大约占去 60-70% 的总参数。 GPT-3 那 1750 亿参数里,绝大部分都在 FFN。
为什么现在的模型参数规模越来越大?
2021 年起,Geva 等人通过内部探针实验给 FFN 的"键值表"解读补上了直接证据—— 他们发现中间层的某些维度被激活时, 会专门把某一类后续 token 的概率推高 (比如一旦"小动物 + 抓"的模式被点亮,「坏」「破」这类词的概率就会被显著拉升); 另一些维度被激活时,会专门让模型倾向于某种句式或语气。 也就是说,中间层的每一个维度, 都对应着一条具体的事实或语言模式。
这背后藏着一条朴素的等式:
模型参数 ≈ FFN 参数 ≈ 模型记得的事实和模式的总量
所以"把模型做大几乎永远奏效"—— 做大的本质,是给 FFN 增加更多的"问答槽位"。 后面几乎所有"模型越大越聪明"的故事, 都可以在脑子里翻译成:FFN 的键值表又扩容了一次。
参考:Geva et al., Transformer Feed-Forward Layers Are Key-Value Memories, EMNLP 2021.
基础设施:残差连接 + LayerNorm——让深堆叠成为可能
知道了 FFN 是主角,剩下两件东西就很好理解了—— 它们都是为了让 Transformer 能堆得很深而存在的隐形支柱。 不增加智能,但没有它们,今天上百层的 LLM 根本无法训练。
残差连接(Residual Connection) 解决的问题是「信息会不会被冲淡」。 attention 把一个 token 跟全句加权混合之后, 原本这个 token 自己的身份很可能被覆盖。 研究者的办法朴素到几乎可笑: 把混合前的原始向量保留下来,直接加回到混合后的新向量上。 就像改稿子时另抄一份原稿放旁边—— 万一这一层学糟了,原稿至少还在,下一层接着改还有救。
LayerNorm(层归一化) 解决的是「数字会不会越算越炸」。 每层算完之后,那一串数字往往会失控—— 有的维度变成几千,有的几乎为 0。 这种数值失控像滚雪球,下一层就会算出更离谱的结果。 LayerNorm 的工作就是把这一层的所有数字重新缩放到一个温和的范围, 洗完澡再走进下一层。
这两样单独看都不起眼, 但合起来回答了一个非常重要的问题—— 为什么 2017 年之后突然能训练几十、上百层的网络了? 答案是因为残差连接(2015)和 LayerNorm(2016)这两块基础设施恰好在 Transformer 之前一两年成熟了。 没有它们,attention 再聪明也只能停留在三五层的小模型。
一层走完,把它重复 N 次
至此,一层 Transformer Block 已经完整走完:
Attention(群聊)→ 残差 + LayerNorm → FFN(独处 + 调用知识)→ 残差 + LayerNorm
但完整的模型从来不止一层。 它把上面这套原样堆叠 N 次:
- 原论文:N = 6
- BERT-base:N = 12
- GPT-3:N = 96
- 2026 年的前沿模型:动辄上百层
每多一层,相当于让模型对同一句话再做一轮"读 + 想"—— 每一轮都在上一轮的基础上再向前推进一步。
研究者通过"探针实验"反推过每一层大致在干什么——
- 第 1 层可能只学到"哪些词是名词、哪些是动词"
- 第 5 层可能开始学习"哪些词指代哪些词"(也就是 §三 那个「它」的问题)
- 第 20 层可能在追踪整段话的情感和语气
- 第 50 层甚至可能在揣摩作者真正想表达的意图
层数越深,能捕捉的模式越抽象。 这正是过去八年最朴素也最有效的一条进步路线—— 把模型做大、做深。 配合刚才那条 FFN 的规律—— "做大 = 给 FFN 增加记忆插槽"、 "做深 = 让模型对同一段话做更多轮的读与想"—— 你就握住了理解过去八年 LLM 进化史的两把最关键的钥匙。
五、输出端:从向量到下一个词
当一句话经过了所有 N 层 Transformer Block 之后, 输出的是一串最终的向量——每个位置一个向量。
要预测下一个词,所以重点关注最后一个位置的那个向量。
这个向量经过一个叫 LM Head(Language Model Head,语言模型头) 的简单层, 变成一个和词表一样长的概率分布——
词表里每个 token 都得到一个分数, 全部相加后永远等于 1。
把我们之前的例句完整喂进去——
小李昨天买了一只小猫,今天它就把家里的沙发抓
它的最后一个 token 正是「抓」。 模型站在「抓」之后, 要从词表的几万个 token 里给每一个打分, 得到的概率分布大概长这样:
| 候选 token | 概率 | 说明 |
|---|---|---|
| 坏 | 0.61 | 「抓坏」是这种叙事节奏下最自然的搭配——主语是小猫、宾语是沙发,结果"坏"几乎是默认结局 |
| 破 | 0.18 | 「抓破」也很常见,尤其是沙发这种布面/皮面家具 |
| 烂 | 0.05 | 「抓烂」更口语,也合理 |
| 了 | 0.04 | 「抓了」直接收尾,"抓了一下"这种开头 |
| 伤 | 0.02 | 「抓伤」("抓伤"主人胳膊那种语境,但宾语已经是"沙发",所以低) |
| 出 | 0.01 | "抓出洞来"这种延展 |
| ……(其余几万个) | 总和 0.09 | — |
注意一件事—— 模型并不知道这句话之后"该写什么"。 它只是基于训练时见过的几百亿句话, 推断「在『小李买了猫……它就把家里的沙发抓』之后,人类最常写哪个 token」。 「坏」之所以排第一,不是因为模型懂"小猫真的能抓坏沙发",而是因为这条搭配在训练语料里出现过太多次。
到这一步,模型完成了它的任务—— 告诉你下一个 token 的概率分布。
采样(Sampling)
模型如何从上文说的概率分布中挑选出最合适的词?是按概率最高的挑?还是按概率分布随机抽?还是只在前几个里抽? 这背后就是 Temperature、Top-P、Top-K 这些你在 SillyTavern 里调过的参数。
关于采样,本章不做赘述,之后会有专门的章节带你详细了解各采样参数的作用。
六、三大变体:Encoder / Decoder / Decoder-only
前面拆解的,是 Transformer 的通用机制。 但实际部署的模型有三种不同的"形态", 它们决定了模型能做什么任务。
原版:Encoder + Decoder(编码器 + 解码器)
2017 年原论文要做的任务是机器翻译——把英语翻成德语。
它的结构是这样的:
- Encoder(编码器):读完整句英文,把它"压缩"成一组带语义的向量
- Decoder(解码器):根据 Encoder 的输出,逐个生成德文 token
Encoder 和 Decoder 都是由 N 层 Transformer Block 堆出来的, 区别只在于 Decoder 多了一个 cross-attention 让它去"看" Encoder 的输出。
今天还能见到这种结构的,主要是翻译模型和某些多模态模型。
BERT:仅 Encoder(理解任务)
2018 年 Google 把 Encoder 单独拿出来,做了 BERT。
BERT 只用 Encoder 部分,专门做理解类任务—— 情感分析、文本分类、问答(找答案,不是生成答案)、命名实体识别。
它的特点是双向—— 每个 token 在算 attention 时,可以同时看到自己前后的所有 token。 这对"理解"来说很自然——人类读一句话也是前后都看。
但 BERT 不会"生成"——它做不到接着一句话往下写。
GPT、Claude、Gemini、DeepSeek、Llama……:仅 Decoder(生成任务)
2018 年 OpenAI 反方向操作——他们只用 Decoder 部分,做出了 GPT-1。
仅 Decoder 的结构专门做生成—— 给一段话,让它接着写下去。
这种结构有一个关键约束叫 Causal Mask(因果掩码):
每个 token 在算 attention 时,只能看到自己和自己之前的 token,不能看到后面。
为什么?因为生成时本来就还没有"后面"—— 模型一个 token 一个 token 地往外写, 它生成第 5 个 token 时,第 6、7、8 个还不存在。
所以训练时也要模拟这种情况:把"未来"遮住, 强迫模型只根据"过去"做预测。
这就是今天所有 LLM 的统治形态——Decoder-only + Causal Mask。 ChatGPT、Claude、Gemini、DeepSeek、Llama、千问、豆包—— 全都是 Decoder-only。
为什么是它赢了?
- 结构简单:只有一种 attention,不需要 cross-attention
- 训练简单:一种目标——预测下一个 token——就能解决一切
- 可扩展性最好:模型一变大就涨分,没有架构瓶颈
那为什么不用 Encoder-Decoder 做生成?
其实有人做过——Google 的 T5、UL2 都是 Encoder-Decoder 生成模型, 某些任务上表现也很好。
但 Decoder-only 的胜出是因为预训练范式更简洁—— "预测下一个 token" 这一个任务,可以吃下整个互联网的所有文本, 不需要 input/output 配对的数据。 这让 Decoder-only 在数据规模和扩展性上赢在了起跑线。
七、写给下一章
陪着「小李昨天买了一只小猫,今天它就把家里的沙发抓」这句没写完的话走完了一整趟旅程—— 从汉字到 token、从 token 到向量、过完 attention 的群聊与 FFN 的独处, 最后在「抓」字之后停下,吐出一组概率:「坏」的概率最高、「破」次之,其余几万个 token 共享剩下的可能性。
整台机器,到这里你已经亲眼见过它的每一个房间。
接下来,我们要先回到历史—— 看看人类把这台机器抓到手之后, 都对它做了一些什么样最大胆的事。
下一章,我们从 2018 年的 GPT-1 出发,一路走到 2026 年的 GPT-5.5—— 看 GPT 系列是如何把这台机器越做越大、最终做到改变世界的。
要点回顾
- 一切都是数字:模型从未见过文字,它处理的全是向量。token 是它的眼睛,embedding 是它的母语。
- attention 本身完全不知道顺序——它会把"小李把书还给图书管理员"和"图书管理员把书还给小李"看成同一句话。是位置编码给了它分辨先后的能力。
- attention = 加权混合上下文——每个 token 都向所有相关 token "借一点意义",按相关度加权融合。它从不在两个候选里二选一,永远是按概率混合。
- Q/K/V 只是 attention 的算法实现,不是它的本质——本质就是"借一点意义"这件事
- FFN 是 Transformer Block 真正的主角——它是模型存放世界知识的"键值表",参数量占全模型 60-70%
- 残差连接 + LayerNorm 是基础设施——它们不增加智能,但没有它们就堆不起几十、上百层的网络
- 一层 Transformer Block = "群聊(attention)+ 独处查记忆(FFN)+ 两次基础设施修正",把它原样堆 N 次就是完整的模型
- Decoder-only + Causal Mask 是今天所有 LLM 的统治形态——只看过去、不偷看未来,一个 token 一个 token 地往外写
- 模型输出的永远是一个概率分布,而不是"那个答案"——选哪个,是采样的事。
参考文献
- Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., Kaiser, Ł., & Polosukhin, I. (2017). Attention Is All You Need. In Advances in Neural Information Processing Systems (NIPS), pp. 5998–6008. arXiv:1706.03762.
- Ba, J. L., Kiros, J. R., & Hinton, G. E. (2016). Layer Normalization. arXiv:1607.06450.
- He, K., Zhang, X., Ren, S., & Sun, J. (2016). Deep Residual Learning for Image Recognition. CVPR.
- Devlin, J., Chang, M.-W., Lee, K., & Toutanova, K. (2018). BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. arXiv:1810.04805.
- Radford, A., Narasimhan, K., Salimans, T., & Sutskever, I. (2018). Improving Language Understanding by Generative Pre-Training. OpenAI.
- Su, J., Lu, Y., Pan, S., Murtadha, A., Wen, B., & Liu, Y. (2021). RoFormer: Enhanced Transformer with Rotary Position Embedding. arXiv:2104.09864.
- Sennrich, R., Haddow, B., & Birch, A. (2016). Neural Machine Translation of Rare Words with Subword Units. ACL.
- Geva, M., Schuster, R., Berant, J., & Levy, O. (2021). Transformer Feed-Forward Layers Are Key-Value Memories. EMNLP. arXiv:2012.14913.