Fine Tuning Vlm Trl
使用 Hugging Face 生态系统(TRL)对视觉语言模型 (Qwen2-VL-7B) 进行微调
作者: Sergio Paniego
🚨 警告:本 Notebook 资源需求较大,需要强大的计算能力。如果你在 Colab 中运行,它将使用 A100 GPU。
在本教程中,我们将演示如何使用 Hugging Face 生态系统,特别是 Transformer 强化学习库 (TRL),对 视觉语言模型 (VLM) 进行微调。
🌟 模型与数据集概述
我们将使用 Qwen2-VL-7B 模型,基于 ChartQA 数据集进行微调。该数据集包含各种图表类型的图像,并配有问答对,非常适合增强模型的视觉问答能力。
📖 其他资源
如果你对更多 VLM 应用感兴趣,请查看:
- 多模态检索增强生成 (RAG) :我将带你了解如何使用文档检索(ColPali)和视觉语言模型(VLMs)构建 RAG 系统。
- Phil Schmid 的教程:一个深入讲解如何使用 TRL 微调多模态 LLMs 的精彩教程。
- Merve Noyan 的 smol-vision 仓库:一个关于前沿视觉与多模态 AI 主题的 Notebook 集合。
1. 安装依赖
让我们从安装微调所需的核心库开始!🚀
登录 Hugging Face 以上传你的微调模型!🗝️
你需要通过 Hugging Face 帐户进行身份验证,以便直接从本 Notebook 保存和共享你的模型。
VBox(children=(HTML(value='<center> <img\nsrc=https://huggingface.co/front/assets/huggingface_logo-noborder.sv…
2. 加载数据集 📁
在这一部分,我们将加载 HuggingFaceM4/ChartQA 数据集。该数据集包含图表图像及其相关的问答对,非常适合用于视觉问答任务的训练。
接下来,我们将为视觉语言模型 (VLM) 生成一个系统消息。在这种情况下,我们希望创建一个系统,能够作为分析图表图像的专家,并根据图表提供简明的回答。
我们将把数据集格式化为聊天机器人结构进行交互。每次交互将包括一个系统消息,接着是图像和用户的查询,最后是对查询的回答。
💡有关此模型的更多使用技巧,请查看 模型卡。
出于教育目的,我们将只加载数据集中每个部分的 10%。然而,在实际应用中,通常会加载整个样本集。
让我们看一下数据集的结构。它包含一个图像、一个查询、一个标签(即答案),以及一个我们将丢弃的第四个特征。
Dataset({
, features: ['image', 'query', 'label', 'human_or_machine'],
, num_rows: 2830
,}) 现在,让我们使用聊天机器人结构来格式化数据。这将使我们能够为模型适当地设置交互。
[{'role': 'system',
, 'content': [{'type': 'text',
, 'text': 'You are a Vision Language Model specialized in interpreting visual data from chart images.\nYour task is to analyze the provided chart image and respond to queries with concise answers, usually a single word, number, or short phrase.\nThe charts include a variety of types (e.g., line charts, bar charts) and contain colors, labels, and text.\nFocus on delivering accurate, succinct answers based on the visual information. Avoid additional explanation unless absolutely necessary.'}]},
, {'role': 'user',
, 'content': [{'type': 'image',
, 'image': <PIL.PngImagePlugin.PngImageFile image mode=RGB size=308x369>},
, {'type': 'text',
, 'text': 'Is the rightmost value of light brown graph 58?'}]},
, {'role': 'assistant', 'content': [{'type': 'text', 'text': 'No'}]}] 3. 加载模型并检查性能!🤔
现在我们已经加载了数据集,接下来让我们加载模型,并使用数据集中的一个样本来评估其性能。我们将使用Qwen/Qwen2-VL-7B-Instruct,这是一款能够理解视觉数据和文本的视觉语言模型(VLM)。
如果你在寻找替代方案,可以考虑以下开源选项:
- Meta AI的Llama-3.2-11B-Vision
- Mistral AI的Pixtral-12B
- Allen AI的Molmo-7B-D-0924
此外,你还可以查看一些排行榜,比如WildVision Arena或OpenVLM Leaderboard,找到表现最好的VLM模型。

The cache for model files in Transformers v4.22.0 has been updated. Migrating your old cache. This is a one-time only operation. You can interrupt this and resume the migration later on by calling `transformers.utils.move_cache()`.
0it [00:00, ?it/s]
接下来,我们将加载模型和分词器,为推理做准备。
config.json: 0%| | 0.00/1.20k [00:00<?, ?B/s]
model.safetensors.index.json: 0%| | 0.00/56.5k [00:00<?, ?B/s]
Downloading shards: 0%| | 0/5 [00:00<?, ?it/s]
model-00001-of-00005.safetensors: 0%| | 0.00/3.90G [00:00<?, ?B/s]
model-00002-of-00005.safetensors: 0%| | 0.00/3.86G [00:00<?, ?B/s]
model-00003-of-00005.safetensors: 0%| | 0.00/3.86G [00:00<?, ?B/s]
model-00004-of-00005.safetensors: 0%| | 0.00/3.86G [00:00<?, ?B/s]
model-00005-of-00005.safetensors: 0%| | 0.00/1.09G [00:00<?, ?B/s]
`Qwen2VLRotaryEmbedding` can now be fully parameterized by passing the model config through the `config` argument. All other arguments will be removed in v4.46
Loading checkpoint shards: 0%| | 0/5 [00:00<?, ?it/s]
generation_config.json: 0%| | 0.00/244 [00:00<?, ?B/s]
preprocessor_config.json: 0%| | 0.00/347 [00:00<?, ?B/s]
tokenizer_config.json: 0%| | 0.00/4.19k [00:00<?, ?B/s]
vocab.json: 0%| | 0.00/2.78M [00:00<?, ?B/s]
merges.txt: 0%| | 0.00/1.67M [00:00<?, ?B/s]
tokenizer.json: 0%| | 0.00/7.03M [00:00<?, ?B/s]
chat_template.json: 0%| | 0.00/1.05k [00:00<?, ?B/s]
To evaluate the model's performance, we’ll use a sample from the dataset. First, let’s take a look at the internal structure of this sample.
[{'role': 'system',
, 'content': [{'type': 'text',
, 'text': 'You are a Vision Language Model specialized in interpreting visual data from chart images.\nYour task is to analyze the provided chart image and respond to queries with concise answers, usually a single word, number, or short phrase.\nThe charts include a variety of types (e.g., line charts, bar charts) and contain colors, labels, and text.\nFocus on delivering accurate, succinct answers based on the visual information. Avoid additional explanation unless absolutely necessary.'}]},
, {'role': 'user',
, 'content': [{'type': 'image',
, 'image': <PIL.PngImagePlugin.PngImageFile image mode=RGB size=422x359>},
, {'type': 'text', 'text': 'Is the value of Favorable 38 in 2015?'}]},
, {'role': 'assistant', 'content': [{'type': 'text', 'text': 'Yes'}]}] 我们将使用没有系统消息的样本来评估VLM的原始理解能力。以下是我们将使用的输入:
[{'role': 'user',
, 'content': [{'type': 'image',
, 'image': <PIL.PngImagePlugin.PngImageFile image mode=RGB size=422x359>},
, {'type': 'text', 'text': 'Is the value of Favorable 38 in 2015?'}]}] 现在,让我们来看一下与该样本对应的图表。你能根据视觉信息回答问题吗?
让我们创建一个方法,接受模型、处理器和样本作为输入,以生成模型的答案。这将帮助我们简化推理过程,并轻松评估VLM的性能。
'No, the value of Favorable is not 38 in 2015. According to the chart, the value of Favorable in 2015 is 38.'
尽管模型成功地提取了正确的视觉信息,但它在准确回答问题方面存在困难。这表明微调可能是提高其性能的关键。让我们继续进行微调过程!
移除模型并清理GPU
在我们继续下一部分的模型训练之前,让我们清理当前的变量并清理GPU,以释放资源。
4. 使用TRL进行模型微调
4.1 加载用于训练的量化模型 ⚙️
接下来,我们将使用bitsandbytes加载量化模型。如果你想了解更多关于量化的内容,可以查看这篇博客文章或这篇文章。
量化能够显著减小模型的存储需求并提高推理效率,特别适用于需要部署到资源有限的设备上的场景。
Loading checkpoint shards: 0%| | 0/5 [00:00<?, ?it/s]
4.2 设置QLoRA和SFTConfig 🚀
接下来,我们将为训练设置配置QLoRA。QLoRA使得大语言模型的高效微调成为可能,同时与传统方法相比显著减少内存占用。与标准的LoRA方法通过应用低秩近似来减少内存使用不同,QLoRA通过量化LoRA适配器的权重,进一步降低内存需求。这不仅减少了内存占用,还提升了训练效率,使其成为在不牺牲质量的前提下优化模型表现的理想选择。
4. 训练模型 🏃
我们将使用trackio来记录我们的训练进度。让我们将 Notebook 与W&B连接,以便在训练过程中捕获重要信息。
现在,我们将定义SFTTrainer,它是transformers.Trainer类的包装器,并继承了其属性和方法。这个类通过在提供PeftConfig对象时,正确初始化PeftModel,简化了微调过程。通过使用SFTTrainer,我们可以高效地管理训练工作流,确保我们的视觉语言模型微调过程顺利进行。
该训练模型了! 🎉
让我们保存结果 💾
adapter_model.safetensors: 0%| | 0.00/10.1M [00:00<?, ?B/s]
5. 测试微调后的模型 🔍
现在我们已经成功微调了我们的视觉语言模型(VLM),是时候评估它的表现了!在这一部分,我们将使用来自ChartQA数据集的示例来测试模型,看看它在基于图表图像回答问题方面的表现如何。让我们深入探索并查看结果吧!🚀
让我们清理GPU内存,以确保最佳的性能 🧹
我们将使用之前相同的管道重新加载基础模型。
Loading checkpoint shards: 0%| | 0/5 [00:00<?, ?it/s]
我们将把训练好的适配器附加到预训练模型上。这个适配器包含了我们在训练过程中所做的微调调整,允许基础模型在不改变其核心参数的情况下利用新学到的知识。通过集成适配器,我们可以增强模型的能力,同时保持其原有结构。
adapter_config.json: 0%| | 0.00/650 [00:00<?, ?B/s]
adapter_model.safetensors: 0%| | 0.00/10.1M [00:00<?, ?B/s]
我们将使用之前从数据集中选取的样本,这是模型最初无法正确回答的样本
[{'role': 'system',
, 'content': [{'type': 'text',
, 'text': 'You are a Vision Language Model specialized in interpreting visual data from chart images.\nYour task is to analyze the provided chart image and respond to queries with concise answers, usually a single word, number, or short phrase.\nThe charts include a variety of types (e.g., line charts, bar charts) and contain colors, labels, and text.\nFocus on delivering accurate, succinct answers based on the visual information. Avoid additional explanation unless absolutely necessary.'}]},
, {'role': 'user',
, 'content': [{'type': 'image',
, 'image': <PIL.PngImagePlugin.PngImageFile image mode=RGB size=422x359>},
, {'type': 'text', 'text': 'Is the value of Favorable 38 in 2015?'}]}] 'Yes'
既然这个样本来自训练集,模型在训练过程中已经接触过它,这可能被视为一种“作弊”方式。为了更全面地了解模型的表现,我们将使用一个未见过的样本来进行评估。
[{'role': 'system',
, 'content': [{'type': 'text',
, 'text': 'You are a Vision Language Model specialized in interpreting visual data from chart images.\nYour task is to analyze the provided chart image and respond to queries with concise answers, usually a single word, number, or short phrase.\nThe charts include a variety of types (e.g., line charts, bar charts) and contain colors, labels, and text.\nFocus on delivering accurate, succinct answers based on the visual information. Avoid additional explanation unless absolutely necessary.'}]},
, {'role': 'user',
, 'content': [{'type': 'image',
, 'image': <PIL.PngImagePlugin.PngImageFile image mode=RGBA size=850x600>},
, {'type': 'text', 'text': 'What is the value of Slovenia in the graph?'}]}] '1'
模型已经成功地学习了根据数据集中的查询作出响应。我们达到了目标! 🎉✨
6. 比较微调模型与基础模型 + 提示策略 📊
我们已经探讨了如何通过微调VLM将其适应特定需求的过程。另一种值得考虑的方法是直接使用提示(prompting)或实现RAG(检索增强生成)系统,这在另一个教程中有详细介绍。
微调 VLM 需要大量数据和计算资源,这可能会产生一定的成本。相比之下,我们可以尝试使用提示,看看是否能在没有微调开销的情况下实现类似的结果。
清理 GPU 内存以确保最佳性能 🧹
GPU allocated memory: 0.02 GB GPU reserved memory: 0.27 GB
🏗️ 首先,我们将按照之前相同的管道加载基础模型。
Loading checkpoint shards: 0%| | 0/5 [00:00<?, ?it/s]
📜 在这种情况下,我们将再次使用之前的样本,但这次我们将包括系统消息,如下所示。这一添加有助于为模型提供更多上下文,从而可能提高其响应的准确性。
[{'role': 'system',
, 'content': [{'type': 'text',
, 'text': 'You are a Vision Language Model specialized in interpreting visual data from chart images.\nYour task is to analyze the provided chart image and respond to queries with concise answers, usually a single word, number, or short phrase.\nThe charts include a variety of types (e.g., line charts, bar charts) and contain colors, labels, and text.\nFocus on delivering accurate, succinct answers based on the visual information. Avoid additional explanation unless absolutely necessary.'}]},
, {'role': 'user',
, 'content': [{'type': 'image',
, 'image': <PIL.PngImagePlugin.PngImageFile image mode=RGB size=422x359>},
, {'type': 'text', 'text': 'Is the value of Favorable 38 in 2015?'}]}] 让我们看看他是如何表现的!
'Yes'
💡 正如我们所看到的,模型在没有任何微调的情况下,通过使用预训练模型并结合附加的系统消息,成功生成了正确的答案。这种方法在某些具体应用场景中,可能成为微调的有效替代方案。根据不同的任务需求,采用提示(prompting)或RAG(检索增强生成)等方法,可以在降低计算成本的同时实现类似的性能。
7. 继续学习之旅 🧑🎓️
为了进一步增强你在使用多模态模型方面的理解和技能,以下是一些推荐的资源:
- 多模态检索增强生成(RAG)指南
- Phil Schmid 的教程
- Merve Noyan 的 smol-vision 仓库
- 使用 AutoAWQ 对 Qwen2-VL 模型进行量化
- 使用 TRL 优化视觉语言模型的偏好
- Hugging Face Llama 指南:针对 VLM 的 SFT
- Hugging Face Llama 指南:PEFT 微调
- Hugging Face 博客:IDEFICS2
这些资源将帮助你加深对多模态学习的理解和技能。继续探索、学习并尝试更多的技术,你会在这个领域走得更远!