第三章 · 大语言模型基础(详尽展开版)
📌 本章定位 :前两章讲了"智能体是什么、怎么发展来的"。本章彻底聚焦一个问题------**现代智能体的"大脑"(大语言模型)到底是怎么工作的?** 学完这章,你要建立一条清晰的技术链:
统计语言模型 → 神经网络/词嵌入 → RNN/LSTM → Transformer → Decoder-Only → 提示工程 → 分词 → 本地部署 → 模型选型 → 缩放法则与幻觉
3.1 语言模型演进:从统计到深度学习
3.1.1 统计语言模型与 N-gram
📖 原文核心
语言模型的根本任务是计算一个词序列(句子)出现的概率。好模型能告诉我们"什么样的句子是通顺的"。
🔍 展开讲解
1. 链式法则------理论上完美,实践上爆炸
原文公式:
P(S)=P(w1)⋅P(w2∣w1)⋅P(w3∣w1,w2)⋅⋅⋅P(wm∣w1,...,wm−1)
含义很直观:一个句子出现的概率 = 每个词在它前面所有词的条件下的概率连乘。
问题 :条件越长,这个概率越难从语料里统计出来。比如要算"我喜欢吃妈妈做的红烧肉"中"红烧肉"的概率,你得统计前面 9 个词的全部组合,绝大多数组合在语料里一次都没出现过(术语叫"数据稀疏")。
2. 马尔可夫假设------大胆截断历史
核心思想:一个词的出现概率,只看前面有限的 n-1 个词,更远的历史忽略不计。
| 模型 | 假设 | 例子 |
|---|---|---|
| Unigram | 每个词独立 | P(我)P(喜欢)P(你) |
| Bigram | 只看前1个词 | P(喜欢 |
| Trigram | 只看前2个词 | P(你 |
马尔可夫假设示意图
3. 最大似然估计------用"数数"代替复杂计算
原文例子用 datawhale agent learns 和 datawhale agent works 两句话演示,过程很清楚:
-
P(datawhale) = 2/6 ≈ 0.333
-
P(agent|datawhale) = 2/2 = 1
-
P(learns|agent) = 1/2 = 0.5
-
最终概率 = 0.333 × 1 × 0.5 ≈ 0.167
4. N-gram 的两个致命缺陷(⚠️ 重点)
| 缺陷 | 说明 |
|---|---|
| 泛化能力差 | 没见过的词对概率直接为 0,模型"死记硬背" |
| 维度灾难 | n 越大,需要统计的参数越多,语料永远不够 |
这就引出了下一步:用神经网络把词变成"向量",让没见过的词也能有合理的概率。
✅ 本节知识总结
一句话:N-gram 用"数数"算概率,简单但记不住新东西。
关键词:链式法则、马尔可夫假设、最大似然估计、数据稀疏、泛化能力差。
承上启下:正因为 N-gram 把词当孤立符号,才有了"词嵌入"的革命。
🧠 思维导图(文字版)
语言模型
├── 根本任务:计算 P(句子)
├── 链式法则:P(S) = ∏ P(wi | w1...wi-1)
├── 马尔可夫假设(截断历史)
│ ├── Unigram:不看历史
│ ├── Bigram:看前1个词 ✅ 文中示例
│ └── Trigram:看前2个词
├── 参数估计:最大似然估计(计数/总数)
└── 致命缺陷
├── 泛化差(未见词对 = 0)
└── 维度灾难(参数随 n 指数增长)
↓ 引出
神经网络语言模型 + 词嵌入
3.1.2 神经网络语言模型与词嵌入
📖 原文核心
2003 年 Bengio 等人里程碑式工作:把词变成连续向量(词嵌入),用神经网络预测下一个词。
🔍 展开讲解
1. 为什么"词嵌入"是革命性的?
N-gram 把词当"离散符号"------"国王"和"王后"在字面上毫无关系。词嵌入的核心洞察是:
词义 = 向量空间中的位置。语义相近的词,向量也离得近。
2. 网络结构
输入层 → 查表得到词嵌入 → 拼接 → 隐藏层(tanh) → 输出层(softmax) → 预测下一个词
关键:词嵌入矩阵 C 是和神经网络一起"训练出来"的。为了完成"预测下一个词"这个任务,模型会自动把语义相近的词在向量空间里拉近。
神经网络语言模型架构示意图
1. 用前几个词预测下一个词
图左侧是输入:
Wt−n+1,Wt−n+2,…,Wt−1可以理解为:模型拿到了一个滑动窗口里的历史词序列,比如:
"人工智能可以帮助人类"
如果目标是预测下一个词,模型可能用:
人工智能, 可以, 帮助, 人类
去预测:
Wt
也就是图中右侧输出的 y^,最终对应预测词 Wt。
所以核心任务是:
给定前 n-1 个词,预测下一个词是什么。
这和传统 N-gram 很像,但实现方式不同:
N-gram:靠统计共现频率,比如"帮助 人类 的"出现多少次;
神经网络语言模型:把词变成向量,再用多层神经网络学习上下文到下一个词的概率映射。
2. 输入层:词不再是编号,而是向量
图左边标了:
Input Layer
X=A0
这里的输入 X 不是原始文本,也不是简单的 one-hot 编号,而是经过词嵌入后的向量表示。
早期神经网络语言模型的一个关键创新就是:词嵌入是在训练过程中自动学出来的。
也就是说,模型一开始并不知道:
"agent" 和 "robot" 语义接近;
"apple" 作为水果和 "orange" 接近;
"apple" 作为公司名可能和 "Google"、"Microsoft" 有一定关联。
但通过大量语料训练,为了更好预测下一个词,模型会调整每个词的向量位置,使得经常出现在相似上下文里的词,向量也越来越接近。
例如:
"国王 - 男人 + 女人 ≈ 女王"
"北京 - 中国 + 法国 ≈ 巴黎"
"agent" 和 "assistant"、"bot"、"robot" 在向量空间中距离较近
这就是文中说的:
构建一个语义空间,把每个词映射为高维向量;语义相近的词,向量位置也相近。
3. 隐藏层:多层非线性变换提取上下文模式
图中间是:
Hidden Layers
A1,A2,A3
每一层都有多个神经元:
a1[1],a2[1],…,an[1]
a1[2],a2[2],…,an[2]
a1[3],a2[3],…,an[3]这些层之间是全连接结构:前一层的每个神经元都会连到后一层的很多神经元。
它的作用是做非线性特征变换。
简单理解:
输入层负责把词变成向量;
第一层隐藏层可能捕捉局部组合特征;
第二层隐藏层组合更高阶的模式;
第三层进一步抽象上下文表达。
比如输入是:
"智能体可以执行任务"
模型可能学到:
第一层:识别词与词之间的局部搭配;
第二层:理解"智能体 + 执行"这种动作关系;
第三层:形成更适合预测下一个词的上下文表示。
不过要注意,这张图是前馈神经网络 / 多层感知机结构 ,不是 RNN,也不是 Transformer。它处理序列的方式通常是:固定窗口输入。
也就是它只看前 n-1 个词,不会像 RNN 那样真正"记忆"任意长历史,也不像 Transformer 那样用自注意力动态看整段上下文。
4. 输出层:Softmax 把分数变成概率分布
图右侧是:
Output Layer
Softmax
y^
Wt
输出层通常会对应整个词表。假设词表有 10 万个词,那么输出层就会有 10 万个维度,每个维度代表"下一个词是某个词的概率"。
Softmax 的作用是:
把任意实数分数转换成合法概率分布。
例如模型输出可能是:
候选词 原始分数 Softmax 概率 任务 5.2 0.45 代码 4.1 0.18 苹果 0.3 0.01 天气 0.1 0.008 经过 Softmax 后,所有词的概率加起来等于 1。
模型最终选择概率最高的词,或者按概率采样一个词作为 Wt。
这也对应文中说的:
学习一个函数,输入是前 n-1 个词的词向量,输出是词汇表中每个词作为下一个词的概率分布。
5. 为什么词嵌入比 N-gram 强?
传统 N-gram 有个问题:稀疏性。
比如:
"人工智能可以帮助人类"
如果训练数据没见过"人工智能可以帮助人类完成某任务"这个完整 4-gram,模型就可能认为它概率为 0 或很低。
但词嵌入模型不一样。它学到的是连续向量空间中的相似关系。
"帮助人类完成"和"帮助用户完成任务"虽然有不同词,但向量空间里可能很接近,因此模型可以泛化。
可以理解为:
N-gram:靠"精确匹配片段";
词嵌入神经网络:靠"语义近似匹配 + 模式泛化"。
这也是神经网络语言模型的重要进步。
6. 余弦相似度怎么衡量词向量关系?
文中提到余弦相似度。它的直观含义是:
看两个向量方向有多接近。
公式大致是:
cos(A,B)=∥A∥∥B∥A⋅B结果范围通常在 −1,1:
接近 1:方向很接近,语义/用法相似;
接近 0:关系不大;
接近 -1:方向相反/差异很大。
比如:
cos(agent,robot) 可能较高;
cos(agent,apple) 可能较低;
cos(king,queen) 会比 cos(king,car) 高。
但要注意:向量接近不一定等于人类意义上的"同义",也可能是句法角色、搭配环境、领域用法接近。
7. 这张图和现代 LLM 的关系
这张图代表的是比较早期的思想:
固定窗口上下文 + 词嵌入 + 全连接隐藏层 + Softmax 预测下一个词。
现代大语言模型在此基础上发展了很多:
RNN / LSTM / GRU
引入循环结构,处理更长序列;
但仍受限于长距离记忆和并行效率。
Transformer
用自注意力机制代替全连接固定窗口;
可以动态关注上下文中任意位置;
更适合大规模训练。
Decoder-Only GPT 类模型
核心仍然是"预测下一个 token";
但用了海量数据、超大规模参数、自注意力、残差连接、LayerNorm、RoPE/位置编码等。
所以可以说:
这张图里的"词嵌入 + 下一个词预测"思想,一直延续到了今天的 LLM,只是模型结构、规模、上下文建模能力大大升级了。
3. 仍有限制:固定上下文窗口
和 N-gram 一样,只能看前面固定数量的词。这引出了 RNN。
✅ 本节知识总结
一句话:词嵌入把"符号"变成"向量",让模型能理解语义。
关键词:词嵌入(Word Embedding)、查表、余弦相似度、语义类比、固定窗口限制。
经典结论:King - Man + Woman ≈ Queen。
🧠 思维导图
神经网络语言模型
├── 核心创新:词嵌入(连续向量表示词)
├── 训练方式:预测下一个词(任务驱动)
├── 网络结构
│ ├── 输入 → 词嵌入查表
│ ├── 拼接 → 隐藏层(tanh)
│ └── 输出层(softmax) → 预测
├── 词嵌入的性质
│ ├── 语义相近 → 向量相近
│ └── 支持类比运算(King-Man+Woman≈Queen)
├── 度量方式:余弦相似度
└── 遗留问题:上下文窗口固定
↓ 引出
RNN / LSTM(循环结构,处理任意长度)
3.1.3 RNN 与 LSTM
📖 原文核心
RNN 引入"隐藏状态"作为记忆,理论上能处理任意长序列;LSTM 用门控机制解决 RNN 的"长期依赖"难题。
🔍 展开讲解
1. RNN 的核心结构
RNN结构示意图
每个时间步 t:
-
输入:当前词 xt + 上一时刻隐藏状态 ht−1
-
输出:当前隐藏状态

-
ht 同时传给下一步和输出层
直觉理解:隐藏状态 ht 就是模型的"短期记忆",随着时间步不断滚动更新。
输出解析:
这个公式就是 RNN 在一个时间步里"脑子里发生了什么"的数学表达。我把它拆成"零件 → 组装 → 直觉"三层讲,你马上就能懂。
1. 先认清楚公式里每个符号是谁
符号 是什么 直觉比喻 xt 当前时间步输入的词向量(比如"我") 这一秒看到的信息 ht−1 上一时刻的隐藏状态 上一秒脑子里的记忆 Wxh 输入到隐藏状态的权重矩阵 "怎么把新词变成记忆的一部分" Whh 上一隐藏状态到当前隐藏的权重矩阵 "旧记忆有多少要留下来" b 偏置项 基础音量/底色 tanh 双曲正切激活函数,输出在 -1, 1 防止数值爆炸,保持信息压缩 ht 当前新的隐藏状态 这一秒更新完的短期记忆
2. 公式在算什么(一步一步)
第一步:把"新输入"加工一下
xt 是当前词向量(比如 300 维)
乘一个矩阵 Wxh,把它投影/压缩成和隐藏状态同维度的东西
意义:"当前这个词,对记忆有什么贡献"
第二步:把"旧记忆"加工一下
上一刻的记忆 ht−1 乘另一个矩阵 Whh
意义:"上一步记住的东西,哪些还要继续带着走"
第三步:两股信息加起来,再加偏置
新信息 + 旧记忆 + 一点基础偏移
此时得到一个"原始混合记忆",但数值可能很大或很小
第四步:过 tanh 压缩
tanh(上面那坨)
tanh 把任何实数压到 -1, 1
作用:
防止数值越滚越大(梯度爆炸)
让不同时间步的信息尺度一致
引入非线性,使 RNN 能拟合复杂模式
最终结果
ht=压缩后的“新记忆”
3. 用一句话翻译这个公式
当前隐藏状态 = 把"当前词"和"上一刻记忆"按可学习的方式混合后,再压缩一下的结果。
或者更白话:
模型每秒都做一件事:
"我看了一眼新词(xt),又回顾了一下刚才在想啥(ht−1),把两者搅在一起,过一道 tanh 过滤,变成这一刻的新想法(ht)。"
4. 为什么叫"滚动更新"
时间步推进时:
h0 = 初始记忆(通常全0) h1 = tanh(Wxh·x1 + Whh·h0 + b) h2 = tanh(Wxh·x2 + Whh·h1 + b) h3 = tanh(Wxh·x3 + Whh·h2 + b) ...每一个新 ht 都依赖前一个 ht−1,像滚雪球一样把历史压进一个固定大小的向量里。
这就是你说的:
隐藏状态 ht 就是模型的"短期记忆",随着时间步不断滚动更新。
2. 长期依赖问题(⚠️ 重点)
原文讲得很清楚:反向传播时,梯度要沿着时间步一路乘回去。
-
序列长 → 连乘次数多
-
权重 < 1 → 梯度趋向 0(梯度消失)→ 学不到远距离关系
-
权重 > 1 → 梯度爆炸
结果:RNN 能记住"近处"的词,但"远处"的词影响传不回来。
理解部分:
这是 RNN 最经典、也最容易"看懂字面但没建立直觉"的一点。我用一条时间线 + 一个具体例子 + 反向传播的乘法链三层来讲,你看完能直接复述给别人。
1. 先建立正向直觉:RNN 怎么"记东西"
RNN 每个时间步:
h_t=tanh(W_xh*x_t+W_hh*h_(t−1)+b)关键信息在 W_hh*h_(t−1) 这一项:
上一步的记忆 h_(t−1) 乘一个矩阵 W_hh 再传过来
所以"远处的信息"必须一步步借由 h 往前传
比如句子:
"小明小时候住在北京,......(中间 50 个词)......所以他说话带点北京口音。"
要让模型在句尾猜"口音"相关词,它得把"北京"这个信息从 t=1 一直带到 t=50。
这条路不是直连的,是:
h1→h2→h3→⋯→h50每一步都过一次 W_hh 和 tan(h)。
2. 反向传播时,梯度是怎么传的(核心)
训练时算梯度,要用链式法则从损失 L 反推到早期参数。
对"早期隐藏状态" h1 的梯度,粗略可以写成(忽略 tanh 导数细节):
∂h1∂L∝∂h49∂h50⋅∂h48∂h49⋅⋯⋅∂h1∂h2而每一步:
∂ht−1∂ht≈Whh⊤⋅diag(tanh′(Wxhxt+Whhht−1+b))重点来了:
连乘的是矩阵(或近似标量)Whh 和相关导数,乘了几十次。
3. 两种悲剧:消失 vs 爆炸
情况 A:权重"整体收缩" → 梯度消失
如果 Whh 的特征值 小于 1(最常见情况,因为要稳定),再乘上 tanh′(最大值才 1,大部分时候更小):
乘 1 次:0.8
乘 10 次:0.810≈0.107
加 30 次:0.830≈0.001
乘 50 次:几乎是 0
结果:
句尾损失对"北京"那个位置的梯度 ≈ 0
参数几乎不更新
模型"学不到"远距离因果关系
👉 这就是梯度消失 → 长期依赖失败
情况 B:权重"整体放大" → 梯度爆炸
如果 W_hh 特征值 大于 1:
乘 10 次:1.210≈6.2
乘 30 次:1.230≈237
乘 50 次:天文数字
梯度直接 NaN 或震荡,训练崩掉。
👉 这就是梯度爆炸(现在常用梯度裁剪治,但消失更难治)
4. 用"传话游戏"比喻(最好记)
把 RNN 想象成一排人传话:
第一个人看到"北京",小声告诉第二个人
第二个人再小声告诉第三个(声音 ×0.8)
传到第 50 个人时,声音几乎没了 → 梯度消失
如果每人反而大声一点(×1.2),第 50 人聋了/喊破喉 → 梯度爆炸
RNN 没有"扩音器",也没有"直接打电话给第 50 人"的能力,只能挨个传。
5. 为什么"近处能学,远处学不到"
相邻词(t 和 t-1):梯度连乘 1 次,信号强 → 能学"帮助→人类"
隔 10 个词:连乘 10 次,信号衰减明显
隔 50 个词:连乘 50 次,梯度≈0 → "北京"影响不到"口音"
所以 RNN 实际表现:
语法局部搭配还行(就近原则)
跨段落指代、长程因果、篇章主题,基本废
6. 这句话你原文里写的对,但要补一句"为什么是乘法"
反向传播时,梯度要沿着时间步一路乘回去。
序列长 → 连乘次数多
权重 < 1 → 梯度趋向 0(梯度消失)
权重 > 1 → 梯度爆炸
结果:RNN 能记住"近处"的词,但"远处"的词影响传不回来。
补一个本质句:
因为 RNN 把长距离依赖压进了一条共享权重的递归连乘链,信息要么被指数压缩、要么被指数放大,很难在中长距离保持稳定传递。
一张极简思维图
长期依赖问题
├── 正向:远处信息必须逐跳经 h_t 传递
├── 反向:梯度沿时间连乘 W_hh
│ ├── |W_hh|<1 → 连乘→0 → 梯度消失(常见)
│ └── |W_hh|>1 → 连乘→∞ → 梯度爆炸
├── 现象:近处词影响大,远处词梯度≈0
└── 后果:学不会"开头决定结尾"的长程关系
↓ 解法
LSTM(门控记忆)
Transformer(注意力直达)
一句话收口:
RNN 的长期依赖问题,本质是**"用一条共享权重的递归链路传梯度和记忆,而链式连乘会让信号指数级衰减或膨胀"**------所以它能听懂隔壁词,却记不住一段话开头说了啥。
3. LSTM 的三道门(⚠️ 核心创新)

初看起来非常复杂。让我们忽略中间部分,只看单元的输入和输出。网络有三个输入,𝑋𝑡 是当前的输入;ℎ𝑡−1 是上一个 LSTM 单元的输出;𝐶𝑡−1 是我认为最重要的输入------上一个 LSTM 单元的"记忆"。ℎ𝑡 是当前网络的输出,𝐶𝑡 是当前单元的记忆。
所以,一个单元接收当前的输入、前一个输出和前一个记忆做出决策,并且产生新的输出,更新记忆。

中间部分记忆 𝐶𝑡 产生变化的方式非常类似于从管道中导出水流。把记忆想象成管道中的水流。你想要改变记忆流,而这种改变有两个阀门控制。
第一个阀门是遗忘阀门。如果你关掉阀门,旧的记忆不会被保留;如果完全打开,旧的记忆就会完全通过。
第二个阀门是新记忆阀门。新的记忆会通过一个 T 形连接,并于同旧的记忆混合。第二个阀门决定要通过多少新的记忆。

在图示中,顶部的管道是记忆管道。输入是旧的记忆(以向量的形式)。通过的第一个 × 是遗忘阀门,事实上这是一个逐点乘法运算。如果你将旧的记忆 𝐶𝑡−1 与一个接近 0 的向量相乘,这意味着你想要忘记绝大部分记忆。如果你让遗忘阀门等于 1 ,旧的记忆就会完全通过。
记忆流通过的第二个运算是加法运算符 +,即逐点相加,它的功能类似 T 形连接。新旧记忆通过这个运算混合。另一个阀门控制多少新的记忆来和旧的记忆混合,就是 + 下面的 ×。
两步运算之后,你就将旧的记忆 𝐶𝑡−1 变成了新的记忆 𝐶𝑡。

现在让我们看看阀门。第一个阀门称为遗忘阀门。它由一个单层神经网络控制。它的输入是 ℎ𝑡−1(前一个 LSTM 模块的输出)、𝑋𝑡(当前 LSTM 模块的输入)、𝐶𝑡−1(前一个模块的记忆)和最终的偏移向量 𝑏0。这个神经网络有一个 S 形激活函数,它的输出向量是遗忘阀门,用来和旧的记忆 𝐶𝑡−1 做逐点乘法。

第二个阀门称为新记忆阀门。它也是一个单层神经网络,接收的输入和遗忘阀门一样。这个阀门用来控制多少新的记忆用来影响旧的记忆。
但是,新的记忆却由另一个神经网络产生。这也是一个单层神经网络,但是用 tanh 作为激活函数。这个神经网络的输出将会和新记忆阀门的输出做逐点乘法,然后和旧的记忆相加产生新的记忆。

上图中:两个 × 分别是遗忘阀门和新记忆阀门。

最终,我们需要产生这个 LSTM 单元的输出。这一步有一个输出阀门,它被新的记忆、前一个输出 ℎ𝑡−1、当前输入 𝑋𝑡 和偏移向量共同控制。这个阀门控制向下一个 LSTM 单元输出多少新的记忆。
LSTM创新点
LSTM 在 RNN 基础上加了细胞状态(Cell State) 和三道门:
| 门 | 作用 | 直觉比喻 |
|---|---|---|
| 遗忘门 | 决定从细胞状态里丢掉什么 | "这段记忆不重要,忘掉" |
| 输入门 | 决定把什么新信息写进细胞状态 | "这条新信息值得记住" |
| 输出门 | 决定当前时刻对外输出什么 | "现在该说出哪部分记忆" |
数学上(了解即可):
-
ft=σ(Wf⋅ht−1,xt+bf) 遗忘门
-
it=σ(Wi⋅ht−1,xt+bi) 输入门
-
ot=σ(Wo⋅ht−1,xt+bo) 输出门
-
Ct=ft∗Ct−1+it∗C~t 更新细胞状态
-
ht=ot∗tanh(Ct) 输出
关键优势:细胞状态像一条"高速公路",信息可以不经 tanh 直接流过,梯度不容易消失。
4. 仍有限制:无法并行
RNN/LSTM 必须一步一步算,第 t 步依赖第 t-1 步,无法像 CNN 那样并行。这成为大模型时代的致命瓶颈,最终被 Transformer 取代。
✅ 本节知识总结
一句话:RNN 有记忆但记不久,LSTM 用门控延长记忆,但都算得慢。
关键词:隐藏状态、时间步、梯度消失/爆炸、长期依赖、细胞状态、遗忘门/输入门/输出门。
对比记忆:RNN ≈ 金鱼记忆;LSTM ≈ 有笔记本的学生。
🧠 思维导图
序列建模
├── RNN(循环神经网络)
│ ├── 核心:隐藏状态 h_t(滚动记忆)
│ ├── 优点:理论上看任意长上下文
│ └── 缺陷:长期依赖问题
│ ├── 梯度消失 → 学不到远距离
│ └── 梯度爆炸 → 训练不稳定
├── LSTM(长短时记忆)
│ ├── 核心创新:细胞状态(信息高速公路)
│ ├── 三道门
│ │ ├── 遗忘门:丢掉旧信息
│ │ ├── 输入门:写入新信息
│ │ └── 输出门:决定输出什么
│ └── 效果:缓解长期依赖
└── 共同瓶颈:必须串行计算,无法并行
↓ 引出
Transformer(完全并行 + 注意力机制)
3.1.4 Transformer 架构(⚠️ 本章最重点)
原文给出了自顶向下的代码骨架和详细模块拆解。我按"从整体到局部"帮你再展开一遍。
(1)Encoder-Decoder 整体结构(原文图 3.4)
原文的团队比喻非常精准,我帮你再细化:
| 模块 | 角色 | 职责 |
|---|---|---|
| **Encoder(编码器)** | 阅读理解员 | 通读输入句子,产出"理解后的表示" |
| **Decoder(解码器)** | 写作员 | 基于编码器输出 + 已生成内容,逐词生成 |
信息流向:输入序列 → Encoder → 上下文向量 → Decoder → 输出序列
(2)自注意力 → 多头注意力(原文图 3.5,⚠️ 重中之重)
① 自注意力(Self-Attention)的直觉
原文"开卷考试"的比喻再复述一遍:
-
每个词(学生)有三样东西:Q (问题)、K (标签)、V(答案内容)
-
一个学生想答题,就拿自己的 Q 去和所有词的 K 比对
-
比对得分高(相关度高)的词,其 V 在最终答案里占比就大
② 数学公式(结合原文)
Attention(Q,K,V)=softmax(dkQKT)V
逐步拆解:
-
QKT:计算"每个词对每其他个词"的相关度得分(点积)
-
除以 dk:缩放,防止点积太大导致 softmax 梯度消失
-
softmax:变成概率分布(权重)
-
乘 V:按权重加权求和,得到每个词的新表示
③ 多头注意力(Multi-Head Attention)
单头注意力只能关注一种关系。多头 = 多组 Q/K/V 并行计算,每组关注不同子空间:
-
头1 可能关注语法关系(主谓一致)
-
头2 可能关注指代关系(it → agent)
-
头3 可能关注语义关系(同义/反义)
最后把 h 个头的输出拼接 + 线性变换合并。
代码层面(原文已给出参考实现):
# 伪代码逻辑
Q = linear_q(x) # 投影成 Query
K = linear_k(x) # 投影成 Key
V = linear_v(x) # 投影成 Value
# 分头
Q = Q.view(batch, seq, heads, d_k).transpose(1, 2)
K = K.view(...)
V = V.view(...)
# 缩放点积注意力
scores = Q @ K.transpose(-2, -1) / sqrt(d_k)
attn = softmax(scores, dim=-1)
out = attn @ V
# 合并多头
out = out.transpose(1, 2).reshape(batch, seq, d_model)
out = linear_out(out)
(3)前馈神经网络(FFN)
每个位置独立过一遍两层全连接 + ReLU:
FFN(x)=max(0,xW1+b1)W2+b2
-
通常 dff=4×dmodel(先放大再缩小)
-
"逐位置"意味着对序列中每个词独立 处理,但共享权重
(4)残差连接与层归一化(Add & Norm)
每个子层(注意力、FFN)都包了一层 Add & Norm:
-
Add(残差连接):output=x+Sublayer(x) ------ 解决深层网络梯度消失,让信息直通
-
Norm(层归一化):把每一层的输出归一化到均值为0、方差为1,稳定训练
经典堆叠方式(原文代码骨架体现):
x = x + MultiHeadAttention(LayerNorm(x)) # 子层1
x = x + FFN(LayerNorm(x)) # 子层2
(5)位置编码(Positional Encoding)
问题 :自注意力本身不区分顺序------"我打你"和"你打我"对它来说一样。
解法 :给每个词加上一个"位置向量",用正弦/余弦函数生成(原文公式):
-
偶数维度:sin(pos/100002i/dmodel)
-
奇数维度:cos(pos/100002i/dmodel)
特点:
-
不需要学习,固定公式
-
不同频率的 sin/cos 能表达绝对位置 + 相对位置
-
让模型能推断出"两个词之间隔了多少位置"
✅ 本节知识总结
一句话 :Transformer 用自注意力代替循环,实现了完全并行的序列建模。
关键词:Encoder-Decoder、Q/K/V、缩放点积注意力、多头、FFN、残差连接、层归一化、位置编码。
核心公式:Attention=softmax(QKT/dk)V
🧠 思维导图
Transformer
├── 宏观:Encoder-Decoder
│ ├── Encoder:理解输入(N层堆叠)
│ └── Decoder:生成输出(N层堆叠)
├── 核心:自注意力机制
│ ├── Q(查询)、K(键)、V(值)
│ ├── 缩放点积:softmax(QK^T/√dk)·V
│ └── 多头:多组QKV并行 → 拼接 → 线性
├── 前馈网络 FFN
│ ├── 逐位置、共享权重
│ └── d_ff = 4 × d_model(放大再缩小)
├── 稳定训练三件套
│ ├── 残差连接(Add):x + Sublayer(x)
│ ├── 层归一化(Norm)
│ └── Dropout(防过拟合)
└── 位置编码
├── 问题:自注意力无顺序感
├── 解法:sin/cos 固定公式
└── 效果:注入绝对+相对位置信息
3.2 Decoder-Only 架构:GPT 的简化哲学
3.2.1 从 Transformer 到 GPT
📖 原文核心
OpenAI 提出:语言的核心任务就是"预测下一个词"。于是砍掉 Encoder,只保留 Decoder,这就是 GPT 系列。
🔍 展开讲解
1. 两种架构对比
| 对比项 | Encoder-Decoder(如翻译) | Decoder-Only(如 GPT) |
|---|---|---|
| 结构 | 编码器 + 解码器 | 只要解码器 |
| 输入处理 | 编码器通读全文 | 边读边生成 |
| 典型任务 | 翻译、摘要 | 对话、写作、代码 |
| 代表 | T5, BART | GPT 系列、Llama、Qwen |
2. 自回归生成(Autoregressive)
原文"文字接龙"比喻很形象:
-
第1步:输入"今天天气",模型预测"真"
-
第2步:输入"今天天气真",模型预测"好"
-
第3步:输入"今天天气真好",模型预测","
-
...... 直到输出
<EOS>(结束符)
3. 掩码自注意力(Masked Self-Attention,⚠️ 关键)
问题:训练时模型一次性看到整句话,它会不会"偷看"后面的答案?
解法 :在计算完注意力分数、softmax 之前,把当前位置之后所有位置 的分数替换为 −∞。经过 softmax 后这些位置概率变为 0,模型在数学上无法看到未来。
注意力矩阵(词1能看到词2、3、4吗?)
词1: [ 能看, 看不到, 看不到, 看不到 ]
词2: [ 能看, 能看, 看不到, 看不到 ]
词3: [ 能看, 能看, 能看, 看不到 ]
词4: [ 能看, 能看, 能看, 能看 ]
这保证了训练和生成时行为一致------都只依赖已生成的左侧上下文。
4. Decoder-Only 的优势(原文总结)
-
✅ 结构简单,容易堆叠到极大规模(千亿参数)
-
✅ 统一范式:任何任务都能变成"预测下一个词"(翻译、问答、代码...)
-
✅ 自回归天然适合开放生成(聊天、写作)
✅ 本节知识总结
一句话:GPT = 只要 Decoder + 掩码自注意力 + 预测下一个词。
关键词:Decoder-Only、自回归、掩码自注意力、因果掩码、统一范式。
记忆口诀:"预测下一个词"一句话开启了大模型时代。
🧠 思维导图
Decoder-Only 架构(GPT 系列)
├── 核心思想:语言 = 预测下一个词
├── 结构:仅保留 Transformer 的 Decoder 堆叠
├── 自回归生成
│ ├── 训练:掩码自注意力(看不到未来)
│ └── 推理:逐词生成,喂回自身
├── 掩码实现
│ ├── 注意力分数矩阵
│ ├── 未来位置 → -∞
│ └── softmax → 概率 0
└── 优势
├── 结构简单,易扩展
├── 统一任务范式
└── 天然适合开放生成
3.3 提示工程(Prompt Engineering)
3.3.1 模型采样参数
原文讲得比较完整,我帮你提炼成一张决策表,更好用:
| 参数 | 作用 | 低值效果 | 高值效果 | 推荐场景 |
|---|---|---|---|---|
| Temperature | 控制随机性 | 精准、确定 | 多样、发散 | 0.2 代码 / 0.7 对话 / 1.2 创意 |
| Top-k | 只保留前 k 个候选 | k 小→保守 | k 大→发散 | 通常 20~50 |
| Top-p | 累积概率截断 | p 小→集中 | p 大→开放 | 通常 0.8~0.95 |
协同优先级 (原文指出):温度调整 → Top-k → Top-p,三者取交集。
实用建议:
-
日常 Agent 开发:Temperature=0.3~0.7 + Top-p=0.9 基本够用
-
代码/事实类任务:Temperature 趋近 0
-
创意类任务:Temperature 0.8+,可配合 Top-p
3.3.2 零样本 / 单样本 / 少样本
| 类型 | 示例数 | 适用场景 |
|---|---|---|
| Zero-shot | 0 | 模型已具备的能力(分类、翻译) |
| One-shot | 1 | 格式示范、风格对齐 |
| Few-shot | 3~5+ | 复杂格式、边界情况多 |
直觉:示例越多,模型越"懂你要什么",但也会消耗更多 token、可能过拟合到示例风格。
3.3.3 指令调优 & 基础提示技巧
-
指令调优:用"指令-回答"数据微调,让模型从"文本补全"变成"听话助手"。你现在用的所有 Chat 模型都是指令调优过的。
-
角色扮演 :
你是一位资深运维工程师...→ 引导风格和知识范围 -
上下文示例:在 prompt 里塞几个范例,比长篇指令往往更有效
3.3.4 思维链(Chain-of-Thought, CoT)
这是智能体设计的灵魂技巧之一。原文强调了"请逐步思考"这句魔法。
为什么有效:
-
直接要答案 → 模型容易"跳步"出错
-
让它"一步一步写下来" → 把推理过程显式化,每一步都更可靠
-
同时让人类能检查推理链,便于调试 Agent
示例对比:
❌ 直接问:小明有3个苹果,妈妈又给了他5个,他吃了2个,还剩几个?
→ 模型可能直接说 6(错)
✅ CoT 问:...请逐步思考。
→ 模型输出:
1. 开始有 3 个
2. 妈妈给了 5 个 → 3+5=8
3. 吃了 2 个 → 8-2=6
答案:6 个 ✅
✅ 本节知识总结
一句话:提示工程就是"学会和大模型说话",参数控制随机性,示例控制格式,CoT 控制推理。
关键词:Temperature / Top-k / Top-p、Zero/One/Few-shot、指令调优、角色扮演、思维链。
Agent 设计启示:CoT + 工具调用 + 验证 = 可靠 Agent 的核心配方。
🧠 思维导图
提示工程
├── 采样参数(控制输出风格)
│ ├── Temperature:随机性旋钮
│ ├── Top-k:前k候选
│ └── Top-p:累积概率截断
├── 示例策略
│ ├── Zero-shot:直接指令
│ ├── One-shot:1个范例
│ └── Few-shot:多个范例
├── 指令调优:从补全 → 听话助手
├── 提示技巧
│ ├── 角色扮演
│ └── 上下文示例
└── 思维链 CoT ⭐
├── 引导语:"请逐步思考"
├── 效果:提升推理可靠性
└── Agent 价值:可检查、可调试
3.4 分词(Tokenization)
3.4.1 为什么不能直接用字符/单词
| 方案 | 问题 |
|---|---|
| 字符级 | 序列太长,语义信息稀疏 |
| 单词级 | 词表巨大(百万级),未登录词无解 |
**子词分词(Subword)** 是折中:常见词保留完整,罕见词拆成有意义的片段。
-
"agent" →
agent -
"Tokenization" →
Token+ization
3.4.2 BPE 算法(结合原文表 3.1 与代码)
核心流程(贪心合并):
-
从字符级词表开始
-
统计所有相邻词对的出现频率
-
合并最高频的一对,加入词表
-
重复,直到词表达到目标大小
原文代码的要点 :get_stats 统计频次 → merge_pair 执行合并 → 循环迭代。
实际影响(⚠️ 开发者必知):
-
不同模型分词器不同 → 同一段文本 token 数不同
-
Token 数直接影响 API 费用 和 上下文长度
-
中文通常 1 个字 ≈ 1~2 个 token;英文 1 个词 ≈ 1~3 个 token
✅ 本节知识总结
一句话:BPE 用"贪心合并"从字符逐步构建出高效的子词词表。
关键词:子词分词、BPE、合并规则、词表大小、Token 数 = 成本。
3.5 本地部署 & 模型选型 & 缩放法则 & 幻觉
这几节原文偏概览,我帮你提炼成决策框架。
3.5.1 本地部署(原文 3.2.3 实践)
原文用 Hugging Face + Qwen1.5-0.5B-Chat 做演示,四步走:
-
pip install transformers torch -
AutoTokenizer.from_pretrained(...)+AutoModelForCausalLM.from_pretrained(...) -
构造对话模板 →
tokenizer(...)→model.generate(...) -
tokenizer.decode(...)还原文本
意义:本地部署 = 数据不出域 + 可微调 + 零 API 费用,是构建企业级 Agent 的常见选择。
3.5.2 模型选型四维度
| 维度 | 闭源 API(GPT/Claude/Gemini) | 开源本地(Llama/Qwen/DeepSeek) |
|---|---|---|
| 性能 | ⭐⭐⭐⭐⭐ 前沿 | ⭐⭐⭐~⭐⭐⭐⭐ 追赶中 |
| 成本 | 按量付费,量大则贵 | 一次性硬件 + 电费 |
| 数据隐私 | 数据出域 | 完全本地 |
| 可控性 | 黑盒,不能改 | 可微调、可裁剪 |
选型口诀:要最强效果 + 省事 → 闭源 API;要数据隐私 + 定制 → 开源本地。
3.5.3 缩放法则(Scaling Laws)
三条幂律关系(原文引用 Kaplan 2020):
-
性能 ∝ 参数量↑
-
性能 ∝ 数据量↑
-
性能 ∝ 计算量↑
Chinchilla 定律(2022,重要修正):
给定计算预算,更小的模型 + 更多的数据 比"更大的模型 + 更少的数据"更优。
能力涌现 :规模过了某个阈值,突然学会 CoT、代码、指令遵循等新能力------这是小模型没有的。
3.5.4 幻觉(Hallucination,⚠️ Agent 设计必面对)
定义:模型生成与事实矛盾的内容(编造实体、错误推理、虚构引用)。
成因:
-
训练数据本身有错
-
自回归只预测"下一个最可能词",没有事实核查
-
复杂推理易出错
缓解(原文提到 + 补充):
| 方法 | 思路 |
|---|---|
| **检索增强生成(RAG)** | 先查资料再回答,给模型"开卷" |
| 外部工具调用 | 让 Agent 查数据库/搜索引擎验证 |
| 多步推理 + 自检 | CoT + "请检查你的答案" |
| 引用溯源 | 要求模型给出信息来源 |
对 Agent 的启示 :永远不要完全信任 LLM 的输出,关键决策要加验证环节(这正是你前面讨论的 SEE/FIND/GET/PUT 架构的价值------GET 拿到的事实可以反过来校验 LLM 的推理)。
📚 全章终极思维导图(串起来看)
第三章 · 大语言模型基础
│
├── 一、语言模型演进
│ ├── 统计语言模型(N-gram)
│ │ └── 马尔可夫假设 + 最大似然估计
│ │ → 缺陷:泛化差、维度灾难
│ ├── 神经网络 + 词嵌入
│ │ └── 词→向量,语义可计算
│ │ → King - Man + Woman ≈ Queen
│ ├── RNN / LSTM
│ │ └── 滚动记忆 → 门控记忆
│ │ → 缺陷:无法并行
│ └── Transformer ⭐⭐⭐
│ ├── 自注意力:Q/K/V + 缩放点积
│ ├── 多头:多视角并行
│ ├── FFN + Add & Norm
│ └── 位置编码:sin/cos 注入顺序
│
├── 二、Decoder-Only 架构(GPT 系列)
│ ├── 核心:预测下一个词
│ ├── 掩码自注意力(看不到未来)
│ └── 优势:简单、可扩展、统一范式
│
├── 三、提示工程
│ ├── 采样参数:T / Top-k / Top-p
│ ├── 示例策略:Zero/One/Few-shot
│ ├── 指令调优 + 角色扮演
│ └── 思维链 CoT ⭐(Agent 核心技巧)
│
├── 四、分词
│ └── BPE:贪心合并 → 子词词表
│
├── 五、本地部署
│ └── Hugging Face + AutoModel/Tokenizer
│
├── 六、模型选型
│ └── 闭源(强/贵) vs 开源(自由/可控)
│
├── 七、缩放法则
│ ├── 性能 ∝ 参数/数据/算力
│ ├── Chinchilla:小模型+大数据更优
│ └── 能力涌现:规模阈值后突变
│
└── 八、幻觉与缓解
├── 成因:无事实核查 + 自回归本质
└── 解法:RAG / 工具调用 / CoT / 溯源