如何让大模型输出 10k+字长文?
来源:互联网
时间:2026-08-25 14:15:21
随着大语言模型的能力不断攀升,如今很多模型已经能处理超过100k tokens的输入上下文了。但问题来了:当模型需要输出长文本时,输出长度就成了一个明显的瓶颈。
在实际应用中,大家普遍采用“分而治之”的思路——让模型一段一段写,最后拼起来。这招儿从表面看能绕开长度限制,但代价也很明显:一是消耗的tokens量成倍甚至指数级增长;二是前后内容容易脱节,读起来断断续续。
那么,有没有办法让模型自己就能一口气输出长文本?我们研究发现,输出长度受限的根子,在于监督微调(SFT)数据集里缺少足够长的输出样例。换句话说,模型“读”过的内容决定了它能“写”多长。
针对这个问题,我们构建了一个包含6000多条、长度从2k到20k words不等的长输出数据集——LongWriter-6k,并基于它对GLM-4-9B进行了SFT微调和DPO对齐。新模型拥有了**生成超过10,000字/词连贯文本的能力**。
下面是用LongWriter-9B模型,以「黑神话·悟空」为题生成的玄幻小说片段(完整内容可查看视频)。
> prompt: 请帮我撰写一个主题为「黑神话·悟空」的玄幻小说,以孙悟空为核心,讲述一个桀骜不驯、打怪升级、追逐梦想的玄幻故事,不少于10000字
<iframe data-vidtype="2" data-mpvid="wxv_3600844978806816771" data-cover="http%3A%2F%2Fmmbiz.qpic.cn%2Fsz_mmbiz_jpg%2FEu2cI2IojBKdX9dxicDBQPcVCvFUvpVuWOj75fNGPFmj9rfe5f03JNPWo6qyd6WHibNN0sslXoy9KPlCEkohg4ibA%2F0%3Fwx_fmt%3Djpeg" allowfullscreen="" frameborder="0" data-ratio="1.538888888888889" data-w="1662" src="https://mp.weixin.qq.com/mp/readtemplate?t=pages/video_player_tmpl&action=mpvideo&auto=0&vid=wxv_3600844978806816771"></iframe>
**论文:** https://arxiv.org/abs/2408.07055
**代码:** https://github.com/THUDM/LongWriter
**模型:**
Huggingface:https://huggingface.co/THUDM/LongWriter-glm4-9b
魔搭:https://modelscope.cn/models/ZhipuAI/LongWriter-glm4-9b
**数据:**
Huggingface:https://huggingface.co/datasets/THUDM/LongWriter-6k
魔搭:https://modelscope.cn/datasets/ZhipuAI/LongWriter-6k
生成长度限制的根源
我们对当前最先进的长上下文模型做了测试:明确要求它们生成不同长度的内容,比如“写一篇关于罗马帝国历史的10000字文章”。结果很有意思——所有模型生成的内容,几乎都不超过2000字。
**原因是什么呢?**
我们做了一个初步实验:用不同最大输出长度的SFT数据对GLM-4-9B-base进行微调。结果发现:随着要求长度的增加,不同数据集微调出来的模型,存在明显的最大输出长度限制。由此可以得出一个结论——尽管大模型在预训练阶段接触过很长的文本序列,但其最大生成长度实际上被SFT数据集中输出长度的上限给锁死了。
这一发现恰好解释了当前模型普遍存在的2000字输出限制:现有的SFT数据集很少包含超过这个长度的样例;而很多数据集又是用现有LLM自动构建的,于是它们也继承了源模型的输出长度限制,形成了一个“自己生不出长文本,所以数据里没有长文本,于是模型也学不会长文本”的死循环。
生成长度限制的根源
自动构建长输出数据集
为了打破这个循环,我们设计了一个叫**「AgentWrite」**的pipeline。它的思路很直接:把长生成任务拆解开,让现有模型分段完成,再拼成连贯的长文本。
具体来说,AgentWrite分两步走:
- 首先,根据用户的输入自动生成一个详细的写作计划,包括每段的结构和预期字数;
- 然后,模型依次完成每个子任务,把生成的段落串起来,最终形成完整的长文本输出。
用这种方法,AgentWrite能生成超过20,000字的高质量文本,而且段落之间衔接自然。
自动构建长输出数据集
教模型生成超长输出
有了一个利用LLM自动生成的较长输出数据集,接下来的问题就是:能不能把这种分段生成超长输出的“能力”直接教给模型,让它在一轮输出中完成长篇写作?
我们从GLM-4的SFT数据中筛选出3000条(主要是中文),另外从WildChat-1M(包含用户与ChatGPT/GPT-4对话记录的公开日志)中选了3000条(主要是英文),通过AgentWrite并借助GPT-4o生成了6000条长输出的SFT数据,这就是LongWriter-6k。
在模型训练时,为了保持通用能力,我们把LongWriter-6k与通用SFT数据(约18万条)混合,形成完整的训练集。输出长度分布显示:LongWriter-6k有效填补了通用数据中2000字以上输出样例的空白,而且长度在2000到10000词之间分布相当均匀。
**微调(SFT):** 我们分别对GLM-4-9B和Llama-3.1-8B进行了SFT微调——这两个基础模型都支持最多128k tokens的上下文窗口,很适合做长输出训练。得到的两个模型分别命名为LongWriter-9B(GLM-4-9B-LongWriter的缩写)和LongWriter-8B(Llama-3.1-8B-LongWriter的缩写)。
**对齐(DPO):** 为了进一步提升输出质量,并增强模型遵循长度约束的能力,我们在SFT后的LongWriter-9B模型上做了直接偏好优化。DPO数据来自GLM-4的DPO数据(约5万条),同时还加入了4000条我们标注的长输出正负样本对。
教模型生成超长输出
结果怎么样?
我们在LongBench-Write上对4个专有模型和5个开源模型进行了评测,结果见下表:
[此处保留原文中的表格图片,但原文没有表格图片,只有文字描述,因此保留原文字描述]
其中S_l表示输出长度是否符合要求的得分:长度达标得100分;若输出长度超过要求的4倍或低于要求的1/3,得分会线性下降至0。S_q则是从相关性、准确性、连贯性、清晰度、广度与深度以及阅读体验六个维度,用GPT-4o打分后取平均值,代表生成内容的质量。最终得分通过S_l和S_q的平均值计算。
**1. 大多数当前模型都无法满足超过2000字的长度要求,而LongWriter模型在此类提示下能提供更长且更丰富的响应。**
更具体地说,在[2k, 4k)范围内,当前模型普遍表现不佳,只有Claude 3.5 Sonnet得分尚可;而在[4k, 20k)范围里,几乎所有现存模型都完全无法达到目标输出长度,甚至得分为0(意味着所有输出长度均小于要求长度的1/3)。
**2. DPO(直接偏好优化)有效提升了模型的输出质量及其在长文本生成中遵循长度要求的能力。**
对比LongWriter-9B和LongWriter-9B-DPO的得分可以发现,DPO显著提高了S_l(+4%)和S_q(+3%),而且这种提升在所有长度范围内保持一致。这说明在长文本生成场景中,DPO依然能帮助模型提升输出质量,并更好地让输出长度与要求长度对齐。
**3. LongWriter模型的输出长度限制大约在10k至20k字之间。如果想拥有更长输出的能力,则需要更长输出的数据集。**
在混合后的SFT数据集中,大部分数据都在20k以下,超出20k的不到100条。可以预见,未来如果能构建更长的SFT训练数据,模型输出长度的限制有望进一步突破,达到100k甚至更长。
结果怎么样?
论文、代码、模型、数据的链接均在文中,欢迎自行尝试。
-
- 关于宇宙的好的网名有哪些
- 角色扮演 | 1
- 网名