模型微调
模型微调(Fine-tuning)是在预训练模型的基础上,用特定数据继续训练模型,让它更适合某个领域、任务、风格或交互规范。
预训练模型已经学习了通用语言能力和大量世界知识,但它未必知道你的业务术语、输出格式、工具调用规则、审查标准或特定任务偏好。微调的目标不是从零训练一个模型,而是在已有能力上做定向适配。
在大语言模型场景中,微调常用于:
- 让模型稳定遵循特定指令格式、输出结构和回答风格。
- 提升模型在垂直领域任务上的表现,例如客服、法律、医疗、金融、代码和数据分析。
- 把专家标注、历史业务案例或高质量合成数据转化为模型行为。
- 训练更小的专用模型,用较低推理成本完成固定任务。
- 配合 RAG、工具调用、评估系统和安全策略,形成完整的应用闭环。
1. 核心思想
预训练阶段解决的是“模型是否具备通用语言和知识基础”的问题;微调阶段解决的是“模型是否按你希望的方式完成任务”的问题。
可以把微调理解为对模型参数的一次定向更新。训练时,模型先根据输入生成预测,再把预测结果和目标答案计算损失,最后通过反向传播更新部分或全部参数。
微调学习的通常不是单一知识点,而是一组模式:
- 遇到某类输入时应该如何理解任务。
- 应该输出什么格式、语气和粒度。
- 哪些回答是好的,哪些回答应该避免。
- 如何处理领域术语、边界条件和异常场景。
- 在多轮对话中如何保持上下文一致。
因此,微调更适合固化行为和能力模式,而不是临时补充经常变化的事实。
2. 微调与提示词、RAG 的区别
微调、提示词工程和 RAG 都能改善模型效果,但解决的问题不同。
| 方法 | 改变的对象 | 适合解决的问题 | 不适合的问题 |
|---|---|---|---|
| 提示词工程 | 输入上下文 | 快速约束格式、角色和任务步骤 | 大规模稳定复制复杂行为 |
| RAG | 外部知识上下文 | 检索最新资料、私有文档和可溯源事实 | 让模型长期内化固定行为 |
| 微调 | 模型参数或适配器参数 | 固化任务能力、格式偏好、领域风格和决策模式 | 高频更新的知识库检索 |
一个常见误区是认为“微调可以替代 RAG”。实际上二者更常见的关系是互补:
- RAG 负责给模型提供最新、可追溯、可替换的外部知识。
- 微调负责让模型更会使用这些知识,并按稳定格式完成任务。
如果问题是“模型不知道某份新文档内容”,优先考虑 RAG。如果问题是“模型总是不按业务规范回答”,微调通常更合适。
3. 常见微调类型
3.1 全量微调
全量微调会更新模型的大部分或全部参数。
优点:
- 表达能力强,理论上可改变模型较深层的行为。
- 适合数据充足、算力充足、目标任务复杂的场景。
缺点:
- 显存和训练成本高。
- 更容易破坏原模型已有能力。
- 模型版本管理和部署成本更高。
全量微调通常用于有明确模型资产规划、较大训练集和稳定评估体系的团队。
3.2 参数高效微调
参数高效微调(Parameter-Efficient Fine-Tuning, PEFT)只训练少量新增参数或部分参数,保留原模型主体权重不变。
常见方法包括:
- LoRA:在指定线性层旁边加入低秩矩阵,只训练这些低秩参数。
- QLoRA:在量化加载基础模型的同时训练 LoRA,进一步降低显存占用。
- Adapter:在模型层之间插入小型可训练模块。
- Prefix Tuning / Prompt Tuning:训练连续向量形式的软提示。
在实际 LLM 微调中,LoRA 和 QLoRA 最常见。它们成本低、易复现、便于合并或切换适配器,适合多数业务微调任务。
3.3 指令微调
指令微调(Instruction Tuning)使用“指令-回答”格式的数据训练模型,让模型更好地理解人类任务请求。
典型数据格式包括:
{
"instruction": "把下面这段客户反馈分类为正面、负面或中性。",
"input": "物流很快,但包装有破损。",
"output": "中性"
}
指令微调适合提升模型的任务理解、格式遵循和多任务泛化能力。
3.4 监督微调
监督微调(Supervised Fine-Tuning, SFT)使用高质量输入输出对训练模型,是最常见的大模型微调方式。
它常用于:
- 领域问答。
- 信息抽取。
- 分类和打标。
- 结构化生成。
- 代码生成。
- 多轮客服对话。
SFT 的关键不是数据越多越好,而是数据是否准确、覆盖面是否合理、输出是否符合目标风格。
3.5 偏好对齐微调
偏好对齐使用“哪个回答更好”的数据,让模型更贴近人类偏好或业务标准。
常见方法包括:
- DPO:直接用偏好对训练模型,不需要单独训练奖励模型。
- ORPO:把监督学习和偏好优化结合到一个目标中。
- KTO:使用“好 / 不好”反馈信号进行偏好优化。
- Reward Modeling:先训练奖励模型,再配合强化学习或采样策略优化。
这类方法适合处理“答案都能用,但质量有差异”的问题,例如更礼貌、更准确、更简洁、更符合安全规范。
3.6 继续预训练
继续预训练(Continued Pretraining)是在大量领域语料上继续做语言建模训练。
它不一定直接教模型完成某个任务,而是让模型更熟悉某个领域的语言分布、术语体系和表达习惯。
适合场景:
- 行业语料很多,但人工标注数据较少。
- 模型对领域术语、代码库、专业文档不熟。
- 需要先补充领域基础,再做 SFT 或偏好对齐。
4. LoRA 与 QLoRA
4.1 LoRA 的基本原理
LoRA(Low-Rank Adaptation)的核心思想是:不直接更新原模型的大矩阵,而是在目标层旁边训练两个较小的低秩矩阵。
可以简化理解为
原始输出可以写作:
加入 LoRA 后,输出变为:
其中:
W是冻结的原始权重。A和B是新增的低秩矩阵。- 训练时只更新
A和B。
这样做可以显著减少可训练参数量,同时保留原模型大部分能力。
4.2 LoRA 关键参数
| 参数 | 作用 | 影响 | 常见建议 |
|---|---|---|---|
r | 低秩矩阵的秩 | 越大表达能力越强,但显存、训练时间和过拟合风险更高 | 常从 16 或 32 开始 |
lora_alpha | LoRA 更新的缩放强度 | 越大越激进,越小越保守 | 通常设为 r 的 1-2 倍 |
lora_dropout | LoRA 路径上的 dropout | 可降低过拟合,但过大可能欠拟合 | 常用 0.05-0.1 |
target_modules | 注入 LoRA 的模块 | 模块越多可调能力越强,成本也越高 | 常见为 attention 和 MLP 投影层 |
bias | 是否训练 bias | 训练 bias 会增加少量参数 | 多数场景设为 none |
use_rslora | 使用 Rank-Stabilized LoRA | 高 rank 时可能更稳定 | 训练不稳定或 rank 较大时尝试 |
常见 target_modules 包括:
q_projk_projv_projo_projgate_projup_projdown_proj
具体名称取决于模型结构,不同模型系列可能不同。
4.3 QLoRA 的作用
QLoRA 通常会把基础模型以 4-bit 量化形式加载,再训练 LoRA 参数。
它的主要价值是降低显存门槛:
- 单卡也能微调较大的模型。
- 基础权重保持量化存储,LoRA 参数保持可训练。
- 适合实验、个人 GPU 和中小规模业务微调。
需要注意的是,QLoRA 省显存不等于没有成本。长上下文、大 batch、多模态数据和频繁评估仍然会显著增加显存和训练时间。
5. 训练数据
微调效果高度依赖数据质量。很多失败的微调不是模型不行,而是数据本身不稳定。
5.1 数据来源
常见数据来源包括:
- 人工标注的高质量样本。
- 历史客服、销售、运营或工单记录。
- 业务专家整理的标准问答。
- 规则系统或旧模型产出的结构化结果。
- 强模型生成后再经人工筛选的合成数据。
- RAG 系统中的真实问题和高质量答案。
5.2 数据格式
不同训练框架格式略有差异,但核心信息通常包括:
- 用户输入。
- 系统指令。
- 模型应该输出的答案。
- 多轮对话历史。
- 偏好数据中的 chosen / rejected 回答。
对话微调常见格式如下:
{
"messages": [
{"role": "system", "content": "你是一个严谨的合同审查助手。"},
{"role": "user", "content": "请检查这段条款是否存在付款风险。"},
{"role": "assistant", "content": "存在付款周期不明确的风险,建议补充具体付款日期和逾期责任。"}
]
}
5.3 数据质量检查
训练前建议重点检查:
- 答案是否事实正确。
- 格式是否统一。
- 是否存在互相矛盾的标注。
- 是否混入隐私、密钥、内部敏感信息。
- 是否覆盖真实输入中的边界情况。
- 是否存在大量重复样本。
- 是否把“不应该学的坏习惯”也写进了答案。
高质量的小数据集通常比低质量的大数据集更有价值。
6. 基本训练参数
| 参数 | 含义 | 调整影响 |
|---|---|---|
learning_rate | 每次参数更新的步长 | 过高容易不稳定或遗忘,过低可能学不动 |
num_train_epochs | 数据集被完整训练的轮数 | 过多容易过拟合,过少可能欠拟合 |
per_device_train_batch_size | 每张 GPU 单次处理的样本数 | 越大吞吐越高,但显存占用越高 |
gradient_accumulation_steps | 累积多少步梯度再更新参数 | 可在小显存下模拟更大 batch |
max_steps | 最大训练步数 | 常用于覆盖 epoch 设置,便于控制实验成本 |
warmup_ratio | 学习率预热比例 | 可提升训练初期稳定性 |
weight_decay | 权重衰减 | 用于正则化,降低过拟合风险 |
max_seq_length | 最大序列长度 | 越长越耗显存,截断会丢失上下文 |
eval_steps | 每隔多少步评估一次 | 越频繁越容易发现问题,但训练更慢 |
seed | 随机种子 | 用于提升实验可复现性 |
实践中不要只看训练 loss。训练 loss 下降并不代表模型在真实任务中更好,也可能只是记住了训练集。
7. 微调流程
一个较稳妥的微调流程通常包括:
- 明确目标:确定要提升的是格式遵循、领域能力、任务准确率还是偏好风格。
- 建立评估集:先准备不会进入训练集的测试样本。
- 准备训练数据:清洗、去重、统一格式并做敏感信息检查。
- 选择基座模型:根据语言、上下文长度、许可证、部署成本和任务难度选择模型。
- 选择微调方法:优先从 LoRA 或 QLoRA 开始。
- 小规模试训:用少量数据和短步数验证格式、脚本和指标是否正常。
- 正式训练:记录参数、数据版本、模型版本和随机种子。
- 离线评估:用固定评估集比较基座模型和微调模型。
- 人工抽检:检查真实业务样本、边界场景和失败案例。
- 部署灰度:小流量验证稳定性,再逐步扩大使用范围。
如果没有评估集,微调很容易变成“感觉更好了”。这会让后续迭代难以判断方向。
8. 评估指标
微调评估要和目标任务对应。
| 任务类型 | 常见指标 |
|---|---|
| 分类 | Accuracy、F1、Precision、Recall |
| 信息抽取 | 字段准确率、严格匹配率、缺失率、误抽率 |
| 问答 | 人工评分、事实一致性、引用命中率、拒答准确率 |
| 代码 | 单元测试通过率、编译通过率、静态检查结果 |
| 对话 | 帮助性、准确性、简洁性、安全性、多轮一致性 |
| 格式生成 | JSON 可解析率、Schema 通过率、字段完整率 |
建议至少比较三组结果:
- 基座模型。
- 只改提示词或 RAG 后的模型。
- 微调后的模型。
这样才能判断微调是否真的带来了超过提示词和检索增强的收益。
9. 常见问题与风险
9.1 过拟合
模型在训练集上表现很好,但真实样本效果下降。常见原因包括数据太少、轮数太多、学习率太高或样本重复过多。
处理方式:
- 减少 epoch 或训练步数。
- 降低学习率。
- 增加验证集监控。
- 清理重复和低质量样本。
- 增加更真实的多样化数据。
9.2 灾难性遗忘
模型学会了新任务,但损失了原本的通用能力。
处理方式:
- 使用 LoRA 而不是全量微调。
- 降低学习率和训练强度。
- 混入少量通用指令数据。
- 保留基座模型评估项,避免只看目标任务。
9.3 格式学偏
训练数据格式不统一时,模型可能输出混乱。例如有些样本输出 Markdown,有些输出 JSON,有些输出解释文本。
处理方式:
- 明确统一的输出 schema。
- 删除不符合规范的数据。
- 在 system prompt 和训练答案中保持一致。
- 用自动化脚本检查 JSON、字段和标签。
9.4 数据污染
如果测试集样本混入训练集,评估结果会虚高。
处理方式:
- 训练前固定评估集。
- 做去重和相似度检查。
- 按时间、客户、项目或来源切分数据。
9.5 安全与合规风险
微调数据可能包含个人信息、内部资料、密钥、客户隐私或未经授权内容。模型也可能学习到不应该复述的敏感信息。
处理方式:
- 训练前脱敏。
- 删除密钥、账号、手机号、身份证号等敏感字段。
- 对输出做安全评估。
- 保留数据来源和授权记录。
10. 工具与框架
| 工具 | 特点 | 适合场景 |
|---|---|---|
| LLaMA-Factory | 配置友好,覆盖 SFT、LoRA、QLoRA、DPO 等流程 | 快速上手和常规业务微调 |
| Unsloth | 优化单卡训练速度和显存占用 | 消费级 GPU、LoRA/QLoRA 实验 |
| MS-SWIFT | 对 Qwen 等模型生态支持较好 | 中文模型、SFT、DPO 和部署联动 |
| XTuner | OpenMMLab 生态,配置灵活 | 中文模型、多模态和实验研究 |
| ColossalAI | 面向大规模分布式训练 | 多卡、多机和工程化训练 |
| Hugging Face TRL | 偏好优化和强化学习工具链完整 | DPO、奖励模型和对齐实验 |
选择工具时,不要只看是否“支持某个算法”,还要看数据格式、模型兼容性、断点续训、日志记录、评估集接入和部署路径是否顺畅。
11. 实践建议
微调前可以先问三个问题:
- 能不能用更好的提示词解决?
- 能不能用 RAG 提供外部知识解决?
- 是否有足够稳定、干净、可评估的数据?
如果答案仍然指向微调,建议从小实验开始:
- 先用 LoRA 或 QLoRA,不急着全量微调。
- 先准备评估集,再准备训练集。
- 先跑 100-500 条样本验证流程,再扩大数据规模。
- 每次只改少量变量,记录数据版本和训练参数。
- 把失败案例沉淀回数据集,而不是只调训练参数。
微调不是一次性操作,而是“数据、训练、评估、部署、反馈”的循环。
12. 总结
模型微调的本质是:用特定数据改变模型的行为分布,让模型更稳定地完成某类任务或遵循某种规范。它适合固化领域能力、输出格式、交互风格和偏好标准。
微调最重要的不是参数技巧,而是四件事:
- 目标是否清楚。
- 数据是否高质量。
- 评估是否可信。
- 部署后是否能持续收集反馈。
对于 LLM 应用来说,微调通常不是单独存在的。更常见的完整方案是:提示词定义任务边界,RAG 提供外部知识,微调固化行为模式,评估系统持续发现问题,最后通过数据迭代不断提升模型表现。