模型微调:从「会说话」到「会你的活」
预训练给模型装了世界知识,微调才真正把它变成你的同事。这篇把微调光谱讲透:SFT、指令模板、RLHF/DPO、LoRA/QLoRA、数据工程、超参直觉、评估回归——以及更重要的:什么时候根本不该微调。
为什么需要微调
基座模型什么都懂一点,为什么还是写不好你的工单摘要? 多写两段 prompt 能不能代替训练?什么时候不能?
微调(fine-tuning)是在已经预训练好的权重上,用更少、更对口的数据继续学——把「通才」压成「专才」,或把「会补全」练成「会听话」。
可以拿学徒做隐喻:预训练像把一个人扔进图书馆读了互联网;他词汇量大、常识多,但没跟过你的班组。微调是带他跟几周班:看你们怎么写 PR、怎么拒不安全请求、怎么把 JSON 字段填齐。他不是从零学语言,只是改习惯。
神经网络的知识主要压在权重里。预训练已经学到了语法、常识、推理的「基底」;微调只在这个基底上做小幅位移,所以用远少于预训练的数据与算力,就能换来领域语气、格式、任务流程上的大变化。
微调改的是默认行为,不是往脑子里塞一本新百科。
这也解释了三件常被搞混的事:
- 微调 ≠ 教新事实的最佳手段。 新法规、新 SKU、昨天的工单——优先 RAG / 工具检索;硬塞进权重容易过时、难审计。
- 微调擅长「怎么做」。 语气、步骤、输出 schema、拒答策略、工具调用习惯——这些是行为,适合写进权重。
- Prompt 是运行时说明书,微调是写进肌肉记忆。 Prompt 灵活、零训练成本;一旦同一套说明每请求都要贴几千 token,或规则复杂到提示词装不下,微调才划算。
适配光谱:从 Prompt 到全参
把「改模型」想成从轻到重的光谱。越往右,成本越高、行为越稳、回滚越难。
核心直觉:权重在学什么
训练一步,模型到底改了自己什么?
监督微调时,模型对每个该预测的 token 算交叉熵损失:预测越离谱,loss 越大。反向传播把「误差」传回权重,用学习率迈一小步。成千上万步后,模型在你的数据分布上更会「接下一词」。
几个必须刻进直觉的词
- Base / Instruct / Chat 模型:Base 多是「补全机」;Instruct/Chat 已经过 SFT(常再加对齐)。多数应用从 Instruct 再微调;从 Base 起步要自己扛指令能力。
- Epoch:整份训练数据过一遍叫 1 epoch。小高质量数据常 1–3 epoch;猛刷容易背答案(过拟合)。
- Learning rate:步子大小。太大震荡、忘掉预训练;太小学不动。LoRA 常用比全参更大的 LR(如 1e-4 量级,视模型而定)。
- Context / packing:样本拼进上下文窗口。packing 提高吞吐,但要注意样本边界与 attention 隔离。
- Catastrophic forgetting:专精过度 → 通用能力掉点。解药:混入通用数据、较小 LR、PEFT、早停、多任务混合。
SFT:用示范教行为
SFT 是微调宇宙的地基:给模型看「输入 → 理想输出」对,让它模仿。
形式可以是:指令–回答、对话多轮、(输入, 思维链, 答案)、工具调用轨迹。关键不在格式花哨,而在示范质量与分布覆盖。
SFT 真正优化的是什么
它优化的是「在类似输入下,产出类似输出」的条件概率。所以:
- 示范错 → 模型学会错(垃圾进垃圾出)。
- 示范风格单一 → 输出风格单一(有时是好事)。
- 示范从不拒答 → 模型很难学会拒答。
- 示范从不调用工具 → 别指望它会稳定调工具。
{
"messages": [
{"role": "system", "content": "你是内部工单助手,只输出合法 JSON。"},
{"role": "user", "content": "用户说打印机卡纸,影响出货。"},
{"role": "assistant", "content": "{\"priority\":\"P1\",\"team\":\"facilities\",\"summary\":\"打印机卡纸影响出货\"}"}
]
}
SFT 的天花板
SFT 教的是「像示范一样做」,不直接教「A 比 B 好」。当多条回答都语法正确、但你更想要简短/更安全/更敢拒时,需要偏好学习(第 06 章)。先 SFT 再 DPO,是业界常见两段式。
指令微调与对话模板
「指令微调」本质仍是 SFT,只是数据形态是「人类指令 + 助手回答」。真正把工程坑放大的是 chat template:模型训练时用的特殊符号、角色分隔、是否加 generation prompt。
训练用一套模板、推理用另一套——等于你用英文考试大纲教,考场却发中文卷。
- Hugging Face 上几乎每个 Instruct 模型都有
tokenizer.chat_template(Jinja)。微调时应用同一模板渲染 messages。 - 多轮对话要正确插入 assistant 轮次边界;截断时优先保最近轮次与系统提示。
- 若基座没有 chat 模板,你要自己定义并在训练/推理两端锁死版本。
apply_chat_template 打一条样本,肉眼看特殊 token 是否齐全,再开训练。偏好对齐:教模型「哪个更好」
两条回答都对,你为什么更喜欢短的那条?模型怎么学这种「品味」?
偏好对齐不给唯一标准答案,而给比较信号:chosen 优于 rejected。目标是把策略推向人类(或 AI)更认可的区域。
RLHF:经典三段
KL 惩罚防止策略漂得离 SFT 模型太远(胡言乱语换高分)。RLHF 强但重:要训 RM、要在线采样、超参敏感、工程复杂。
DPO:绕过显式奖励模型
Direct Preference Optimization(Rafailov et al., 2023)证明:在一定假设下,可把偏好目标改写成对策略的分类式损失——直接拉高 chosen 相对 rejected 的对数概率比,并相对参考模型(通常是 SFT 模型)做隐式约束。
实现简单、不需在线 RL 环、在开源社区与中小团队可复现性高。很多「对齐」流水线变成:高质量 SFT → 偏好对上跑 DPO/ORPO。
{
"prompt": "用一句话解释向量数据库。",
"chosen": "用向量相似度检索非结构化内容的数据库。",
"rejected": "向量数据库是一种非常重要且在现代人工智能与大语言模型检索增强生成场景中被广泛讨论的……(空话 200 字)"
}
一族变体,怎么记
| 方法 | 核心想法 | 你何时考虑 |
|---|---|---|
| RLHF (PPO 等) | 显式 RM + 在线 RL | 资源足、要极致控行为、有对齐团队 |
| DPO | 偏好对 → 直接优化策略 | 开源默认首选之一;已有 SFT 与偏好数据 |
| ORPO | SFT + 偏好信号合一 | 想少一阶段、数据同时含对错示范 |
| KTO | 只需「好/坏」不必成对 | 容易标二元反馈、难凑 pair |
| RLAIF | 用 AI 当偏好标注员 | 规模化标注;需防教师模型偏见 |
方法名是地图,不是宗教。先有可靠偏好数据,再挑算法。
PEFT:用 1% 参数办 80% 的事
Parameter-Efficient Fine-Tuning:冻结原模型绝大部分权重,只训练少量附加参数。省显存、省时间、可多任务切换。
LoRA 一句话几何
对某个大矩阵 W(如注意力的 Q/V 投影),不直接改 W,而学两个瘦矩阵 A、B,令更新 ΔW ≈ B A(低秩分解)。秩 r 很小(如 8、16、64)时,可训练参数暴降。
QLoRA:量化 + LoRA
把基座权重量化到 4-bit(如 NF4)以塞进小显存,再在其上挂 LoRA 以较高精度训练适配器。思想:冻住的大身子用廉价存储,学习的小补丁用认真精度。这是消费级单卡微调 7B–70B 级模型的主流配方之一。
还有哪些亲戚
- DoRA:把权重幅度与方向解耦再适配,常比同设置 LoRA 更稳一点。
- Adapter / (IA)3 / Prefix-Tuning:插小模块或前缀向量;LoRA 因可合并、生态好而成事实标准。
- 多 LoRA:客服 / 代码 / 法务各一个 adapter,推理时切换或组合——像给同一大脑换不同技能卡。
数据工程:微调的真正护城河
算法差一档可以换;数据差一档,训练只会更高效地学会错误。
业界共识几乎一边倒:数据质量 > 数据数量 > 花哨算法。1 万条精修示范,往往打赢 100 万条网页噪声。
五条硬规则
- 先写失败案例。 线上哪类输出不合格?每类至少凑齐足够「正确示范」。微调是在补行为漏洞,不是堆样本量。
- 覆盖边界。 拒答、模糊意图、多语言、超长输入、工具失败重试——训练集里没有,上线必翻车。
- 防泄漏。 评估集必须与训练严格隔离;从同一会话切两边会虚高分数。
- 合成数据要「验货」。 用强模型造数很快,但会复制教师偏见与模板腔。抽检 + 规则过滤 + 少量人审。
- 隐私与合规。 日志进训练集前脱敏;客户数据、密钥、PII 是红线。能进 RAG 的机密别写进权重。
训练动力学:少踩坑的旋钮
超参没有宇宙真理,只有可复现的起点 + 看曲线决策。下面是开源社区反复验证过的直觉(具体数字随模型与框架变,当指南不当教条)。
| 旋钮 | 常见起点(LoRA/SFT) | 症状 → 调整 |
|---|---|---|
| 学习率 | 1e-4 量级(LoRA);全参更小 | loss 炸 / 胡言 → 降 LR;几乎不动 → 略升或查数据 |
| Epoch | 1–3(小精数据) | 训练 loss 极低、评测掉点 → 过拟合,减 epoch / 增数据 |
| 有效 batch | 梯度累积凑 32–128 | 不稳 → 加大有效 batch 或降 LR |
| 序列长 | 贴合真实任务,勿盲目 128k | 过长浪费算力;过短截断关键指令 |
| LoRA r / α | r=8–64;α 常 2r 或与 r 同量级 | 欠拟合 → 加 r 或解冻更多模块;过拟合 → 减 r / 增 dropout |
| 预热与调度 | 短 warmup + cosine/linear decay | 前期尖刺 → 加 warmup |
工程上省显存的几板斧
- 梯度检查点(gradient checkpointing)
- Flash Attention / 高效注意力实现
- 8-bit/4-bit 基座 + LoRA(QLoRA)
- 梯度累积代替超大 batch
- 冻结 embedding / 只挂部分层的 LoRA
评估:你怎么知道「变好了」
没有评估的微调是玄学。评估要回答两件事:目标任务更好了吗?别的能力坏了吗?
建议把评估集当产品资产版本管理:每次改数据或超参,跑同一套套件,生成「变好 / 变坏」表再决定是否发布。
何时不该微调
你确定问题出在权重,而不是检索、工具或产品流程?
实战:工具栈与一条推荐路径
常见工具(按角色)
- 训练框架:Hugging Face TRL(SFT/DPO 教练脚本)、Axolotl、LLaMA-Factory、Unsloth(速度/显存友好)、DeepSpeed / FSDP(多卡)。
- PEFT 库:
peft(LoRA 配置与合并)、bitsandbytes(量化)。 - 数据:自建 JSONL + 严格 schema;开源指令集仅作「通用复训」辅料。
- 推理:vLLM / SGLang / llama.cpp;LoRA 可 merge 或动态加载。
- 托管微调:云厂商与模型 API 的 fine-tuning 端点——适合不想碰 GPU 的团队,但要接受平台约束与数据出境策略。
一条务实默认路径
# 概念流程,非某一框架的可复制脚本 base = load_instruct_model(..., load_in_4bit=True) model = attach_lora(base, r=16, alpha=32, target=["q_proj","v_proj"]) train_sft(model, dataset, lr=1e-4, epochs=2, on_responses_only=True) metrics = eval_suite(model, gold_set) # schema + 人工抽检 + 回归 if metrics.pass_gate: export_or_merge_lora(model) else: diagnose(data_bugs=True, lr=True, template=True)
发布前 10 问
- 训练/推理 chat template 是否一致?
- loss 是否只算在 assistant?
- 评估集是否与训练隔离?
- 结构化输出通过率比基线如何?
- 通用与安全集是否回归?
- 隐私数据是否脱敏?
- 是否保留基线模型可一键回滚?
- LoRA 是 merge 还是多卡路由?版本怎么管?
- 线上监控哪些业务指标?
- 失败时,是数据问题还是算法问题——你有没有样本级 error analysis?
微调的终局不是「训了一个模型」,而是「建了一条可回归的行为改进流水线」。
参考资料
概念与方法名核实于公开论文与主流工程文档;具体超参随模型与版本变化,以你所用框架文档为准。本文侧重建立完整心智模型,而非某一供应商的操作手册。