LongLLMLingua
朴素困惑度压缩是“问题无关”的,把噪声一并留下——LongLLMLingua 把压缩改造成“问题感知”:用问题条件下的对比困惑度选 token,再按相关度重排文档去打 lost-in-the-middle。
取自 LongLLMLingua 原论文(Jiang et al., Microsoft, 2023,arXiv:2310.06839v2,“LongLLMLingua: Accelerating and Enhancing LLMs in Long Context Scenarios via Prompt Compression”)。它是 hard prompt(token 级剪枝)一支的代表,与本章 上下文压缩 的 harness 层自然语言方案互补——一个是研究层的 token 机制,一个是 harness 层的操作。
方法
LongLLMLingua 建立在 LLMLingua 之上,先看底座。LLMLingua 用一个小模型 M_S 算每个 token 的困惑度(perplexity),
删掉困惑度低的 token——低困惑度意味着“最不意外”,删掉它对模型整体熵增益影响可忽略。这是“LM is compression”思想的直接应用。
问题出在:这种纯困惑度/信息熵的压缩是问题无关的。长上下文里,与问题相关的关键信息通常稀疏且动态分布,纯困惑度会把大量噪声一并留下, 论文实测在 NaturalQuestions 上甚至比 zero-shot 还差。LongLLMLingua 的核心主张因此是一句话:压缩必须问题感知。它给出四个机制(对应四项贡献)+一个恢复策略。
1. 问题感知的粗粒度压缩(文档级)。 给每个文档 x^doc_k 算重要度 r_k,只保留 r_k 高的文档。关键在条件方向:不是算“文档在问题条件下的困惑度”
(文档含太多无关内容,区分度不够),而是算问题在该文档条件下的困惑度:
r_k = -(1/Nc) · Σ_i log p( x^que,restrict_i | x^doc_k )
并在问题后附一句 restrictive statement(“We can get the answer to this question in the given documents”)作为正则项,抑制幻觉。
论文实测 r_k 的召回率高过 BM25 / OpenAI-embedding / Cohere-Rerank 等一众检索方法。
2. 问题感知的细粒度压缩(token 级)。 对保留下来的文档做 token 级剪枝时,用对比困惑度(contrastive perplexity)衡量每个 token 与问题的关联:
s_i = perplexity(x_i | x_<i) − perplexity(x_i | x_que, x_<i)
即“加入问题这一条件后,困惑度的变化量”。论文证明它等价于条件逐点互信息(conditional PMI)。直接看普通困惑度,分布近乎随机;而高 s_i 的 token
会聚集在含答案的文档附近——对比困惑度把“与问题相关”这件事从噪声里显影出来。
3. 动态压缩比。 LLMLingua 对所有文档用同一压缩比;LongLLMLingua 用粗粒度得到的 r_k 排名动态分配预算——越相关的文档给越低的压缩比(保留越多),用线性调度实现,从而把粗、细两级打通。
4. 文档重排。 粗粒度压缩后按 r_k 重排文档,把最相关的放到开头。这是专门针对 position bias(“lost in the middle”)——同一条信息落在 prompt 中部时利用率显著下降。
5. 子序列恢复。 token 级删除会毁掉实体(人名、地名、数字)——模型生成时倾向复制 prompt 里的实体,压残了就会出错。恢复策略在“响应 / 压缩 prompt / 原始 prompt”三者间做最长公共子序列匹配(前缀树/序列自动机加速),把响应里的残缺实体替换回原文的完整片段(论文 Algorithm 1)。
论文与实验结果
- 设置:目标 LLM 为 GPT-3.5-Turbo-0613 与 LongChat-13B-16k;压缩用的小模型是 LLaMA-2-7B-Chat;数据集 NaturalQuestions(多文档 QA)、LongBench、ZeroSCROLLS、MuSiQue(多跳)、LooGLE(长依赖)。
- 基线:检索类(BM25、Gzip、SentenceBERT、OpenAI-embedding)+压缩类(Selective Context、LLMLingua)。
- 结果:NaturalQuestions 上(答案文档放在第 10 位)性能 +21.4% 而输入 token 减到约 1/4;LooGLE 成本降 94%;~10k token 的 prompt 在 2×-6× 压缩下端到端延迟加速 1.4×-2.6×。
- 对照的关键结论:
- 压缩类基线(Selective Context、LLMLingua)在噪声多的任务上表现很差,因为它们是问题无关的纯信息熵压缩,把噪声一并留下——有时甚至低于 zero-shot。
- 检索类在低压缩比下不错,但压缩比一升(2×→4×)性能就掉,因召回率下降。
- LongLLMLingua 在各任务、各压缩比下都最稳,压缩比升高时性能甚至略有上升——因为问题感知让它在更高压缩比下反而拿到更高的关键信息密度。
- 重排对所有方法都有效,不止对它自己——单独印证了 position bias 的存在。
局限
- 依赖“有一个明确的问题”。整套机制围绕
x_que条件展开,最适合 QA/检索形态的任务;多轮 agent 场景里“当前问题”是什么并不总是清晰。 - 需要跑一个小模型算困惑度——比目标 LLM 便宜,但不是零成本(额外前向)。
- 产物是残缺的自然语言:token 级删除牺牲流畅度、破坏实体,必须靠子序列恢复打补丁;压缩比也有上限(论文主力区间是 2×-6×)。
对我们压缩的启示
这一篇不描述我们的机制(我们不做 token 困惑度剪枝),但它的几条原则可直接迁移:
- “问题感知”是通用杠杆——但要看落在哪一层。我们的压缩已经在摘要这一层部分做到了目标感知:FLOOR 摘要维护一份滚动的任务 checkpoint,把用户诉求(P0)与目标始终保全、只降级不删除。真正问题无关的是另一层——工具结果的削减:它按固定的保头/保尾启发式截断,不按“对当前任务多相关”排序取舍。LongLLMLingua 的启发正落在这一层:把工具输出的保留从均一截断升级为按当前任务相关度排序再削,而非一刀切——这也正是 上下文压缩 的保留政策与 Anthropic“先召回、后精度”配方想做的事。
- 排序是“留什么”之外的第二根杠杆。我们的保留政策只讲了留什么、没讲留下来的东西摆在哪。这篇实证:位置直接影响利用率。启发:压缩后把最相关的内容放到窗口两端(尤其靠前),别埋在中部。
- 对“精确 token”设保护。子序列恢复的教训是:任何有损压缩都会毁掉 ID、路径、数字、错误码这类必须逐字的信息,不能交给摘要模型复述。这直接对应我们“工具结果截断保头保尾”“紧凑引用只保路径”的做法——把精确片段与可摘要的叙事分开对待。
- 它还为我们的一个成本选择背书:便宜的小模型足以定位关键信息,用 Haiku 级模型做压缩在理论上站得住。
相关阅读
- 上下文压缩 —— 本章的实践主线;LongLLMLingua 是它“压缩谱系”里 hard prompt 那一支的研究背书。
- 上下文压缩 → 研究谱系 —— 另一支 soft prompt(ICAE → 500xCompressor,把文本编码成模型直读的 KV 值)的要点归在那里。
来源
- LongLLMLingua: Accelerating and Enhancing LLMs in Long Context Scenarios via Prompt Compression —— Jiang et al., Microsoft, 2023(arXiv:2310.06839v2)
- LLMLingua: Compressing Prompts for Accelerated Inference of Large Language Models —— Jiang et al., Microsoft, 2023(本文的底座方法)