06 · 训练 · 10 min

它如何学习

损失函数、梯度下降、反向传播。以及为什么需要数十亿参数。

误差,被量化

一开始,模型是随机的。给它"天空是",它预测"香蕉"和"蓝色"的概率差不多。我们想要的是让它预测"蓝色"(或一个合理的词)。

要达到这个目标,需要两件事:

  1. 一种衡量它有多错的方法。
  2. 一种朝着正确方向修正参数的机制。

训练就是这样。

交叉熵,不谈公式

在每一步,我们给模型一段文本。它将下一个 Token 预测为一个分布(第 01 章)。我们查看它给实际出现在文本中的 Token 分配的概率。如果概率高,说明它预测对了。如果概率低,说明它预测错了。

交叉熵用对数概率来衡量这个误差:

模型越自信且正确,损失越小。 模型越自信且错误,损失越大。

这是一种严格的衡量方式:对正确答案只分配 0.01% 的概率,代价远比分配 10% 大得多。模型学会了避免错误的自信

沿坡而下

一旦计算出损失,我们如何调整参数?

想象损失是一个在巨大空间(维度数等于参数数:数十亿)中的曲面。模型是这个曲面上的一个点。我们希望它向谷底下降。

这个算法叫做梯度下降:在每一步,我们计算最陡下降的方向(梯度),然后朝那个方向走一小步。

参数 ← 参数 − η × 梯度

η(eta)是学习率:步长。太小,我们原地踏步。太大,我们跳过谷底,发散了。

Loss 曲线呈台阶式下降——每个台阶对应模型刚刚学完的一个新模式。四种 learning rate 状态揭示了经典陷阱:太低则停滞,太高则发散。

在可视化中可以观察到三种状态:

  • 极低学习率(≤ 0.001) — 曲线在下降,但很慢。模型在学习,但我们等不到那一天。
  • 最优学习率(≈ 0.01) — 稳步下降,达到较低的渐近值。这是目标。
  • 过高学习率(≥ 0.05) — 损失震荡,甚至发散。模型在最小值之间"跳跃",无法落定。

这里补一句以免误会:上面这三个数值是演示里的取值,选它们只是为了把三种状态显示得足够清楚。真实 LLM 的预训练学习率大致在 1e-4 到 6e-4 之间,小上一百倍。忠实的是这些状态,不是这些数字。

在实践中,我们在训练过程中动态调整学习率:开始时线性预热(避免把一切搞砸),然后余弦衰减。

Adam:梯度下降,但更好

公式 参数 ← 参数 − η × 梯度 描述的是纯粹的梯度下降。但实际上,没有人会用这种原始形式来训练大语言模型。

参考标准的优化器叫做 Adam(以及它的现代变种 AdamW)。它的思路是:与其盲目地朝着当前梯度的方向迈步,不如为每个参数保留一份最近平均方向(即动量)和更新方差的滚动记忆。

  • 梯度方向始终一致的参数会迈出大步
  • 梯度震荡(噪声大)的参数则迈出小步

因此,Adam 会自动适配每一个参数,而 SGD 则对所有参数应用同一个学习率。Adam 更稳定,并且在实践中收敛快得多。AdamW(如今最常用的版本)还额外加入了一种叫做 weight decay 的正则化,防止权重在训练过程中爆炸。

AdamW 依然是默认选项,是你没有特别理由时就该选的那个。但它的垄断已经出现裂缝:2025 年以来,Muon 优化器已经被用来训练一线的生产级模型(Kimi K2、GLM-4.5),并且进入了主流训练框架,包括 NVIDIA 的 Megatron。

优化器不是什么管道工层面的细节:它决定了几百万美元的 GPU 以多快的速度变成一个模型。

反向传播,一句话概括

为了计算梯度——也就是知道每个参数如何影响损失——我们使用反向传播。这是一种将误差从网络输出向输入逐层传播的算法,应用微积分中的链式求导法则。

你不需要理解推导过程就能直觉地感受发生了什么。可以这样理解:

"如果我把这个旋钮调动 0.001 个单位,损失会上升还是下降,上升/下降多少?"

对模型数十亿个旋钮中的每一个,并行地回答这个问题,正是反向传播所做的事。这就是为什么在一个集群上训练一个 700 亿参数的模型大约需要十天时间成为可能。

预训练 = 阅读互联网

为了让大语言模型学到有用的东西,它需要大量文本。非常非常多。现代模型会接触到:

  • 预训练期间从几万亿Token 到几十万亿个不等(Llama 3:2024 年 15 万亿;Qwen3:2025 年 36 万亿)。这个数字每一代都在往上走
  • 经过过滤的文本(Common Crawl、维基百科、书籍、代码、论文)
  • 对某些部分(最好的书籍)进行多次处理(多个 epoch

在整个过程中,任务始终相同:预测下一个 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)

为了检测它,我们预留出语料库的一部分——验证集——不参与训练。在训练过程中,我们同时测量两者的损失。只要两者都在下降,一切正常。当验证集损失上升而训练集损失继续下降时,我们开始过拟合了。这时候应该停止训练(或增加数据,或加强正则化)。

在可视化中,虚线曲线代表验证集损失。它在最后略有上升——这正是过拟合的信号。

有一点很重要,也常常出人意料:上面这个场景说的是微调,也就是在一个小数据集上反复多轮训练的情形。在预训练里,验证损失几乎从不回升。原因很简单:模型看到的是数万亿个互不重复的 Token,连一个完整 epoch 都跑不满,根本没有机会把语料背下来。一个预训练模型的典型问题不是训练过头,而是训练不足

算力 = 能力

最后一件事。为什么需要这么多参数和这么多数据?因为学习遵循非常规律的Scaling Laws(缩放定律)

损失 = L + A × (算力)−α

L∞ 这一项至关重要,而人们引用这个公式时又常常把它漏掉:它是一个下限,代表语言中不可消除的那部分不可预测性。哪怕是一个完美的模型,也没法百发百中地猜出句子的下一个词。因此,真正服从幂律的并不是损失本身,而是超出这个下限的那部分损失。

有了这层澄清:算力翻倍(参数 × 数据 × 迭代次数),这部分超额损失就除以一个常数因子。这条曲线在 6 个数量级上都是平滑可预测的。整个行业都建立在这种规律性之上:你可以事先预知,投入 10 倍的 GPU 资源会带来可量化的提升。

我们会在第 19 章详细回到这一点(Kaplan 与 Chinchilla 的缩放定律)——包括为什么 GPT-3 在数据上训练不足,以及参数与 Token 之间真正的最优比例是多少。

接下来

预训练完成的模型现在是一个非常有能力的 Token 预测器。它可以以惊人的自然度补全任何文本。但它还不是一个助手。

在到达那一步之前,还有一件事需要理解:一旦预测了分布,我们如何选择一个 Token?我们在下一章回到这个问题。

更新于