Attention is Limited - Lost in the Middle
我在昨天建议一个人把反复插入的知识库和记忆放入 user prompt 里而非 system prompt 中。
我提出了 system prompt 全局可见和高权重两点,如果冲突的话模型会出幻觉。
而 user prompt 则是局部的和越近的注意力权重越高。
当时提到这两点的时候,我是出于经验以及对 gemini 2.5 pro 的信任。
但是我们也有必要再有依据地分析一下。
首先是,局部的和越近的注意力权重越高,这点其实 system prompt 和 user prompt 都有。
而有一点偏颇我认为后续 system prompt 的插入注意力权重均不如 primary prompt。(实际上它并不是这么回事,开头和最新的注意力最大,其余的比较轻,参见下面 Lost in the Middle。)
简单地把 LLM 看成一个具有超长上下文的 Transformer, 而它是这样区分 System Prompt 和 User Prompt 的,而如果训练它大概率会这么区分不同角色, special token (<|system|>
, <|user|>
, <|assistant|>
, <|startoftext|>
, <|endoftext|>
),而且对 system 似乎有额外的惩罚和约束所以它显得更重要。
后续在输入的时候,我们也是把整个上下文窗口输入进去,而之所以第一条系统提示词能够被很好地记住即使对话很长也不会被忘掉是下面原因。
Lost in the Middle
它纠正了我之前错误的一个认识(我以为 LLM 的注意力始终是越靠近最新的越高),实际上它的注意力分配是一个 U 型的。在对开头和结尾记得很清楚, Lost in the Middle
。
观点:
论文提到,人们对 LLM 的注意力权重希望是像上帝那样子比较稳定均衡地审视整个上下文。但它们利用这些长上下文信息的效率和鲁棒性是值得怀疑的。作者认为,模型在处理长文本时,其性能会因为关键信息在文本中所处位置的不同而产生巨大差异。
实验:
作者采用了两种实验方式:
- 多文档问答 (multi-document question answering)
- 键值检索 (key-value retrieval)
似乎也公开了实现:
他们通过把关键信息放在开头,中间和结尾然后分别进行提问进而评估模型对上下文的利用能力。
结论:
U型性能曲线:模型的性能表现出一种明显的“U型”曲线。当关键信息位于输入文本的开头(首位效应或 结尾(末位效应) 时,模型的表现最好。而当关键信息被放置在文本的中间部分时,模型的性能会显著下降。
上下文越长,性能越差:研究还发现,即使是那些专门为处理长上下文而设计的模型,随着输入文本长度的增加,其整体性能也会大幅下降。
有趣的现象
不管什么模型在长上下文中都会变蠢,实际上应该叫做对关键信息的利用能力变低,简单地概括可以认为是注意力分散了。
或者说如果假设 U 型函数是固定的,那么积分值代表着注意力权重,横轴代表着回答时序条目。
原本短对话中,三条时序条目共享的注意力权重现在被六条甚至十条分走,每条就更低了。对其中关键信息(问题的理解,需求的理解) 的提取能力就更差。
如果假设 U 型函数会变化,且开头三条和最新三条的注意力权重分配量和之前保持不变,那么久代表这个 U 型更“陡峭”了,那么也意味着模型 “忘性” 更大了,对中间的事情几乎都不记得,自然性能也更低。
模型总是只清楚地记得开头和现在,这和人类的思维方式有点不谋而合。
而鉴于 special token , system prompt 可能在权重分配时有更高分配(这也导致了一定程度上的"全局可见"), 所以我们更应该珍惜地分配 system prompt。珍惜并且利用好模型的注意力,就好像对人类自己那样。
注意力是有限的。
总结 - 费曼式的结尾
我发现提出一个观点然后逐步修正它比直接接受一个正确观点要来得深刻清晰地多,而且也远比直接套用经验要更有可靠感。
而且这个方式似乎和费曼学习法不谋而合,我以前似乎就发现自己更适合边写博客边学,但是后来过于依赖 LLM,我发现写的大多数都是一个问题的解决方式和解决路径,这种流水账的记录在我看来是相当令人沮丧的。而今天反而重新体会到了记录的快感。
我之前在看电影和小说的时候,约束自己不要发表任何意见式的评论,因为很累,而且这样的观点漫无边际,每个人看法不同,就又容易被意见不合的人冲。
但是反而对于有确定答案的,意见似乎是必要的,它让我不断审视和修正自己的这个观点是否正确是否误人子弟,并且更深入地去解析。然后可能还可以帮自己修正一下观点。
那么我就给这篇加一个费曼式的结尾——用图解和更简单的语言来概括它。
20条上下文窗口注意力权重分配
40条上下文窗口注意力权重分配
我们用这两张函数图来比喻短上下文(二十条),和长上下文(四十条)之间的注意力权重分配。(如果比喻是被允许的,因为首先我就无法证明它是对称的,暂时应该也没人能量化出来这个具体能力,所以我们暂时就不纠结这些。)。
它具有这样的初始条件:
- 在整个上下文窗口内,注意力总和(上下文最大 token 数量)是不变的,也就是说,二十条和四十条的积分值是一致的(这里它们应该不一致,但假设它们一致)。
- system prompt 因为训练时的惩罚机制而对模型有更高约束力(红线), user prompt 是蓝线。
- 两者均呈现 U 型分布,模型在开始和结尾的注意力权重分配更高, Lost in the Middle。
- 长上下文下模型的性能(对关键信息的提取能力)逐渐下降, y 值更低。
除了以上条件其余图中函数特征均不生效,比如,我无法说明它具有这种对称性,我也无法证明长上下文下注意力处处更低。所以即使你看到了也请装作没看到。
但仅仅以我们上面的模型就足以回复为什么要用 User Prompt 反复插入知识库和日记来引导下次回复。
第一,反复插入引导内容到独立 prompt,会拉长整个对话上下文轮数,进而加快模型性能衰减。
当时一条 user prompt 用三条 system prompt 引导(core mem, long mem, knowledge base),相当于一条对话使用了四条窗口长度。
第二,system prompt 一定程度上比 user prompt 更加全局可见,冲突的引导更容易引起模型幻觉。