666条数据教会AI写万字长文!模型数据集都开源

666条数据教会AI写万字长文!模型数据集都开源

666条数据教会AI写万字长文!模型数据集都开源

关注前沿科技  2024年09月27日 17:38 北京

魔搭ModelScope团队 投稿
量子位 | 公众号 QbitAI

仅需600多条数据,就能训练自己的长输出模型了?!

事情是酱婶儿的——

虽然大模型的上下文(Context)支持越来越长,但包括GPT-4o,Llama-3.1-70B,Claude 3.5 Sonnet在内的这些业界领先模型,在用户指定所需输出长度的情况下,其最大输出长度仍无法满足要求。

例如,针对“写一篇关于罗马帝国历史的10000字文章”的要求,所有这些通用模型在输出长度上均无法超过2000字。

对此,基于GLM4-9B,智谱通过构建长输出的训练数据得到了LongWriter-GLM4-9B模型,能够应对超长输出(10000+ words)场景。

与此同时,智谱开源了训练该模型所需的长输出文本数据集LongWriter-6K。

现在,魔搭社区上基于LongWriter-6K过滤精选了666条数据(LongWriter-6K-Filtered),也一并开源了。

有啥用??

一句话,使用该数据集,你就能在自己的模型中集成长输出能力了。

www.zeeklog.com  - 666条数据教会AI写万字长文!模型数据集都开源

LongWriter数据生成与模型训练

通过分析训练SFT数据,团队发现对于“模型无法输出较长文本”的一个合理解释为:

模型所能生成的最大长度,会受限于其SFT数据中存在的输出长度上限。

以GLM4-9B-Chat模型为例,其SFT训练使用的180K条chat数据中,输出长度超过500、1,000和2,000字的数据,分别仅占SFT数据量大的28%、2%和0.1%。

可见,长输出长度的训练数据占比较小,而2000字长度以上的数据样本占比更是微乎其微。

有了这个分析,LongWriter-GLM-9B是智谱基于GLM4-9B模型,通过构建长输出的训练数据而得到的模型,在输出长文方面表现突出。

在LongWriter工作的基础上,团队利用社区的Swift微调训练工具和EvalScope评估框架,进一步探索了在扩展模型输出长度这个任务上,高质量数据对于模型质量的重要性。

同时,将这个模型训练的receipt,扩展到其他模型(例如Qwen2)上。

在这个过程中,团队还分享了一些有趣的发现和实践经验:

a)少即是多:数据质量比数据数量更关键。

通过对数据的分析过滤,团队发现LongWriter-6K的6000条数据,依然存在优化空间。

他们从中选出了10%左右(666条)的高质量数据并基于这些数据做微调训练。

在Qwen2-7b-instruct和GLM4-9B-Chat两个模型上,只需要3.7%训练计算消耗,就能获取和原论文中,LongWriter-GLM-9B类似的性能提升。

此外,随着基础模型的升级,支持长输出这个能力,在新迭代中本身也会有所增强。但LongWriter的技术方案,还是有其适用性。例如在新鲜出炉的Qwen2.5模型上,团队通过第一时间的测试和验证发现,一方面Qwen2.5模型本身在文本生成长度上,已经有了长足进步,但同样的训练微调方案,还是能进一步带来很好的任务能力提升。

b)对于提升输出文本长度这个具体任务,从base模型开始SFT似乎不是必须的。

以对齐版本(chat/instruct)模型为起点,在模型输出质量和输出长度两方面,也都能获取较好的效果。

下面来看团队对数据的处理。

LongWriter-6K数据

LongWriter-6K数据是通过AgentWriter生成,也就是将长文写作任务分解为多个子任务,每个子任务负责撰写一段。

实验发现,在GPT-4o上使用AgentWriter策略,能够得到近乎线性的Output Length,且长度远超2000词,甚至可以达到30000词的量级。

www.zeeklog.com  - 666条数据教会AI写万字长文!模型数据集都开源

LongWriter-6K数据集由6000条”Required Length”超过2000字的用户指令构成,来自于GLM-4的SFT数据,其中大部分为中文。

另外,从WildChat中选择了3000条指令,主要为英文。

在这个基础上,使用GPT-4o过滤掉有毒数据并人工检查了自动选择的指令。

最后,利用AgentWrite生成与这些instruction对应的response。

www.zeeklog.com  - 666条数据教会AI写万字长文!模型数据集都开源
LongWriter训练数据输出长度分布
LongWriter模型训练与评估

LongWriter-GLM4-9B模型训练使用GLM4-9B作为基模,将LongWriter-6k与180k的GLM-4通用chat SFT数据结合,形成整个训练集。

LongWriter-6k有效补充了输出长度超过2k字的通用chat SFT 数据的稀缺性,且LongWriter-6k的输出长度在2k-10k之间的分布相对均匀。

评价指标

针对输出长文本任务,LongWriter模型采用两个指标:

输出长度(SL)评分

输出质量(SQ)评分

为了让模型的输出长度尽可能接近指令中规定的要求,使用了分段线性函数来计算输出长度得分(SL):

www.zeeklog.com  - 666条数据教会AI写万字长文!模型数据集都开源

输出质量SQ则使用GPT-4o,从以下6个维度来评价

Relevance,相关性

Accuracy,准确性

Coherence,连贯性

Clarity,清晰度

Breadth and Depth,广度和深度

Reading Experience,阅读体验

每个维度分值为1到5中的整数,最低分1,最高分5;最后6个维度整体求平均,并缩放到100分。

训练4个epoch,大约需要 2,500-3,000 step。

实验结果

www.zeeklog.com  - 666条数据教会AI写万字长文!模型数据集都开源
www.zeeklog.com  - 666条数据教会AI写万字长文!模型数据集都开源
LongWriter实验结果

可以看到,LongWriter-9B相较于GLM4-9B-Chat,Overall绝对提升12.2个百分点(68.3->80.5),同时再叠加DPO训练,可以有进一步3.5个点的提升。

从LongWriter-6k到LongWrier-6k-filtered:数据质量提升

通过观察LongWriter-6k数据集,团队发现针对任务的评估标准,这个数据集中仍然有较多的数据并不完全符合目标任务的要求。

例如,大量样本中,对输出长度没有明确要求(“Required Length”):

{"messages": [

实际输出长度(Response Length),与prompt要求的长度(Required Length)差距较大,例如:

{"messages": [{"role": "user", "content": "你是一位优秀的辩手,请针对以下辩题,给出观点立论:\n辩题:当代大学生是否应该住校\n立论角度:阐述不住校的好处\n立论要点:运用数据、事例等论证住校的必要性;从锻炼独立能力、培养社交技巧等方面论证观点\n内容要求:表达清晰,论点突出,精辟见解,让人信服 20000字"}, {"role": "assistant", "content": "### 引言:住校与否的辩论\n\n大学生活是每个青少年成长过程中的关键阶段,而当代大学生是否应该住校则成为一个备受争议的话题, ..."}], "length": 20000, "response_length": 7739}

——其Required Length为20000,但输出为7739

此外还有不少数据,由于输入内容被模型直接拒答,导致输出长度极短,对于整体数据质量有较大的污染。

鉴于这些数据对于目标任务可能造成的反作用,团队在LongWriter-6k数据基础上,实施了两个数据清洗剔除策略。

策略1

剔除prompt中对输出长度没有明确要求(Required Length)的数据

数据总量:6000条 → 1748条

策略2

剔除输出长度和prompt中的Required Length差距较大的数据,即eval_length score—SL得分小于80分的数据

数据总量:1748条 → 666条

www.zeeklog.com  - 666条数据教会AI写万字长文!模型数据集都开源
策略1过滤后 vs 策略2过滤后的数据特性

可以看到,在经过两轮策略过滤后的数据,其实际Output Length体现了对于Required Length非常好的遵循能力,整体数据样本长度关联接近线性。

这样经过对LongWriter-6k数据极限“压榨”,最终得到了包含666条经过清洗后的LongWrier-6k-filtered数据集,并开源在ModelScope。

基于这个新的LongWrier-6k-filtered数据集,下面开始探索:

这些“少而精”的数据,是否能训练出效果相当甚至更为出色LongWriter模型。

基于不同数据集和模型的LongWriter微调

为了验证“通过基础长输出文本数据,以及精选的输出长度遵循数据,来调教基础模型的长文写作能力”这一方案的通用性,团队选择了Qwen2和GLM4模型来验证上述假设。

同时团队认为,对于长文本写作这一任务,人类对齐过的chat或instruct模型已经提供了一个较好的基准,故可能不需要完全base模型并带上全量的chat SFT数据开始训练。

所以团队分别选用了Qwen2-7b-instruct和GLM4-9B-Chat模型作为训练的基准模型。

当然还有一个原因是,团队确实也没有Qwen2或GLM4的完整SFT数据(doge)。

在不同的实验里,团队选用的数据集,除了LongWrier-6k和LongWrier-6k-filtered之外,还包括了:

Qwen2-72B-Instruct生成并经过筛选的200k中文以及英文对话数据集Magpie-Qwen2-Pro-200K-Chinese和Magpie-Qwen2-Pro-200K-English。

在loss函数的选择方面,使用了“long-ce”loss函数,这与原始LongWriter文章中采用的策略相同:

为避免长输出数据中每个target token对损失的贡献低于短输出的问题,long-ce loss通过计算该批次中所有target token的average loss来获得。

基于ModelScope Swift项目提供的多数据集混合能力,数据混合的训练微调都可以通过一个命令行完成。

例如,如下命令完成的是将longwriter-6k-filtered、Qwen2-Pro-200K-Chinese和Qwen2-Pro-200K-English三个数据集抽样后按自定义混合(包括随机抽样)策略,使用long-ce loss来进行SFT:

swift sft \

同时遵照LongWriter paper定义的输出长度(SL)和 输出质量(SQ)评分,可以基于EvalScope框架来进行相关评测。

在评测过程中,对于模型推理的配置为repetition_penalty=1.1, temperature=0.5。

LongWriter评测:

# pip install evalscope[framework]

训练配置

硬件环境:NVIDIA A100 x 4

初始学习率:1e-5

batch size:1,开启梯度累加

模型效果评估

基于Qwen2-7b-instruct

团队首先使用Qwen2-7b-instruct作为基础模型,来微调生成LongWriter模型。实验设计如下:

www.zeeklog.com  - 666条数据教会AI写万字长文!模型数据集都开源

通过上述实验可以看出,针对遵循指令进行长文本写作这个任务,使用“少而精”的数据,对于模型最终的性能至关重要。

事实上,在实验3中,只通过LongWriter-6k-filtered数据集4个epoch训练,总共2.6K条数据,其训练出来的模型,无论在写作长度,还是写作质量上,都显著优于LongWriter-6k + 180k的通用数据混合训练的模型。

同时,在实验3使用的LongWriter-6k-filtered数据集基础上,实验4再添加1:20混合的通用数据集,总共13.6K数据训练2个epoch,能进一步获得更好的结果。

Qwen2-7b-instruct的这个结果,也验证了使用LongWriter-6k-filtered数据集来微调长文本写作能力,具有一定的通用性,不只局限于GLM4系列模型。

此外,如同LongWriter论文里展示的一样,在写作质量方面,增强了长文本能力的模型,在质量上有小幅度的波动(-1.47点)。

在这些实验里,最终选择了实验4产出的模型作为MS-LongWriter-Qwen2-7b-instruct,并开源到ModelScope。

www.zeeklog.com  - 666条数据教会AI写万字长文!模型数据集都开源

图6展示了训练定制前后的模型,在输出文本遵循指定长度方面的对比。

可以看到,训练后的模型的文本输出长度,能更好的贴合prompt的要求,特别是在要求输出的文本长度较长的时候。

基于GLM4-9b-Chat

接下来,团队把LongWriter-6k-filtered数据集,以及对应微调定制模型的方法(也就是上述实验4的配置),也以GLM4-9b-Chat模型作为基座进行了定制训练,并且与LongWriter-GLM4-9B结果做了对比。

如下表所示:

www.zeeklog.com  - 666条数据教会AI写万字长文!模型数据集都开源

可以看到基于实验4的配置,使用GLM4-9b-Chat作为基础,总共使用了13.6K数据,训练2 epoch;而原始LongWriter-GLM4-9B使用186K数据,训练4 epoch

实验4训练用的总数据量在仅为原始LongWriter-GLM4-9B训练使用数据量7.5%(实际消耗计算资源为3.7%)的情况下,获取了类似的效果。

当然这里一个显著的区分点,是团队是以GLM4-9b-Chat作为训练的基础。

考虑到原始论文中使用的是GLM4-9b base模型作为基座,客观上确实需要更多通用对齐数据集。

但如同之前讨论的,对于遵循指令进行长文本写作这个具体任务,从base模型开始训练可能并不必要。

在这些实验里,最终选择了实验4产出的模型作为MS-LongWriter-GLM4-9B-Chat,并开源到ModelScope。

基于Qwen2.5-7b-instruct

在团队的这个探索接近尾声之时,Qwen模型家族正式推出Qwen2.5系列

相比Qwen2系列,Qwen2.5支持的输出长度有了较大的提升。团队也在第一时间基于Qwen2.5-7B-Instruct模型做了初步的实验,结果如下:

www.zeeklog.com  - 666条数据教会AI写万字长文!模型数据集都开源

对比上述表格,可以清晰看到,未经定制的Qwen2.5-7B-Instruct模型在遵循指令进行长文本写作的输出长度(SL)方面的评分,无论是对比Qwen2-7B-Instruct,还是GLM4-9b-Chat,都已经有了较大的提升。

而通过实验4的13.6K条数据2个epoch的定制训练,模型综合指标(S-avg)就已经达到达到最佳。在这个基础上,额外进行了基于LongWriter-6k-filtered 666 条数据的2个epoch退火训练,则在SL, SQ和S-avg几个指标上都全面超越了其他测试模型

其中具体实验5的退火(annealing)训练的命令行如下:

CUDA_VISIBLE_DEVICES=0,1,2,3 nohup swift sft \

最终采取实验5的产出模型,作为MS-LongWriter-Qwen2.5-7B-Instruct开源到了ModelScope。

微调对于基础能力的影响

最后,为评估针对遵循指令进行长文本写作任务定制的模型,在基础能力上是否存在退化,在mmlu、ceval、ARC_c、gsm8k上,使用EvalScope对于MS-LongWriter-Qwen2-7b-instruct进行了评估。

通过swift接口与EvalScope的对接,可以一键完成模型部署,推理和评估流程。

例如可以通过如下命令,完成对于Qwen2-7b-instruct的基础能力评估:

CUDA_VISIBLE_DEVCIES=0 swift eval --model_type qwen2-7b-instruct --eval_dataset mmlu ceval ARC_c gsm8k

比较几个模型在基础benchamrk上的得分,结果如下:

www.zeeklog.com  - 666条数据教会AI写万字长文!模型数据集都开源

可以看到,针对遵循指令进行长文本写作任务定制微调的模型,除了在ceval上有一些提升,在其他通用任务,尤其是偏逻辑推理的benchmark上,能力还是会有一定的regression,例如在MMLU上的掉点是较为明显的。

结论

总体来看,多种证据表明,针对遵循指令进行长文本写作这个任务,要来训练定制模型,训练数据的质量,会比数量更加重要。

且在这个任务上,可能从对齐的chat或instruct模型开始训练,会比从未对齐的base模型开始训练更加经济。

在这个最佳实践中,得益于ModelScope Swift训练工具和EvalScope评估工具,团队很方便的进行了各种不同的对比实验。

本文中使用到的开源工具包括:

模型训练微调框架:MS-Swift

模型评估工具:EvalScope

并且通过基于chat和instruct模型作为起点,只使用相比原始LongWrite训练所需的3.7%的数据和计算消耗,就在Qwen2-7b-instruct和GLM4-9b-Chat上,在长文本撰写任务上都获得了和原paper里几乎一致的效果提升(12pt左右)。

而在Qwen2.5-7b-instruct本身提供了较好长文本输出能力的基础上,通过同样少量高质量数据的训练定制,在这个任务上,能全方位获得最佳的效果。

团队训练使用的数据,以及最后输出的模型,目前都开源到了ModelScope。

参考资料:

1、LongWriter: Unleashing 10,000+ Word Generation from Long Context LLMs, Bai et al. 2024
2、Magpie: Alignment Data Synthesis from Scratch by Prompting Aligned LLMs with Nothing, Xu et al. 2024
3、LIMA: Less Is More for Alignment, Zhou et al. 2023
4、InstructionGPT-4: A 200-Instruction Paradigm for Fine-Tuning MiniGPT-4, Wei et al. 2023
5、Qwen2 Technical Report, Yang et al. 2024
6、ChatGLM: A Family of Large Language Models from GLM-130B to GLM-4 All Tools, ZhipuAI 2024

文中使用到的开源工具框架:
模型训练微调框架MS-Swift:https://github.com/modelscope/ms-swift
模型评估工具EvalScope:https://github.com/modelscope/evalscope/


精筛后的666条数据集构成的LongWriter-6K-Filtered数据集:

https://www.modelscope.cn/datasets/swift/longwriter-6k-filtered

训练微调后开源的长文本模型:

MS-LongWriter-Qwen2.5-7b-instruct:
https://www.modelscope.cn/models/swift/MS-LongWriter-Qwen2.5-7B-Instruct

MS-LongWriter-Qwen2-7b-instruct:
https://www.modelscope.cn/models/swift/MS-LongWriter-Qwen2-7B-Instruct
MS-LongWriter-GLM4-9B-Chat:
https://www.modelscope.cn/models/swift/MS-LongWriter-GLM4-9B-Chat


原始开源的LongWriter-GLM4-9B模型:
https://www.modelscope.cn/models/ZhipuAI/LongWriter-glm4-9b

其他相关数据集

WildChat:
https://www.modelscope.cn/datasets/thomas/WildChat

Magpie-Qwen2-Pro-200K-Chinese:
https://modelscope.cn/datasets/AI-ModelScope/Magpie-Qwen2-Pro-200K-Chinese
Magpie-Qwen2-Pro-200K-English:
https://modelscope.cn/datasets/AI-ModelScope/Magpie-Qwen2-Pro-200K-English

Read more

科普文:Java基础系列之【java框架基础:字节码增强技术框架ASM】

科普文:Java基础系列之【java框架基础:字节码增强技术框架ASM】

,之前的文章我们介绍了字节码的基础知识,今天我们将介绍字节码相关的应用场景,首先要介绍的是如何对字节码做解析和修改,本文将会详细给大家介绍一个工业级字节码操作框架 ASM。 ASM 当我们需要对一个 class 文件做修改时,我们可以选择自己解析这个class 文件,在符合 Java 字节码规范的前提下进行字节码改造。如果你写过 class 文件的解析程序,会发现这个过程极其繁琐,更别说进行增加方法等操作了。 ASM 最开始是 2000 年 Eric Bruneton 在 INRIA(法国国立计算机及自动化研究院)读博士期间完成的一个作品。那个时候包含 java.lang.reflect.Proxy 包的 JDK 1.3 还没发布,ASM 被作为代码生成器,用来生成动态代理的代理类。经过多年的发展,ASM 在诸多框架中已经遍地开花,成为字节码操作领域事实上的标准。 实现 Evaluate 要解决的第一个问题就是怎么改变原有代码的行为,它的实现在

By Ne0inhk
科普文:Java基础系列之【java框架基础:字节码增强技术框架ASM#ClassReader实现原理及源码分析】

科普文:Java基础系列之【java框架基础:字节码增强技术框架ASM#ClassReader实现原理及源码分析】

1 概述 ASM是Java中比较流行的用来读写字节码的类库,用来基于字节码层面对代码进行分析和转换。 在读写的过程中可以加入自定义的逻辑以增强或修改原来已编译好的字节码,比如CGLIB用它来实现动态代理。ASM被设计用于在运行时对Java类进行生成和转换,当然也包括离线处理。ASM短小精悍、且速度很快,从而避免在运行时动态生成字节码或转换时对程序速度的影响,又因为它体积小巧,可以在很多内存受限的环境中使用。 ASM的主要优势包括如下几个方面: 1. 它又一个很小,但设计良好并且模块化的API,且易于使用。 2. 它具有很好的文档,并且还有eclipse插件。 3. 它支持最新的Java版本。 4. 它短小精悍、快速、健壮。 5. 它又一个很大的用户社区,可以给新用户提供支持。 6. 它的开源许可允许你几乎以任何方式来使用它。 2 ASM Core设计 主要有以下几个类、接口(在org.objectweb.asm包中): * ClassReader类:字节码的读取与分析引擎。它采用类似SAX的事件读取机制,每当有事件发生时,调用注册的ClassVisitor、

By Ne0inhk
科普文:Java基础系列之【java正则表达式】

科普文:Java基础系列之【java正则表达式】

一、概叙 从Java1.4起,Java核心API就引入了java.util.regex程序包,它是一种有价值的基础工具,可以用于很多类型的文本处理, 如匹配,搜索,提取和分析结构化内容. java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包。它包括两个类:Pattern和Matcher. Pattern是一个正则表达式经编译后的表现模式。 在java中,通过适当命名的Pattern类可以容易确定String是否匹配某种模式.模式可以象匹配某个特定的String那样简单,也可以很复 杂,需要采用分组和字符类,如空白,数字,字母或控制符.因为Java字符串基于统一字符编码(Unicode),正则表达式也适用于国际化的应用程序. 正则表达式(regex)是一个字符串,由字面值字符和特殊符号组成,是用来描述匹配一个字符串集合的模式,可以用来匹配、替换和拆分字符串。 例如可以检查一个字符串是否含有某种子字符串、将匹配的子字符串做替换或者从某个字符串中取出符合某个条件的子字符串等。 java.util.regex 包 java.util.regex

By Ne0inhk
科普文:Java基础系列之【Java 异常处理】

科普文:Java基础系列之【Java 异常处理】

异常处理概叙 在使用计算机语言进行项目开发的过程中,即使程序员把代码写得尽善尽美,在系统的运行过程中仍然会遇到一些问题,因为很多问题不是靠代码能够避免的。 比如: 客户输入数据的格式, 读取文件是否存在, 网络是否始终保持通畅等等。 异常定义 异常:在Java语言中, 将程序执行中发生的不正常情况称为“异常” 。 (开发过程中的语法错误和逻辑错误不是异常) Java程序在执行过程中所发生的异常事件可分为两类: * Error: Java虚拟机无法解决的严重问题。 如: JVM系统内部错误、 资源耗尽等严重情况。 比如: StackOverflowError和OOM。 一般不编写针对性的代码进行处理。 * Exception: 其它因编程错误或偶然的外在因素导致的一般性问题, 可以使用针对性的代码进行处理。 例如: 1、空指针访问 2、试图读取不存在的文件 3、网络连接中断 4、数组角标越界 对于这些错误, 一般有两种解决方法: * 一种是遇到错误就终止程序的运行。 * 一种方法是由程序员在编写程序时, 就考虑到错误的检测、 错误消息的提示, 以及错误的处理。

By Ne0inhk