百万上下文,模型终于会挑重点了

最新研究提出 Declarative Attention,让语言模型在生成过程中主动声明需要读取全局、局部区域还是近期输出,从而跳过大部分 KV Cache。它不压缩记忆,而是让模型学会决定何时、何处读取记忆。
百万上下文,模型终于会挑重点了
9 月 5 日,一篇题为《Language Models Can Control Their Own Attention》的最新研究提出了 Declarative Attention(DA,声明式注意力)协议:让语言模型在生成答案时,主动声明自己需要读取完整上下文、某个特定区域,还是仅依赖最近生成的内容。推理引擎解析这些声明后,可以跳过大部分 KV Cache 的读取。
这项工作的核心判断很直接:模型通常并不需要每一步都重新查看全部上下文,真正影响下一个 token 的信息往往只占很小一部分。问题在于,传统 Transformer 并不知道这一点,哪怕用户只问百万 token 对话中某个细节,模型也通常要在每个解码步骤扫描完整的历史 KV Cache。

真正的瓶颈,不只是 KV Cache 太大
KV Cache 是语言模型在自回归生成时保存历史 token 的 Key 和 Value 向量,用来避免每生成一个新 token 都重复计算历史内容。
它解决了一个重要问题:模型不必重新处理已经读过的 prompt。但在长上下文场景里,KV Cache 本身又变成了新的瓶颈。上下文越长,缓存占用的显存越多;生成每一个新 token 时,注意力层还需要读取更多历史 Key 和 Value,内存带宽与访存延迟随之上升。
对于 1M token 上下文来说,模型可能已经完成了 prompt 的 prefill,却仍然要在 decoding 阶段反复读取一百万个 token 对应的缓存。用户问的是一个局部问题,硬件执行的却是近似全局检索。
| 场景 | 用户真正需要的信息 | 传统全局注意力的行为 | DA 的目标行为 | |---|---|---|---| | 询问刚刚生成的内容 | 最近几十到几百个 token | 读取完整 KV Cache | 进入 local 模式 | | 追问长文档某一章节 | 一个明确区域 | 每步扫描完整上下文 | 进入 focus 模式 | | 总结全篇文档 | 多个分散区域或全局关系 | 每步扫描完整上下文 | 按需切换 global 与 focus | | 需要寻找早期细节 | 上下文中的远端片段 | 全量读取后自行筛选 | 声明目标区域并读取 |
传统长上下文优化通常围绕两个方向展开:减少缓存本身的大小,或者在读取前用额外机制挑出可能重要的 token。DA 选择了第三条路线:不急着压缩模型的记忆,而是让模型自己决定什么时候需要哪部分记忆。
DA 的关键:让模型先声明,再读取
Declarative Attention 是一种让模型在生成过程中显式声明注意力范围的协议。
研究将生成过程划分为三种模式:<global>、<focus> 和 <local>。其中,<global> 表示需要访问完整上下文;<focus> 表示模型只需要读取上下文中的某个具体区域;<local> 表示当前生成主要依赖最近的输出,不必访问远端 KV Cache。
这和普通的工具调用有些相似。模型不是把注意力范围当成隐含的内部计算,而是先输出一种可被推理引擎识别的控制信号。引擎看到声明后,再决定从 KV Cache 中加载哪些内容。
可以把它理解成图书馆里的两种检索方式。
传统注意力像是每次回答问题都把整座图书馆的书搬到桌面上,再从里面找一句话。DA 则要求模型先说清楚:这次要查全馆索引、某一本书的第几章,还是只看刚刚写下的草稿。只有在确实需要时,系统才扩大检索范围。
这种设计的价值不在于让模型少算几次矩阵乘法这么简单,而在于把“是否需要读取历史信息”从固定规则变成了模型可以控制的推理动作。
它和 Top-K 注意力不是一回事
DA 与常见的稀疏注意力、Top-K token 选择有相似目标,但技术路径并不相同。
动态稀疏注意力通常会先为上下文中的 token 计算重要性分数,再保留分数最高的一部分。这个方法可以减少真正参与注意力计算的 token 数量,但如果每一步都要先给百万 token 打分,前置筛选本身仍然可能是 O(N) 成本,其中 N 是上下文长度。
Top-K KV Cache 压缩则更像是提前整理仓库:系统按照注意力分数、局部窗口或其他策略,保留少量关键 token,删除或压缩其余缓存。它的优点是显存压力更低,缺点是被删掉的信息可能在后续突然变得重要,恢复成本也可能很高。
DA 的不同之处在于,它试图绕开每一步的全量候选评分。模型先作出范围声明,推理引擎再按声明读取缓存。论文将这种路径称为 intrinsic,也就是内生式控制;相对地,依赖外部代理分数进行筛选的方法属于 extrinsic,即外生式筛选。
| 方法 | 主要做法 | 是否需要每步扫描全上下文 | 主要风险 | 适合场景 | |---|---|---:|---|---| | 全量注意力 | 每步读取完整 KV Cache | 是,近似 O(N) | 访存和延迟随上下文增长 | 短上下文、强全局依赖任务 | | Top-K/动态稀疏注意力 | 先计算重要性,再保留部分 token | 通常仍需要候选打分 | 重要 token 误删 | 可接受近似的长文本任务 | | KV Cache 压缩与量化 | 降低缓存精度或删除冗余 token | 可能减少读取量 | 信息损失、恢复复杂 | 显存受限的部署环境 | | Prefix Cache | 复用重复前缀的 KV Cache | 减少重复 prefill,但不改变解码读取逻辑 | 前缀不匹配时命中率下降 | 固定系统提示词、多轮会话 | | Declarative Attention | 模型声明全局、聚焦或局部访问范围 | 目标是不再每步全量读取 | 错误声明会导致遗漏 | 超长对话、长文档问答、Agent 轨迹 |
这意味着 DA 并不是 KV Cache 压缩的替代品。更准确地说,它优化的是 KV Cache 的读取路径,而量化、跨层合并、token 淘汰优化的是缓存的存储形态。两者理论上可以叠加:先用量化降低每个 token 的存储成本,再用 DA 减少每一步真正搬运到计算单元的数据量。
三种模式,背后是三种推理状态
<global> 模式适合需要建立全局关系的任务,例如总结整篇文档、比较多个章节、寻找跨段落矛盾,或者处理需要回看系统指令的 Agent 工作流。这个模式的代价最高,但它不应该被完全取消。
<focus> 模式是 DA 最有价值的部分。它允许模型把注意力集中到一个特定区域,例如长对话中的第 120000 至 125000 个 token,或者一份代码库中某个文件、某个函数附近的内容。对于“之前提到的数据库连接超时是多少”这类问题,模型理论上只需要回到包含该细节的区域。
<local> 模式则面向连续生成。模型正在写一段解释、补全一段代码,或者根据刚刚确定的结构继续输出时,远端上下文可能暂时没有贡献。此时只读取最近输出,可以减少大量无效访存。
这三个模式并不是一次性选择,而是可以在生成过程中切换。模型可能先使用 <focus> 找到一段原始材料,再使用 <local> 连续组织答案,最后通过 <global> 检查是否遗漏全局约束。对推理引擎来说,这更像一个轻量级的注意力调度器。
最大看点:模型可能已经知道自己该看哪里
这项研究最有启发性的地方,是它没有把模型当成一个必须由外部系统不断纠正的黑盒。
现有很多长上下文优化方案默认认为:模型不会主动告诉我们哪些 token 重要,因此需要一个独立的打分器、检索器或缓存管理器替它做决定。DA 则提出了一个反问:模型在产生答案之前,难道没有能力判断自己需要哪些信息吗?
语言模型在回答问题时,本来就会形成某种隐含的信息检索过程。它知道问题是在问刚刚的句子,还是在追溯很早之前的事实;也知道当前是继续写作,还是需要重新核对文档。DA 做的事情,是把这种隐含判断转化成推理系统可以执行的声明。
这条路线有点像让编译器看到程序员的意图,而不是让编译器每次都遍历全部内存。模型的内部表示负责判断“我要查什么”,推理引擎负责执行“只读这些地方”。如果两者配合得好,长上下文推理就可能从单纯堆硬件,转向模型与系统共同调度。
但它不是免费的午餐
DA 的首要风险是模型可能声明错误的注意力范围。
如果模型把一个需要全局核对的问题误判为 <local>,它会在根本没有读取关键证据的情况下继续生成。对于普通闲聊,这种错误可能只是答案不完整;对于代码审查、合同分析、医学文档或多步骤 Agent 任务,遗漏一段远端上下文可能直接导致结论错误。
第二个风险是注意力声明自身会带来控制开销。模型需要生成模式标记、区域定位或其他调度信息,推理引擎也需要解析这些信息并管理不同缓存片段。只有当跳过的 KV Cache 读取量足够大时,收益才能覆盖协议处理、缓存寻址和可能的区域切换成本。
第三个风险是训练与部署的一致性。一个模型在研究环境里学会输出 <focus>,并不代表现有推理框架会自动理解这种标记。vLLM、TensorRT-LLM、SGLang 等系统需要在调度器、Paged KV Cache、内存管理和注意力 kernel 层面增加支持,硬件也要能够高效处理不连续的缓存读取。
第四个风险来自任务本身。代码仓库、法律合同和多轮 Agent 轨迹经常存在远距离依赖,某个看似无关的定义可能在后文重新生效。DA 如果过度依赖模型的即时判断,可能把“当前没有用”误认为“后面永远不会用”。
因此,可靠的工程实现不应只允许模型自由跳过上下文,还需要保留兜底机制,例如定期执行全局检查、对高风险任务强制使用 <global>、为焦点区域设置最小邻域,以及在模型置信度不足时扩大读取范围。
对百万上下文产品意味着什么
DA 最先受益的可能不是普通聊天,而是长时间运行的 Agent 系统。
在一个持续数小时的编码 Agent 中,历史上下文可能包括数十万 token 的终端日志、代码 diff、工具返回值和用户约束。Agent 当前只是在修改一个函数时,没有必要每生成一个 token 都读取全部日志;但当测试失败时,它又必须快速定位几分钟前甚至几小时前的错误信息。DA 的 <local>、<focus> 和 <global> 模式,恰好对应了这三种工作状态。
长文档问答也是明显场景。用户通常不会要求模型每次回答都重新理解整本报告,而是不断追问某个章节、某个指标或某个结论。若模型能把问题映射到文档区域,推理服务就可以把更多算力用于并发请求,而不是浪费在重复扫描无关缓存上。
不过,DA 对首次读取完整文档的 prefill 阶段帮助有限。它主要优化的是生成阶段的 KV Cache 访问;如果应用每次请求都需要重新处理一百万 token 的输入,仍然需要结合 Prefix Cache、分块预填充、检索增强、KV Cache 量化和跨请求复用等技术。
换句话说,DA 解决的是“已经记住之后,如何少翻记忆”的问题,而不是“第一次读完一百万 token 要花多久”的问题。
这会改变模型和推理引擎的分工
过去,注意力范围几乎完全由模型架构和 kernel 决定;DA 让推理引擎开始理解模型生成的控制意图。
这可能催生一种新的推理接口:模型不只输出文本 token,还输出对上下文访问权限的声明。推理服务则像一个操作系统,根据声明调度缓存页、控制带宽,并决定什么时候允许全局扫描。
从系统角度看,未来的 KV Cache 不一定是一块连续、静态的显存数组,而可能更像分层存储:最近内容放在高速显存,焦点区域按需载入,更远的历史保存在 CPU 内存、SSD 或分布式缓存中。模型先声明访问范围,系统再完成相应的数据迁移。
这也是 DA 与单纯压缩方案的根本区别。压缩是在问“哪些记忆可以扔掉”,DA 问的是“当前这一刻需要打开哪一部分记忆”。前者可能损失信息,后者更接近按需分页。如果模型的判断足够可靠,百万上下文的运行成本就有机会从固定的全量读取,转向由任务复杂度决定。
结论:重要的不是更长,而是更会读
Declarative Attention 的价值,不在于宣称语言模型从此可以免费处理百万 token,而在于它指出了长上下文推理中一个经常被忽视的事实:上下文很长,不代表每一步都需要完整访问上下文。
这项研究目前更像是一条值得验证的系统路线,而不是已经成熟的通用替代方案。它能否在不同模型、不同硬件和高风险任务上稳定工作,取决于三个指标:注意力声明的准确率、跳过 KV Cache 后的真实端到端延迟,以及错误声明导致的答案质量下降。
如果未来的实验能够证明,模型在大多数解码步骤中都能可靠地选择 <local> 或 <focus>,同时在关键时刻主动切换回 <global>,那么长上下文优化的重点就会发生变化。行业竞争不再只是比谁能塞进更多 token,而是比谁能让模型用更低的带宽成本找到真正相关的那几段信息。
对开发者来说,值得记住的判断是:KV Cache 不会因为上下文窗口变长而自动变得高效;真正有效的优化,必须同时处理缓存的存储、检索和读取。DA 选择从模型的自控能力切入,至少为百万上下文推理提供了一个比“每次全量扫描”更符合实际工作方式的答案。
参考来源
- Language Models Can Control Their Own Attention|Reddit 讨论:论文相关研究摘要与社区讨论入口。
- SAGE-KV:自注意力驱动的 KV 缓存淘汰|知乎:介绍长上下文场景下 KV Cache 膨胀与缓存淘汰思路。
- 长上下文不再难:KV Cache 全生命周期优化实战|InfoQ:梳理 KV Cache 生成、压缩、语义检索和解码加载等系统优化方向。
- 探秘 Transformer 系列:KV Cache 优化之处理长文本序列|博客园:介绍 KV Cache 压缩、跨层合并及 token 保留策略。



