上下文窗口不是无限的:算力、显存、注意力划出的三道硬边界
1GB 纯文本大约 10 亿字符,这个换算是按常见编码估的。而公开宣称的最长窗口也就是千万 Token 量级,换算下来只装得下它的百分之一左右。
所以"把整本手册塞给模型"这个想法,从物理上就不成立。
更反常识的是:就算硬件无限,窗口也不是越大越好。塞得越满,模型越容易漏掉关键信息。
一、Token 不是字节
上下文窗口是一次请求里模型能看到的 Token 总量。
它更像工作记忆,不是硬盘:输入和输出共享这块空间,而且不持久——下一次请求从零开始,历史是外面重新拼好再发过去的。
共享这一点常被忽略。你给出的提示词、系统提示、工具清单,加上模型要生成的回答,全都算在这一个额度里。
所以"窗口 128K"不等于"能塞 128K 的资料",还要留出输出的余量。
不同内容的 Token 密度也不一样。代码里的符号、缩进、英文标识符,往往比同等长度的中文更"费 Token"。
一份看起来不长的配置文件,换算成 Token 可能顶得上一篇短文。按字数估窗口容量,误差会很大。
Token 是分词器切出来的单位,不是字符,也不是字节。
同一个词在不同分词器下可能被切成不同的片段;中文的切法差异更大,所以"窗口等于多少汉字"只能粗略换算,不能当精确值。
不同分词器的词表大小不同,同一个字的切法也不同:有的词表能把常见词整块收进去,有的只能切成单字甚至更碎。
这也是同一个"128K"在不同模型上实际容量不同的原因之一。
容量上,早期模型是几千 Token 的量级,现在主流是十几万,少数宣称到百万级,极端的方案做到千万级。
这些都是截至发布时的公开规格,具体数字要以各家模型卡为准,我这里不逐个点名。
超过窗口的内容不会被"自动摘要",通常是被截断或直接忽略,有些接口干脆报错。
这一点值得反复说:很多人的长文档任务失败,不是模型不会总结,是后半段根本没进模型。
模型看不到,就不会知道自己漏了什么,更不会主动告诉你"我只读了一半"。
还有一点容易被忽略:窗口也不是持久内存。它不会因为上一轮聊过,这一轮就多记一点。
所谓的"它记得我们刚才说的",其实是客户端每一轮把历史重新拼进请求。历史越长,每一轮要付的输入费用就越高。
所以长会话的成本不是线性地"多聊几句",而是每一轮都在为全部历史付费。
一个比喻:窗口像桌面,不是你身后的书架。桌面上放什么,决定了你这一小时能干什么。
桌面上摊开的每一张纸都要占地方,哪怕你这一分钟只看其中一张。
二、边界一:平方级复杂度
自注意力要让每个 Token 和序列里所有 Token 算关联度。
长度是 n,两两比较就是 n 乘 n 对。长度翻一倍,计算量大约涨到四倍;长度涨十倍,计算量大约涨到一百倍。
放到具体量级上看会更直观。示意一下:如果一万 Token 的请求需要一份算力,十万 Token 的请求大约需要一百份。
注意这是"注意力这一部分"的账,不是整条推理链的账。实际耗时会混入其他开销,所以真实倍数会小于一百。
这里的平方来自结构本身:每个位置都要和每个位置发生一次交互。想让它变线性,就得改变"谁和谁交互"这件事——那就是另一种架构,而不是调大参数。
这个算术是示意,不是说真实实现一点优化都没有。
真实实现当然有优化:稀疏注意力、分块计算、近似方法都在省。但省的是常数和系数,平方这个形状改不掉。
除了算力,中间矩阵本身也占显存。所以长上下文的成本是两头一起涨。
还有一层容易被误读:平方项在训练和推理里都存在,只是推理按次计费,感受更直接。
训练的成本高在别处——数据规模、梯度更新、多轮迭代;推理的平方项,才是你按次付费的那部分。
商业上就很直白了:窗口扩十倍,成本大约涨一百倍,按原来的价格卖就很难了。
厂商宣传的长上下文,通常靠工程手段打了折扣——分块处理、压缩记忆、只对部分位置做全注意力。
这些手段确实能把成本压下来,但压下来的是"跑得起的程度",不是"和白送一样便宜"。
这也是为什么长上下文服务往往按输入长度阶梯计价:不是运营商想多收,是成本真的跟着涨。
这是架构层的基因限制,不是"显卡不够"。
还有一个容易被混淆的点:批量处理会放大这笔账。
同时处理多个请求时,每个请求都有自己的长度,为了并行,短请求往往要按最长的那条一起算。一条超长请求混进来,整批的平均成本都会被拉高。
所以服务方的调度策略也会悄悄影响价格:不是只看你的单条请求有多长。
三、边界二:显存墙与 KV Cache
KV Cache 是推理时存下来的中间状态:已经算过的 Key 和 Value 留在显存里,生成下一个 Token 时直接复用,不用把整段重算一遍。
没有它,每生成一个 Token 都要把前面所有 Token 重算一次,慢到没法用。
可以把 KV Cache 想成草稿纸:算过的中间结果摊在旁边,下一次不用重算,直接翻回来看。
问题在于它随序列长度线性增长,还要乘上层的数量、注意力头的数量、每个数值占几个字节。
一个粗略的示意:假设一份缓存每 Token 占几十 KB,十万 Token 就是几个 GB;这还没算模型权重本身和其他开销。
这个估算会随模型规模变化,所以只作量级参考,不是精确值。
并发请求各自有一份。同一张卡上,八个短请求和一路超长请求,占用的显存可能完全不在一个量级。
并发和长度是在抢同一块资源。服务方要保吞吐,就得限制单条请求能占多少;要保长请求,就得接受并发数下降。
所以"支持多长的上下文"和"能同时服务多少人"往往是一道二选一的题,模型卡上不会同时写这两个数。
涨到头就是 OOM:显存分配失败,请求中断。调度器这时候只能做两件事,少并发或者截断上下文。
截断通常发生在你没注意的地方——不是你的代码主动截的,是引擎按上限截的。日志里可能只有一行警告。
加卡能推迟这堵墙,但不能消除它。数据并行、张量并行本身还有通信开销,规模上去之后边际收益会递减。
而且显存不是免费的:同样的预算,多买显存放长上下文,就少买了并发。这是一笔很直接的取舍。
缓和这堵墙的办法只有一个方向:把缓存本身压小,比如降低缓存精度。它换来的空间有限,而且可能影响精度。
工程上还有一种思路是分页管理:把缓存切成固定大小的块,按需分配,减少碎片。
它能把利用率提上去一些,但缓存的增长速度还是跟着上下文长度走,没有改变增长方向。
所以"窗口越大越贵"在这里是一个物理量,不是营销话术。
四、边界三:注意力稀释与上下文腐烂
假设算力管够、显存管够,窗口塞满是不是就更好?
不是。
注意力机制每一层都要把权重分配给上下文里的 Token。上下文越长,可分配的 Token 越多,每个 Token 分到的相对权重就越薄。
无关内容一多,关键信息在向量空间里会被噪声"稀释",模型为了看完所有内容,会把关键信息的内部表征压得更紧。
结果就是所谓的上下文腐烂:上下文变长之后,模型对中段信息的召回下降,也更容易被无关内容带偏。
这个词说的是一个复合现象:不是单点遗忘,而是整体判断质量下滑——答得更啰嗦、更容易自相矛盾、更容易被最近出现的无关内容牵着走。
这个现象还有个更具体的名字,叫"中间迷失"——同一份材料,关键信息放在开头或结尾时模型用得更好,放在中段则召回下降。这个位置效应方向稳定,但具体的召回机制本文不展开。
要记住的是:注意力是统计机制,位置和密度都会影响模型看到什么。
还有一层更隐蔽的影响:当上下文里存在互相矛盾的信息时,模型倾向于采信更靠后、或者表述更具体的那个。
所以同一件事的两份说法,谁写得细、谁放得晚,谁就更容易赢——哪怕它其实是错的。
这也解释了为什么"多给点资料总没坏处"是一个危险的直觉。资料里只要有冲突,模型就多了一次选错的机会。
上下文腐烂还有一个可观察的表现:指令遵循质量下降。
同样是"输出 JSON、不要加解释"这一条要求,放在短上下文里几乎百发百中;上下文一长,它开始加客套话、开始漏字段。
这不是模型退化了,是那条指令在注意力分配里被稀释了。
所以长上下文场景下,关键指令通常要重复一次,或者放到离输出最近的位置。
这也说明"装得下"和"读得到"是两件事,而后者才是任务成败的关键。
五、"无限注意力"能救吗
学术上确实有一批方案在往这个方向试。
思路大致是:久远的内容压进一块固定大小的"压缩记忆",近期内容用局部注意力,再想办法在两者之间做检索。
有一类方案被讨论得比较多,叫 Infini-attention。它的论文归属和发表年份我没有核实,所以这里只讲思路,不写机构和时间。
这类方案的路子,是把"全量精确回忆"换成"压缩后的大致记得"。
问题是这类方案改变的是成本曲线,不是效果曲线的形状。
压缩本身有损。把一万 Token 压进固定大小的记忆,必然要丢细节;长程的精确召回仍然难。
另一条路是流式处理:把长文档切成块,逐块读,读的过程中维护一份状态。它把一次超长请求变成多次短请求,本质上是把窗口问题转成了工程调度问题。
这条路更实用,但它引入了一个新问题:块与块之间的信息怎么衔接,谁来保证不丢关键约束。
还有一类做法是调整位置编码,让模型能处理超出训练时见过的长度。它解决的是"位置编号不够用",不是"注意力不用算"。
换句话说,这些方案各有各的着力点,但都绕不开"信息要么占空间、要么被压缩"这个约束。
工程界不太押注这些方案,还有一个现实原因:长上下文的效果很难稳定评估。
同一套方案,在"找一句原文"的任务上表现很好,在"跨章节推理"的任务上就可能掉下来。而后者恰恰是真实业务更常见的需求。
所以工程界的共识还是那句:无限上下文是伪命题。
真正的问题不是"能装多少",而是"怎么找到有用的那几条"。
六、正确解法不是堆硬件
既然扩不动,方向就得换:从"扩大容量"转向"提高利用率"。
窗口不是越大越好的草稿纸,而是一张被算力、显存和注意力同时压着的桌子。你能做的不是换更大的桌子,而是决定桌上只放什么、什么时候清空、哪些根本不拿上来。
这三个动作通常叫压缩、卸载、隔离,共同的前提是承认窗口有限。接受这个前提,做法就会从"尽量多塞"转向"尽量准";不接受,就会一直停留在"再买点卡就好了"的循环里。
具体每一件怎么判断、怎么落地,是另一套方法,这里只留结论。
图注:算力、显存、注意力同时收紧可用区间;曲线只表达趋势,示意非实测。