Skip to content
Gains Summary
Main Navigation 首页 / Home
C++ 编程 / C++ Programming
系统与高性能 / Systems & Performance
Web 开发 / Web Development
人工智能 / Artificial Intelligence
工业软件 / Industrial Software
其他内容 / Other Topics
C++ 编程 / C++系统与性能 / SystemsWeb 开发 / Web人工智能 / AI工业软件 / Industrial

外观

Sidebar Navigation

← 人工智能 / Artificial Intelligence

大语言模型 / Large Language Models

1. LLM 前置知识学习路线 / A Prerequisite Learning Path for Large Language Models

2. 神经网络基础 - 从零理解 AI 的"计算单元" / Neural Network Fundamentals from Artificial Neurons

3. Token 与上下文窗口 - LLM 的计费与记忆单位 / Tokens and Context Windows as the Units of LLM Cost and Memory

4. 解码策略 - 控制 LLM 输出的艺术 / Decoding Strategies for Controlling LLM Output

5. 消息角色 - 构建 Agent 对话的基础 / Message Roles as the Foundation of Agent Conversations

6. 流式输出 - 实时交互的体验优化 / Streaming Output for Responsive Interaction

7. Prompt 工程基础 - 与 LLM 高效对话的技巧 / Prompt Engineering Fundamentals for Effective LLM Interaction

8. LLM 进化史 - 从词向量到 Transformer / The Evolution of LLMs from Word Embeddings to Transformers

9. Transformer 手动计算:从 Attention 到 Encoder-Decoder 完整数据流

10. Transformer 核心原理 - 现代 LLM 的基石 / Transformer Fundamentals Behind Modern LLMs

11. Decoder-Only LLM 深度解析:为什么扔掉 Encoder,以及 KV Cache 如何工作

12. 训练 vs 推理:同一个 Transformer,两条完全不同的执行路径

13. Transformer 训练阶段计算详解 - 手算每一行矩阵 / Transformer Training Computation Matrix by Matrix

14. Transformer 推理阶段详解 — 模型如何"思考"并生成回答 / Transformer Inference and Autoregressive Generation

15. 训练基础扫盲 - 理解 Fine-tune 在做什么 / A Training Primer for Understanding Fine-Tuning

16. LLM 预训练全景:数据管道、Scaling Laws 与训练稳定性

17. 训练基础设施 - 从单卡到千卡集群 / Training Infrastructure from One GPU to Thousand-GPU Clusters

18. Post-Training Pipeline - 从 Base Model 到可用助手 / The Post-Training Pipeline from Base Model to Assistant

19. SFT 深度解析:从 Base Model 到指令跟随——后训练第一步 / SFT Deep Dive: Teaching Base Models to Follow Instructions

20. RLHF 深度解析:从 Reward Model 到 PPO 的完整对齐流程

21. DPO 与对齐方法:从 RLHF 复杂度到直接偏好优化

22. 研究视角:DL/RL 理论到 LLM 训练的完整映射

本页目录

训练基础扫盲 - 理解 Fine-tune 在做什么 / A Training Primer for Understanding Fine-Tuning ​

📅 创建时间:2026-05-31 🏷️ 标签:#训练基础 #Loss函数 #反向传播 #优化器 #微调 📚 前置知识:[[01 - 神经网络基础]] [[08 - Transformer 核心原理]] 🎯 文档定位:科普深入 × 专业浅显 — 比科普深(讲清楚为什么),比专业浅(不推公式)


📋 本章目标 ​

阅读完本文档后,你将能够:

  • [ ] 完整描述一次训练循环的四个步骤(Forward → Loss → Backward → Update)
  • [ ] 解释什么是 Loss 函数,以及它如何衡量模型"有多错"
  • [ ] 理解反向传播的本质(不是玄学,就是链式法则)
  • [ ] 区分 SGD / Adam / AdamW 的适用场景
  • [ ] 解释为什么 Fine-tune 比 Pretrain 便宜得多
  • [ ] 理解 Epoch / Batch / Step 的关系
  • [ ] 为后续理解 RLHF 和 SFT 打下基础

第1部分:训练循环四步曲 ​

1.1 什么是训练? ​

训练 = 让模型的参数从"随机值"变成"有用的值"的过程。

打个比方:

随机参数模型 = 一个从未上过学的孩子,能说话但不懂知识
训练        = 送他去上学,学习的过程
训练好的模型 = 毕业后掌握了知识的成年人
1
2
3

这个"学习的过程"在代码里,就是一个训练循环(Training Loop),每循环一次,模型就"变聪明一点"。

1.2 训练循环四步骤 ​

┌─────────────────────────────────────────────────────────────────┐
│                       训练循环(Training Loop)                    │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  第1步:Forward Pass(正向传播)                                    │
│  ┌─────────────────────────────────┐                            │
│  │  输入数据 → 模型 → 预测结果      │                            │
│  │  "模型说:下一个词应该是 X"        │                            │
│  └─────────────────────────────────┘                            │
│                    ↓                                              │
│  第2步:计算 Loss(损失)                                          │
│  ┌─────────────────────────────────┐                            │
│  │  预测结果 vs 正确答案 → Loss 值  │                            │
│  │  "模型预测是 X,答案是 Y          │                            │
│  │   差了多少?Loss = 0.7"          │                            │
│  └─────────────────────────────────┘                            │
│                    ↓                                              │
│  第3步:Backward Pass(反向传播)                                   │
│  ┌─────────────────────────────────┐                            │
│  │  Loss → 梯度(Gradient)        │                            │
│  │  "往哪个方向调整,每个参数改多少"   │                            │
│  └─────────────────────────────────┘                            │
│                    ↓                                              │
│  第4步:参数更新(Update)                                         │
│  ┌─────────────────────────────────┐                            │
│  │  参数 = 参数 - 学习率 × 梯度      │                            │
│  │  "每个权重都按计算好的方向调整一点"  │                            │
│  └─────────────────────────────────┘                            │
│                    ↓                                              │
│  ────────────── 重复成千上万次 ──────────────                      │
│                    ↓                                              │
│              模型越来越好                                          │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

1.3 具体数值示例:一次完整的训练步骤 ​

为了把四步曲讲透,我们用一个极度简化的例子:

场景:教模型识别"正面评论"和"负面评论"

  • 输入:"这个产品太棒了!" → 正确答案:正面
  • 简化:输入用一个数字 x = 1.0 表示,真实标签 y = 1(正面)

模型(单神经元):y_pred = ReLU(w × x + b)

第一步:Forward Pass

假设初始参数:w = 0.5, b = 0.1

计算:
z = w × x + b = 0.5 × 1.0 + 0.1 = 0.6
y_pred = ReLU(0.6) = 0.6

模型预测:0.6(接近1,表示"正面",还算对)
1
2
3
4
5
6
7

第二步:计算 Loss

用 MSE Loss(均方误差):
Loss = (y_pred - y)² = (0.6 - 1.0)² = 0.16

Loss = 0.16 表示"错了 0.16"
目标:让这个值越来越小
1
2
3
4
5

第三步:Backward Pass(反向传播)

反向传播 = 链式法则 = 从后往前,每个参数承担多少"责任"

Loss = (y_pred - y)²
y_pred = ReLU(z)
z = w × x + b

求导链:
∂Loss/∂w = ∂Loss/∂y_pred × ∂y_pred/∂z × ∂z/∂w

逐项计算:
∂Loss/∂y_pred = 2 × (y_pred - y) = 2 × (0.6 - 1.0) = -0.8
∂y_pred/∂z = ReLU'(z) = 1(因为 z=0.6 > 0)
∂z/∂w = x = 1.0

∂Loss/∂w = (-0.8) × 1 × 1.0 = -0.8

类似地:
∂Loss/∂b = (-0.8) × 1 × 1 = -0.8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

直观理解:梯度 -0.8 告诉我们:如果把 w 变大一点,Loss 会变小一点。

第四步:参数更新

学习率(Learning Rate)= 0.1

w_new = w - lr × ∂Loss/∂w = 0.5 - 0.1 × (-0.8) = 0.5 + 0.08 = 0.58
b_new = b - lr × ∂Loss/∂b = 0.1 - 0.1 × (-0.8) = 0.1 + 0.08 = 0.18
1
2
3
4

结果验证:

用新参数再算一次:
z_new = 0.58 × 1.0 + 0.18 = 0.76
y_pred_new = ReLU(0.76) = 0.76

Loss_new = (0.76 - 1.0)² = 0.0576

Loss 从 0.16 降到了 0.0576!
模型变好了一点点
1
2
3
4
5
6
7
8

第2部分:Loss 函数 — 模型怎么知道自己错了 ​

2.1 Loss 的直观理解 ​

Loss(损失)= 衡量"模型预测"和"正确答案"之间的差距

Loss 是一个数字:
- Loss = 0:完美预测
- Loss → ∞:完全错误
- 训练的目标:让 Loss 越来越小
1
2
3
4

就像考试打分:

正确答案:这道题选 B
模型答案:这道题选 A

Loss = 1(错了)
模型:下次遇到类似的,我得改改参数

正确答案:这道题选 B
模型答案:这道题选 B

Loss = 0(对了)
模型:很好,这个参数是对的,记住了
1
2
3
4
5
6
7
8
9
10
11

2.2 分类任务常用 Loss:Cross-Entropy(交叉熵) ​

LLM 和分类模型最常用的 Loss 是 Cross-Entropy(交叉熵)。

直观理解:

假设模型对"正面"和"负面"两个类别的预测分布是:

正确答案(One-Hot):正面=1, 负面=0
模型预测:正面=0.7, 负面=0.3

Cross-Entropy = -Σ y_true × log(y_pred)
              = -[1×log(0.7) + 0×log(0.3)]
              = -[log(0.7)]
              = -(-0.357) = 0.357

如果模型预测是:正面=0.99, 负面=0.01
Cross-Entropy = -log(0.99) = 0.01  ← 几乎为0,预测很准

如果模型预测是:正面=0.1, 负面=0.9(完全相反!)
Cross-Entropy = -log(0.1) = 2.3  ← Loss 很大
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

Cross-Entropy 的特点:

  • 预测越接近正确答案,Loss 越接近 0
  • 预测越偏离正确答案,Loss 越大
  • 对"自信的错误预测"惩罚更重(log 特性)

2.3 LLM 的 Loss 是什么 ​

LLM 的训练本质上是一个下一个 token 预测任务:

输入:"今天天气真"
正确答案:"好"

模型预测所有 token 的概率分布:
"好"    → 0.7
"不错"  → 0.15
"糟糕"  → 0.1
"一般"  → 0.05

Cross-Entropy Loss = -log(0.7) = 0.357
1
2
3
4
5
6
7
8
9
10

整个训练语料(万亿 token)上,平均 Cross-Entropy Loss 越低,模型越好。


第3部分:反向传播 — 不是玄学,就是链式法则 ​

3.1 反向传播的本质 ​

很多人听到"反向传播"就觉得是高级玄学,其实它的本质就是高中/大学学过的链式法则。

链式法则复习:

f(x) = (2x + 1)²

df/dx = 2 × (2x + 1) × 2 = 4(2x + 1)

这就是链式法则:一层层往外求导
1
2
3
4
5

反向传播就是链式法则在神经网络上的应用:

LLM 前向计算:
Token → Embedding → Self-Attention → MLP → Logits → Softmax → Loss

反向传播(从后往前):
Loss → Softmax → Logits → MLP → Self-Attention → Embedding

Loss 对 Embedding 层每个参数的梯度 = 链式相乘
1
2
3
4
5
6
7

3.2 为什么叫"反向" ​

正向传播(Forward):
输入 → [层1] → [层2] → [层3] → 输出

反向传播(Backward):
Loss ← [层3] ← [层2] ← [层1] ← 输入

         ↑
         梯度从后往前传
         一层层算偏导数
1
2
3
4
5
6
7
8
9

3.3 梯度消失与梯度爆炸(回顾 + 深化) ​

在[[01 - 神经网络基础]]中我们学过 ReLU 可以缓解梯度消失。反向传播时,梯度需要从最后一层一直传回第一层:

┌─────────────────────────────────────────────────────────────────┐
│                    梯度消失与梯度爆炸                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  梯度消失(Vanishing Gradient):                                   │
│                                                                  │
│  梯度在反向传播时,每经过一层都乘以一个 < 1 的数                   │
│  → 传到前面几层时,梯度几乎变成 0                                   │
│  → 前面的层学不到东西                                             │
│                                                                  │
│  例如:                                                          │
│  梯度从后往前:0.5 → 0.3 → 0.1 → 0.02 → 0.003 → 0.0001        │
│  第1层收到的梯度几乎为 0,根本不知道怎么调整!                    │
│                                                                  │
│  ─────────────────────────────────────────────────────────────  │
│                                                                  │
│  梯度爆炸(Exploding Gradient):                                   │
│                                                                  │
│  梯度在反向传播时,每经过一层都乘以一个 > 1 的数                   │
│  → 传到前面几层时,梯度变成天文数字                                 │
│  → 参数剧烈震荡,训练崩溃                                          │
│                                                                  │
│  例如:                                                          │
│  梯度从后往前:0.5 → 1.2 → 2.8 → 6.5 → 15.2 → 35.4            │
│  参数更新一步跳太远,Loss 直接爆炸!                               │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

解决方案回顾:

  • 梯度消失:ReLU(正区梯度恒为1)、残差连接(ResNet)、LayerNorm
  • 梯度爆炸:Gradient Clipping(梯度裁剪:超过阈值就截断)

3.4 Gradient Clipping(梯度裁剪)直观理解 ​

Gradient Clipping 的规则:
如果 ||梯度|| > 阈值,就把梯度的长度截断到阈值

举例:
计算出来的梯度:[10, 20, 15, -8]
梯度范数 ||g|| = sqrt(10² + 20² + 15² + (-8)²) = sqrt(789) ≈ 28.1

阈值 = 5.0
因为 28.1 > 5.0,需要裁剪

裁剪后的梯度 = [10, 20, 15, -8] × (5.0 / 28.1)
             ≈ [1.78, 3.56, 2.67, -1.42]
             范数正好 = 5.0

方向不变,大小受限
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

第4部分:优化器 — 怎么更新参数 ​

4.1 梯度下降的三种形态 ​

有了梯度,我们就知道"往哪个方向走"。但走多远、走多快由优化器决定。

┌─────────────────────────────────────────────────────────────────┐
│                    梯度下降三种形态                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  SGD(Stochastic Gradient Descent):                            │
│                                                                  │
│  每次只用 1 个样本算梯度,然后更新                                 │
│  梯度方向噪声大,但有跳出局部最优的能力                            │
│                                                                  │
│  ─────────────────────────────────────────────────────────────  │
│                                                                  │
│  Mini-batch GD:                                                 │
│                                                                  │
│  每次用一批(batch)样本算梯度,然后更新                           │
│  实际训练中使用的方法                                             │
│  平衡了速度和稳定性                                               │
│                                                                  │
│  ─────────────────────────────────────────────────────────────  │
│                                                                  │
│  BGD(Batch GD):                                               │
│                                                                  │
│  每次用全部样本算梯度,然后更新                                     │
│  梯度方向最准确,但速度最慢                                        │
│  基本不用在深度学习中                                            │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

4.2 SGD 的问题 ​

问题:固定步长不适合所有方向

想象一个椭圆的Loss曲面:
  ↙ 陡峭的方向:走一步变化很大
  ↘ 平缓的方向:走一步变化很小

用固定学习率:
- 在陡峭方向:可能"overshoot"(迈过头了)
- 在平缓方向:走太慢
1
2
3
4
5
6
7
8
9

4.3 Adam — 最常用的优化器 ​

Adam(Adaptive Moment Estimation)= 动量法 + 自适应学习率

Adam 的核心思想:
1. 动量(Momentum):积累历史梯度方向,避免来回震荡
2. 自适应学习率(Adaptive LR):每个参数有自己专属的学习率

更新公式(直观理解):
m_t = β₁·m_{t-1} + (1-β₁)·g_t        # 动量(梯度的一阶矩估计)
v_t = β₂·v_{t-1} + (1-β₂)·g_t²      # 自适应(梯度的二阶矩估计)
θ_t = θ_{t-1} - lr·m_t / (√v_t + ε)  # 更新

其中:
g_t = 当前梯度
β₁ = 0.9(动量衰减)
β₂ = 0.999(二阶矩衰减)
ε = 10⁻⁸(防止除零)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

为什么 Adam 效果好:

梯度的"历史积累"(动量 m):
- 如果某个参数一直往同一个方向梯度,每次更新就加强
- 如果方向忽正忽负,互相抵消

梯度的"平方"(自适应 v):
- 如果某个参数梯度一直很大 → v 大 → 有效学习率降低
- 如果某个参数梯度一直很小 → v 小 → 有效学习率提高

结果:每个参数都"自动"找到合适的学习率
1
2
3
4
5
6
7
8
9

4.4 Adam vs SGD ​

特性AdamSGD
适用场景快速收敛,适合大多数场景最终精度高,适合调参充分
收敛速度快慢
泛化能力稍差(有时会过拟合训练集)更好
调参难度低(默认参数通常可用)高(需要仔细调学习率)
大模型训练常用逐渐流行

业界趋势:GPT-3 及其之前的模型多用 AdamW。但近两年(2024-2025)的研究发现,SGD(如 Lion 优化器)在某些大模型训练中效果更好。不过实际工程中,Adam 仍然是默认选择。

4.5 AdamW — Adam + 权重衰减 ​

AdamW = Adam + 正确的 L2 正则化。

简单理解:在 Adam 的更新公式中加一个权重衰减项

原版 Adam:
θ_t = θ_{t-1} - lr·m_t / (√v_t + ε)

AdamW:
θ_t = θ_{t-1} - lr·(m_t / (√v_t + ε) + λ·θ_{t-1})

λ·θ 这一项就是权重衰减(weight decay)
效果:让大的权重受到额外惩罚,防止过拟合
1
2
3
4
5
6
7
8
9
10

为什么 LLM 训练都用 AdamW:因为它同时做了梯度更新 + 正则化,比 Adam + 额外 L2 正则项更好。Transformer 模型的训练几乎都用 AdamW。

4.6 Learning Rate Schedule — 学习率怎么变 ​

训练不是从头到尾用同一个学习率,而是动态调整的:

┌─────────────────────────────────────────────────────────────────┐
│                 典型 Learning Rate Schedule                       │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Warmup + Cosine Decay(最常见):                                │
│                                                                  │
│  LR        │                                                       │
│  (最大值)  ╱│▓▓▓▓▓▓▓                                              │
│           ╱ │     ╲                                                │
│          ╱  │       ╲____                                          │
│         ╱   │            ╲___                                      │
│        ╱    │                ╲____                                 │
│  ─────/─────┴───────────────────╲────── 时间                       │
│       ↑    ↑                     ╲                                 │
│    warmup  峰值                  cosine 衰减到接近 0                │
│                                                                  │
│  ┌───────────────────────────────────────────────────────────┐   │
│  │  Warmup(预热):                                              │   │
│  │  从很小的 LR(如图上0)逐渐增加到峰值 LR                        │   │
│  │  目的:                                                       │   │
│  │  1. 初期参数是随机的,大的 LR 可能导致训练不稳定                │   │
│  │  2. 慢慢增大学习率,让模型先"找对方向"                         │   │
│  │                                                              │   │
│  │  Cosine Decay(余弦退火):                                    │   │
│  │  峰值 LR → 按余弦曲线慢慢下降 → 接近 0                         │   │
│  │  目的:                                                       │   │
│  │  1. 训练后期用小 LR 精细调整,避免大跳                         │   │
│  │  2. 余弦曲线比线性下降更平滑                                   │   │
│  └───────────────────────────────────────────────────────────┘   │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

第5部分:Epoch / Batch / Step — 训练的基本度量 ​

5.1 三个核心概念 ​

┌─────────────────────────────────────────────────────────────────┐
│              Epoch / Batch / Step 的关系                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  假设数据集有 1000 个样本,Batch Size = 100                       │
│                                                                  │
│  1 Epoch = 把 1000 个样本全部看一遍                              │
│           = 1000 / 100 = 10 个 Step                              │
│                                                                  │
│  训练 10 Epoch = 把数据集看 10 遍                                 │
│               = 10 × 10 = 100 个 Step                           │
│               = 100 次参数更新                                    │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14

5.2 Batch Size 的影响 ​

Batch Size 小(8-64)Batch Size 大(1024-8192)
梯度噪声大(噪声多但可能帮跳出局部最优)小(方向更准但可能陷入局部最优)
显存占用低高
训练速度慢(GPU 利用率可能不高)快(GPU 利用率高)
泛化能力可能更好可能稍差
收敛稳定性震荡稳定

实际选择:LLM 预训练通常用大的 global batch size(如 4M tokens,包含多卡),但学习率也要相应调整(Linear Scaling Rule:batch size 翻倍,学习率也翻倍)。


第6部分:Fine-tune 为什么比 Pretrain 便宜得多 ​

6.1 预训练在做什么 ​

预训练(Pretraining):
- 目标:让模型学会"语言的基本规律"
- 数据量:万亿 token(GPT-3 用了 3000 亿)
- 方式:预测下一个词(Next Token Prediction)
- 参数量:从头开始学(或从随机初始化开始)
- 算力:巨大(GPT-3 训练据说用了 3640 PetaFLOP/s-day)
1
2
3
4
5
6

6.2 微调在做什么 ​

微调(Fine-tuning):
- 目标:让模型"对齐人类意图"(遵循指令、回答有用)
- 数据量:几万到几十亿 token(SFT 通常用几万到几百万)
- 方式:给定 Prompt + 期望回答,让模型模仿
- 参数量:复用预训练权重,只调整部分(或全部)
- 算力:比预训练少 100-10000 倍
1
2
3
4
5
6

6.3 形象的类比 ​

预训练 = 从小学到大学的通识教育
微调   = 入职后的专业培训

一个刚毕业的大学生:
- 已经掌握了基础知识(预训练的结果)
- 但不知道怎么在公司做事(需要微调)

专业培训(微调):
- 不需要重学小学到大学的知识
- 只需要学习"怎么在这家公司做事"
- 时间短,成本低,效果好
1
2
3
4
5
6
7
8
9
10
11

6.4 数学层面的解释 ​

预训练:优化所有参数 θ(从随机初始化开始)
        θ_new = θ_old - lr × ∇L_all_parameters(θ)

微调:  只优化部分参数(如 LoRA 的低秩矩阵)
        θ_new = θ_old - lr × ∇L_few_parameters(θ)

参数更新的数量差了 100-1000 倍
梯度计算量也相应减少
1
2
3
4
5
6
7
8

6.5 预训练后模型为什么不能直接用 ​

给 Pretrained Model 输入:"帮我写一封请假邮件"

Pretrained Model 的输出(续写风格):
"写一封请假邮件是职场中常见的需求。通常包括以下几个部分:
1. 标题
2. 称谓
3. 正文
4. 落款

下面是一个示例..."

问题:模型在续写"写请假邮件"这段文本,
     而不是真正"执行"写请假邮件这个指令!
     
这就是为什么需要 SFT / RLHF 来做 Post-Training。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

第7部分:PEFT 概念预告 — 为什么不改动全部参数 ​

7.1 全量微调的问题 ​

全量微调(Full Fine-tuning):
- 更新模型的所有参数
- 7B 模型:70亿个参数全部更新
- 问题:
  1. 算力要求高(至少需要多卡)
  2. 灾难性遗忘(学了新任务,忘了旧知识)
  3. 每个任务都要存一份完整模型(存储成本高)
1
2
3
4
5
6
7

7.2 LoRA — 只改"关键部分" ​

**LoRA(Low-Rank Adaptation)**的核心思想:

Full Fine-tuning:更新 W(d×d 矩阵,几十亿参数)

LoRA:
  不直接更新 W
  而是训练两个小矩阵 A 和 B

  W' = W + ΔW
  ΔW = B × A         (B: d×r, A: r×d, r << d)

  原来更新 70 亿参数
  现在只更新 2 × r × d 参数

  如果 r = 8:
  7B 模型 → 只训练 ~8M 参数(减少 1000 倍!)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
直观理解:
原来:改造整栋楼(换所有窗户、所有管道、所有电线)
LoRA:只在关键节点加几个开关(训练低秩矩阵)

LoRA 为什么有效:
- 预训练已经学到了好的特征表示
- 新任务只需要"轻微调整"这些特征的关系
- 这些调整可以用低秩矩阵近似
1
2
3
4
5
6
7
8

7.3 QLoRA — LoRA + 量化 ​

QLoRA = LoRA + 4-bit 量化

训练时:
- 模型主体用 4-bit 存储(显存大幅减少)
- LoRA 参数用 16-bit 计算(保证精度)
- 效果:单卡 3090 也能训练 65B 模型!
1
2
3
4
5
6

PEFT 的详细内容会在[[13 - 训练基础设施]]中进一步展开。


核心总结 ​

总结1:训练循环 = Forward → Loss → Backward → Update ​

Forward:数据过模型,得到预测
Loss   :预测 vs 正确答案 → Loss 值(越大越错)
Backward:Loss 反向传播 → 每个参数的梯度
Update :参数 = 参数 - lr × 梯度
1
2
3
4

总结2:优化器选择 ​

默认选 AdamW
大模型训练:AdamW + Cosine LR Schedule
资源有限:SGD + 仔细调参(更省显存)
1
2
3

总结3:Fine-tune vs Pretrain ​

Pretrain:从随机开始,学语言规律(万亿token)
Fine-tune:复用权重,只学行为(万级token)
         便宜 100-10000 倍
1
2
3

总结4:Epoch / Batch / Step ​

1 Step = 一次参数更新
1 Epoch = 所有数据过一遍 = N / BatchSize 个 Step
1
2

章节测试 ​

测试1:训练循环 ​

一个训练循环有哪四个步骤?按顺序写出。

测试2:反向传播 ​

反向传播的核心数学原理是什么?用它来解释为什么梯度可以用来更新参数。

测试3:Loss 函数 ​

如果模型预测正面评论为 0.99(正确答案也是正面),Cross-Entropy Loss 是多少?如果预测为 0.01 呢?

测试4:优化器选择 ​

某创业公司想在单卡 A100 上微调一个 7B 模型,你会推荐 AdamW 还是 SGD?为什么?

测试5:Fine-tune vs Pretrain ​

解释为什么 Fine-tune 只需要几万 token 的数据,而 Pretrain 需要万亿 token。

测试6:Batch Size ​

Batch Size 从 16 增加到 1024,以下指标会怎么变化:梯度噪声、显存占用、训练速度。


参考答案 ​

测试1答案 ​

答案:Forward Pass → 计算 Loss → Backward Pass → 参数更新(Update)

解析:

1. Forward Pass:数据通过模型得到预测
2. Loss:用 Loss 函数计算预测与真实答案的差距
3. Backward Pass:反向传播求梯度,知道每个参数该往哪个方向改
4. Update:用优化器更新参数
1
2
3
4

测试2答案 ​

答案:反向传播的核心是链式法则。

解析:

链式法则:
y = f(g(x))
dy/dx = (df/dg) × (dg/dx)

反向传播中:
Loss 对第一层参数的梯度 = Loss对第二层输出的梯度 × 第二层对第一层输出的梯度 × ...
                        = 链式相乘

梯度告诉参数:
"如果把这个参数的值增加一点点,Loss 会增加(梯度>0)还是减少(梯度<0)?"

所以:梯度 > 0 → 参数应该减小
     梯度 < 0 → 参数应该增大
     参数_new = 参数_old - lr × 梯度
1
2
3
4
5
6
7
8
9
10
11
12
13
14

测试3答案 ​

答案:

  • 预测 0.99:Loss = -log(0.99) ≈ 0.01
  • 预测 0.01:Loss = -log(0.01) = 2.3

解析:

Cross-Entropy = -Σ y_true × log(y_pred)

真实标签是正面(1),负面(0):
Loss = -[1 × log(0.99) + 0 × log(0.01)]
     = -log(0.99)
     = 0.01

预测 0.01 时:
Loss = -log(0.01) = 2.3

-log(0.99) ≈ 0.01,说明预测很准,Loss 很低
-log(0.01) = 2.3,说明预测很错,Loss 很高
1
2
3
4
5
6
7
8
9
10
11
12

测试4答案 ​

答案:推荐 AdamW。

解析:

原因:
1. AdamW 开箱即用,默认参数效果就不错
   SGD 需要仔细调学习率、动量等参数

2. 单卡微调,计算资源有限
   AdamW 收敛快,适合资源受限场景

3. LoRA + AdamW 是 7B 模型单卡微调的标准组合
   大多数开源模型(Llama、Qwen 等)都提供 LoRA 微调方案
1
2
3
4
5
6
7
8
9

测试5答案 ​

答案:预训练需要学习"语言的基本规律",微调只需要学习"如何遵循指令"。

解析:

Pretrain 的目标:
- 让模型理解词与词的关系、语法结构、世界知识
- 这些知识分散在万亿 token 中
- 没有足够多的数据,模型学不全面

Fine-tune 的目标:
- 模型已经具备了语言理解能力(预训练的结果)
- 只需要学习"什么样的回答是人类喜欢的"
- 这种行为模式可以通过几万到几十万条数据学会

类比:
预训练 = 学会所有汉字的写法和基本语法
Fine-tune = 学会写"请假条"的格式
1
2
3
4
5
6
7
8
9
10
11
12
13

测试6答案 ​

答案:

指标Batch 16 → 1024原因
梯度噪声显著降低更多样本平均,方向更准
显存占用大幅增加batch越大,中间激活值越多
训练速度加快GPU 利用率更高(但有限度)

解析:

梯度噪声:16 个样本的平均梯度 vs 1024 个样本的平均梯度
         样本越多,噪声越小,方向越准
         
显存占用:batch=16 时,每个样本的激活值都要存
         batch=1024 时,是 64 倍的激活值
         大模型训练的主要显存瓶颈就在这里

训练速度:GPU 有大量并行计算单元
         batch 大时利用率高
         但超过某个点后,增加 batch 不再提速(受限于通信等)
1
2
3
4
5
6
7
8
9
10

相关笔记 ​

  • [[01 - 神经网络基础]] - 神经元、激活函数、MLP 的基础
  • [[08 - Transformer 核心原理]] - Transformer 架构中的前向传播
  • [[12 - Post-Training Pipeline]] - 从 Fine-tune 到 RLHF 的完整流程

下一步学习 ​

  • [ ] 阅读 12 - Post-Training Pipeline

学习状态:🟡 待学习

最后更新于:

Pager
上一篇14. Transformer 推理阶段详解 — 模型如何"思考"并生成回答 / Transformer Inference and Autoregressive Generation
下一篇16. LLM 预训练全景:数据管道、Scaling Laws 与训练稳定性

持续记录,持续成长

Copyright © Tidenflow