Skip to content
L2 里面是什么

上下文窗口:模型一次能看多少字

它能看进去两百万字,但你问第三页,它可能答的是第一页。

像一张摊开的桌面和一块硬盘 ​

上下文窗口(context window)——模型一次能看进去的词元总数。

比喻成实物:模型的工作台就那么大。你一次能摊开的资料就是上下文窗口。窗口之外的东西,它不是「忘了」,是压根没进过这间屋子。

这事在 2022 年是个硬伤。2017 年那篇 Transformer 里,注意力是两两连线的,句子长一倍,计算量涨四倍。所以早期模型的窗口通常是几千个词元,塞一篇完整文档就爆。

Google 2024 年 2 月发 Gemini 1.5 的时候,定价档位从 12.8 万词元起,往上能到 100 万。官方页面给的换算是:100 万词元大约相当于 1500 页文字,或者 3 万行代码。听着已经不像一个数字了。

键值缓存:别把桌子扫了再摆 ​

上下文窗口能扩到这么大,光靠改结构不够。有一笔更笨的浪费要先堵上。

模型每写一个新词元,都要把前面所有的词元重新算一遍。写第 100 个词的时候,前 99 个的处理过程被重跑了 99 遍。而这个计算结果,只取决于前面那句话,跟新词是什么无关。

键值缓存(KV cache)——把这些算过的中间结果存下来,下次直接取用。

存的是什么?上一节提到的三个角色里的两个:键和值。查询每次都在变,因为它就是「当前正在处理的那个词」。键和值不变。

效果是缓存之后每写一个新词的工作量,不再随前文长度增长。没有缓存的话,写一段 2000 词元的回复和写 200 词元的回复,成本差距不是十倍,是百倍。

我第一次在服务器上看别人跑长文生成,就是被这个吓到的:显卡占用曲线是一条斜线往上爬,因为缓存本身也在吃内存。

缓存吃掉了显存,于是有了分页 ​

问题接着来了。显存(video memory)—— 显卡上那块存模型和中间结果的内存。缓存要占显存,占太多就没法同时服务多个用户。

而缓存的分配是很浪费的——每生成一个词元就多占一点,但总长度事先不知道。Berkeley 那批人 2023 年的做法是借鉴操作系统的虚拟内存分页:把内存切成固定大小的块,哪块要放哪个用户的数据就现分配。论文标题里的 PagedAttention 就是这个意思,上面那套系统叫 vLLM。

同一个团队 2022 年那篇 FlashAttention 解决的是另一头的问题:不改计算结果,但改变数据在显存里的搬运顺序,减少读写次数。标题里那个 IO-awareness 就是说这个。

两篇的区别值得记一下:vLLM 管的是「缓存怎么摆不浪费」,FlashAttention 管的是「摆好了怎么搬得快」。

窗口大 ≠ 记得住 ​

这是我最想提醒的一句。

窗口是「能看进去」的上限,不是「能用上」的上限。一篇 50 万字的文档塞进去,模型每一段都能看到,但从中精确抽出某个细节的准确率会明显掉。业内管这叫大海捞针测试。

窗口能开多大,还受另一件事限制:钱。100 万词元的输入和 1000 个词元的输入,价格不是一个量级。

至于窗口满了之后旧内容去了哪、怎么处理,这块各家做法不一样,而且这部分已经卷成产品细节了,不在这一层讲。

延伸阅读 ​

  • Efficient Memory Management for Large Language Model Serving with PagedAttention(Woosuk Kwon、Zhuohan Li、Siyuan Zhuang et al.,2023,SOSP)—— 摘要开门见山:每个请求的 KV 缓存很大而且会动态增减,管理不好就因为碎片和冗余浪费掉一大块,限制了同时能服务多少请求。他们的解法就是抄操作系统的分页,做出了 vLLM 这个现在谁都在用的开源推理框架。arXiv: 2309.06180

  • FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness(Tri Dao、Daniel Y. Fu、Stefano Ermon et al.,2022,arXiv 预印本)—— 标题里的 exact 是重点:结果跟原来一模一样,只是把计算分块做、尽量让数据待在显存里不出来回搬。Stanford 那位 Tri Dao 后来去了 Together AI,这条路线一路做到了 FlashAttention-3。arXiv: 2205.14135

动手试试 ​

在你常用的那个 AI 工具里(挑支持上传文件的),做一次对照实验:

  1. 传一份一万字左右、里面埋了一个只有后半部分才提到的细节的文档(比如某个编号、某个日期)
  2. 问那个细节
  3. 换一个更短的对话,只把包含答案的那两段复制进去,再问一次

我猜第二次答得更好。第一次通常也对,但如果你把问题改成需要综合全文的开放问题,差距会明显拉开。

看完再回头读上面那段「窗口是能看进去的上限,不是能用上的上限」。

下一站 ​

前面都讲完了:字进来了,注意力连上了,向量长好了,参数喂出来了,缓存也用上了。现在还剩最后一个也是最日常的一件事——同样一句提示词,为什么它每次答得都不一样。

内容用 VitePress 构建,站内链接全部为相对路径。