首页

大模型微调

大模型微调
Photo by Aerps.com / Unsplash

大模型微调完全指南:从数学原理到工程实战

完整记录低秩(LoRA)原理、过拟合欠拟合画像、核心训练参数调优、以及对齐技术(SFT/RLHF/DPO)的全链路知识体系。

第一部分:底层数学基石——低秩(Low Rank)

1.1 什么是“秩”?

在矩阵中,“秩”(Rank)代表矩阵列(或行)向量的最大线性无关组个数,也就是矩阵能表达的独立信息维度

  • 满秩矩阵:信息密度高,毫无冗余,无法压缩(如随机噪声)。
  • 低秩矩阵:矩阵内部存在大量线性相关性,数据高度冗余,可以用极少的基向量线性组合还原。

1.2 在 LoRA 中的应用

核心公式ΔW = B × A

  • W:原始权重矩阵(如 10000 × 20000,冻结不动)
  • B10000 × 5 的低秩矩阵
  • A5 × 20000 的低秩矩阵
  • 中间的 5 就是秩 r,它充当“信息瓶颈”。

参数量对比

场景 可训练参数量 说明
全量微调 10000 × 20000 = 2亿 需要巨大显存
LoRA 微调 (10000×5) + (5×20000) = 15万 减少 1300 多倍

第二部分:过拟合与欠拟合——AI的心理画像 🎭

2.1 过拟合(Overfitting)= 强迫症

  • 特征:训练集 100 分,测试集 40 分(死记硬背,换题就懵)。
  • 成因:LoRA 的 r 值设得太大,或数据太少、训练轮数过多。
  • 解法:降低 r、增加 Dropout、早停。

2.2 欠拟合(Underfitting)= 学渣

  • 特征:训练集 30 分,测试集 25 分(稳定地差,啥也没学会)。
  • 成因:LoRA 的 r 值设得太小(如 1),或学习率太低。
  • 解法:增大 r、增加 Epochs。

第三部分:核心训练参数详解(工程师操作面板) ⚙️

3.1 Batch Size(批次大小)——“卡车载重量”

  • 定义:模型一次更新参数时同时“吃进去”的样本条数。
  • 注意:受限于显卡显存。
  • 公式1 个 Epoch 的总步数 = 数据总条数 ÷ Batch Size
  • 比喻:卡车一次拉 4 箱货,需要跑 250 趟才能拉完 1000 箱。

3.2 Epochs(训练轮数)——“复习遍数”

  • ⚠️ 重大误区:增加 Epochs ≠ 增加新数据。Epochs 是把同一本练习册反复做 N 遍;增加数据才是买不同版本的练习册
  • 新手默认3 ~ 5 轮。

3.3 max_steps(最大步数)——“紧急制动闸”

  • 核心规则:如果同时设置 num_train_epochs=5max_steps=30,后者拥有**“一票否决权”**,训练在第 30 步直接停止,无视 Epochs。
  • 建议:正式训练时删掉 max_steps,仅在调试代码时使用。

3.4 LoRA 专用参数

参数 推荐值 比喻 作用
r(秩) 8~16 手术刀精细度 控制参数量,r 太小变学渣,r 太大变强迫症
alpha 16(= r) 手术力度 控制 LoRA 影响大小,实际缩放 = alpha/r
target_modules ["q_proj", "v_proj"] 手术部位 决定插在模型哪个位置
Dropout 0.0~0.1 随机失忆 数据少时调高防过拟合

3.5 梯度累积(Gradient Accumulation)——“蚂蚁搬家”

  • 公式有效 Batch Size = per_device_batch_size × gradient_accumulation_steps
  • 案例:物理 BS=4,累积步数=4 → 等效 BS=16(先欠着梯度,攒够 4 次再统一更新)。
  • 注意:累积步数不要超过 8~16,否则模型长期不更新容易“跑偏”。

第四部分:对齐技术全家桶(SFT / RLHF / DPO)🚀

4.1 SFT(监督微调 / 指令微调)

  • 本质在大模型语境下,SFT ≈ 指令微调。它是所有下游微调的起点。
  • 作用语文老师,教模型“听懂人话”,纠正语法格式。
  • 缺陷:只解决“答非所问”,无法解决“三观不正”(SFT 数据里几乎没有“拒绝回答”的样本)。

4.2 DPO(直接偏好优化)——“拉差距”的数学艺术

  • 核心操作:不用复杂的强化学习,直接用 chosen(好回答)和 rejected(坏回答)文本对,拉大两者间的对数概率差值
  • 重点澄清 1(打分):数据里没有分数!分数是模型前向传播时自己算出来的(对数概率)。DPO 只管把“好回答”的分数往上抬,把“坏回答”的分数往下踩。
  • 重点澄清 2(防止遗忘):引入冻结的参考模型(Reference Model) 作为锚点。只允许在旧模型附近微调,保护通用知识不被误伤(调节参数 beta 控制力度)。
  • 对比 RLHF:显存消耗小、训练稳定,是个人开发者替代 PPO 算法的首选。

第五部分:前向传播与反向传播 🔄

维度 前向传播 反向传播
做什么 推理 / 预测(做题) 学习 / 纠错(听老师评卷)
数据流向 输入 → 输出(单向向前) 输出(损失)→ 输入(反向倒推)
是否修改模型 ❌ 不改(权重冻结) ✅ 改(更新权重)

🎯 新手必记参数速查表(抄作业版)

参数类别 参数名称 推荐值 一句话作用
数据流 Batch Size 4~8(24G显存) 卡车一次拉几箱货
Epochs 3~5 把练习册做几遍
max_steps 不设(正式训练) 紧急制动闸,优先级最高
LoRA r(秩) 16 手术刀精细度
alpha 16 手术力度
target_modules ["q_proj", "v_proj"] 手术部位
训练节奏 Learning Rate 1e-4(LoRA) 油门深度
梯度累积 4(显存不够时) 蚂蚁搬家
Weight Decay 0.01 防漂移限制器
对齐 DPO beta 0.1 遗忘与对齐的平衡

个人开发者最佳路径:基座模型 → SFT(使用 LoRA 高效微调) → DPO(轻量级对齐) → 部署推理。

流程图:

flowchart LR
  用户 --> 检索
  检索 --> 权限过滤
  权限过滤 --> 生成

公式:

行内 $E = mc^2$,独立一行:

$$
\mathrm{Cost} = \frac{n_{\mathrm{in}} P_{\mathrm{in}} + n_{\mathrm{out}} P_{\mathrm{out}}}{10^6}
$$

flowchart TD
    A[用户下单] --> B{库存是否充足?}
    B -- 否 --> C[提示缺货]
    C --> D{是否接受预售?}
    D -- 是 --> E[创建预售订单]
    D -- 否 --> F[取消订单]
    E --> G[等待补货]
    G --> H[通知用户发货]
    B -- 是 --> I[锁定库存]
    I --> J[生成支付单]
    J --> K{支付是否成功?}
    K -- 否 --> L{是否超时?}
    L -- 否 --> M[等待用户支付]
    M --> K
    L -- 是 --> N[释放库存]
    N --> F
    K -- 是 --> O[扣减库存]
    O --> P[生成物流单]
    P --> Q[通知仓库拣货]
    Q --> R[出库发货]
    R --> S[更新订单状态]
    S --> T[通知用户已发货]
    H --> S
  flowchart LR
   subgraph 客户端层
       A1[Web 前端]
       A2[移动 App]
       A3[小程序]
   end

   subgraph 网关层
       B1[API Gateway]
       B2[鉴权中心]
       B3[限流熔断]
   end

   subgraph 服务层
       C1[用户服务]
       C2[订单服务]
       C3[支付服务]
       C4[库存服务]
       C5[通知服务]
   end

   subgraph 数据层
       D1[(MySQL 主库)]
       D2[(Redis 缓存)]
       D3[(MQ 消息队列)]
       D4[(Elasticsearch)]
   end

   A1 --> B1
   A2 --> B1
   A3 --> B1
   B1 --> B2 --> B3
   B3 --> C1
   B3 --> C2
   B3 --> C3
   B3 --> C4

   C1 --> D1
   C1 --> D2
   C2 --> D1
   C2 --> D3
   C3 --> D1
   C3 --> D3
   C4 --> D1
   C4 --> D2

   D3 --> C5
   C5 --> A1
   C2 --> D4
   flowchart TD
   subgraph Main[主流程]
       A[开始] --> B{判断}
       B -- 是 --> C[处理]
       B -- 否 --> D[结束]
   end