一、什么是 SFT
SFT = Supervised Fine-Tuning(监督微调)
SFT 是在预训练模型 基础上,用带标注的数据做进一步训练,让模型学会按人类意图回答问题。
预训练(Pre-training) → 学到通用知识(但不会"听话")
↓
SFT(监督微调) → 学会按指令做事(问答、对话、图文理解)
↓
RLHF/DPO(可选) → 进一步优化输出质量(对齐人类偏好)
预训练 vs SFT 对比
| 预训练 | SFT | |
|---|---|---|
| 目标 | 预测下一个 token(自监督) | 按指令生成正确答案(监督) |
| 数据 | 海量无标注文本(TB 级) | 少量高质量标注数据(万~百万条) |
| 任务 | 语言建模(next token prediction) | 指令跟随(instruction following) |
| 输出 | 续写文本(不会问答) | 回答问题、执行任务 |
例子:
- 预训练后:输入"中国的首都是" → 输出"哪里?"(只会续写)
- SFT 后:输入"中国的首都是哪里?" → 输出"北京。"(会回答问题)
二、SFT 在多模态训练管线中的位置
多模态训练分三层:
① 视觉与语言预对齐 → 让视觉"接得上"语言空间(大量图文对,冻结主体训 Connector)
② 指令微调(SFT) → 让模型"按任务说话"(高质量指令数据,训 LLM 部分参数)
③ 偏好对齐/任务特化 → 让模型"更像产品"(DPO/KTO/RLHF,进一步减少幻觉)
SFT 是中间层------预对齐解决"能不能看图",SFT 解决"会不会按要求回答",偏好对齐解决"回答得好不好"。
SFT 的作用
- 让模型"听话":预训练模型只会续写,SFT 后能按指令做事
- 注入领域知识:用医疗/法律/金融数据微调,得到专业模型
- 控制输出格式:让模型输出 JSON、表格、代码等结构化内容
- 多模态对齐:让视觉编码器学到的特征与语言模型的指令跟随能力结合
三、SFT 的数据类型
SFT 的效果由数据配方决定。5 类关键数据:
| 数据类型 | 目标能力 | 典型样本 |
|---|---|---|
| 图文描述 | 基础语义对齐 | "请描述这张图" → "一只猫坐在沙发上" |
| 图像问答(VQA) | 围绕问题提取证据 | "图中有几个人?" → "3 个人" |
| OCR 与文档 | 读字、读版面、读表格 | 票据/合同/PPT → 字段抽取 |
| Grounding/Referring | 定位与指代 | "左上角红色按钮在哪?" → 坐标框 |
| 推理数据 | 多步判断 | 图表推理、视觉数学、流程判断 |
核心警告 :如果训练集几乎都是"请描述图片",模型只会看图写说明文,不擅长复杂问答。数据配比决定能力分布。
四、SFT 的数据格式
多模态 SFT 数据采用交错图文格式(区别于纯文本 ShareGPT):
纯文本 ShareGPT 格式(LLM SFT)
json
{
"conversations": [
{"from": "human", "value": "请解释什么是梯度下降。"},
{"from": "gpt", "value": "梯度下降是一种优化算法..."}
]
}
多模态交错图文格式(VLM SFT)
json
{
"id": "sft-042",
"images": ["receipt_001.png", "receipt_002.png"],
"messages": [
{
"role": "user",
"content": [
{"type": "image", "image": "receipt_001.png"},
{"type": "text", "text": "这张发票总金额是多少?"}
]
},
{
"role": "assistant",
"content": [{"type": "text", "text": "总金额为 ¥1,280.00。"}]
},
{
"role": "user",
"content": [
{"type": "image", "image": "receipt_002.png"},
{"type": "text", "text": "两张发票的总金额差多少?"}
]
},
{
"role": "assistant",
"content": [{"type": "text", "text": "第二张总金额为 ¥956.50,两张相差 ¥323.50。"}]
}
]
}
关键差异
| 维度 | 纯文本 ShareGPT | 多模态交错图文 |
|---|---|---|
| 内容类型 | 纯文字 value 字段 |
content 为列表,可混合 image 和 text |
| 图片引用 | 无 | images 列表存放路径,content 中用 {"type": "image"} 引用 |
| 多图支持 | 不适用 | 同一轮可插入多张图,多轮可交替图文 |
| 数据校验 | 只需检查文本非空 | 需额外检查图片是否存在、路径是否匹配、分辨率是否合理 |
关键 :content 是列表,可混合 image 和 text,天然支持多图、多轮、图文交错。每条样本不仅要保证文本质量,还要保证图文对应关系正确。
五、SFT 的训练策略
5.1 全量微调 vs LoRA vs QLoRA
| 策略 | 做法 | 适用场景 | 代价 |
|---|---|---|---|
| 全量微调 | 更新所有参数 | 资源充足、数据量大 | 显存大、易过拟合 |
| LoRA | 冻结主体,注入低秩矩阵 | 资源有限、场景适配 | 表达能力受限 |
| QLoRA | 4-bit 量化 + LoRA | 单卡微调 7B~13B | 轻微精度损失 |
5.2 LoRA 关键参数
| 参数 | 含义 | 常见值 | 影响 |
|---|---|---|---|
| rank ® | 低秩矩阵的秩 | 8, 16, 32, 64 | 越大表达能力越强,显存和训练时间也越高 |
| alpha | 缩放系数 | rank 或 2×rank | 控制 LoRA 输出对原模型的影响强度 |
| target_modules | 注入哪些层 | 因模型而异 | 决定哪些注意力/FFN 层参与微调 |
target_modules 参考值:
- Qwen2.5-VL:
["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"] - LLaVA:
["q_proj", "v_proj"](早期版本只调这两个) - 通用原则:先调 attention 的 q/v_proj,不够再加 FFN 层
5.3 QLoRA 说明
- 把基座模型先量化为 4-bit(NF4),再在 4-bit 模型上加 LoRA
- 效果:7B 模型可在 16GB 显存上微调,24GB 可微调 13B(具体与序列长度、batch size、gradient checkpointing 等相关)
- 代价:推理时需合并权重或保持量化状态,轻微精度损失
六、哪些模块该冻结?
实用判断表
| 目标 | 建议训练的部分 |
|---|---|
| 只是把视觉接进来 | Projector / Connector |
| 提升回答风格与任务遵循 | LLM 部分层 + 指令数据 |
| 提升 OCR、版面、细节理解 | 更强视觉侧 + 分辨率策略 + 相关数据 |
| 提升领域知识 | 领域数据 + 语言侧适配 |
VLM 微调的三个冻结决策
1. Vision Tower 冻不冻?
- 默认冻结(它已经"会看"了)
- 例外:医学影像、卫星图等视觉差异极大的场景
2. Projector / Connector 冻不冻?
- 通常不冻(场景适配需要视觉-语言对齐的微调)
- 如果只做纯文本风格迁移(如让模型说话更像客服),可冻结
3. LLM 冻不冻?
- LoRA:只训注入的低秩矩阵
- 全量微调:全部更新(资源充足时)
自检三问
在动显卡之前,用三个问题自检:
- 失败主因更像视觉漏看、还是更像指令/格式没对齐? 前者优先补数据与分辨率策略,后者优先统一 chat template 与答案风格。
- 基座模型在目标场景上是否已经"勉强可用"? 若完全不可用,先换模型或先缩小场景,再谈 LoRA。
- 是否已有一批 JSONL + 离线 eval 能对齐迭代? 没有验收集时扩数据容易变成扩噪声。
七、SFT 之后的偏好对齐
SFT 让模型"会回答",但可能包含幻觉(没看图却瞎编)。6 种偏好对齐方法:
| 方法 | 核心思想 | 数据需求 | 适合场景 |
|---|---|---|---|
| DPO | 直接比较"好回答"和"差回答"的似然,无需奖励模型 | 成对偏好数据 | 快速上线,资源有限 |
| KTO | 只需要知道"这条回答好/不好"的二元信号 | 二元反馈数据 | 比 DPO 数据收集更简单 |
| RLHF-V | 用人类反馈做强化学习,专门优化视觉忠实度 | 人类标注的偏好对 | 幻觉严重的场景 |
| RLAIF-V | 用 AI(如 GPT-4V)替代人类提供偏好判断 | AI 生成的偏好对 | 降低标注成本 |
| VLFeedback | 大规模 VLM 偏好数据集,覆盖多种视觉任务 | 现成数据集 | 研究/通用能力提升 |
| POVID | 针对"物体存在性"的偏好优化,减少"图中没有却说有" | 物体存在性标注 | 细粒度幻觉抑制 |
务实建议
- 先做好 SFT:偏好对齐的前提是模型已经能"基本答对",不要跳步
- DPO 是最小可行路径:如果你有 500~2000 条"好回答 vs 差回答"的配对,DPO 是性价比最高的选择
- 幻觉评测优先用 POPE / HallusionBench:这两个 benchmark 专门测幻觉,对齐前后务必跑一遍对比
- 工具链 :TRL 库的
DPOTrainer、LLaMA-Factory 的 DPO 模式、OpenRLHF 都支持多模态 DPO
八、SFT 实战流程
场景微调五步法
① 明确任务边界(电商图文?文档抽取?截图问答?)
② 收集 200~2000 条高质量样本(不追求大规模)
③ 保持统一消息格式和答案风格
④ 先做 Connector 或 LoRA 微调,快速看收益
⑤ 抽样人工评估,再决定是否扩数据
这比一上来追求"大而全"靠谱得多。
配套工具
sample_multimodal_sft.jsonl--- 样例数据prepare_dataset_manifest.py--- 数据校验create_placeholder_images.py--- 生成占位图lora_finetune_minimal.py--- 最小 LoRA 微调脚本
九、SFT 的常见坑
| 坑 | 后果 | 解法 |
|---|---|---|
| 图文错配 | 污染对齐效果 | 数据校验脚本 |
| 过度依赖描述型数据 | 只会写说明文,不擅长问答 | 混合 VQA、推理数据 |
| 忽略 OCR 与文档 | 自然图像好,票据差 | 补 OCR 样本 |
| Prompt 模板不一致 | 训练/推理风格错配 | 统一 chat template |
| 只看 loss 不看抽样 | loss 降了但效果没变 | 人工抽样 + 评测集 |
工程速记 :有人 SFT 后 loss 曲线很漂亮,同一批业务截图在评测集上却仍只会泛泛描述;复盘 JSONL 才发现几乎全是"请描述这张图",缺少带证据指向的问答对。这类配方问题不会写进单个 loss 数字里,却会原样暴露在按 tags 拆开统计的失败率上。
十、总结
SFT 的核心逻辑
数据配方 → 训练策略 → 冻结决策 → 偏好对齐
↓ ↓ ↓ ↓
能力分布 资源效率 适配方向 幻觉抑制
三句话带走
- 多模态模型的训练效果很大程度上由数据配方决定。
- 预对齐解决"接得上",指令微调解决"用得顺手",任务特化解决"能落地"。
- 资源有限时,优先做高质量小规模实验,比盲目扩大规模更有效。
SFT 不是"调参游戏",而是"数据工程"------先想清楚要什么能力,再决定用什么数据、训哪些参数。