第 06 · 训练 · 10 min
它如何学习
损失函数、梯度下降、反向传播。以及为什么需要数十亿参数。
误差,被量化
一开始,模型是随机的。给它"天空是",它预测"香蕉"和"蓝色"的概率差不多。我们想要的是让它预测"蓝色"(或一个合理的词)。
要达到这个目标,需要两件事:
- 一种衡量它有多错的方法。
- 一种朝着正确方向修正参数的机制。
训练就是这样。
交叉熵,不谈公式
在每一步,我们给模型一段文本。它将下一个 Token 预测为一个分布(第 01 章)。我们查看它给实际出现在文本中的 Token 分配的概率。如果概率高,说明它预测对了。如果概率低,说明它预测错了。
交叉熵用对数概率来衡量这个误差:
模型越自信且正确,损失越小。 模型越自信且错误,损失越大。
这是一种严格的衡量方式:对正确答案只分配 0.01% 的概率,代价远比分配 10% 大得多。模型学会了避免错误的自信。
沿坡而下
一旦计算出损失,我们如何调整参数?
想象损失是一个在巨大空间(维度数等于参数数:数十亿)中的曲面。模型是这个曲面上的一个点。我们希望它向谷底下降。
这个算法叫做梯度下降:在每一步,我们计算最陡下降的方向(梯度),然后朝那个方向走一小步。
参数 ← 参数 − η × 梯度
η(eta)是学习率:步长。太小,我们原地踏步。太大,我们跳过谷底,发散了。
Loss 曲线呈台阶式下降——每个台阶对应模型刚刚学完的一个新模式。四种 learning rate 状态揭示了经典陷阱:太低则停滞,太高则发散。
在可视化中可以观察到三种状态:
- 极低学习率(≤ 0.001) — 曲线在下降,但很慢。模型在学习,但我们等不到那一天。
- 最优学习率(≈ 0.01) — 稳步下降,达到较低的渐近值。这是目标。
- 过高学习率(≥ 0.05) — 损失震荡,甚至发散。模型在最小值之间"跳跃",无法落定。
在实践中,我们在训练过程中动态调整学习率:开始时线性预热(避免把一切搞砸),然后余弦衰减。
Adam:梯度下降,但更好
公式 参数 ← 参数 − η × 梯度 描述的是纯粹的梯度下降。但实际上,没有人会用这种原始形式来训练大语言模型。
参考标准的优化器叫做 Adam(以及它的现代变种 AdamW)。它的思路是:与其盲目地朝着当前梯度的方向迈步,不如为每个参数保留一份最近平均方向(即动量)和更新方差的滚动记忆。
- 梯度方向始终一致的参数会迈出大步。
- 梯度震荡(噪声大)的参数则迈出小步。
因此,Adam 会自动适配每一个参数,而 SGD 则对所有参数应用同一个学习率。Adam 更稳定,并且在实践中收敛快得多。AdamW(如今最常用的版本)还额外加入了一种叫做 weight decay 的正则化,防止权重在训练过程中爆炸。
如今,不用 AdamW 来训练一个大语言模型,就跟没有正当理由用汇编写代码一样罕见。
反向传播,一句话概括
为了计算梯度——也就是知道每个参数如何影响损失——我们使用反向传播。这是一种将误差从网络输出向输入逐层传播的算法,应用微积分中的链式求导法则。
你不需要理解推导过程就能直觉地感受发生了什么。可以这样理解:
"如果我把这个旋钮调动 0.001 个单位,损失会上升还是下降,上升/下降多少?"
对模型数十亿个旋钮中的每一个,并行地回答这个问题,正是反向传播所做的事。这就是为什么在一个集群上训练一个 700 亿参数的模型大约需要十天时间成为可能。
预训练 = 阅读互联网
为了让大语言模型学到有用的东西,它需要大量文本。非常非常多。现代模型会接触到:
在整个过程中,任务始终相同:预测下一个 Token。没有标注好的问答对,没有"这是正确的翻译",没有人类奖励。只有原始文本,以及预测下一步内容的目标。
这就是我们所说的自监督:数据提供自己的"标签"。不需要人工标注——只需要有文本。
Batch size:一次处理多少个样本
我们从来不会只在单个样本上计算梯度。我们会把多个序列组合成一个 batch,在整个 batch 上计算平均梯度,然后只对参数做一次更新。
batch 越大,梯度越稳定(噪声越小),可以使用的学习率也越大。但你需要足够的 GPU 显存来存放它。
对于现代大语言模型,有效 batch size 可以达到数百万个 Token——通常通过结合以下方式获得:
- 本地 batch(每个 GPU 上)——受 VRAM 限制。
- 梯度累积(gradient accumulation)——计算多个小 batch,最后才统一应用更新。
- 数据并行——把 batch 分摊到几十、几百,有时上千个 GPU 上。
工程师所说的 global batch size,指的是参与单次优化步骤的总数据量。对于 GPT-4,每一步要消耗数百万个 Token。
数据:一半的工作量
我们谈论参数谈得很多。但很少谈到数据准备——而这恰恰占据了所有认真训练模型的团队一半的时间。
- 过滤——剔除低质量内容(垃圾信息、404 错误页、机器自动生成的内容、没有上下文的产品列表)。
- 去重——移除重复内容。Common Crawl 包含同一页面的大量副本;如果不处理,模型会死记这些页面,而不是泛化。
- 混合——按各来源(维基百科、书籍、代码、科学论文)的教学价值(而不是原始体量)来平衡比例。
- 质量过滤——在最优秀的团队那里,会用一个分类器为每篇文档评分,只保留看起来像教科书或精心研究文章的内容。
- 去污染——确保评估基准(MMLU、HumanEval……)不会泄漏到训练语料中。
一位 Meta 研究员的直白总结:「我们 10% 的时间花在训练模型上,90% 的时间花在准备数据上。」
这也是为什么最好的开源模型(Llama、Mistral、DeepSeek)几乎从不公开数据配方的细节:这是它们最主要的竞争优势。
过拟合与验证
训练一个模型的时间越长,它就越来越熟悉它的语料库,烂熟于心。到某个时刻,它开始记忆而不是泛化。这就是过拟合(Overfitting)。
为了检测它,我们预留出语料库的一部分——验证集——不参与训练。在训练过程中,我们同时测量两者的损失。只要两者都在下降,一切正常。当验证集损失上升而训练集损失继续下降时,我们开始过拟合了。这时候应该停止训练(或增加数据,或加强正则化)。
在可视化中,虚线曲线代表验证集损失。它在最后略有上升——这正是过拟合的信号。
算力 = 能力
最后一件事。为什么需要这么多参数和这么多数据?因为学习遵循非常规律的Scaling Laws(缩放定律):
损失 = A × (算力)−α
算力翻倍(参数 × 数据 × 迭代次数),损失除以一个常数因子。这条曲线在 6 个数量级上都是平滑可预测的。整个行业都建立在这种规律性之上:你可以事先预知,投入 10 倍的 GPU 资源会带来可量化的提升。
我们会在第 19 章详细回到这一点(Kaplan 与 Chinchilla 的缩放定律)——包括为什么 GPT-3 在数据上训练不足,以及参数与 Token 之间真正的最优比例是多少。
接下来
预训练完成的模型现在是一个非常有能力的 Token 预测器。它可以以惊人的自然度补全任何文本。但它还不是一个助手。
在到达那一步之前,还有一件事需要理解:一旦预测了分布,我们如何选择一个 Token?我们在下一章回到这个问题。
更新于