原文:LLMLingua: Compressing Prompts for Accelerated Inference of Large Language Models

摘要:大型语言模型(LLMs)由于其惊人的能力已被广泛应用。随着链式思维(CoT)提示与上下文学习(ICL)等技术的发展,输入给 LLM 的提示长度越来越长,甚至超过数万个 token。为了加速模型推理并降低成本,本文提出 LLMLingua,一种粗到细的提示压缩方法,包括:

  • 预算控制器(Budget Controller):用于在高压缩率下保持语义完整性;

  • 基于 Token 级的迭代压缩算法:更好地建模压缩内容之间的依赖关系;

  • 基于指令微调的分布对齐方法:用于提升语言模型间的数据分布一致性。

1,引言

ChatGPT 的广泛应用依托于大型语言模型(LLMs)强大的泛化与推理能力,已经改变了大量应用场景。在实际应用中,构造合适的 Prompt 至关重要,通常需要运用链式思维(Chain-of-Thought)、上下文学习(In-Context Learning)、检索相关文档或历史对话(Wei et al., 2022;Chase, 2022)等技术。虽然这些方法能够激活 LLM 的领域知识,从而产生高质量输出,但往往也会导致提示长度变得更长。因此,在 LLM 巨大的计算开销与长提示需求之间取得平衡 已成为一个紧迫的问题。

一些研究尝试通过量化(Dettmers et al., 2022;Xiao et al., 2023)、模型压缩(Frantar and Alistarh, 2023)等方式修改模型参数以加速推理。然而,当 LLM 只能通过 API 调用,而无法修改底层模型参数时,这类方法就不适用。

近年来,一些方法开始尝试在 保留关键信息的前提下缩短原始 Prompt 的长度。这些方法基于一个核心思想:自然语言本身具有冗余性(Shannon, 1951),因此可以压缩。Gilbert et al.(2023)也指出,LLMs 能够从压缩后的文本描述中有效重建源代码,并保持较高功能准确率。因此,我们沿着这一方向,研究如何将长提示压缩为更短的提示,同时 无需让梯度流入 LLM 本体,以支持更广泛的 LLM 应用场景。

从信息熵角度来看,困惑度(PPL)较低的 Token 对语言模型的信息增益贡献较小。换言之,移除这些 Token 对模型理解上下文的影响较低。基于此,Li(2023)提出了 Selective-Context 方法:首先利用一个小型语言模型计算原始 Prompt 中每个句子、短语或 Token 的自信息量,然后删除较不重要的部分实现压缩。然而,该方法仍存在两个问题:

  • 忽略了压缩内容之间的依赖关系;

  • 压缩所使用的小模型与目标 LLM 之间存在分布差异。

为了解决这些问题,本文提出 LLMLingua,一种自粗到细的 Prompt 压缩方法。具体来说:

  • 我们设计了 预算控制器(Budget Controller),用于动态地为原始 Prompt 中不同组件(如指令、示例、问题)分配不同压缩比例,并通过示例级的粗粒度压缩在高压缩率下保持语义完整;

  • 我们提出了 Token 级迭代压缩算法,用于更细粒度地压缩 Prompt。相比 Selective-Context,该方法能更好地保留关键语义,因为它考虑了 Token 之间的条件依赖;

  • 针对小模型与目标 LLM 之间的分布差异问题,我们进一步提出一种基于指令微调的分布对齐方法

据我们所知,这是首个在高效大模型场景中评估推理与上下文学习能力的工作

2,相关工作

2.1,高效大语言模型

随着 ChatGPT 的广泛使用,高效大语言模型近年来在研究领域受到越来越多的关注。大部分方法通过修改模型参数来降低推理或微调成本,例如量化(Dettmers et al., 2022; Frantar et al., 2023; Xiao et al., 2023)、模型压缩(Frantar and Alistarh, 2023)、指令微调(Taori et al., 2023; Chiang et al., 2023; Xu et al., 2023)或增量微调(delta tuning)(Hu et al., 2022)。

另一类研究尝试从 输入 Prompt 的角度优化推理成本。基于输入文本与生成结果之间存在大量重复片段这一现象,Yang et al.(2023)提出通过直接复制 Prompt 中的 Token 来加速解码过程。

还有一些方法专注于 Prompt 压缩,具体做法是通过 Prompt Tuning 训练特殊 Token,从而减少模型推理过程中的 Token 数量(Mu et al., 2023; Ge et al., 2022; Wingate et al., 2022; Chevalier et al., 2023; Ge et al., 2023)。然而,这类方法通常针对特定任务设计,并且其中部分方法(例如 Mu et al., 2023;Chevalier et al., 2023)甚至需要对整个语言模型进行微调,极大限制了其应用范围。

此外,还有研究尝试利用 LLM 对对话或数据进行总结,构建长期记忆或知识库(Chase, 2022; Zhang et al., 2023)。但这些方法通常需要多次调用 LLM,因此成本非常高。

有部分方法通过选择示例子集减少提示长度。例如,Zhou et al.(2023)提出一种强化学习算法,用于为每个问题分配特定数量的示例。也有研究关注 Token 剪枝(Goyal et al., 2020; Kim and Cho, 2021; Kim et al., 2022; Rao et al., 2021; Modarressi et al., 2022)和 Token 合并(Bolya et al., 2023)。但这些方法大多是为较小规模模型(如 BERT、ViT)提出的,并且依赖于模型微调或推理过程中的中间输出,因此无法直接用于黑盒大模型(如 ChatGPT、GPT-4)。

与本文最相关的工作是 Selective-Context(Li, 2023),该方法通过一个小型语言模型计算词语的自信息量来评估信息重要性,然后丢弃相对不重要内容以实现 Prompt 压缩。本研究受其启发,并提出一种从粗到细的 Prompt 压缩框架,以解决其局限性。

2.2,分布外(OoD)检测

近年来,许多研究提出了用于无监督 OoD(Out-of-Distribution,分布外)检测的方法。在仅有分布内文本可用于训练的情况下,这类方法要么对预训练语言模型进行微调(Arora et al., 2021),要么从零开始训练一个语言模型(Mai et al., 2022)。Wu et al.(2023)对这些方法的特性进行了分析,并采用多层次知识蒸馏方式整合它们的优势,同时缓解其局限性。最终,所得到语言模型生成的困惑度(Perplexity)被用于判断样本是否属于分布外数据。

本文同样将困惑度视为衡量语言模型预测样本效果的指标。但与 OoD 检测中将高困惑度样本视为预测不可靠或异常数据的做法不同,我们认为 困惑度较高的 Token 在语言模型的推理过程中具有更高影响力

2.3,将大语言模型视为压缩器

近年来,一些研究从新的视角将大语言模型及无监督学习解释为一种 世界知识的压缩器(Sutskever, 2023;Delétang et al., 2023),其理论基础来自算术编码(Arithmetic Coding)(Rissanen, 1976;Pasco, 1976)。我们的研究可以被视为顺着这一方向进一步延伸:通过利用大语言模型类似压缩机制的特性,对 Prompt 中的信息进行进一步压缩。

3,问题表述

一个提示压缩系统旨在从给定的原始提示 x=(x_{ins},x_{dems},x_{que}) 中生成一个压缩后的提示 x^e=\{x_i^e\}_{i=1}^{L_e} 。

其中:x_{ins}=\{x_{ins},i\}_{i=1}^{L_{ins}} 表示指令部分(instruction),x_{dems}=\{x_{dems,i},i\}_{i=1}^{L_{dems}} 表示示例部分(demonstrations),x_{que}=\{x_{que,i}\}_{i=1}^{L_{que}} 表示问题部分(question),L_e,L_{ins},L_{dems},L_{que} 分别表示 x^e,x_{ins},x_{dems},x_{que} 中 token 的数量。

设原始提示的总 token 数为:L=L_{ins}+L_{dems}+L_{que}

则压缩率(compression rate)定义为:\tau =\frac{L_e}{L},\tau \in [0,1]

对应的压缩倍数(compression ratio)为 1/\tau。越小的 \tau 表示推理成本越低,因此更理想。

x_G^e​ 为使用压缩提示 x^e 得到的大语言模型输出,而 x_G​ 为使用原始提示 x 得到的输出。理想情况下,希望这两者的分布尽可能接近。

这一目标可形式化为如下优化问题:\underset{x^e,\tau }{min}KL(P(x_G^e|x^e ),P(x_G|x))

4,方法论

在本节中,我们详细介绍所提出的自粗到细的提示压缩方法 LLMLingua。首先,我们引入预算控制器(budget controller),用于动态地为提示中的不同组成部分分配不同的压缩率,同时进行粗粒度、示例级的压缩,以便在高压缩率条件下仍保持语义完整性。接下来,我们描述提出的迭代提示压缩算法(iterative prompt algorithm),其目标是在压缩过程中尽可能保留提示中的关键信息。最后,我们引入分布对齐机制(alignment),用于解决小模型与黑盒大模型之间的分布差异问题。

4.1,预算控制器

预算控制器旨在针对提示词中的不同组成部分(如指令、示例和问题),在句子级或示例级进行差异化的压缩比例(即预算)分配。

【信息重要性差异】通常来说,提示词中的指令(instruction)和问题(question)对最终生成结果具有直接影响,因为它们应包含生成答案所需的全部关键信息。相反,如果提示词中包含多个示例(demonstrations),则其信息可能存在冗余。因此,预算控制器应执行差异化预算分配策略:

  • 指令与问题分配较低压缩率(更多保留 tokens);

  • 示例部分分配更高压缩率(更少预算)。

高压缩比例场景下避免语义破坏当系统需要达到较高压缩比例时,如果像 Li (2023) 那样执行token级随机丢弃(token-level dropout),则压缩后的提示词可能过于稀疏,造成关键信息丢失。为避免这种问题,预算控制器会转而采用句子级丢弃(sentence-level dropout),以保持语义和语法的完整性。特别是在提示词中存在较多冗余示例时,还可以进行示例级(demonstration-level)压缩控制,以满足目标压缩率要求。

推导示例(demonstrations)部分的压缩比例:首先,需要根据目标整体压缩比例 \tau,以及预先设定好的指令部分压缩比例 \tau_{ins} 和问题部分压缩比例 \tau _{que},来计算示例部分的压缩比例 \tau _{dems}。换句话说,我们通过已知的整体压缩要求和对提示词中关键组件(即指令与问题)的固定压缩比例,反推示例部分应采用的压缩比例,使整个提示词在压缩后仍满足目标比例 \tau

\tau_{dems}=\frac{\tau L-(\tau_{ins} L_{ins}+\tau_{que}L_{que})}{L_{dems}}

示例级(Demonstration-level)提示压缩:在推导出示例部分的压缩比例 \tau _{dems} 后,我们首先执行粗粒度的示例级压缩,即从原始提示词中的示例集合 x_{dems} 中筛选出一个子集 D,作为保留的示例内容。

  • 使用小规模语言模型(small LLM)估计信息重要性:我们使用一个较小的语言模型 M_s​(例如 GPT-2 或 LLaMA),计算每个示例的困惑度(perplexity)。困惑度越高,说明示例越“难预测”,意味着其包含的信息越独特或关键。

  • 按困惑度排序并逐步选取示例:将所有示例按困惑度从高到低排序,并依次选择示例加入集合 D,直到加入下一个示例会使总 token 数超过限制为止。集合 D 中示例的 token 总数不得超过:k\cdot \tau_{dems}\cdot L_{dems},其中 k 细粒度控制系数,\tau_{dems} 针对示例部分的压缩率,L_{dems}  原始示例部分的 token 数总量。也就是说,示例级压缩过程会严格限制保留部分的 token 数不超过预算范围。

调整 instruction 和 question 的压缩比例:在得到粗粒度压缩结果 D=\{x_i\}_{i=1}^{\tilde{L}_D} 后,我们将剩余的 token 预算分配给指令部分和问题部分:

\Delta \tau =\frac{k\cdot \tau_{dems} \cdot L_{dems}-eL_D}{L_{ins}+L_{que}}

其中,eL_D 表示集合 D 中 token 的总数量。

4.2,迭代式 Token 级提示压缩

利用困惑度(perplexity)进行提示压缩会遇到一种内在限制,即独立性假设,这一点与 Mask Language Model(Yang 等人,2019)存在的缺陷类似:

p(\tilde{x})=\prod_{i=1}^{\tilde{L}}p(\tilde{x}_i|\tilde{x}_{<i})\approx p(x^{'})=\prod^{L^{'}}_{i=1}p(x_i|\tilde{x}_{<i},\bar{x}_{<i})

其中,x^{'}=(x^{ins},x^D,x^{que}) 表示经过示例级压缩后的原始提示;x^D 是集合 D 中所有示例(demonstrations)的串联结果;\tilde{x} 表示最终压缩后的提示;\tilde{x}_{<i},\bar{x}_{<i} 分别表示在第 i 个 token x_i 之前保留的 token 和被压缩的 token;L^{'},\tilde{L} 分别表示 x^{'}, \tilde{x} 的 token 总数。

【困惑度】  对于一个token序列,困惑度衡量模型预测该序列的"惊讶程度",删除某个token后,如果困惑度变化小,说明该token不重要。

  • 如果删除 x_i 后困惑度上升很多 → token很重要
  • 如果删除 x_i 后困惑度几乎不变 → token可以删除

【困惑度-独立性假设】理论上,我们应该考虑token之间的交互效应, 但这需要计算所有可能的token组合,复杂度是 O(2^N),实际不可行。 假设每个token对困惑度的贡献是独立的,不受其他 token 的影响。

"The quick brown fox jumps over the lazy dog"

如果同时删除 "brown" 和 "fox",语义损失远大于单独删除的总和。
------------------------
"He went to the store because he needed milk"

删除 "because" 和 "needed" 的组合效应 > 单独效应之和

在此,我们提出一种迭代式 Token 级提示压缩(ITPC)算法,用于缓解由条件独立假设带来的不准确性。算法 2 展示了其伪代码。

具体而言,我们首先将目标提示 x^{'} 划分为若干片段,即 S=\{s_1,s_2,...,s_m\}。随后,我们使用较小的模型 Mₛ 来获取所有片段的困惑度分布。来自每个片段的压缩结果会与后续片段进行拼接,从而使条件概率估计更加准确。相应的概率估计函数可表示为:

p(\tilde{s}_j)=\prod_{i=1}^{\sum_{k}^j\tilde{L}_s,k}p(\tilde{s}_{j,i}|\tilde{s}_{j,<i},\tilde{s}_{<j})\approx \prod^{L_{s,j}+\sum_{k}^{j-1}\tilde{L}_{s,k}}_{i=1}p(s_{j,i}|s_{j,<i},\tilde{s}_{<j})

其中,s_{j,i} 表示第 j 个片段中的第 i 个 token;L_{s,j} 和 \tilde{L}_{s,j} 分别表示第 j 个原始片段与压缩后片段的 token 数量。当获得每个片段的条件概率 p(s_j) 后,我们会基于困惑度(PPL)分布以及对应的压缩比例 \tau _{s_j},动态计算与片段 s_j 对应的压缩阈值 \gamma_j,即:

\tau_{s_j}=\left\{\begin{matrix} \tau_{ins}+\Delta \tau &if\,s_j\,from \,x^{ins} \\ \tau_{dems} & if\,s_j\,from \,x^{D}\\ \tau_{que}+\Delta & if\,s_j\,from \,x^{que} \end{matrix}\right.

最后,在每个片段 s_j 中,困惑度(PPL)大于阈值 \gamma_j 的 token 将被保留到压缩后的提示中。

\tilde{s}_j=\{s_{j,i}|p(s_{j,i})>\gamma_j\}

4.3,分布对齐

为了缩小大语言模型(LLM)与用于提示压缩的小语言模型之间的分布差异,我们在此通过指令微调(instruction tuning)来实现分布对齐。

具体来说,我们从一个预训练的小语言模型 M_s 出发,利用由 LLM 生成的数据对其进行指令微调。M_s 的优化目标可表示为:

\underset{\theta_s}{min}\,\mathbb{E}\left [ \frac{1}{N}\sum_{i=1}^N L(x_i,y_i,LLM;\theta_{M_s}) \right ]

  • \theta_{M_s} 表示小模型 M_s 的参数;

  • (x_i,y_i,LLM) 表示指令 x_i 与由 LLM 生成的对应文本 y_i LLM 组成的数据对;

  • N 表示用于指令微调的样本数量。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐