目录
- 第一部分:监督微调(SFT)与损失计算
- 1.1 SFT 是什么?
- 1.2 SFT 的损失是怎么计算的?(重点)
- 1.3 预训练(CLM)和微调(SFT)的损失计算有什么区别?
- 1.4 SFT 训练的最佳实践
- 第二部分:LoRA 与参数高效微调
- 2.1 为什么需要 LoRA?
- 2.2 LoRA 的核心思想
- 2.3 LoRA 的两个模块加在哪里?
- 2.4 为什么只改 1% 的参数,影响却不小?
- 2.5 为什么推理时要"吸收(合并)"LoRA?
- 2.6 LoRA 的秩(Rank)怎么选?
- 2.7 LoRA 的变种们
- 2.8 QLoRA 和 DoRA 的区别
- 2.9 QLoRA 的显存账单
- 第三部分:混合专家模型(MoE)
- 3.1 为什么需要 MoE?
- 3.2 MoE 的架构拆解
- 3.3 速度悖论
- 3.4 负载均衡
- 3.5 训练的核心谜团:TopK 不可导,路由器怎么学?
- 3.6 著名的 MoE 模型
- 3.7 总结:MoE 的优缺点
摘要:本文系统梳理了大模型训练中的三大核心主题:监督微调(SFT)的损失计算原理与最佳实践、参数高效微调方法 LoRA 及其变种的核心思想与选型指南,以及混合专家模型(MoE)的架构设计、训练谜团与工业界方案。文章以通俗易懂的比喻和手算示例,帮助读者从原理到实战全面理解这些关键技术。
第一部分:监督微调(SFT)与损失计算
1.1 SFT 是什么?
SFT(Supervised Fine-Tuning,监督微调),就是把一个已经会“文字接龙”的预训练大模型,调教成一个能听懂人话、按指令办事的智能助手。
- 预训练模型:像个看过海量书籍的“书呆子”,只会根据上文猜下文(比如看到“今天天气真”,会接“好”)。
- SFT 之后:变成了能回答问题的“助理”。你问它“今天天气怎么样?”,它能回答“今天天气晴朗,适合出游”。
这个过程需要给它看大量的“问题-标准答案”对,让它学习如何给出高质量的回答。
1.2 SFT 的损失是怎么计算的?(重点)
这是很多人的困惑:模型是一字一字地预测,那损失也是一字一字算的吗?
答案是:是的,数学上是“一字一字”算的,但显卡是“一眼”全看完一起算的(矩阵并行计算)。它的核心机制叫做“教师强制(Teacher Forcing)”。
1.2.1 什么是“教师强制”?
在训练时,我们把“问题”和“答案”拼成一条完整的序列送进模型。模型会并行地预测每一个位置的下一个字。但关键点在于:模型预测时看到的“上文”,永远是正确的原文,而不是自己猜错的结果。
举个具体例子,我们要训练模型回答“我爱你”:
- 训练数据:输入是 [我, 爱, 你]。
- 模型内部计算:
- 看到 [我],预测下一个字是爱。
- 看到 [我, 爱],预测下一个字是你。
注意:在预测你的时候,模型看到的输入是 [我, 爱],其中“爱”是数据里给的正确答案,而不是模型自己在第一步预测出来的结果(哪怕它第一步预测错了,算第二步时依然用正确的“爱”)。
打个比方:这就像老师给你做完形填空,句子是“我( )你”。
- 训练时(Teacher Forcing):老师直接把正确答案“爱”写在括号里,让你看着“我爱”去填后面的“你”。就算你第一空填了“恨”,老师也会用板擦把“恨”擦掉,强行把“爱”写回去,再让你填第二空。
- 推理时(生成答案):没有老师管你了,你第一空填了“恨”,第二空就只能基于“我恨”去填,所以会生成“我恨你”。
1.2.2 那损失到底怎么算?
我们用上一步的例子来手算一遍。
- 第一步:看位置 1(预测“爱”)
- 模型根据输入的[我],预测下一个词。
- 模型输出的原始分数(Logits)经过 Softmax 变成概率:概率(我)=0.4,概率(爱)=0.5,概率(你)=0.05,概率(EOS)=0.05
- 计算这个位置的损失(负对数似然):Loss₁ = -log(概率_爱) = -log(0.5) ≈ 0.693
- 第二步:看位置 2(预测“你”)
- 模型根据输入[我, 爱],预测下一个词。
- 输出的概率:概率(我)=0.1,概率(爱)=0.2,概率(你)=0.6,概率(EOS)=0.1
- 计算这个位置的损失:Loss₂ = -log(概率_你) = -log(0.6) ≈ 0.511
- 第三步:算出最终的 Loss
- 因为答案长度是 2,所以总损失 = (Loss₁ + Loss₂) / 2 = (0.693 + 0.511) / 2 = 0.602
- 这个 0.602,就是最终传回给模型、用来更新参数的那一个数字(标量)。
1.2.3 提示词(Prompt)有损失吗?
绝对没有!在 SFT 中,我们只计算“答案部分”的损失,提示词部分的标签会被设为 -100。PyTorch 的 CrossEntropyLoss 函数看到 -100 就会自动跳过,不计算损失,也不传回梯度。
打个比方:这就像老师改卷子,只改学生在答题卡上写的答案(Response),至于试卷上的题目(Prompt)本身写了什么,看都不看,更不会扣分,因为题目是本来就印在上面的!
1.3 预训练(CLM)和微调(SFT)的损失计算有什么区别?
| 对比维度 | 预训练 (CLM) | 微调 (SFT) |
|---|---|---|
| 数据长什么样 | 连续的一段话:[A, B, C, D] | 拼凑的两段话:[问题, 答案] |
| 标签(Label)设置 | [B, C, D, EOS](全是正常ID,没有-100) | [-100, -100, 答案, 答案](问题部分挖掉,答案部分保留) |
| 哪些位置算损失 | 每个位置(除了开头的第一个字) | 只有“答案”部分的位置 |
| 学习目标 | 学会预测任何一个下文单词(学语法、常识) | 只学会预测针对特定问题的回答(学指令跟随) |
一句话总结:CLM 算所有位置,是因为全是正文;SFT 只算答案,是因为人为把前半段标记成了只读的“上下文”。
1.4 SFT 训练的最佳实践
1.4.1 数据质量:LIMA 原则
重质不重量:论文证明,1000 条极其精良的问答数据,训练效果能超过 5 万多条的粗糙数据。
好数据必须满足:
- 多样性:涵盖问答、摘要、代码、数学、创意写作、多轮对话等。
- 正确性:每个回答必须事实准确、格式规范。
- 长度平衡