06. 训练与系统
1. 一个 LLM 是怎么练出来的
先把全流程串起来,后面几章讲的都是其中某一环:
| 阶段 | 数据 | 目标 | 产出 | 详见 |
|---|---|---|---|---|
| Pretraining | 万亿 token 级无标注文本 | Next-token CE | Base model | 本节 |
| SFT | 十万级指令—回答对 | Next-token CE | 会听指令的助手 | 本节 |
| 偏好对齐 | 人类偏好 pair | RM + RL 或 DPO | 对齐后的 chat 模型 | 08. 对齐与 RLHF |
| RL for Reasoning | 可验证的题目 | 可验证奖励 + RL | 推理模型 | 08. 对齐与 RLHF |
一句话概括三者的分工:预训练学知识,SFT 学格式,RL 学取舍。
阶段一:Pretraining
目标就是最朴素的 next-token prediction:
\[ \mathcal L=-\sum_t\log p_\theta(y_t\mid y_{<t}) \]
在海量文本上最小化这个交叉熵,模型被迫把语法、事实、推理模式全都压进权重里——因为要准确预测下一个词,这些都是必需的。
数据比模型结构更决定上限,工程上真正花时间的是:
- 去重:近似重复的文档会让模型走向记忆而非泛化,也会浪费算力。通常做 MinHash / SimHash 级别的模糊去重。
- 质量过滤:规则(长度、符号比例、语言识别)加分类器打分,把网页垃圾筛掉。
- 去污染:把评测集从训练数据里洗出去,否则跑分虚高、决策全错。
- 配比:网页、代码、书籍、论文、多语种的比例。代码数据能提升推理能力,是常见的「便宜加成」。
- 课程安排:常见做法是训练末期提高高质量数据比例(annealing),以及分阶段把上下文窗口从 4k 扩到 128k,而不是全程用长序列(长序列太贵)。
产出的 base model 只会续写,不会听指令。你问它「法国的首都是哪里」,它可能续写出「德国的首都是哪里?意大利的首都是哪里?」——因为训练语料里这种句子后面常常跟着更多同类问题。
阶段二:SFT(Supervised Fine-Tuning)
用 (instruction, response) 对做监督微调,把续写机变成助手。损失函数和预训练完全一样,区别只在数据形态和两个细节:
- 只在 response 上算 loss,prompt 部分 mask 掉——我们要模型学会「怎么答」,不是学会「怎么问」。
- 质量远比数量重要。几万条精心构造的高质量样本,常胜过几百万条噪声样本(LIMA 的经典观察)。
SFT 的天花板也很清楚:它只能模仿示范,学不到「A 比 B 好多少」这种偏好取舍,对模型自己会犯但示范里没有的错误也给不出负反馈。这正是要接 RLHF 的原因。
2. 知识蒸馏(Distillation)
用一个强模型(teacher)的输出去训练一个小模型(student)。它在 LLM 时代有两种完全不同的做法。
① Logit 蒸馏(经典 Hinton 做法)
\[ \mathcal L=\alpha\underbrace{\operatorname{CE}(y,p_S)}_{\text{对真实标签}} +(1-\alpha)\,\tau^2\underbrace{D_{\mathrm{KL}}(p_T^{(\tau)}\Vert p_S^{(\tau)})}_{\text{对齐 teacher 分布}} \]
核心洞察是 teacher 的完整概率分布里藏着「暗知识」(dark knowledge):它不只说「这是猫」,还顺带说了「有 10% 像狗、0.01% 像汽车」。这些类别之间的相对关系,信息量远大于 one-hot 标签——one-hot 只告诉你答案,teacher 的分布还告诉你「哪些答案错得不离谱」。
式子里两个细节:温度 \(\tau\) 把两边的分布都调软,让暗知识(那些小概率的相对大小)显现出来;前面乘 \(\tau^2\) 是因为软化会把梯度整体缩小 \(\tau^2\) 倍,乘回来才能让这一项的权重不随温度漂移。
② 序列级 / 数据蒸馏(LLM 时代的主流)
直接让 teacher 生成大量回答,student 拿这些回答当 SFT 数据训。
- 不需要 teacher 的 logits,只要能调用它就行,因此闭源模型也能当 teacher(尽管这通常违反其服务条款)。
- 实现上就是 SFT,没有任何新机制,这是它流行的最大原因。现在绝大多数开源小模型都这么来的。
- 一定要过滤:只保留答案正确、通过单测的轨迹(即拒绝采样),否则等于在系统性地学习错误示范。
DeepSeek-R1 报告里一个值得记住的结论:把大模型的长链推理轨迹蒸馏进小模型,效果显著优于直接对小模型做 RL。推理能力可以「教」,但小模型自己「悟」很难——RL 只能强化模型已有的行为,而小模型压根没有那些行为可强化。
注意
- student 会继承 teacher 的错误、风格和偏见,且在没有 verifier 过滤的情况下基本无法超过 teacher。
- 蒸馏出来的模型在被蒸馏的那类任务上很强,泛化到别的分布上则未必。
3. 合成数据(Synthetic Data)
为什么需要:高质量人类数据既有限又贵,而某些能力几乎没有现成语料——多轮函数调用、长上下文推理、罕见语言、特定格式输出,网上根本不存在成规模的例子。
常见造法
- 蒸馏式:直接用更强的模型生成(见上一节)。
- Self-Instruct 式:给少量种子任务,让模型自己扩写出更多指令,再自己作答,人工只做抽检。
- 拒绝采样(STaR / RFT):对有标准答案的题目采样多条解法,只保留答案正确的拿去训练。这是把推理能力自举上去的主力方法。
- 程序化生成:用代码、模板或形式化系统造题,天然自带标准答案。比如先随机生成一段代码再反推题面,或用符号计算库生成数学题。
- 改写原始语料:把网页内容改写成问答对或教科书风格(Phi 系列的路子),提高信息密度。
核心是「能不能自动判对错」
合成数据的价值上限,取决于你有没有一个可靠的验证器。有 verifier 的领域(数学答案匹配、代码跑单测、形式化证明检查)收益最大,因为可以放心地大规模生成再筛选;开放式写作最难,因为没人能自动判断「这段文案好不好」。
风险
- 模型崩溃(model collapse):反复用自己的生成物训练自己,分布的尾部会逐渐消失,多样性坍缩,模型越来越平庸。缓解办法是始终保留真实数据作锚点,并做严格过滤,而不是无限自举。
- 错误会被放大:一个事实错误被生成一万次,就成了模型眼中的「常识」。
- 评测污染:合成题可能与评测集撞车,需要做污染检测。
4. 常见并行策略
训练时,GPU 内存主要用于保存:
- Parameters:模型参数;
- Gradients:每个参数的梯度;
- Optimizer States:例如 AdamW 的一阶和二阶动量;
- Activations:前向传播产生、反向传播需要的中间结果;
- Temporary Buffers:Attention、通信和算子使用的临时空间。
不同并行方法切分的是不同内容:
| 并行方法 | 主要切分对象 | 主要解决的问题 |
|---|---|---|
| Data Parallelism | 训练数据 | 提高整体吞吐 |
| ZeRO / FSDP | 参数、梯度、Optimizer States | 减少单卡模型状态 |
| Tensor Parallelism | 单层中的矩阵计算 | 单层模型放不下 |
| Pipeline Parallelism | 不同网络层 | 整个模型放不下 |
| Sequence / Context Parallelism | 序列和激活值 | 长上下文激活占用过大 |
| Expert Parallelism | MoE Experts | MoE Expert 参数过大 |
实际训练通常不会只使用一种,而是根据内存、通信和集群拓扑组合使用。
Data Parallelism
Data Parallelism 的基本做法是:
- 每张 GPU 保存一份完整模型;
- 不同 GPU 处理不同数据;
- 每张 GPU 独立完成前向和反向传播;
- 通过 All-Reduce 同步梯度;
- 所有 GPU 使用相同梯度更新参数。
DP 和 DDP 的区别
在 PyTorch 中:
-
DataParallel通常由一个进程控制多张 GPU,主卡容易成为瓶颈; -
DistributedDataParallel通常每张 GPU 使用一个独立进程,通过 All-Reduce 同步梯度。
实际多 GPU 训练一般使用 DDP,而不是旧式的 DataParallel。
需要注意:
Data Parallelism 并不会减少单张 GPU 保存的模型状态,只是把数据分给不同 GPU。
如果模型本身无法装入单卡,需要使用 FSDP、ZeRO、TP 或 PP。
ZeRO 与 FSDP
普通 Data Parallelism 在每张 GPU 上都保存完整的:
- Parameters;
- Gradients;
- Optimizer States。
ZeRO 的核心思想是:
既然不同 Data-Parallel Ranks 最终维护的是同一个模型,就不需要让每张 GPU 永久保存所有模型状态。
Tensor Parallelism(TP)
把单层矩阵乘法沿维度切到多卡。例如列并行和行并行线性层。适合模型单层过大时,但层内频繁 collective,对高速互联要求高。
Tensor Parallelism 的优点:
- 可以切分单个超大线性层;
- 降低每张 GPU 保存的参数和部分激活值;
- 适合单层参数已经无法放入一张 GPU 的模型。
主要代价:
- 几乎每一层都需要 Collective Communication;
- 对 GPU 间带宽和延迟要求很高;
- TP Degree 越大,单张 GPU 的矩阵越小,计算效率可能下降。
Pipeline Parallelism(PP)
Pipeline Parallelism 按网络深度切分模型。
例如,一个 48 层模型可以分成 4 个 Stage:
- Stage 1:第 1–12 层;
- Stage 2:第 13–24 层;
- Stage 3:第 25–36 层;
- Stage 4:第 37–48 层。
一个完整 Batch 会进一步切成多个 Micro-batches,在不同 Stage 之间流水执行。
Pipeline Parallelism 的优点:
- 每张 GPU 只保存部分网络层;
- 通信内容主要是 Stage 之间的激活值和梯度;
- 可以将模型扩展到多个节点。
主要问题是 Pipeline Bubble。流水线启动和结束阶段,会有部分 GPU 等待其他 Stage。
实际选型
通常组合为 DP/FSDP + TP + PP,MoE 再加入 EP。原则是:
- TP 尽量限制在高速互联域内。
- PP 跨更慢节点也相对可行,但要减少 bubble。
- DP 扩全局吞吐。
- 并行度不是越高越好,通信、batch、内存和容错必须联合优化。
目录
| 章节 |
|---|
| 00. 机器学习核心概念 |
| 01. 基础与神经网络机制 |
| 02. 模型评估与指标 |
| 04. 经典机器学习 |
| 05. NLP、RNN 与词向量 |
| 06. LLM 基础 |
| 07. 训练与系统 |
| 08. 对齐与 RLHF |
| 09. 推理与部署 |
| 12. ML Coding |
| 参考资料 |