AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


大模型Prompt压缩
发布日期:2024-10-10 14:10:48 浏览次数: 1628 来源:LambdaGo


Prompt压缩是大模型应用中常用的一种技术,在不显著改变大模型输出的质量的前提下,通过减少输入Prompt的长度来降低大模型输入token的数量,达到提升大模型相应速度、降低大模型调用费用的目的。[1]

1. What - 什么是提示词压缩?

  伴随着ChatGPT的爆火,也带火了一个名为“提示词工程师”(Prompt Engineer)的新职业。现实场景中的任务通常很复杂,使用任务的文本描述作为Prompt输入通常会显得文本冗余,叠加上外部知识、文档的输入,通常Prompt的长度会非常长。过长的Prompt一方面会导致大模型响应速度的降低,另一方面也会导致调用费用的提高。大多数情况下,自然语言本身就存在信息冗余;另一方面,大模型本身就学会了很多知识,外部输入的知识、文档也存在较多冗余。从这个角度出发,将输入给大模型的Prompt进行压缩是一种显而易见的降本增效手段。

  Prompt压缩是指在不显著改变大模型输出的质量的前提下,通过减少输入Prompt的长度来降低大模型输入token的数量,达到提升大模型相应速度、降低大模型调用费用的目的。


2. Why - 为什么要压缩提示词?

2.1 必要性

  在实际应用当中,合适的提示词(Prompt)对于任务和场景来说至关重要,随着研究的深入,诸如思维链(CoT)、上下文学习(In-Context Learning)、检索增强(RAG)等技术被提出,通过激活大模型的领域特定知识提高生成的效果,极大拉高了Prompt工程的可操作性,也带来了Prompt越来越长的问题。于是Prompt工程带来的效果提升与Prompt过长带来的计算需求增长之间存在着矛盾,在两者之间取得平衡也成为一个亟待解决的问题。

  具体说来,Prompt压缩有如下几个好处:

  1. 提高推理速度:过长的响应延迟对用户体验来说是毁灭性的,对于大模型来说,主要的响应延迟来自于Prompt的prefill计算阶段,对Prompt进行压缩可以极大地降低推理延迟。

  2. 降低推理成本:通常大模型推理服务的成本来自于两个方面:Prompt的prefill计算和回复的decode生成。两者又与输入、输出的Token数量直接相关,压缩Prompt可以降低输入Token数量,达到降低推理成本的目的。

  3. 提高响应相关性:对于大模型来说,Prompt中的“不相关”输入会对模型的效果产生一定影响,而Prompt的压缩过程可以消除这部分影响,达到提升回复结果相关性的效果。

2.2 可行性

  上述一切都建立在一个基础之上:自然语言是冗余的,也就是可以被压缩的[13]。这是香农在1951年提出的观点,信息论不仅可以应用于计算机语言,也可以应用于自然语言。这表明,我们可以在不降低语言表达能力的基础之上压缩Prompt。

  而另一方面,众多研究表明[14]:语言模型在其参数中隐式编码了大量知识,通过一定的手段(Prompt)可以诱导出这些知识,把语言模型当做知识库来使用。在这个假设基础之上,Prompt中那些大模型本身就“知晓”的知识就可以被压缩掉,以几乎无损的程度缩短Prompt的长度。


3. How - 压缩提示词的方法有哪些?

3.1 通过自信息(self-information)压缩Prompt

  在信息论中,自信息(英语:self-information),由克劳德·香农提出。自信息指的是当我们接收到一个消息时所获得的信息量。具体来说,对于一个事件,其自信息的大小与该事件发生的概率有关,它是与概率空间中的单一事件或离散随机变量的值相关的信息量的量度。它用信息的单位表示,例如 bit、odds或者log-odds,使用哪个单位取决于在计算中使用的对数的底。自信息的期望值就是信息论中的熵,它反映了随机变量采样时的平均不确定程度。[4]

  一个很简单的压缩思路就是删除那些不能为LLMs带来“信息”的文本,达到压缩Prompt的目的。这里很容易联想到信息论中熵的概念,在信息论中,一般使用self-information来衡量一个事件在一个特定的概率分布中所蕴含的信息。对应到大模型的场景中,这里的“特定的概率分布”可以视为大模型输出token的概率分布,而事件可以视作输入输出的文本。

Selective Context[2]

论文[2]就据此提出了一种非常简单的压缩方案:

1. 计算token级别自信息(Computing Self-Information)

  这里的token级别自信息就是如下所示的最基础的统计概率语言模型,对应到大模型中,就是每个token在对应输入上下文条件下输出的概率分布。

$I(x) = -log2 P(x_i|x_0,x_1,…,x{i-1})$

2. 合并基础语义单元自信息(Merging into Lexical Units)

  所谓的基础语义单元就是指字、词、短语、句子等表征一定完整“语义”的最小集合。这些集合内部部分token(例如数字’2009’,被压缩成’209’则严重破坏了整体信息)的信息熵很低,但是如果破坏了这些语义单元,文本内容会非常不连贯,导致大模型稳定性降低。根据条件概率的事件合并计算方式,对应到基础语义单元的概率分布如下。

$I(u) = \sum_{i=t}^{\alpha}I(x_i)$

3. 设置比例或阈值进行压缩(Selective Retention of Informative Context)

  最后一步就是在划分好的基础语义单元(一般是词、短语或句子)的基础上,设置一定的比例删除得分较低的部分,或者设置一定的阈值删除得分低于阈值的部分,得到压缩后的Prompt。这里需要说明一点,这个过程中使用的大模型不一定需要是真正完成任务的大模型,可以使用较小的模型A来对Prompt进行压缩,然后将压缩后的Prompt调用较大的模型B完成任务。

图中所示是一个短语级别的Prompt压缩示例,论文[2]中在超长对话、长文本摘要、长文本问答等场景进行实验,并使用BLEU、Rouge、BERTScore等指标对比Prompt压缩前后输入到相同大模型得到的输出与标准答案的差别,主要结论如下:

  • 压缩比例设置为0.2时,模型的生成性能下降很低:ROUGE下降了约0.03,而BERTScore下降了约0.007。

  • 压缩比例设置为0.35时,指标略微下降:ROUGE下降了约0.07,而BERTScore下降了约0.013。

  • 压缩比例设置为0.5时,指标有明显下降,但明显优于Random Select的结果:ROUGE下降了约0.12,BERTScore下降了0.23。

  • 压缩比例设置为0.8时,Prompt压缩结果基本上等同于Random Select结果。

  这种Prompt压缩的方案的优势显而易见:即插即用,整个过程不需要“修改”模型;可扩展性优秀;多任务之间没有排斥性。缺点也很明显:压缩比不能太高,效果不可控。

LLMLingua[7]

  微软最近两年在Prompt压缩上做了不少工作,主要是LLMLigua系列的几篇文章([7],[8],[9])。LLMLingua[7]的核心还是通过语言的自信息(self-information)来压缩Prompt,与前面的方法类似,区别主要有以下几个方面:

  1. Distribution Alignment:使用了一个与大模型对应的“小模型”来做信息熵的计算,“小模型”的分布需要与大模型进行对齐(SFT);

  2. Budget Controller:将Prompt的各个部分(指令Instruction,示例Demonstrations,问题Question)做了详细的区分建模,使用一个预算控制器来“平衡”各部分的压缩;

  3. Iterative Token-level Prompt Compression:放松了token独立性的假设,更加细致地建模了利用语言信息熵对Prompt进行压缩的过程。

  这里详细介绍了第3个核心点,Selective Context[2]直接通过阈值或比例删除掉信息熵较低的部分token,这其中带有一个假设:删除前后各个token的信息熵不变,即token独立性假设。但是实际上删除前后语言的信息熵很显然发生了变化,由条件语言模型的公式可知,删除任意一个token之后,整个句子的信息熵都会受到影响。但是如果采用直接贪心的方案,每次删除得分最低的元素之后都重新计算整个文本的信息熵,这对于整个压缩过程来说都是不可接受的,于是LLMLigua采用了折中的方法,如下图的公式所示:将文本分为若干个组,假设组内的分布具有独立性,采取阈值或比例的方式进行压缩;每次压缩完前一组后,再计算后一组的信息熵进行压缩,即组间的分布不具有独立性。

实验结果显示LLMLingua拥有很好的压缩性能,在多数场景中都优于Selective Context[2]方法。

LongLLMLingua[8]

  上述以信息熵为核心的建模方式在类似RAG的场景中都有一个致命的缺陷:绝大多数内容自身都拥有很大的信息熵,但是对回答问题(Query)毫无益处。后续提出的LongLLMLingua[8]就是为了解决这个问题,此时一个很直接的想法就是计算Document与Query之间的条件熵,以此来判断Document相对于Query的“重要性”。此时有两种选择:计算给定Document下的Query的熵,计算给定Query下的Document的熵。很显然考虑到Document自身拥有的信息熵可能差距非常悬殊,而且难以归一化,所以直接计算给定Document下的Query的熵更加合理。

  据此,文章提出了它的两个核心点:粗粒度压缩(Question-Aware Coarse-Grained Compression)和细粒度压缩(Question-Aware Fine-Grained Compression)。

  • 粗粒度压缩:使用给定Document下的Query的熵作为整篇文档的“重要性”,如图公式所示,用于筛选文档,也用于给文档进行重新排序。

  • 细粒度压缩:为了消除文档自身信息熵的影响,使用不带query的上下文条件熵与带query的上下文条件熵之间的差作为当前token的“重要性”,如图6公式所示,用于筛选文档内的token。

  其他的贡献还包括:

    • 为了应对中间信息丢失的问题,将文档按照重要程度进行排序,防止“重要”信息放置在中间导致信息丢失;

    • 为了获得最佳的全局压缩能,在LLMLingua预算控制器的基础上,还为不同重要性的文档设置不同的压缩“预算”;

    • 为了解决由于压缩导致某些关键实体信息丢失(例如数字’2009’,被压缩成’209’),提出了一种子串回复机制(Subsequence Recovery),对照压缩前后结果回复LLM生成的回复中的关键子串;

  LLMLingua在RAG类似的场景中有很好的效果,例如在NaturalQuestions数据集上,几乎没有压缩损失,在文档较多的情况下还能取得一定的效果提升。

3.2 训练专门的压缩模型“生成”压缩Prompt

LLMLinga-2[9]

  上述以信息熵为核心的方法都将语言模型的logits输出当做语言的信息熵,同样的也可以在后面加上一层Linear来进行token级别的分类来做压缩。LLMLingua-2[9]就提出训练一个token级别分类模型来做token“重要性”的识别,以此达到压缩的目的。

  LLMLinga-2[9]提出上述基于信息熵的方法都有两个问题:压缩的实际目标与基于小模型logits的信息熵并不一致;使用双向语言模型可以做到的压缩性能上限要高出单向语言模型。

  最终问题被归为了BERT+Classification的标准范式中来,如下图中所示。

  看到这里就会有一个很显然的问题:为什么不使用一个生成模型来做呢?因为成本,有能力做Prompt任务压缩的模型基本上也有能力做Prompt任务的回答,所以用一个“同等”程度的模型来做Prompt压缩很显然得不偿失。

  在构建数据集过程中,论文提出可以采用类似数据蒸馏的方法,来从大语言模型(GPT-4)中抽取“知识”,来作为压缩后的Prompt,构建数据集。主要过程如下:

    • 数据蒸馏:为GPT-4构建一个特殊的Prompt,让GPT-4在不向生成文本中引入新词汇的前提下,剔除原始文本中的冗余词汇,从而实现文本的压缩。

    • 数据标注:由于GPT-4生成的结果需要与原始文本“对应上”,才能构建token级别分类模型,采用“滑动窗口”策略限定搜索范围,基于模糊匹配的策略生成每个token的分类标签(preserve or discard)。

    • 质量控制:采用Variation Rate(VR)和Alignment Gap(AG)两个指标衡量压缩性能,筛除不合格的样本。

  模型训练过程就是一个标准的BERT的token级别分类模型,将每个token输出的logits作为起“保留”的概率,卡一个压缩比例阈值来进行压缩。

       实验结果上还是在LLMLingua的基础上有不小的提升,模型也具有相当程度的通用性;缺点则是迁移性没有保证,模型对于没见过的领域效果可能受限。

RECOMP[10]

  RECOMP[10]是一个建模在RAG场景中的模型压缩方案,整体架构如图中所示。其主要核心是3个部分+2个模型:

  • Retrieve:一个基于Embedding的文档召回系统,用于召回与query相关的文档。

  • Compress:一个基于BERT模型的、使用对比学习loss的相似度模型,用于衡量文档与query之间的相似度,筛选召回的文档。

  • Prepend:一个基于Encoder-Decoder架构的摘要生成模型,用于对召回的文档进行摘要压缩。

3.3 把Prompt替换为特殊Token

  另外一个很直观的思路则是直接把长长的Prompt替换为几个特殊的Token,利用训练过程来“教会”模型每个token代表的任务类型。这个很类似几年前很火的prompt tuning的思路,利用若干个unused token来构造prompt,然后微调这些token形成Prompt模板。但是这种方案很显然扩展性极差:没有使用到自然语言Prompt所带来的多任务之间的天然的“联系”,完全封闭了模型扩展到其他任务的能力。

GistingToken[5]

  论文[5]利用语言模型特殊的Masking机制,将多任务的自然语言Prompt与特殊Token相结合,利用多任务的自然语言Prompt定义来“影响”固定的Gist Token,另一方面又使用特殊的Masking,只让Gist Token来“指导”生成任务的进行。

  具体过程如图所示,以图中的自回归语言模型(decode only)为例:

  • “Translate Fench:”是原始任务的自然语言Prompt定义;

  • “<G1\> <G2\>“是若干个Gist Token,初始化为unused token,所有任务都使用同一套Gist Token;

  • “The Cat”是任务样本的输入输出。

  可以看到Gist Masking通过Mask掉原始任务的自然语言Prompt和任务样本的输入输出,使得在推理过程中可以提前计算好不同任务类型的”Gist Token”,使用过程中只需要”Gist Tokens”的KV-Cache就可以完成对应样本的生成任务,在这个过程中没有阻断多任务之间的天然的“联系”,依然保留了模型扩展到其他类型任务的能力。

  作者对比了原始Instruction Tuning范式和Gist Tokens方法,下图中Pos代表在Instruction Tuning范式对应位置插入1个Gist Token(不修改Masking)的结果,Gist则是论文提出的方法,TF-IDF则是使用tf-idf指标压缩Prompt到同一水平的结果,Neg则是删除了任务的自然语言Prompt对应的结果。

  可以看出相较于原始的Instruction Tuning方法,Gist Tokens方案效果有一定程度的下降,但是效果还是很有保证的。作者还对比了方案在Seen Task与Unseen Task上面的结果,也显示Gist Tokens方案可以相当程度上保证模型在其他类型任务上的泛化能力。

  目前来看Gist Tokens方案压缩比可以做到非常高,虽然推理过程可能需要预先计算不同任务对应的KV-Cache,但是在很多场景中可以有很好的应用。比较大的缺点可能在于较多任务场景上,少量的Gist Token的表示能力不足,而较多的Gist Token在实验过程中反而表现出效果下降的趋势,多任务场景下还有很多优化空间。

AutoCompressors[12]

  上面提出的GistTokens方案还仅仅在fine-tuning截断进行单上下文压缩,AutoCompressors[12]则是贯穿了预训练截断进行长上下文“级联”压缩。主体部分如图所示,以“summary tokens”和“summary vectors”作为压缩“结果”传递于文档片段之间,达到“级联”压缩长文本的效果。

 其模型架构核心改动有如下几个部分:

    • Summary vectors:引入了特殊的summary tokens作为“压缩点”,上下文遇到summary tokens后会被压缩成较短的“summary vectors”传递给后面;

    • Summary accumulation:长文本会被分割成多个文档片段,文档片段之间由“summary vectors”传递上文“压缩”后的信息;

    • Positional embeddings:文档片段内使用位置编码,文档片段之间不计算位置编码。使用绝对位置编码时,不会为summary tokens增加position embedding;使用相对位置编码时,将summary tokens视为普通的token分配position embedding。

  由于引入了“summary vectors”传递上文“压缩”后的信息,其训练策略改动有如下几个部分:

    • Training objective:使用next-token probabilities作为训练目标,剔除summary tokens;

    • Randomized segmenting:文本划分段落的长度是不固定的;

    • BPTT with stop-gradients:类似Transformer-XL的训练策略,每次只保留2个(一对)文档片段间“summary vectors”的梯度传递,其他的进行梯度截断。

        当预训练好的模型应用到下游任务中时,利用“summary vectors”可以压缩“示例”、“文档”等大量信息,然后经由任务定义作用于下游任务中,如图所示。

  在困惑度实验中,在OPT-2.7B作为base model基础上进行AutoCompressor的继续预训练,可以看到对比直接预训练结果(Extended FA),AutoCompressor的困惑度都有相当程度的优势。在下游任务实验中,相比于对应的In-Context Learning,AutoCompressor可以压缩多达150个文档或示例样本,获得不错的效果提升。(没有SFT对比实验)




53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询