模型微调完全指南(SFT / LoRA / QLoRA / RLHF)
2025年Agent工程师必考内容,涵盖从原理到实战的完整知识体系。
一、微调基础
1.1 为什么需要微调?
预训练模型的局限
预训练模型(如 LLaMA、Qwen、Mistral)通过海量通用语料训练,具备强大的语言理解和生成能力,但存在以下局限:
| 局限 | 说明 |
|---|---|
| 领域知识不足 | 医疗、法律、金融等垂直领域的专业知识覆盖不够深 |
| 输出格式不可控 | 无法稳定输出 JSON、特定模板等结构化格式 |
| 风格不匹配 | 语气、角色、回复长度难以精确控制 |
| 指令遵循差 | base 模型不擅长遵循复杂指令 |
| 幻觉问题 | 对特定领域事实容易编造 |
| 安全对齐缺失 | base 模型没有安全边界 |
微调 vs RAG vs Prompt Engineering 的选择决策树
1 | 需求分析 |
详细对比:
| 维度 | Prompt Engineering | RAG | 微调 |
|---|---|---|---|
| 成本 | 最低 | 中等 | 最高 |
| 开发周期 | 小时级 | 天级 | 周级 |
| 新知识注入 | ❌ | ✅ | ⚠️ 需重新训练 |
| 行为改变 | 有限 | 有限 | ✅ 深度改变 |
| 推理延迟 | 低 | 中(检索开销) | 低 |
| 可维护性 | 高 | 中 | 低 |
| 适合场景 | 简单任务 | 知识密集型 | 行为定制型 |
什么时候该微调、什么时候不该
✅ 应该微调的场景:
-
需要模型学会特定的输出格式(如 Function Calling、Agent 工具调用格式)
-
需要特定领域的专业语言风格(如医疗报告生成)
-
需要模型遵循复杂的业务规则
-
有高质量的领域标注数据(>1000条)
-
需要降低推理成本(用小模型替代大模型+长 prompt)
-
安全对齐和价值观定制
❌ 不应该微调的场景:
-
知识会频繁更新(用 RAG)
-
数据量太少(<100条,用 few-shot)
-
Prompt Engineering 已经能解决
-
没有 GPU 资源
-
任务太简单,不值得投入
1.2 微调范式演进
全参数微调(Full Fine-tuning)
-
更新模型的所有参数
-
优点:效果上限最高,充分利用模型容量
-
缺点:显存需求巨大,7B模型全参微调需要 ~120GB 显存(AdamW优化器)
-
计算公式:显存 ≈ 模型参数量 × (2 + 2 + 2×4) = 参数量 × 12 字节(fp16 + AdamW)
-
例:7B × 12 = 84GB(加上激活值约 120GB)
参数高效微调(PEFT)
核心思想:冻结大部分参数,只训练少量新增或选定参数
主要方法:
| 方法 | 原理 | 可训练参数占比 |
|---|---|---|
| LoRA | 低秩矩阵分解 | 0.1% - 1% |
| Prefix Tuning | 在输入前加可学习前缀 | <0.1% |
| Adapter | 在层间插入小型网络 | 1% - 3% |
| IA³ | 学习激活值的缩放向量 | <0.01% |
| Prompt Tuning | 学习连续的 soft prompt | <0.01% |
指令微调(Instruction Tuning)
-
目标:让模型学会遵循人类指令
-
数据形式:(instruction, input, output) 三元组
-
代表工作:FLAN、InstructGPT、Alpaca
-
关键发现:少量高质量指令数据(~1000条)就能显著提升指令遵循能力(LIMA论文)
对齐微调(Alignment)
-
目标:让模型的输出符合人类价值观和偏好
-
方法:RLHF、DPO、KTO、ORPO、GRPO
-
核心:从"能力"到"对齐"——不是让模型更聪明,而是让它更安全、更有用、更诚实
-
HHH原则:Helpful(有用)、Honest(诚实)、Harmless(无害)
二、SFT(Supervised Fine-Tuning)
2.1 原理
监督学习范式
SFT 本质上是一个条件语言建模任务:给定输入序列 x,生成目标序列 y。
训练目标:最大化条件概率 P(y|x)
1 | 输入: [系统提示] + [用户指令] + [输入] |
损失函数(Cross-Entropy)
-
T: 目标序列长度
-
: 第 t 个 token
-
: 前 t-1 个 token
-
x: 输入序列
关键细节 —— Loss Mask:
1 | 输入tokens: [BOS] 你 是 谁 ? [SEP] 我 是 AI 助 手 [EOS] |
只对输出部分计算 loss,输入部分被 mask 掉。这是 SFT 区别于预训练的核心。
训练流程
1 | 1. 准备数据 → 2. 数据预处理(Tokenize + Padding/Packing) |
2.2 训练数据构建(重点!)
数据格式
1. Alpaca 格式(最简单)
1 | { |
2. ShareGPT 格式(多轮对话)
1 | { |
3. ChatML 格式(OpenAI 标准)
1 | <|im_start|>system |
4. LLaMA-3 格式
1 | <|begin_of_text|><|start_header_id|>system<|end_header_id|> |
数据质量 vs 数据数量
质量 >> 数量,这是2023-2025年的核心共识。
| 研究 | 结论 |
|---|---|
| LIMA (2023) | 仅 1000 条精选数据微调 LLaMA-65B,效果接近 GPT-4 |
| Alpaca (2023) | 52K 条合成数据,效果显著但有天花板 |
| Deita (2024) | 6K 条精选数据 > 100K 条随机数据 |
| 质量指标 | 多样性 > 复杂度 > 数量 |
高质量数据的特征:
-
✅ 指令清晰、无歧义
-
✅ 回复准确、详细、有逻辑
-
✅ 覆盖多种任务类型和难度
-
✅ 格式一致
-
❌ 避免重复、矛盾、过时信息
数据清洗和去重
1 | # 1. 基于 MinHash 的近似去重 |
合成数据生成
Self-Instruct(斯坦福 Alpaca)
1 | 1. 准备种子任务(175条人工编写) |
Evol-Instruct(WizardLM)
1 | 原始指令: "写一个排序算法" |
2024-2025年数据合成趋势:
-
Magpie:直接从对齐模型中提取高质量指令
-
Persona-driven:用不同人格生成多样化数据
-
Rejection Sampling:生成多个回复,选最好的
多轮对话数据构建
1 | { |
多轮数据的 Loss Mask 策略:
-
全部assistant轮计算loss:最常见,每轮回复都参与训练
-
仅最后一轮计算loss:适合对话式推理,防止中间轮过拟合
-
加权loss:后面轮次权重更大
2.3 训练技巧
学习率调度
1 | # Cosine 退火(最常用) |
Batch Size 选择
-
经验法则:有效 batch size = 实际 batch size × 梯度累积步数 × GPU数量
-
推荐有效 batch size:32 ~ 128
-
小 batch size(<16):训练不稳定,loss 抖动大
-
大 batch size(>256):可能影响泛化,收敛到更尖锐的最小值
梯度累积
1 | # 显存不够时,用梯度累积模拟大 batch |
混合精度训练(bf16/fp16)
| 特性 | fp32 | fp16 | bf16 |
|---|---|---|---|
| 位数 | 32 | 16 | 16 |
| 指数位 | 8 | 5 | 8 |
| 尾数位 | 23 | 10 | 7 |
| 数值范围 | 大 | 小(易溢出) | 大(同fp32) |
| 精度 | 高 | 中 | 较低 |
| 显存节省 | 基准 | 50% | 50% |
| 推荐 | ❌太慢 | ⚠️需loss scaling | ✅ 首选 |
1 | training_args = TrainingArguments( |
DeepSpeed ZeRO Stage 1/2/3
1 | // ds_config_zero3.json |
三、LoRA(Low-Rank Adaptation)
3.1 原理详解
低秩分解的数学原理
LoRA 的核心思想:预训练权重矩阵的更新量是低秩的。
1 | 原始: Y = W₀X (W₀ ∈ ℝ^{d×k}, 冻结) |
初始化:
-
A:高斯随机初始化(或 Kaiming 初始化)
-
B:零初始化
-
保证训练开始时 BA = 0,即不改变原模型行为
为什么有效?(内在维度假说)
Aghajanyan et al. (2021) 的研究表明:
预训练模型的任务适应过程具有很低的内在维度(intrinsic dimension)。即使参数空间是百万维的,有效的适应只需要在一个很低维的子空间中进行。
直觉理解:
-
预训练已经学到了通用的语言知识
-
微调只需要在这个基础上做小幅调整
-
这些调整可以用低秩矩阵近似
实验证据:
-
LoRA rank=8 在大多数任务上就能达到全参微调 90%+ 的效果
-
rank 从 4 增到 64,边际收益递减
-
不同任务的最优 rank 不同(简单任务低 rank,复杂任务高 rank)
rank r 的选择
| rank | 参数量(7B模型) | 适用场景 | 效果 |
|---|---|---|---|
| 4 | ~4M | 简单任务(分类、情感) | 够用 |
| 8 | ~8M | 通用指令微调 | ✅ 常用 |
| 16 | ~17M | 复杂任务(代码、推理) | ✅ 推荐 |
| 32 | ~34M | 领域深度定制 | 好 |
| 64 | ~67M | 接近全参效果 | 最佳但性价比降低 |
| 128+ | ~134M+ | 特殊需求 | 考虑全参微调 |
选择建议:
-
默认从 r=16 开始
-
如果数据少(<1K),用 r=8
-
如果效果不够,先提高数据质量,再考虑增加 rank
alpha 参数的作用
1 | 实际缩放: ΔW = (α/r) × BA |
最佳实践: alpha 通常设为 rank 的 1-2 倍。常见配置:
-
r=16, alpha=32
-
r=8, alpha=16
-
r=64, alpha=128
target_modules 的选择
1 | # Transformer 注意力层的组成(以 LLaMA 为例) |
研究结论:
-
只训练 q_proj + v_proj 是 LoRA 论文的原始建议
-
2024年共识:训练更多模块 + 更低 rank 效果优于 少模块 + 高 rank
-
加入 FFN 层(gate/up/down_proj)能显著提升复杂任务的效果
3.2 LoRA 变体
LoRA+
-
核心改进:A 和 B 矩阵使用不同的学习率
-
B 的学习率设为 A 的 λ 倍(论文推荐 λ = 16)
-
理论依据:B 初始化为零,需要更大的学习率来快速学习
-
效果:在相同训练步数下收敛更快,最终效果提升 1-2%
1 | # LoRA+ 配置 |
DoRA(Weight-Decomposed Low-Rank Adaptation)
1 | 标准 LoRA: W' = W + BA |
-
灵感来自权重归一化(Weight Normalization)
-
分离了权重的"大小"和"方向"的学习
-
效果:在多数基准测试上比 LoRA 提升 1-3%
-
代价:略增加计算量
AdaLoRA(自适应 rank 分配)
-
核心思想:不同层/模块的重要性不同,动态分配 rank
-
训练时用 SVD 分解监控每个模块的重要性
-
重要模块分配更高的 rank,不重要的降低
-
总参数量预算固定,实现更优的参数利用
1 | Layer 1: 不太重要 → rank=4 |
rsLoRA(Rank-Stabilized LoRA)
-
修改缩放因子从 α/r 为 α/√r
-
使得 LoRA 在不同 rank 下的训练动态更稳定
-
特别是在高 rank(r=64, 128)时效果更好
-
2024年被集成到 HuggingFace PEFT 中
3.3 实战配置
HuggingFace PEFT 库使用
1 | import torch |
超参数最佳实践
| 超参数 | 推荐值 | 说明 |
|---|---|---|
| rank | 16-32 | 复杂任务用 32-64 |
| alpha | 2×rank | 常见设置 |
| dropout | 0.05 | 数据少时可增到 0.1 |
| lr | 1e-4 ~ 3e-4 | LoRA 比全参微调大10倍 |
| epochs | 2-5 | 数据少多跑几轮 |
| batch_size | 32-128(有效) | 通过梯度累积达到 |
| max_seq_len | 2048-4096 | 根据数据分布选择 |
| warmup | 3-10% | 总步数的比例 |
| weight_decay | 0.01-0.1 | 防止过拟合 |
四、QLoRA
4.1 原理
QLoRA(Quantized LoRA)是 2023 年由 Dettmers et al. 提出的方法,核心创新是在 4-bit 量化的模型上做 LoRA 训练。
4-bit NormalFloat (NF4) 量化
1 | 传统量化: 均匀分布的量化级别 |
NF4 的 16 个量化级别(4 bit = 2⁴ = 16 个值):
1 | [-1.0, -0.6962, -0.5251, -0.3949, -0.2844, -0.1848, -0.0911, 0.0, |
双重量化(Double Quantization)
1 | 第一层量化: 模型权重 fp16 → NF4 (每64个权重共享一个 fp32 缩放因子) |
分页优化器(Paged Optimizer)
1 | 问题: 训练中的显存峰值(前向+反向传播时)可能超出GPU显存 |
在量化模型上做 LoRA
4.2 优势与局限
显存节省数据
| 模型大小 | 全参微调 | LoRA (fp16) | QLoRA (NF4) |
|---|---|---|---|
| 7B | ~120GB | ~18GB | ~6GB |
| 13B | ~220GB | ~32GB | ~10GB |
| 30B | ~480GB | ~70GB | ~24GB |
| 70B | ~1120GB | ~160GB | ~48GB |
💡 QLoRA 使得 70B 模型在单张 A100 80GB 上可训练!
精度损失分析
| 对比 | MMLU | GSM8K | HumanEval |
|---|---|---|---|
| 全参微调 | 63.5 | 52.1 | 35.4 |
| LoRA fp16 | 63.1 | 51.5 | 34.8 |
| QLoRA NF4 | 62.8 | 50.8 | 34.1 |
| 损失 | ~1% | ~2.5% | ~3.6% |
结论:QLoRA 精度损失在 1-4% 范围内,对大多数应用可接受。
训练速度影响
-
QLoRA 比 LoRA fp16 慢约 30-50%(反量化计算开销)
-
但由于显存节省,可以用更大的 batch size 部分弥补
-
综合性价比:QLoRA 是资源受限场景的最优选择
4.3 实战
bitsandbytes 配置
1 | import torch |
与 LoRA 的对比实验数据
五、RLHF / DPO / GRPO
5.1 RLHF 三阶段
总体流程
阶段1: SFT(已在前面详述)
用指令数据训练基础模型,获得初始的指令遵循能力。
阶段2: 奖励模型训练
1 | 输入: prompt x + response y |
1 | # 奖励模型训练(简化版) |
阶段3: PPO 优化
1 | 目标函数: |
PPO 的 KL 惩罚为什么重要?
没有 KL 惩罚时:
-
模型会学会"欺骗"奖励模型(reward hacking)
-
例如生成冗长但无意义的回复来获得高分
-
输出会变得不自然
5.2 DPO(Direct Preference Optimization)
核心思想:跳过奖励模型
1 | RLHF: 数据 → 训练RM → PPO训练 (复杂、不稳定) |
DPO 的关键洞察:奖励函数可以用最优策略的闭式解表示,从而跳过显式奖励建模。
数学推导(简化版)
1 | RLHF 的最优解: |
优缺点
| 维度 | DPO | PPO (RLHF) |
|---|---|---|
| 实现复杂度 | ✅ 简单 | ❌ 复杂(4个模型) |
| 训练稳定性 | ✅ 稳定 | ❌ 不稳定 |
| 显存需求 | ✅ 2个模型 | ❌ 4个模型 |
| 超参数敏感度 | ✅ 少(主要是β) | ❌ 多 |
| 效果上限 | ⚠️ 受限于离线数据 | ✅ 在线探索更强 |
| 奖励过优化 | ⚠️ 可能 | ⚠️ 可能但可控 |
代码思路
1 | from trl import DPOTrainer, DPOConfig |
5.3 DeepSeek GRPO
Group Relative Policy Optimization
GRPO 是 DeepSeek 在 DeepSeek-R1 中使用的对齐方法,核心改进:
1 | PPO: 一个样本 → 一个奖励值 → 需要 Critic 网络估计基线 |
1 | GRPO 流程: |
为什么 DeepSeek 选择 GRPO?
-
省资源:不需要 Critic 网络,减少 ~25% 显存
-
更稳定:组内相对排序比绝对奖励更鲁棒
-
适合推理任务:可以用规则奖励(如数学答案正确性)替代奖励模型
-
可扩展:G 越大,梯度估计越准确
1 | DeepSeek-R1 的奖励设计: |
5.4 偏好数据构建
人工标注 vs AI标注(RLAIF)
| 方法 | 成本 | 质量 | 规模 | 代表 |
|---|---|---|---|---|
| 人工标注 | $$$$ | ✅ 最高 | 小(千级) | InstructGPT |
| AI标注(RLAIF) | $ | 较高 | 大(万级) | Constitutional AI |
| 混合方案 | $$ | 高 | 中等 | LLaMA-2 |
AI标注(RLAIF)流程:
1 | 1. 给同一个 prompt 生成多个回复(不同模型或不同采样) |
数据格式
1 | // 标准偏好数据格式 |
六、训练工具链
6.1 框架对比
| 特性 | HuggingFace TRL | LLaMA-Factory | Axolotl | OpenRLHF |
|---|---|---|---|---|
| SFT | ✅ | ✅ | ✅ | ✅ |
| LoRA/QLoRA | ✅ | ✅ | ✅ | ✅ |
| DPO | ✅ | ✅ | ✅ | ✅ |
| RLHF/PPO | ✅ | ✅(基础) | ❌ | ✅(专精) |
| GRPO | ✅ | ✅ | ❌ | ✅ |
| Web UI | ❌ | ✅(LLaMA Board) | ❌ | ❌ |
| 多模态 | ✅ | ✅ | ⚠️ 有限 | ❌ |
| 上手难度 | 中 | ✅ 最简单 | 中 | 较难 |
| 配置方式 | Python代码 | YAML/Web | YAML | Python |
| 分布式 | ✅ DeepSpeed/FSDP | ✅ DeepSpeed | ✅ DeepSpeed | ✅ Ray+vLLM |
| 社区活跃度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 适合场景 | 研究/灵活定制 | 快速上手/生产 | 灵活配置 | 大规模RLHF |
推荐选择:
-
🔰 入门/快速实验 → LLaMA-Factory(YAML 配置,带 Web UI)
-
🔬 研究/自定义 → HuggingFace TRL(灵活,文档最全)
-
🏗️ 大规模 RLHF → OpenRLHF(Ray 分布式,支持 70B+ 模型 PPO/GRPO)
-
⚙️ 多实验配置管理 → Axolotl(YAML 配置管理优秀)
6.2 训练基础设施
单卡 vs 多卡 vs 多机
DeepSpeed vs FSDP
| 维度 | DeepSpeed | PyTorch FSDP |
|---|---|---|
| 维护方 | 微软 | PyTorch 官方 |
| ZeRO 支持 | Stage 1/2/3 | 等效 Stage 2/3 |
| CPU Offload | ✅ 成熟 | ✅ |
| 配置方式 | JSON 配置文件 | Python API |
| 生态集成 | HuggingFace/各框架 | PyTorch 原生 |
| 推荐 | ✅ 目前更成熟 | 🔄 快速追赶中 |
显存需求计算公式
七、面试题(20题)+ 完整参考答案
1. LoRA的原理?rank r怎么选?
答: LoRA(Low-Rank Adaptation)的核心思想是将微调过程中的权重更新矩阵 ΔW 分解为两个低秩矩阵的乘积:ΔW = BA,其中 B ∈ ℝ^{d×r},A ∈ ℝ^{r×k},r << min(d, k)。前向传播时 Y = W₀X + BAX,其中 W₀ 冻结,只训练 A 和 B。初始化时 B=0 保证训练起点不改变原模型。
为什么有效? 基于内在维度假说——预训练模型的任务适应只需在一个低维子空间中进行。Aghajanyan et al. 实验表明,即使将微调限制在很低维的子空间,仍能保留 90%+ 的全参微调性能。
rank r 选择策略:
-
r=8:简单分类、情感分析等任务足够
-
r=16:通用指令微调的推荐起点
-
r=32-64:复杂任务(代码生成、数学推理)
-
2024年最佳实践:用
target_modules="all-linear"+ 较低 rank (8-16),效果优于少模块 + 高 rank
实际操作:先用 r=16 跑 baseline,如果欠拟合则增加 rank;如果过拟合则减小 rank 或增加 dropout。一般 r=16 + alpha=32 覆盖 80% 场景。
2. QLoRA相比LoRA多了什么?为什么能省显存?
答: QLoRA 在 LoRA 基础上增加了三项关键技术:
1. NF4 量化: 将基础模型从 fp16(16 bit)量化到 NF4(4 bit)。NF4 是专为正态分布权重设计的量化类型,其 16 个量化级别按正态分布分位数排列,信息损失最小。一个 7B 模型从 14GB (fp16) 降到 3.5GB (NF4)。
2. 双重量化(Double Quantization): 量化过程中每 64 个权重需要一个 fp32 的缩放因子(scale),双重量化把这些缩放因子进一步量化到 fp8,额外节省约 0.4GB/7B参数。
3. 分页优化器(Paged Optimizer): 利用 NVIDIA 统一内存机制,当 GPU 显存不足时自动将优化器状态临时转移到 CPU 内存,类似操作系统的 swap。
显存节省原理: LoRA fp16 中基础模型仍然以 fp16 存储(7B×2=14GB),QLoRA 将其压缩到 NF4(7B×0.5=3.5GB),LoRA 的 A/B 矩阵仍用 bf16 训练但参数量只有全模型的 ~1%。结果是 7B 模型从 ~18GB 降到 ~6GB,70B 模型可以在单张 A100 80GB 上训练。代价是训练速度慢 30-50%(反量化计算开销)。
3. SFT的训练数据如何构建?数据质量和数量哪个更重要?
答: 数据质量远比数量重要,这是 2023-2025 年的核心共识。
数据构建流程:
-
确定任务类型:指令遵循、对话、代码、推理等
-
种子数据收集:人工编写 200-500 条高质量样本
-
数据扩充:用 Self-Instruct 或 Evol-Instruct 合成更多数据
-
质量过滤:去重(MinHash)、去短回复、去低质量样本
-
多样性保证:覆盖不同任务类型、难度级别、输出格式
关键数据格式:Alpaca 格式 {instruction, input, output} 用于简单任务;ShareGPT/ChatML 格式用于多轮对话。
质量 vs 数量的研究证据:
-
LIMA 论文:仅 1000 条精选数据微调 LLaMA-65B,媲美 GPT-4
-
Deita 研究:6K 精选 > 100K 随机
-
数据质量三要素:准确性 > 多样性 > 复杂度
实践建议: 先用 1000-5000 条高质量数据训练,评估效果,再决定是否扩充。扩充时优先提高多样性而非数量。使用 GPT-4 生成数据后必须人工审核至少 10%。
4. 全参微调 vs LoRA 各自适用场景?
答:
全参微调适用场景:
-
需要模型深度领域适配(如训练一个医疗专用模型)
-
训练数据量大(>100K 条)
-
有充足 GPU 资源(多卡或大显存)
-
追求效果上限,对成本不敏感
-
任务与预训练分布差异大(如新语言或特殊领域)
LoRA 适用场景:
-
资源受限(单卡或消费级 GPU)
-
快速实验迭代(训练快,可以多跑几组超参)
-
需要多个任务特化版本(每个任务一个 LoRA adapter,共享基座模型)
-
部署灵活性(可以在推理时动态加载不同 LoRA)
-
数据量适中(1K-50K)
效果对比: 在大多数下游任务上,LoRA 可以达到全参微调 95%+ 的效果。当 rank 增大到 64-128 时差距更小。但在需要模型学习全新知识分布的场景(如从英文模型训中文能力),全参微调仍然明显更优。
2025年趋势: LoRA 已成为默认选择,全参微调仅在特定场景使用。多 LoRA 服务(如 S-LoRA、PunicaV2)使得单基座模型可同时服务数百个 LoRA 适配器。
5. 微调 vs RAG,如何选择?
答: 这是最高频的架构决策问题,核心在于区分知识注入和行为改变。
选 RAG 的场景:
-
知识频繁更新(新闻、商品信息、法规变化)
-
需要引用来源(可追溯性要求)
-
知识量大且不断增长
-
需要精确的事实性回答(减少幻觉)
-
快速上线(天级别)
选微调的场景:
-
需要改变模型的输出风格/格式/语气
-
让模型学会特定的推理模式
-
需要降低推理延迟(无需检索步骤)
-
需要降低成本(用小模型+微调替代大模型+长prompt)
-
安全对齐和价值观定制
两者结合的场景(最强方案):
-
微调让模型学会使用检索结果的能力
-
RAG 提供实时知识,微调提供行为模式
-
例:微调模型学会 Agent 工具调用格式 + RAG 提供工具调用需要的文档
决策矩阵: 问自己两个问题——① 是否需要新知识?→ RAG;② 是否需要新行为?→ 微调。都需要 → 两者结合。
6. RLHF三阶段详解
答: RLHF(Reinforcement Learning from Human Feedback)包含三个阶段:
阶段1 — SFT: 用指令-回复对 (x, y) 训练基础模型,使其具备基本的指令遵循能力。通常用 1K-100K 高质量指令数据,训练 1-3 个 epoch。这一步是后续对齐的基础。
阶段2 — 奖励模型训练: 收集偏好数据 (x, y_w, y_l),其中 y_w 是人类偏好的回复,y_l 是不偏好的。用 Bradley-Terry 模型训练奖励模型:L = -log σ(r(x, y_w) - r(x, y_l))。奖励模型通常用 SFT 模型初始化,去掉最后的 LM head,换成输出标量的线性层。数据量一般需要 50K-500K 偏好对。
阶段3 — PPO优化: 这是最复杂的部分。训练循环为:① 用当前策略 π_θ 生成回复;② 用奖励模型打分;③ 用 GAE 计算优势函数;④ 用 PPO 目标函数更新模型。同时加入 KL 惩罚 β × KL(π_θ || π_ref) 防止模型偏离 SFT 基线太远(reward hacking)。整个过程需要同时维护 4 个模型:当前策略、参考策略(冻结的SFT模型)、奖励模型、价值模型(Critic),显存需求巨大。
InstructGPT 的成果: 1.3B 的 RLHF 模型效果优于 175B 的 GPT-3。
7. DPO和PPO的本质区别?
答: PPO(Proximal Policy Optimization) 是一种在线强化学习方法,需要四个模型:策略模型、参考模型、奖励模型、Critic模型。训练过程中策略模型会生成新的回复,由奖励模型实时评分,形成"探索-反馈-更新"的循环。优点是能持续探索新的回复空间,缺点是实现复杂、训练不稳定、资源消耗大。
DPO(Direct Preference Optimization) 将强化学习问题转化为分类问题。核心洞察:最优奖励函数可以用策略的闭式解表示,因此不需要显式训练奖励模型。只需两个模型(策略模型+参考模型),直接在偏好数据上优化,增大 chosen 回复的概率,减小 rejected 回复的概率。
本质区别:
-
PPO 是在线的:每步生成新数据 → 评分 → 更新,可以探索
-
DPO 是离线的:直接在静态偏好数据上优化,不生成新数据
-
PPO 理论上限更高(能探索到数据集未覆盖的好回复),但实践中 DPO 更容易获得稳定的好结果
-
2024-2025 年实践:大多数团队选择 DPO 或其变体(SimPO、ORPO)作为默认方案
8. DeepSeek的GRPO是什么?
答: GRPO(Group Relative Policy Optimization)是 DeepSeek 在 DeepSeek-R1 中使用的强化学习算法,核心创新是用组内相对排序代替 Critic 网络。
流程: 给定一个 prompt x,用当前策略采样 G 个回复(如 G=64)。用奖励函数(可以是规则或模型)给每个回复打分。然后在组内做标准化:r̂ᵢ = (rᵢ - mean) / std,将标准化后的分数直接作为优势函数,跳过 Critic 网络的估计。
与 PPO 的关键区别:
-
无需 Critic:PPO 需要额外的价值网络估计基线,GRPO 用组内均值作为基线,节省 ~25% 显存
-
相对评估:不关心绝对分数,只关心组内相对好坏,更鲁棒
-
规则奖励兼容:DeepSeek-R1 用简单规则(答案正确+1,错误-1,格式正确+0.5)代替神经网络奖励模型
DeepSeek 选择 GRPO 的原因: 在数学/代码推理任务中,正确性可以通过规则验证,不需要复杂的奖励模型。GRPO 简化了训练流水线,降低了资源需求,同时效果不输 PPO。这也是 DeepSeek-R1 能以较低成本训出强推理能力的关键技术之一。
9. LoRA的target_modules怎么选?
答: target_modules 决定了 LoRA 应用于模型的哪些权重矩阵。
Transformer 中的可选模块:
-
注意力层:q_proj, k_proj, v_proj, o_proj
-
FFN 层:gate_proj (或 fc1), up_proj, down_proj (或 fc2)
-
其他:embed_tokens, lm_head(通常不选)
选择策略演进:
-
2023 原始 LoRA:只选 q_proj + v_proj(论文实验结果)
-
2024 共识:选所有注意力层 q/k/v/o_proj
-
2025 最佳实践:
target_modules="all-linear"(所有线性层),配合较低 rank
实验数据(LLaMA-3-8B, MT-Bench):
| target_modules | 参数量 | 分数 |
|---|---|---|
| q,v | 0.4% | 7.31 |
| q,k,v,o | 0.8% | 7.52 |
| q,k,v,o + FFN | 1.6% | 7.68 |
| all-linear | 1.6% | 7.71 |
结论是覆盖更多模块 + 较低 rank 优于少模块 + 高 rank,因为这样能更均匀地调整模型各层的表示。注意力层主要影响"关注什么",FFN 层主要影响"如何处理",都应该调整。
10. alpha和rank的关系?
答: LoRA 的实际权重更新是 ΔW = (α/r) × BA,其中 α(alpha)和 r(rank)共同决定了更新的缩放因子 α/r。
设计意图: 当改变 rank 时,缩放因子 α/r 可以保持更新量的相对大小稳定。例如 α=16, r=16 时缩放=1;如果增大 r=32 但 α 不变,缩放=0.5,更新变小。这就是为什么通常 α = 2×r 或者固定 α 然后调整学习率。
常见配置模式:
-
α = r:缩放=1,最保守
-
α = 2r:缩放=2,推荐默认值(如 r=16, α=32)
-
固定 α 调 rank:一些实践者固定 α=16,只调 r。此时 r 越大缩放越小,需要相应增大学习率
rsLoRA 的改进: 将缩放因子改为 α/√r,使得不同 rank 下训练动态更一致。这在 r 较大时(64, 128)特别有用,避免缩放因子过小导致学习不充分。
实践建议: 入门使用 r=16, α=32 即可。调参时先固定 α/r=2 的比例,调整 rank 大小。如果使用 rsLoRA,可以更自由地选择高 rank。
11. 混合精度训练(bf16 vs fp16)的区别?
答: 两者都是 16 位浮点数,但位分配不同,导致特性差异显著:
fp16:5 位指数 + 10 位尾数 + 1 位符号
-
精度高(尾数 10 位)但数值范围小(最大 65504)
-
容易发生溢出(overflow)和下溢出(underflow)
-
必须使用 loss scaling 防止梯度下溢出
-
适用于 V100、T4、RTX 3090 等 Ampere 之前的 GPU
bf16:8 位指数 + 7 位尾数 + 1 位符号
-
精度稍低(尾数 7 位)但数值范围大(与 fp32 相同)
-
不需要 loss scaling,训练更稳定
-
适用于 A100、H100、RTX 4090 等 Ampere 及之后的 GPU
-
2024-2025 年的默认选择
对训练的影响:
-
fp16 训练可能出现 loss spike(梯度溢出导致),需要仔细调参
-
bf16 训练几乎不会出现数值问题,但最终精度可能略低于 fp16(尾数少 3 位)
-
对于 LLM 微调,bf16 的精度损失可忽略不计
1 | # 检查GPU是否支持bf16 |
12. DeepSpeed ZeRO三个Stage分别优化什么?
答: ZeRO(Zero Redundancy Optimizer)通过在多个 GPU 间分片存储来消除冗余:
Stage 1 — 优化器状态分片:
-
分片内容:AdamW 的一阶动量、二阶动量、fp32 参数副本
-
每张 GPU 只存 1/N 的优化器状态(N=GPU数量)
-
显存节省:~4×(对于 AdamW,优化器状态占训练显存的 75%)
-
通信开销:与 DDP 相同(只需 AllReduce 梯度)
-
适用:2-8卡场景,简单高效
Stage 2 — 优化器状态 + 梯度分片:
-
在 Stage 1 基础上,梯度也分片存储
-
每张 GPU 只存 1/N 的梯度
-
显存节省:~8×
-
通信:Reduce-Scatter(梯度)+ AllGather(更新后参数)
-
适用:中等规模模型(13B-30B)
Stage 3 — 优化器状态 + 梯度 + 模型参数分片:
-
最激进的分片策略,模型参数本身也分片
-
每张 GPU 只存 1/N 的一切
-
显存节省:与 GPU 数量线性相关
-
通信开销最大(前向/反向传播时需要 AllGather 拉取参数)
-
支持 CPU Offload 进一步扩大容量
-
适用:超大模型(70B+)或显存紧张场景
选择建议: 能用 Stage 1 就不用 Stage 2,能用 Stage 2 就不用 Stage 3。通信开销:Stage 1 < Stage 2 < Stage 3。
13. 微调后模型效果变差(灾难性遗忘)怎么办?
答: 灾难性遗忘是微调中最常见的问题——模型学会了新任务但忘记了旧能力。解决方案:
1. 混合训练数据: 在微调数据中混入部分通用数据(如原始预训练数据的子集)。比例建议:专业数据 70% + 通用数据 30%。
2. 降低学习率: 使用更小的学习率(如从 2e-4 降到 5e-5),减少对原始权重的修改幅度。
3. 使用 LoRA 而非全参微调: LoRA 只修改 <2% 的参数,天然具有对抗遗忘的能力。论文数据显示 LoRA 微调的遗忘程度比全参微调低 50%+。
4. 减少训练轮数: 过多 epoch 会加剧过拟合和遗忘。通常 2-3 个 epoch 足够,超过 5 个 epoch 风险增大。用验证集 early stopping。
5. L2 正则化 / 权重衰减: weight_decay=0.01-0.1,约束参数不要偏离预训练值太远。
6. EWC(弹性权重合并): 计算每个参数对旧任务的重要性,重要的参数少更新。理论上优雅但实践中计算成本高。
7. 评估方法: 同时在新任务和旧任务上评估。推荐用 MMLU、GSM8K 等通用基准持续监控模型的通用能力。
14. 如何评估微调效果?
答: 评估需要覆盖多个维度:
1. 自动评估基准:
| 基准 | 评估能力 | 说明 |
|---|---|---|
| MMLU | 通用知识 | 57个学科,选择题 |
| GSM8K | 数学推理 | 小学数学应用题 |
| HumanEval | 代码能力 | 函数级代码生成 |
| MT-Bench | 对话质量 | GPT-4 打分,1-10分 |
| AlpacaEval | 指令遵循 | 与 GPT-4 对比胜率 |
| IFEval | 指令遵循 | 精确指令遵循度 |
2. 人工评估: 抽样 100-200 条,多人盲评。评估维度:准确性、有用性、安全性、格式遵循。
3. A/B 测试: 将微调模型和基线模型对同一问题生成回复,让评判者(人或 GPT-4)选择更好的。
4. 领域特定评估: 根据具体任务设计。如 Agent 场景评估工具调用准确率、Function Calling 格式正确率等。
5. 过拟合检测: 监控训练 loss vs 验证 loss 的差距。如果训练 loss 很低但验证 loss 不降反升,说明过拟合。
6. 灾难性遗忘检测: 在 MMLU 等通用基准上对比微调前后的得分变化。
15. 训练数据有偏见/噪声怎么处理?
答:
识别偏见/噪声:
-
统计分析:检查类别分布是否均衡,某些 pattern 是否过度出现
-
嵌入聚类:用 Sentence-BERT 编码后聚类,发现异常簇
-
人工抽样审查:随机抽取 5-10% 样本人工检查
处理策略:
1. 数据清洗:
1 | # 去除噪声数据 |
2. 数据均衡: 对少数类别进行上采样,或对多数类别下采样。也可以对不同类别设置不同的 loss 权重。
3. 对抗训练: 训练中加入对偏见的反例数据,主动纠偏。
4. 数据增强: 用改写、回译等方式增加多样性,稀释噪声。
5. 训练后去偏: 微调后用 DPO 进一步对齐,通过偏好数据纠正偏见输出。
核心原则: "垃圾进,垃圾出"。宁可用少量高质量数据,也不要用大量低质量数据。数据清洗的投入回报是最高的。
16. 如何估算微调所需的GPU资源?
答:
快速估算公式:
1 | 全参微调显存 ≈ 参数量(B) × 18 GB (fp16 + AdamW) |
详细计算(以 7B fp16 全参微调为例):
-
模型参数:7B × 2 bytes = 14 GB
-
梯度:7B × 2 bytes = 14 GB
-
AdamW 优化器:7B × 12 bytes = 84 GB(fp32参数+一阶动量+二阶动量)
-
激活值:~8 GB(取决于 batch_size 和 seq_len)
-
总计:~120 GB → 需要 2× A100 80GB
不同场景的最低配置:
| 模型 | 方法 | 最低GPU配置 |
|---|---|---|
| 7B | QLoRA | 1× RTX 4090 (24GB) |
| 7B | LoRA | 1× A100 40GB |
| 7B | 全参 | 2× A100 80GB |
| 13B | QLoRA | 1× RTX 4090 (24GB) |
| 70B | QLoRA | 1× A100 80GB |
| 70B | LoRA | 4× A100 80GB |
还需考虑: batch_size(增大需更多显存)、序列长度(2048 vs 4096 差别 2-3×)、是否使用梯度检查点(可省 40-60% 激活值显存)、Flash Attention(省 ~20% 显存)。
17. LoRA权重如何合并到基础模型?
答:
合并原理: LoRA 训练后得到 A 和 B 两个低秩矩阵。合并就是将 W_merged = W₀ + (α/r) × BA 计算出来,得到完整的权重矩阵。
代码实现:
1 | from peft import PeftModel |
合并 vs 不合并的取舍:
-
合并部署:推理时无额外开销,但每个任务需要一份完整模型
-
不合并部署:基座共享 + 动态加载 LoRA,适合多任务场景
-
多 LoRA 服务:S-LoRA、LoRAX 等框架支持单基座 + 数百个 LoRA 动态切换
注意事项: 合并后的模型无法再拆分回基座+LoRA。建议保留原始 LoRA 权重备份。QLoRA 合并需先反量化基座模型到 fp16/bf16。
18. 多轮对话数据的loss mask是什么?
答: 在多轮对话训练中,一条训练样本包含多轮 user-assistant 交替。Loss mask 决定了哪些 token 参与 loss 计算。
标准做法:只对 assistant 的回复计算 loss
1 | tokens: [SYS] 你是AI助手 [USER] 你好 [ASST] 你好! [USER] 天气呢? [ASST] 今天晴天 |
为什么要 mask?
-
如果对 user 部分也计算 loss,模型会学着"生成用户说的话",产生角色混乱
-
System prompt 也不应该被学习(它是条件,不是要生成的内容)
-
只有 assistant 的回复才是模型需要学会生成的
实现方式:
1 | # 构建 labels |
进阶策略:
-
权重衰减:后面轮次的 loss 权重更大(后面轮依赖前面的上下文,更难)
-
仅最后一轮 loss:适合"思考链"场景,防止中间推理步骤过拟合
-
Packing:多个样本拼接到一个序列中,需要更精细的 attention mask 防止跨样本注意力
19. 指令微调和对齐微调有什么区别?
答:
指令微调(Instruction Tuning)— 教模型"怎么做":
-
目标:让 base 模型学会遵循人类指令
-
数据:(instruction, output) 对
-
方法:标准 SFT
-
效果:从"补全文本"变为"回答问题"
-
类比:教一个聪明人如何理解和执行任务指令
对齐微调(Alignment)— 教模型"怎么做得好":
-
目标:让模型输出符合人类偏好和价值观
-
数据:偏好对 (chosen, rejected)
-
方法:RLHF、DPO、GRPO 等
-
效果:从"能回答"变为"回答得好、安全、有用"
-
类比:教一个能干活的人如何做得让人满意
关系与区别:
1 | 预训练模型 → 指令微调(SFT) → 对齐微调(RLHF/DPO) |
2025年趋势: 两者的边界在模糊化。ORPO 等方法将 SFT 和对齐合并为一步。DeepSeek-R1 证明了在某些场景下可以跳过 SFT 直接从 base 模型做 RL。但主流流程仍然是 SFT → 对齐的两步走。
20. 2025年微调技术的前沿方向?
答:
1. 推理时训练(Test-Time Training / Compute):
-
不再只依赖离线微调,推理时动态调整模型
-
代表:o1/o3 的思维链搜索、DeepSeek-R1 的强化学习推理
2. 合成数据主导:
-
高质量合成数据+自动过滤成为主流
-
Magpie、Persona-Hub 等自动从模型中"蒸馏"指令数据
-
RLAIF(用 AI 代替人类做偏好标注)成本降低 100×
3. 多模态微调:
-
视觉-语言模型(VLM)的 LoRA 微调成为标配
-
图片理解 + 视频理解 + 语音理解的统一微调
-
LLaVA-NeXT、Qwen2-VL 等开源多模态微调方案
4. 长上下文微调:
-
128K-1M 上下文窗口的高效微调技术
-
Ring Attention、序列并行等分布式长序列训练
-
位置编码外推(YaRN、NTK-aware)
5. MoE 模型微调:
-
Mixtral、DeepSeek-V3 等 MoE 架构的高效微调
-
选择性专家微调、专家合并等新方法
6. Agent 专用微调:
-
工具调用、多步推理、环境交互的专项微调
-
从 trajectory data(Agent 轨迹数据)中学习
-
强化学习 + 环境反馈的 Agent 训练(如 WebArena)
7. 联邦微调(Federated Fine-tuning):
-
数据不出域的分布式微调
-
结合 LoRA 降低通信成本
8. 极端效率:
-
1-bit LoRA、BitDelta 等极致压缩
-
在手机/边缘设备上微调(如 Apple MLX on iPhone)
-
训练-推理一体化优化
📌 总结: 微调技术从2023年的"百花齐放"进入2025年的"标准化+前沿探索"阶段。LoRA/QLoRA + DPO 已成为行业标配,前沿方向聚焦于推理增强、多模态和 Agent 能力的训练。掌握本指南的内容,足以应对 2025 年 Agent 工程师面试中 90%+ 的微调相关问题。