训练VLM(视觉语言模型)的经验

图片

知乎:lym
链接:https://zhuanlan.zhihu.com/p/890327005

如果可以用prompt解决,尽量用prompt解决,因为训练(精调)的模型往往通用能力会下降,训练和长期部署成本都比较高,这个成本也包括时间成本。

基于prompt确实不行(情况包括格式输出不稳定、格式输出基本不对、任务不完全会、任务完全不会等情况,难度逐渐加大),选择上SFT微调。

业务场景基本用不到强化学习,强化解决的是最后一公里的问题,可以理解为有两种非常接近的输出(这两种输出都非常接近目标输出,此时已经解决了90%的问题),强化学习会对相同的输入,打压其中一种不希望的输出,同时增强另一种更接近目标的希望的输出(从DPO loss就可以看出)。强化是用来应对细微输出差异的,并且业务场景优先用DPO,DPO只需要pair对数据,更好构造。PPO的reward model几乎没有开源的,需要的数据更多,超参也更多,除非是逻辑或代码场景,在文本场景中,DPO效果是足够的。

业务数据质量最重要,数据量也不能少,越难的任务数据量越多

数据内容:要尽量和期望输出一致,这个一致既包括内容,也包括格式。不要期望垃圾数据能训练出好的VLM模型,不要寄希望于dalle3那种recaptioning,依靠泛化能力变换格式的玩法太高级了,我还把我不住。可以用 手工标注数据+GPT改写(甚至可以是Vision版本) 生成质量尽可能高的业务数据。改写用的GPT原本没有解决对应任务的能力也不要怕,在改写的prompt模板让它参考人工标注就行。

数据量:如果模型会该类任务,但仅是输出格式不稳定(比如json少个括号,文本输出少个\n什么的),几十到上百条业务数据就够了,不用考虑通用数据;一般普通业务需要千条业务数据(类似数据在VLM模型预训练的训练集出现过,但模型对于该任务处于会与不会区间),需要少量通用数据(10:1,1份通用)。如果特别难的task,VLM模型根本没见过(比如文生图生成数据,输出的文本也和输入图之间的关系需要重学),那需要1-2w条业务数据,通用数据5:1。

训练轮次:我训练的task就特别难,4B左右的模型甚至训练10个epoch测试集的loss还在下降。但是一般7B模型训5个epoch,70B模型训练2个epoch,就会开始过拟合了。下面是比较正常的收敛曲线。

图片

图片

当然还有些肯定不正确的曲线:

图片

图片

数据难度:可以用PPL衡量,也可以看训练集上测试的效果。

多个类型数据:先各自训练看效果,确保各自没有问题,再去混合。

训练流程

  1. 收集清洗改写增强广业务数据,同一个问题可以除了文本对话,还可以改写成选择判断,有帮助,而且这些形式更容易做评测,方便确认效果。

  2. 磨刀不误砍柴工:找一个小的VLM模型(2B~7B),按照默认微调参数对纯业务数据集上进行训练,设置较高的lr(1e-5)和较长的epoch(10轮)。训练好的模型在训练集上先测试(对,用什么训练用什么测!)。在训练集上进行测试是非常重要的,它可以一定程度排除数据集质量的问题,也不用担心过拟合的问题,同时也能确保框架底层没什么问题。别管数据质量多垃圾,别管在测试集泛化性有多差,在训练集上都应该有较好的学习效果。如果你的业务数据有多种形式,也可以在这个阶段进行配比的消融。

  3. 确保在训练集上没问题,再结合validation集上的曲线,应该可以大致确认:训练轮次(epoch)、业务数据配比、学习率、batch_size、文本长度、moe专家数量、并行配置(tp pp dp)等绝大部分超参。

PS:在VLM训练中,无论是预训练、对齐还是精调,用的都是SFT loss,没有Pretrain loss。学界可能比较喜欢用lora,但工业届全量调的更多,这俩区别不是很大,lora dim设置成128/256,scaling设置成64(dim的05倍),也能学很多东西。

如果只是输出格式不满意、不稳定,那么调LLM就够。如果全新的知识,那么vit和LLM以及二者间的中间层都放开比较好。参数量的大头在LLM中,但如果图片业务数据和预训练数据差异较大,vit放开也很重要。(上vit冻住,下vit放开,vit解冻后明显收敛更稳定)。我的任务比较难,肯定就是全放开训练了。

图片

图片

图片

图片

往里面加入通用数据,来维护原有通用能力(在业务垂域没搞明白前,一般先别考虑通用数据,否则变量太多,把握不住)。配比从10:1开始,不行可以试试5:1。通用数据包括两种,一种是caption,一种是instruct数据。caption数据的question基本都是”详细描述图中有什么?“,它在VLM预训练中是用来做一阶段的。Instruct数据的question就比较多样了,比如”图中叉子右边的茶杯是什么颜色的?“它一般对应预训练的二阶段微调。VLM这两个阶段虽然一阶段叫训练,二阶段叫对齐,但是loss形式是一样的,超参可能也只有学习率的差异,越往后学习率越小。全用instruct数据问题也不大,但instruct数据可能信息量可能不如caption对图片描述那么丰富,也更难收集一些。

caption的数据我翻译了些sharegpt4o的,整理好了:

https://huggingface.co/datasets/LYM2024/share_gpt4o_zh?row=0

instruct数据用的ALLAVA-4V的,量太大了翻译的还没整理好。

https://huggingface.co/datasets/FreedomIntelligence/ALLaVA-4V

这俩我是1:1用的,没做严格消融。英文数据去llamafactory找就行,中文大部分得自己动手翻译。通用 数据也可以大量用英文,融合一点自己翻译的中文,效果也不会太差的。

然后我发现个特别有意思的现象,我的业务数据是diffusion生成的图片,上面这些数据是自然图片,业务数据的通用能力几乎没有被维护。解决方案:

  1. 用现有VLM对业务数据作captioning,因为caption的question与图无关,直接取sharegpt40的就行。直接生成大量业务图片的通用数据。

  2. 用LCM的SSD或SDXL模型做Img2Img,把正prompt置空,guidance_scale置0(最好negative输出的embedding取torch.zeros),strength强度设置0.025。用无引导生成生成有diffusion特征的图片。

  3. 训练可以分多个阶段,前面用质量差一点的大量数据,后面用质量高的小批量数据,提升最终效果。两阶段question的词汇可以作下隔离,即这两批数据的question最好有点小差异,后续推理测试只用高质量数据的question。实测高质量数据的需求大会大大降低。

  4. 我个人觉得,精调这种任务,如果数据量大,在7B小模型和72B大模型上,在业务(垂域)上效果差异并不大,因为我们一般更关心业务和垂域的性能,而非要成为全面的通才。

  5. 数据质量高可以训练久一些,数据质量差训练短一些,可以保留更好的泛化性。我们的数据比较短,训练10epoch的话,输出就非常短,往往不带主语。训练6epoch就会带一些,所以不是validation loss下降就是好事,它可能同时对应着通用loss的上升,稍微遇到些长尾问题,性能就会崩溃式下降。训练太短也不行,容易学不会,至少要保证训练5epoch,看看整体的结果。

图片

知乎:lym
链接:https://zhuanlan.zhihu.com/p/890327005

如果可以用prompt解决,尽量用prompt解决,因为训练(精调)的模型往往通用能力会下降,训练和长期部署成本都比较高,这个成本也包括时间成本。

基于prompt确实不行(情况包括格式输出不稳定、格式输出基本不对、任务不完全会、任务完全不会等情况,难度逐渐加大),选择上SFT微调。

业务场景基本用不到强化学习,强化解决的是最后一公里的问题,可以理解为有两种非常接近的输出(这两种输出都非常接近目标输出,此时已经解决了90%的问题),强化学习会对相同的输入,打压其中一种不希望的输出,同时增强另一种更接近目标的希望的输出(从DPO loss就可以看出)。强化是用来应对细微输出差异的,并且业务场景优先用DPO,DPO只需要pair对数据,更好构造。PPO的reward model几乎没有开源的,需要的数据更多,超参也更多,除非是逻辑或代码场景,在文本场景中,DPO效果是足够的。

业务数据质量最重要,数据量也不能少,越难的任务数据量越多

数据内容:要尽量和期望输出一致,这个一致既包括内容,也包括格式。不要期望垃圾数据能训练出好的VLM模型,不要寄希望于dalle3那种recaptioning,依靠泛化能力变换格式的玩法太高级了,我还把我不住。可以用 手工标注数据+GPT改写(甚至可以是Vision版本) 生成质量尽可能高的业务数据。改写用的GPT原本没有解决对应任务的能力也不要怕,在改写的prompt模板让它参考人工标注就行。

数据量:如果模型会该类任务,但仅是输出格式不稳定(比如json少个括号,文本输出少个\n什么的),几十到上百条业务数据就够了,不用考虑通用数据;一般普通业务需要千条业务数据(类似数据在VLM模型预训练的训练集出现过,但模型对于该任务处于会与不会区间),需要少量通用数据(10:1,1份通用)。如果特别难的task,VLM模型根本没见过(比如文生图生成数据,输出的文本也和输入图之间的关系需要重学),那需要1-2w条业务数据,通用数据5:1。

训练轮次:我训练的task就特别难,4B左右的模型甚至训练10个epoch测试集的loss还在下降。但是一般7B模型训5个epoch,70B模型训练2个epoch,就会开始过拟合了。下面是比较正常的收敛曲线。

图片

图片

当然还有些肯定不正确的曲线:

图片

图片

数据难度:可以用PPL衡量,也可以看训练集上测试的效果。

多个类型数据:先各自训练看效果,确保各自没有问题,再去混合。

训练流程

  1. 收集清洗改写增强广业务数据,同一个问题可以除了文本对话,还可以改写成选择判断,有帮助,而且这些形式更容易做评测,方便确认效果。

  2. 磨刀不误砍柴工:找一个小的VLM模型(2B~7B),按照默认微调参数对纯业务数据集上进行训练,设置较高的lr(1e-5)和较长的epoch(10轮)。训练好的模型在训练集上先测试(对,用什么训练用什么测!)。在训练集上进行测试是非常重要的,它可以一定程度排除数据集质量的问题,也不用担心过拟合的问题,同时也能确保框架底层没什么问题。别管数据质量多垃圾,别管在测试集泛化性有多差,在训练集上都应该有较好的学习效果。如果你的业务数据有多种形式,也可以在这个阶段进行配比的消融。

  3. 确保在训练集上没问题,再结合validation集上的曲线,应该可以大致确认:训练轮次(epoch)、业务数据配比、学习率、batch_size、文本长度、moe专家数量、并行配置(tp pp dp)等绝大部分超参。

PS:在VLM训练中,无论是预训练、对齐还是精调,用的都是SFT loss,没有Pretrain loss。学界可能比较喜欢用lora,但工业届全量调的更多,这俩区别不是很大,lora dim设置成128/256,scaling设置成64(dim的05倍),也能学很多东西。

如果只是输出格式不满意、不稳定,那么调LLM就够。如果全新的知识,那么vit和LLM以及二者间的中间层都放开比较好。参数量的大头在LLM中,但如果图片业务数据和预训练数据差异较大,vit放开也很重要。(上vit冻住,下vit放开,vit解冻后明显收敛更稳定)。我的任务比较难,肯定就是全放开训练了。

图片

图片

图片

图片

往里面加入通用数据,来维护原有通用能力(在业务垂域没搞明白前,一般先别考虑通用数据,否则变量太多,把握不住)。配比从10:1开始,不行可以试试5:1。通用数据包括两种,一种是caption,一种是instruct数据。caption数据的question基本都是”详细描述图中有什么?“,它在VLM预训练中是用来做一阶段的。Instruct数据的question就比较多样了,比如”图中叉子右边的茶杯是什么颜色的?“它一般对应预训练的二阶段微调。VLM这两个阶段虽然一阶段叫训练,二阶段叫对齐,但是loss形式是一样的,超参可能也只有学习率的差异,越往后学习率越小。全用instruct数据问题也不大,但instruct数据可能信息量可能不如caption对图片描述那么丰富,也更难收集一些。

caption的数据我翻译了些sharegpt4o的,整理好了:

https://huggingface.co/datasets/LYM2024/share_gpt4o_zh?row=0

instruct数据用的ALLAVA-4V的,量太大了翻译的还没整理好。

https://huggingface.co/datasets/FreedomIntelligence/ALLaVA-4V

这俩我是1:1用的,没做严格消融。英文数据去llamafactory找就行,中文大部分得自己动手翻译。通用 数据也可以大量用英文,融合一点自己翻译的中文,效果也不会太差的。

然后我发现个特别有意思的现象,我的业务数据是diffusion生成的图片,上面这些数据是自然图片,业务数据的通用能力几乎没有被维护。解决方案:

  1. 用现有VLM对业务数据作captioning,因为caption的question与图无关,直接取sharegpt40的就行。直接生成大量业务图片的通用数据。

  2. 用LCM的SSD或SDXL模型做Img2Img,把正prompt置空,guidance_scale置0(最好negative输出的embedding取torch.zeros),strength强度设置0.025。用无引导生成生成有diffusion特征的图片。

  3. 训练可以分多个阶段,前面用质量差一点的大量数据,后面用质量高的小批量数据,提升最终效果。两阶段question的词汇可以作下隔离,即这两批数据的question最好有点小差异,后续推理测试只用高质量数据的question。实测高质量数据的需求大会大大降低。

  4. 我个人觉得,精调这种任务,如果数据量大,在7B小模型和72B大模型上,在业务(垂域)上效果差异并不大,因为我们一般更关心业务和垂域的性能,而非要成为全面的通才。

  5. 数据质量高可以训练久一些,数据质量差训练短一些,可以保留更好的泛化性。我们的数据比较短,训练10epoch的话,输出就非常短,往往不带主语。训练6epoch就会带一些,所以不是validation loss下降就是好事,它可能同时对应着通用loss的上升,稍微遇到些长尾问题,性能就会崩溃式下降。训练太短也不行,容易学不会,至少要保证训练5epoch,看看整体的结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/453004.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vScode---配置Pyqt5环境--记录

前提条件: python运行环境已正常安装 1、安装Pyqt5 第三方库下载地址记录: 清华大学:https://pypi.tuna.tsinghua.edu.cn/simple 豆瓣:https://pypi.douban.com/simple 阿里云:https://mirrors.aliyun.com/pypi/simpl…

一文读懂组态图和组态软件,最浅显的解读

一、什么是组态图 组态图是指在工业自动化领域中,用来描述和展示控制系统中各个组件之间关系和工作流程的图形化表示方法。它是一个系统的框架图,通过图形符号和连接线,将各个组件(如传感器、执行器、控制器等)以及它…

linux ps和kill指令

目录 ps 命令 kill指令: 示例: 补充:管道的概念 管道的概念 管道的用途 示例 在Linux系统中,ps 和 kill 是两个非常常用的命令,用于管理和终止进程。 ps 命令 ps 命令用于显示当前系统中的进程状态。它可以提供…

责任链模式下,解决开闭原则问题实践

前言 在现代软件工程中,设计模式是解决常见问题的有效工具之一。它们吸收了前人的经验,不仅帮助开发者编写更清晰、更可维护的代码,还能促进团队之间的沟通和协作。责任链模式(Chain of Responsibility Pattern)作为一…

无人机+视频推流直播EasyCVR视频汇聚/EasyDSS平台在森林防护巡检中的解决方案

随着科技的飞速发展,无人机技术在各个领域的应用日益广泛,特别是在森林防护与巡检方面,无人机以其独特的优势,为传统林业管理带来了革命性的变化。本文将探讨无人机在森林防护巡检中的解决方案,分析其工作原理、优势及…

基于SSM+微信小程序的电子点餐管理系统(点餐1)

👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于SSM微信小程序的电子点餐管理系统实现了管理员及用户。管理员实现了首页、个人中心、餐品分类管理、特色餐品管理、订单信息管理、用户管理、特价餐品管理、活动订单管理、系统管理。…

【论文学习与撰写】使用endnote工具进行论文参考文献的引用与插入

目录 1、软件的安装 2、放入endnote格式文献 3、endnote里文献管理 4、论文里引用参考文献的插入 5、参考文献的格式转换,及格式的下载 1、软件的安装 关注软件管家,进行下载软件和安装软件 下载通道②百度网盘丨下载链接: https://pa…

js.矩阵置零

链接:73. 矩阵置零 - 力扣(LeetCode) 题目: 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1: 输入:matrix [[1,1,1],…

Flutter 11 Android原生项目集成Flutter Module

本文主要讲解如何在已有的Android原生老项目中集成Flutter模块。 实现流程: 1、在Android原生项目根目录下,创建Flutter Module; 2、修改Android原生项目settings.gradle,绑定 Flutter Module; 3、修改Android原生…

15分钟学Go 第6天:变量与常量

第6天:变量与常量 在Go语言中,变量和常量是编程的基础概念。理解如何定义和使用它们不仅能帮助我们管理数据,还能增强代码的可读性和可维护性。在本章中,我们将详细探讨Go语言中的变量和常量,涵盖它们的定义、使用、作…

[Xshell] Xshell的下载安装使用及连接linux过程 详解(附下载链接)

前言 Xshell.zip 链接:https://pan.quark.cn/s/5d9d1836fafc 提取码:SPn7 安装 下载后解压得到文件 安装路径不要有中文 打开文件 注意!360等软件会拦截创建注册表的行为,需要全部允许、同意。或者退出360以后再安装。 在“绿化…

spdlog学习记录

spdlog Loggers:是 Spdlog 最基本的组件,负责记录日志消息。在 Spdlog 中,一个 Logger 对象代表着一个日志记录器,应用程序可以使用 Logger 对象记录不同级别的日志消息Sinks:决定了日志消息的输出位置。在 Spdlog 中&…

程序员节的故事:在代码的海洋中遨游

#1024程序员节 | 征文# 一年一度的程序员节又来了,作为一名热爱编程的开发者,我总是期待着这个特殊的日子。10月24日,不仅是程序员们的节日,更是我们分享故事、交流技术的时刻。今年的1024征文活动让我感到无比兴奋,因…

Axure重要元件三——中继器修改数据

亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! 课程主题:中继器修改数据 主要内容:显示编辑内容、表格赋值、修改数据 应用场景:更新行、表单数据行修改 案例展示: 正文…

STM32L031F6P6基于CubeMX的串口通信调试笔记

用CubeMX创建项目 本实例用的PA14、PA13两个引脚,LPUART1。 对串口参数进行设置: 开启串口中断: 时钟源设置成内部高频时钟: 对项目进行设置: 生成代码: 在串口初始化函数中加入 __HAL_UART_ENA…

C++11 thread,mutex,condition_variable,atomic,原子操作CAS,智能指针线程安全,单例模式最简单实现方式

1.thread 在c11中,c标准委员会开发出了thread库;接下来我们先来看看这个库的使用吧; 1.1 thread类接口介绍 1.1.1 thread类构造函数 我们thread库中的thread类的构造函数可以通过直接传递回调函数与函数的参数来构造线程: int…

THP4 SOP16 芯片 高速光耦芯片

光电耦合器输入端加电信号使发光源发光,光的强度取决于激励电流的大小,此光照射到封装在一起的受光器上后,因光电效应而产生了光电流,由受光器输出端引出,这样就实现了电一光一电的转换。 由于光耦合器输入输出间互相…

mysql主从复制及故障修复

一、主MySQL数据库的配置 分别在三台主机(chen2/10.110、chen3/10.120、chen4/10.130)中安装mysql数据,其中chen2/10.110作为主MySQL服务器,其余两台作为从MySQL服务器。 1、在主机上部署mysql数据库 详细的请看上一篇:mysql数据…

2021年江西省职业院校技能大赛(高职组) “云计算应用”赛项样题

2021年江西省职业院校技能大赛(高职组) “云计算应用”赛项样题 【任务 1】基础运维任务[5 分]【题目 1】基础环境配置【题目 2】镜像挂载【题目 3】Yum 源配置【题目 4】时间同步配置【题目 5】计算节点分区 【任务 2】OpenStack 搭建任务[15 分]【题目…

现今 CSS3 最强二维布局系统 Grid 网格布局

深入学习 CSS3 目前最强大的布局系统 Grid 网格布局 Grid 网格布局的基本认识 Grid 网格布局: Grid 布局是一个基于网格的二位布局系统,是目前 CSS 最强的布局系统,它可以同时对列和行进行处理(它将网页划分成一个个网格,可以任…