长上下文不等于看得懂:窗口、注意力和"中间遗忘"
128K、256K 这些数字到底承诺了什么,又没承诺什么。以及我在长文档任务上反复付过的学费。
"支持 128K 上下文"这句宣传,我最初理解成"能读懂 128K 的内容"。这两个说法的差距,够写一篇文章。
一、窗口是一个上限,不是一个能力
上下文窗口指的是模型一次能处理的 token 总数,包含你的输入和它已生成的输出。它是硬约束,超了要么截断、要么报错,没有第三种。
但它承诺的仅仅是"这些 token 能被送进模型",不承诺:
- 模型会平等地注意每一个位置;
- 它能可靠地找出埋在中间的那一句;
- 塞得越多答得越好。
我自己的经验反而是:在很多任务上,把材料精简到三分之一,效果比全塞进去更稳。因为噪声会稀释信号,模型没有"这里信息密度低、我跳过"的显式机制。
二、成本是怎么涨上去的
自注意力里,序列里的每个 token 都要和其它 token 交互,计算量随长度近似平方增长,KV 缓存随长度线性增长。这意味着:
- 长输入的延迟集中在"首 token 之前"。处理提示(prefill)是算力密集的,输入两万字时,等第一个字出来的时间可能远超后续生成时间。用户体感"卡住了",多数是这一段。
- 长输入的显存压力来自 KV 缓存,不是权重。序列一长,缓存可能反超模型本身占用。这也是为什么"我的卡装得下 7B,怎么还 OOM"经常发生。
- 重复的长前缀是最大浪费。每次请求都重送同一份 2 万 token 的系统提示,就是每次重算一遍。前缀缓存(prompt caching)省的就是这部分,但它只省算力,不扩窗口。
工程上这几条合起来,指向一个朴素的结论:能少送就少送。先检索再喂,永远优于先喂全库再问模型"里面有没有相关内容"。
三、"中间遗忘"是位置偏置,不是记忆衰退
有一类现象被通俗地称为"lost in the middle":同样的信息,放在开头或结尾时模型找得比较准,埋在长上下文中间时命中率明显下降。
我对它的理解是位置偏置:训练分布里,开头(问题、指令)和结尾(最近的对话轮)通常是高价值位置,模型学到的注意力模式本身就偏向两端。这不意味着模型"记不住",而是"不知道该重点看哪"。
需要提醒的是,各家后来都针对长上下文做过优化,具体程度和任务、模型、写法强相关,没有一个通用的排行榜结论可用。所以我的做法是不去相信任何"某模型能可靠处理 XXK"的说法,只在自己那类任务上,用固定探针测一次:把一句无关的关键信息(比如"工单号是 KZ-4471")插入到第 10%、30%、50%、70%、90% 的位置各跑一遍,看它能不能准确复述。这个测试十分钟能写完,比看十篇评测有用。
四、我在长文档任务上交的学费
第一轮:全文塞进去。五十多页的手册,去掉页眉页脚直接怼进窗口,问一个跨章节的配置问题。答案看着很专业,参数名是编的。
第二轮:加检索。切块 + 向量召回 top-8 + 重排 top-3,再喂给模型。参数名不再乱编了,但漏答跨章节的步骤——因为答案分属两个块,top-3 只捞到一个。
第三轮:改召回策略。把"一个问答对应一个块"改成"命中块 + 同级相邻块"一起给,同时在提示里明确要求"若材料不足,回答『材料未覆盖』"。跨章节漏答基本消失,拒答也变得可信了。
这条弯路里没有一步是靠换更大的模型解决的,全是检索和提示的活。
五、几条现在会遵守的规矩
- 指令放两头:任务要求和输出格式,开头写一遍、结尾再重申一遍。长上下文下开头容易被材料淹没,结尾是最可靠的落点。
- 给引用要求:让模型标注每条结论来自哪一段材料,然后真的去抽查。伪引用比没引用更容易被发现,也更能暴露它没读。
- 不要指望它数数:统计类需求("列出全部 37 处配置项")交给正则或程序,模型负责语义判断。它的计数不可靠,窗口越长越不可靠。
- 超窗口先想压缩,别想拼接:分块并发跑再合并,会让模型看到多份重复上下文,一致性反而变差。先问"这份材料里到底哪几段是必需的"。
- 算 token,别算字数:中文按 1~2 token/字估,宁可高估。各家 tokenizer 不同,长任务上线前用官方 tokenizer 精确数一遍。
六、一个还没答案的问题
长上下文会不会最终吃掉"检索"这一层?我自己的判断是不会完全吃掉:检索解决的是"数据总量远大于窗口",这是容量问题;而上下文窗口无论多大都是有限的,且塞得越多越贵、越慢、噪声越大。真正可能变的是切块和重排的粒度会变粗——窗口从 8K 涨到 200K 之后,我不再需要把文档切成很小的块,可以把整节甚至整章直接给模型。这个变化我已经在自己的项目里看到了:切块数量降了一个量级,召回调参的负担小了很多。
内容标识:本文为本人学习笔记;文中提到的测试是我自己写的小脚本跑出来的相对结论,不构成任何评测排名。
本文出处:http://honeysss.cn/post/long-context-is-not-comprehension.html 转载请注明出处。