原文出处:Fine-Tuning VLMs 原作者:Hugging Face · 许可证:Apache-2.0 License 中文译本由诸葛AI学院整理,仅供学习参考,版权归原作者与 Hugging Face 所有。
在第 1 单元里,我们探讨过在 LLM 上做监督微调,也包括用 TRL 实现的高效策略。本节把这些技术搬到视觉语言模型(Vision Language Model, VLM)上,重点放在效率和面向具体任务的表现。
关键的效率技术
微调 VLM 时,显存和算力很快会成为瓶颈。下面是几种主要策略:
量化
量化降低模型权重和激活值的精度,从而减少内存占用、加快计算。
- bfloat16 / float16:内存需求减半,精度基本保住。
- 8-bit / 4-bit 量化:内存进一步压缩,代价是少量的性能损失。
⚠️ 这一点对 VLM 尤其要紧,因为图像特征会抬高内存需求。
PEFT 与 LoRA
低秩适配(Low-Rank Adaptation, LoRA)冻结基座模型的权重,只训练紧凑的低秩分解矩阵,大幅减少可训练参数的数量。和 PEFT(参数高效微调)结合后,微调所需的可训练参数从数十亿降到数百万,让算力有限的硬件也能跑得起大型 VLM。
批量大小优化
想省内存地训练,可以用:
- 梯度累积(Gradient accumulation):跨多个 step 维持有效的批量大小。
- 梯度检查点(Gradient checkpointing):重算中间激活值来省内存。
- 先设一个较大的批量,遇到 OOM(显存溢出)就调小,再配合 LoRA 和量化,效果最好。
监督微调(SFT)
SFT 用带标注的数据集(图文配对)把预训练好的 VLM 适配到具体任务。例子包括:
- 视觉问答(Visual Question Answering, VQA)
- 图像描述(Image captioning)
- 图表或示意图解读
什么时候用 SFT
- 让 VLM 在基座模型吃力的某个领域里做专精。
- 学习领域特有的词汇或视觉模式。
局限
- 需要高质量的标注数据集。
- 可能很吃算力。
- 微调范围太窄时,有过拟合风险。
用法示例
SFTTrainer 支持直接训练 VLM。你的数据集要多加一个 images 列,用来放视觉输入。细节见数据集格式文档。
```python from trl import SFTTrainer
training_args = SFTTrainer( output_dir="./fine_tuned_model", per_device_train_batch_size=4, num_train_epochs=3, learning_rate=5e-5, save_steps=1000, bf16=True, gradient_checkpointing=True, gradient_accumulation_steps=16, logging_steps=50 ) ```
⚠️ 重要: 在 SFTConfig 里把 max_length 设成 None。否则截断可能会在训练过程中把图像令牌(image tokens)去掉。
python
SFTConfig(max_length=None, ...)
实操步骤
-
准备数据 - 用图文配对,例如
HuggingFaceM4/ChartQA。 -
配置模型 - 加载一个预训练 VLM,比如
HuggingFaceTB/SmolVLM2-2.2B-Instruct。 - 初始化一个处理器(processor),用来准备文本和图像输入。 -
微调流程 - 把数据格式化成聊天式消息(
system、user、assistant)。 - 配置优化器、批量大小、梯度累积。 - 上量化和LoRA,做省内存的训练。
偏好优化(DPO)
直接偏好优化(Direct Preference Optimization, DPO)让 VLM 对齐人类偏好,而不是严格地服从指令。
- 适合创意任务、主观判断、多选一的回答。
- 模型学会选出更符合人类偏好的回复,哪怕它并不严格"正确"。
局限
- 需要高质量的偏好标注数据集。
- 训练涉及成对偏好采样,还要精细管理资源。
用法示例
- 数据集:每条样本包含一个提示(图像 + 问题)和两个候选回复:
text
问题:有多少户家庭?
被拒(Rejected):图片没有提供关于家庭数量的信息。
选中(Chosen):图片显示的是一个 Union Organization 表格,涉及 18,000 户家庭。
- 配置模型:加载预训练 VLM,接入 TRL 的 DPO,准备好处理器。
- 训练流水线:
- 把数据集格式化成聊天式消息。
- 应用基于偏好的损失函数。
- 用梯度累积、检查点、LoRA、量化来提效。
SFT 与 DPO 对比
| 特性 | SFT | DPO |
|---|---|---|
| 输入 | 带标注的图文 | 图文 + 按偏好排序的输出 |
| 损失 | 标准监督损失 | 基于偏好的损失 |
| 目标 | 面向具体任务的适配 | 对齐人类偏好的输出 |
| 适用场景 | 领域专精 | 创意、主观、多选一的任务 |
实用建议
- 先小后大:全量训练前,先用数据集的一个子集试跑。
- 用梯度检查点 + LoRA + 量化降低内存占用。
- 留意保存检查点的频率,在存储和安全之间找平衡。
- 在一个小集合上做验证,避免过拟合。
下一步
微调之后,用基准和自建测试集评估 VLM 在多模态任务上的表现,套用第 2 单元里的技术。
用 TRL 在 hf jobs 里微调 VLM
正如前面单元介绍的,Hugging Face Jobs 让微调 VLM 变得很直接。你可以用最少的配置,直接在 Hugging Face 的基础设施上跑监督微调(SFT)或直接偏好优化(DPO),调整我们前面讲过的那些训练参数。
快速示例
bash
hf jobs uv run \
--flavor a100-large \
--secrets HF_TOKEN \
--timeout 2h \
"https://raw.githubusercontent.com/huggingface/trl/main/trl/scripts/sft.py" \
--model_name_or_path HuggingFaceTB/SmolVLM2-2.2B-Instruct \
--dataset_name HuggingFaceM4/ChartQA \
--report_to trackio
--flavor a100-large:训练用的 GPU 类型。--secrets HF_TOKEN:你的 Hugging Face 令牌。
这个脚本会自动处理处理器配置、数据格式化和模型训练。任务跑完,微调好的 VLM 就能下载,用到下游任务里。
提示 想省内存地微调大型 VLM,可以考虑把 LoRA 适配器、梯度累积、量化这些技术组合起来。它们能在保住性能的同时降低内存占用。