LongWriter——从长文本语言模型中释放出10,000+字的生成能力

LongWriter超长文本生成
部署运行你感兴趣的模型镜像

概述

当前的长上下文大型语言模型 (LLM) 可以处理多达 100,000 个词的输入,但它们很难生成超过 2,000 个词的输出。受控实验表明,该模型的有效生成长度本质上受到监督微调(SFT) 期间看到的示例的限制。换句话说,这种输出限制源于现有 SFT 数据集中长输出示例的稀缺性。

长上下文LLM 的最新进展推动了内存容量显着扩展的模型的开发,能够处理长度超过100,000 个标记的历史记录。然而,尽管它们能够处理大量输入,但当前的长上下文LLM 很难生成同样长的输出。

为了探索这一限制,LongWriter使用多个需要不同长度响应的查询来探测最先进的长上下文模型的最大输出长度,例如“写一篇关于罗马帝国历史的 10,000 字的文章”。结果表明,所有模型始终无法产生超过 2,000 字的输出。同时,对用户交互日志的分析显示,超过 1% 的用户提示明确要求输出超过此限制,这凸显了当前研究迫切需要克服这一限制。

为了解决这个问题,LongWriter 引入了AgentWrite,这是一种基于代理的管道,可将超长生成任务分解为子任务,使现成的 LLM 能够生成超过 20,000 个单词的连贯输出。利用 AgentWrite,LongWriter 构建了 LongWriter-6k,这是一个包含 6,000 个 SFT 数据样本的数据集,输出长度从 2k 到 32k 个单词不等。通过将此数据集纳入模型训练,LongWriter 成功地将现有模型的输出长度扩展到 10,000 个单词以上,同时保持了输出质量。

LongWriter 还开发了 LongBench-Write,这是一个用于评估超长生成能力的综合基准。通过 DPO 进一步改进的 9B 参数模型在此基准上实现了最先进的性能,甚至超越了更大的专有模型。

在这里插入图片描述

LongWriter:10,000+ 单词生成框架

长上下文大型语言模型(LLM) 的最新进展导致了内存容量显着增加的模型的创建,这些模型能够处理超过100,000 个标记的历史记录。尽管能够处理大量输入,但当前的长上下文模型仍难以生成相当长度的输出。为了研究这一限制,LongWriter 通过各种需要不同响应长度的查询来检查最先进的长上下文模型的最大输出长度,例如“写一篇10,000 字的关于罗马帝国历史的文章”。根据调查结果,LongWriter 观察到所有模型都无法生成超过2,000 字的输出。此外,对用户交互日志的分析表明,超过1% 的用户提示特别要求超出此限制的输出,凸显了当前研究迫切需要解决这一问题。
在这里插入图片描述
LongWriter 的研究揭示了一个关键见解:输出长度的限制主要源于监督微调 (SFT) 数据集的特性。具体而言,LongWriter 发现,尽管模型在预训练阶段接触了更长的序列,但其最大生成长度实际上受到其 SFT 数据集中存在的输出长度上限的限制。这一发现解释了当前模型中普遍存在的 2,000 字生成限制,因为现有的 SFT 数据集很少包含超过此长度的示例。此外,由于许多数据集都是从最先进的 LLM 中提炼出来的,因此它们也从其源模型继承了输出长度限制。

为了解决这一限制,LongWriter 引入了 AgentWrite,这是一种基于代理的新型管道,旨在利用现成的 LLM 自动构建扩展的连贯输出。AgentWrite 分为两个阶段:首先,它根据用户的输入制定详细的写作计划,概述每个段落的结构和目标字数。然后,按照这个计划,它会提示模型按顺序生成每个段落的内容。LongWriter 的实验证实,AgentWrite 可以生成多达 20,000 个单词的高质量连贯输出。

在 AgentWrite 管道的基础上,LongWriter 利用 GPT-4o 生成了 6,000 个长输出 SFT 数据,命名为 LongWriter-6k,并将这些数据添加到训练现有模型中。值得注意的是,LongWriter-6k 成功释放了模型生成长度超过 10,000 字的结构良好的输出的能力。为了严格评估这种方法的有效性,LongWriter 开发了 LongBench-Write 基准,其中包含一组多样化的用户写作指令,输出长度规格范围从 0-500 字、500-2,000 字、2,000-4,000 字和超过 4,000 字。在 LongBench-Write 上的评估表明,LongWriter 的 9B 大小模型达到了最先进的性能,甚至与更大的专有模型相比也是如此。LongWriter 进一步构建偏好数据并使用 DPO 帮助模型更好地遵循长写作指令并生成更高质量的书面内容,这也已通过实验证明是有效的。

总而言之,LongWriter 的工作做出了以下新颖的贡献:

  • **生成长度限制分析:**LongWriter 确定了限制当前长上下文 LLM 输出长度的主要因素,即 SFT 数据中对输出长度的限制。
  • **AgentWrite:**为了克服这一限制,LongWriter 提出了 AgentWrite,它使用分而治之的方法,利用现成的 LLM 自动构建具有超长输出的 SFT 数据。使用此方法,LongWriter 构建了 LongWriter-6k 数据集。
  • **扩展当前 LLM 的输出窗口大小:**LongWriter 将 LongWriter-6k 数据集整合到其 SFT 数据中,成功将现有模型的输出窗口大小扩展至 10,000 多个字,且不影响输出质量。LongWriter 表明 DPO 进一步增强了模型的长文本写作能力。

AgentWrite:自动数据构建

为了利用现成的 LLM 自动生成输出较长的 SFT 数据,LongWriter 设计了 ​​AgentWrite,一种分而治之式的代理管道。AgentWrite 首先将长篇写作任务分解为多个子任务,每个子任务仅要求模型写一段话。然后模型按顺序执行这些子任务,LongWriter 将子任务的输出连接起来以获得最终的长篇输出。这种使用 LLM 代理将复杂任务分解为多个子任务的方法已经应用于问题解决、软件开发和模型评估等各个领域。LongWriter 的工作首次探索了集成规划以使模型能够完成复杂的长篇写作任务。下面详细介绍了 AgentWrite 的每个步骤。

在这里插入图片描述

第一步:计划

LongWriter 受到人类作家思维过程的启发,人类作家通常首先为长篇写作任务制定一个总体计划,LongWriter 利用 LLM 的规划功能,在给定写作指示的情况下输出这样的写作大纲。该计划包括每个段落的主要内容和字数要求。LongWriter 使用的提示如下:

“I need you to help me break down the following long-form writing instruction into multiple subtasks. Each subtask will guide the writing of one paragraph in the essay and should include the main points and word count requirements for that paragraph. The writing instruction is as follows: {User Instruction}. Please break it down in the following format, with each subtask taking up one line:

Paragraph 1 – Main Point: [Describe the main point of the paragraph, in detail] – Word Count: [Word count requirement, e.g., 400 words]
Paragraph 2 – Main Point: [Describe the main point of the paragraph, in detail] – Word Count: [Word count requirement, e.g. 1000 words].

Make sure that each subtask is clear and specific, and that all subtasks cover the entire content of the writing instruction. Do not split the subtasks too finely; each subtask’s paragraph should be no less than 200 words and no more than 1000 words. Do not output any other content.”

第二步:书写

在获得步骤 I 中的写作计划后,LongWriter 串行调用 LLM 完成每个子任务,逐段生成写作内容。为了保证输出的连贯性,在 LongWriter 调用模型生成第 n 段时,会将之前生成的 n-1 段也一并输入,让模型根据已有的写作历史继续写下一段。虽然这种串行方式无法并行调用模型同时完成多个子任务,输入长度也会变长,但 LongWriter 在验证中表明,这种方式得到的写作整体连贯性和质量远优于并行生成的输出。LongWriter 使用的提示为:

Writing instruction:
{User Instruction}
Writing steps:
{The writing plan generated in Step I}
Already written text:
{Previous generated (n-1) paragraphs}

验证

LongWriter 在两个长篇写作数据集上测试了所提出的 AgentWrite 方法的生成长度和质量。第一个数据集 LongWrite-Ruler 用于精确测量该方法可以提供的输出长度。第二个数据集 LongBench-Write 主要用于评估模型生成的内容在长度和写作质量方面与用户指示的匹配程度。

LongBench-Write :为了评估模型在更多元的长篇写作指令上的表现,LongWriter 收集了 120 条不同的用户写作提示,其中 60 条为中文,60 条为英文。为了更好地评估模型的输出长度是否符合用户要求,LongWriter 确保这些指令都包含明确的字数要求。这些指令根据字数要求分为 0-500 字、500-2,000 字、2,000-4,000 字和 4,000 字以上四个子集。此外,指令根据输出类型分为文学与创意写作、学术与专著、科普、实用写作、新闻报道、社区论坛和教育培训七大类。

在评估过程中,LongWriter 采用两个指标:一个用于对输出长度进行评分,另一个用于对输出质量进行评分。模型的输出长度根据其与说明中指定的要求的接近程度进行评分。对于输出质量,LongWriter 使用 LLM-as-a-judge 方法,选择最先进的GPT-4o模型从六个维度对输出进行评分:相关性、准确性、连贯性、清晰度、广度和深度以及阅读体验。最终得分是通过对长度得分和质量得分取平均值来计算的。

验证结果:LongWriter 在 LongWrite-Ruler 上展示了输出长度测量结果,发现 AgentWrite 成功将 GPT-4o 的输出长度从最大 2k 字扩展到大约 20k 字。LongWriter 还在 LongBench-Write 上评估了输出质量和对所需输出长度的遵守情况,表明在评估 AgentWrite 的性能时,GPT-4o 可以成功完成长度在 2,000 字以下的输出任务。
在这里插入图片描述

监督微调

LongWriter 基于最新的两个开源模型 GLM-4-9B 和 Llama-3.1-8B 进行训练。这两个模型都是基础模型,支持最大 128k token 的上下文窗口,天然适合在长输出上进行训练。为了提高训练效率,LongWriter 采用了带损失权重的打包训练。在这两个模型上训练后,得到了两个模型:LongWriter-9B(简称 GLM-4-9B-LongWriter)和 LongWriter-8B(简称 Llama-3.1-8B-LongWriter)。

同时,LongWriter 注意到,如果按序列平均损失,即取批次内每个序列的平均损失的平均值,则长输出数据中每个目标 token 对损失的贡献将明显小于短输出数据。在 LongWriter 的实验中,还发现这会导致模型在长输出任务上的表现不佳。因此,LongWriter 选择了一种按 token 平均损失的损失加权策略,其中损失被计算为该批次内所有目标 token 损失的平均值。

所有模型均使用具有 8xH800 80G GPU 和 DeepSpeed+ZeRO3+CPU 卸载的节点进行训练。LongWriter 使用批大小为 8、学习率为 1e-5 和打包长度为 32k。模型训练了 4 个 epoch,大约需要 2,500-3,000 步。

对齐(DPO)

为了进一步提高模型的输出质量并增强其遵循指令长度约束的能力,LongWriter 在监督微调的 LongWriter-9B 模型上执行直接偏好优化 (DPO)。DPO 数据来自 GLM-4 的聊天 DPO 数据(约 50k 个条目)。此外,LongWriter 构建了 4k 对专门针对长格式写作指令的数据。对于每个写作指令,LongWriter 从 LongWriter-9B 中抽取 4 个输出,并按照特定方法对这些输出进行评分。长度遵循分数也会在计算时合并。然后选择得分最高的输出作为正样本,并从其余三个输出中随机选择一个作为负样本。

最终的模型 LongWriter-9B-DPO 在上述数据混合上进行了 250 步训练。LongWriter 遵循 DPO 训练的特定配方。

LongWriter:实验和结果

LongWriter 在 LongBench-Writer 上评估了 4 个专有模型和 5 个开源模型,以及经过训练的 LongWriter 模型。据 LongWriter 所知,Suri-IORPO 是唯一一个也适用于长文本生成的先前模型。它基于 Mistral-7B-Instruct-v0.2 使用 LoRA 进行训练。与 LongWrite-Ruler 上的评估设置一致,LongWriter 将输出温度设置为 0.5,并将模型的生成最大令牌参数配置为其 API 调用允许的最大值。对于开源模型,它设置为 32,768。
在这里插入图片描述

大多数先前的模型无法满足超过 2,000 字的长度要求,而 LongWriter 模型始终能够对此类提示提供更长、更丰富的响应。

观察各个要求长度范围内提示的输出长度得分 SlS_lSl​,LongWriter 发现之前的模型在 [2k, 4k) 范围内的提示上普遍表现不佳(得分低于 70),只有 Claude 3.5 Sonnet 取得了不错的分数。对于 [4k, 20k) 范围内的提示,几乎所有之前的模型都完全无法达到目标输出长度,甚至得分为 0(即所有输出长度均小于要求长度的三分之一)。通过添加来自 LongWriter-6k 的训练数据,LongWriter 训练后的模型可以有效达到要求的输出长度,同时保持良好的质量,正如 [2k, 20k) 范围内的得分和散点图所表明的那样。
在这里插入图片描述

DPO有效地提高了模型的输出质量和满足长生成中长度要求的能力。

通过对比 LongWriter-9B 和 LongWriter9B-DPO 的得分,我们发现 DPO 显著提升了 Sl (+4%) 和 Sq (+3%) 的得分,并且这种提升在所有范围内都是一致的。这表明在长代场景下,DPO 仍然有助于提升模型的输出质量,能够更好地将模型的输出长度与请求的长度对齐。后一个结论最近也在 Yuan 等人 (2024) 的较短代中观察到。我们还手动注释了 GPT-4o 和三个 longwriter 模型在 LongBench-Write 中的输出结果的成对胜负,并在图 9 中将结果可视化。我们可以看到,在 58% 的情况下,人类更喜欢 DPO 训练的模型而不是 LongWriter-9B。此外,尽管参数较少,但 LongWriter-9B-DPO 与 GPT-4o 打成平手。
在这里插入图片描述

LongWriter 模型的输出长度限制扩展到 10k 到 20k 字之间,而需要更多具有长输出的数据来支持更长的输出。

继 LongWrite-Ruler 测试之后,我们还展示了 LongWriter 模型的 LongWrite-Ruler 测试结果。结果表明,它们的最大生成长度在 10k-20k 字之间。缺乏具有更长输出的 SFT 数据可能是阻止模型实现更长输出长度的主要原因。

总结

在本文中,我们讨论了 LongWriter,这是一个基于代理的管道,它将超长生成任务分解为子任务,确定了当前 LLM 的 2,000 字生成限制,并建议通过在对齐期间添加长输出数据来增加其输出窗口大小。为了自动构建长输出数据,LongWriter 开发了 AgentWrite,这是一个基于代理的管道,它使用现成的 LLM 创建扩展的、连贯的输出。LongWriter 使用构建的 LongWriter-6k 成功地将当前 LLM 的输出窗口大小扩展到 10,000 字以上。对训练数据的广泛消融研究证明了这种方法的有效性。对于未来的工作,LongWriter 建议以下三个方向:1. 扩展 AgentWrite 框架以构建具有更长输出的数据,以进一步扩展 LLM 的输出窗口大小。2. 改进 AgentWrite 框架以获得更高质量的长输出数据。3. 更长的模型输出给推理效率带来了挑战。已经提出了几种方法来提高推理效率。值得研究这些方法如何在不影响生成质量的情况下确保提高模型效率。

原文地址:https://www.unite.ai/longwriter-unleashing-10000-word-generation-from-long-context-llms/

您可能感兴趣的与本文相关的镜像

Qwen3-8B

Qwen3-8B

文本生成
Qwen3

Qwen3 是 Qwen 系列中的最新一代大型语言模型,提供了一整套密集型和专家混合(MoE)模型。基于广泛的训练,Qwen3 在推理、指令执行、代理能力和多语言支持方面取得了突破性进展

<think>好的,我现在需要帮用户用Flask搭建一个后端服务来对接本地的Ollama里的EntropyYue/longwriter-glm4:9b模型。用户还提到将来可能对接更多模型,比如线上的deepseek r1,所以得考虑扩展性。用户使用的是Windows系统,可能需要处理一些路径或环境的问题。 首先,我得确定用户已经安装了Ollama并且模型已经正确下载。可能需要提醒用户检查Ollama是否运行在默认端口11434,以及模型名称是否正确。然后,用户需要安装Flask和requests库,这些是基础依赖。 接下来,设计Flask的路由。用户需要一个POST接口来接收请求,处理参数,然后调用Ollama的API。可能需要处理JSON数据,确保请求和响应的格式正确。比如,用户发送的prompt参数需要传递给Ollama,而Ollama的响应可能需要解析后返回给客户端。 考虑到未来的扩展,应该将模型调用部分抽象出来,比如创建一个通用的generate_response函数,根据不同的模型选择不同的API调用方式。这样以后添加新的模型时,只需要在函数中添加对应的处理逻辑,而不需要修改主路由。 错误处理也很重要。比如,Ollama服务未启动或模型不存在时,应该返回明确的错误信息。使用try-except块来捕捉异常,并返回相应的HTTP状态码和错误信息。 另外,可能需要处理超时问题,特别是如果模型响应时间较长,Flask的默认超时设置可能需要调整,或者在前端处理超时重试。不过用户目前可能只需要基础功能,这部分可以后续优化。 用户是在Windows系统下运行,需要注意路径分隔符和文件权限的问题,但在这个案例中,由于主要使用网络请求与Ollama交互,可能影响不大。不过,如果将来需要读取本地配置文件,可能需要处理Windows的路径格式。 测试部分,用户可以使用curl或Postman发送POST请求到本地的Flask服务,确保能够正确接收响应。同时,检查Ollama的日志,确认模型是否被正确调用。 最后,用户可能需要部署Flask应用到生产环境,这时候可以考虑使用Waitress或Gunicorn(虽然Gunicorn在Windows上可能不太友好),或者使用Docker容器来部署,以提高性能和稳定性。不过目前开发阶段,使用Flask自带的服务器即可。 总结步骤:安装依赖,创建Flask应用,定义路由,处理请求,调用Ollama API,返回结果,错误处理,扩展性设计,测试验证。</think>好的!以下是一个使用 Flask 搭建后端服务对接本地 Ollama 模型的指南,基于你的 Windows 系统和未来扩展需求设计: --- ### **1. 环境准备** 1. **安装 Python** 确保已安装 Python 3.6+,建议使用虚拟环境(如 `venv`)。 2. **安装依赖包** ```bash pip install flask requests ``` 3. **运行 Ollama** 确保 Ollama 服务已启动(默认运行在 `http://localhost:11434`),且已下载模型: ```bash ollama run entropyyue/longwriter-glm4:9b ``` --- ### **2. 基础 Flask 服务代码** 创建一个 `app.py` 文件: ```python from flask import Flask, request, jsonify import requests app = Flask(__name__) # Ollama 配置 OLLAMA_URL = "http://localhost:11434/api/generate" CURRENT_MODEL = "entropyyue/longwriter-glm4:9b" # 当前默认模型 def generate_response(prompt, model=CURRENT_MODEL): """ 调用 Ollama API 生成文本 """ try: payload = { "model": model, "prompt": prompt, "stream": False # 关闭流式返回,直接获取完整结果 } response = requests.post(OLLAMA_URL, json=payload, timeout=60) response.raise_for_status() # 检查 HTTP 错误 return response.json()["response"] except requests.exceptions.RequestException as e: return f"Error calling Ollama: {str(e)}" @app.route('/api/generate', methods=['POST']) def handle_generate(): data = request.json prompt = data.get('prompt', '') model = data.get('model', CURRENT_MODEL) # 允许动态指定模型 if not prompt: return jsonify({"error": "Prompt is required"}), 400 result = generate_response(prompt, model) return jsonify({"response": result}) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=True) ``` --- ### **3. 扩展性设计(未来支持多模型)** #### **步骤 1:抽象模型接口** 修改 `generate_response` 函数,根据模型类型选择不同 API: ```python def generate_response(prompt, model=CURRENT_MODEL): if model.startswith("deepseek"): # 假设未来对接 DeepSeek return call_deepseek_api(prompt, model) else: # 默认为 Ollama 模型 return call_ollama_api(prompt, model) def call_ollama_api(prompt, model): # 原有 Ollama 调用逻辑 ... def call_deepseek_api(prompt, model): # 添加 DeepSeek 的 API 调用逻辑(需替换为实际 API 地址和密钥) headers = {"Authorization": "Bearer YOUR_API_KEY"} payload = {"model": model, "prompt": prompt} response = requests.post("DEEPSEEK_API_URL", headers=headers, json=payload) return response.json()["result"] ``` #### **步骤 2:配置化** 使用配置文件(如 `config.py`)管理模型参数: ```python # config.py MODEL_CONFIG = { "entropyyue/longwriter-glm4:9b": { "type": "ollama", "url": "http://localhost:11434/api/generate" }, "deepseek-r1": { "type": "deepseek", "url": "https://api.deepseek.com/v1", "api_key": "YOUR_KEY" } } ``` --- ### **4. 运行与测试** 1. **启动 Flask 服务** ```bash python app.py ``` 2. **发送测试请求** 使用 **curl** 或 **Postman** 测试: ```bash curl -X POST http://localhost:5000/api/generate \ -H "Content-Type: application/json" \ -d '{"prompt": "你好,请写一首关于春天的诗", "model": "entropyyue/longwriter-glm4:9b"}' ``` --- ### **5. 部署建议** - **生产环境**:使用 `Waitress`(Windows 友好)替代 Flask 开发服务器: ```bash pip install waitress waitress-serve --port=5000 app:app ``` - **跨平台部署**:未来可考虑用 Docker 容器化部署。 --- ### **常见问题排查** 1. **Ollama 未启动** 检查服务是否运行在 `11434` 端口:`curl http://localhost:11434`。 2. **模型不存在** 确认模型名称拼写正确,并已通过 `ollama pull` 下载。 3. **超时错误** 调整 `timeout` 参数(如 `timeout=120`)。 --- 如果需要更详细的代码或特定功能(如异步处理、鉴权),可以告诉我,我会补充更多细节!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知来者逆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值