AI知识库

53AI知识库

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


内隐语境Prompt,让LLM更懂你的弦外音,用DSPy实现
发布日期:2024-06-05 08:36:54 浏览次数: 2089 来源:AI修猫Prompt


我们在交流时,会有理解和表达“弦外音“的需求,需要传递一种没有直接明说但通过语言、行为、环境等暗示的信息或含义。这在语用学(Pragmatics)中叫做内隐语境(Implicit In-context )。举个例子,在职场中,上司对下属说你觉得这个方案怎么样?,看似在征求意见,但内隐语境(弦外音)可能表明上司希望听到具体的改进建议,而不是简单的好坏评价。这种情况下,下属需要结合对上司的了解和工作背景来解读真正的意图

其实,我们在一般交流时,表达”弦外音“是一种高超的语言艺术,但对于LLM来讲,理解人类的内隐语境是有难度的。但这样复杂的、需要用到LLM理解”内隐语境“的场景却非常常见,比如情感识别、意图识别、关系抽取、文本分类等等。LLM的内隐语境学习Prompt构建是一个难点。


图片由xiumaodalle生成

我们已经熟悉LLM的上下文的“语境学习“(In-context Learning,ICL),ICL的核心思想是在测试query前提供几个演示样例(demonstration),以引导模型进行推理。这种"少样本学习"的能力让LLM展现出了惊人的适应性和灵活性。然而,传统的ICL也有其局限性:


1.    演示样例以token的形式直接拼接在query前,导致计算和内存开销剧增;


2.    对演示样例的选择和排序非常敏感,质量参差不齐的样例会严重影响性能。


为了突破这些局限,来自罗格斯大学的研究者们提出了一种革命性的范式——内隐语境学习(Implicit In-context Learning,I2CL)。

I2CL巧妙地将demonstration信息以向量的形式融入到LLM的激活空间中,在保持零样本推理速度的同时,实现了接近少样本学习的优异表现。(如下图所示)下面,我们一起了解一下I2CL。


I2CL的核心思想是从demonstration examples中提取语境信息,并在inference阶段将其注入到模型的前向计算中,从而实现"语境增强"的效果。这个过程可以分为两个主要阶段:语境向量化(Context Vectorization)和语境注入(Context Injection)。


语境向量化:信息的精炼提取


I2CL的第一步是独立地对每个演示样例进行向量化表征。具体来说,通过预训练的tokenizer和LLM,研究者从每个样例的末位残差流中提取多头注意力(MHA)和多层感知机(MLP)模块的输出激活向量作为演示向量。这些向量随后被置换不变地聚合为一个统一的语境向量。


这一步的精髓在于,末位残差流能够有效地概括序列的整体信息,而线性表征假设则为不同层级抽象的演示向量间的线性变换提供了理论基础。I2CL通过这种巧妙的向量化方式,将原本冗长的token序列浓缩成了一个精炼的语境表征。


语境注入:隐式地融合信息


I2CL的第二步是将语境向量与query的激活向量进行融合。有别于基于注意力的融合,研究者采用了一个简单而有效的线性组合:将语境向量与query的MHA和MLP输出做线性加权,再施加到query的残差流上。


通过引入可学习的标量权重,I2CL能够在不同的层自适应地控制语境信息的注入强度。更重要的是,整个过程只涉及少量标量乘法和逐元素加法,计算开销极低。这使得I2CL在推理阶段的速度可以与零样本学习看齐。



为了进一步提升鲁棒性,研究者还在校准阶段引入了随机高斯噪声扰动残差流。通过这种"噪声自校准"机制,可学习的标量权重能够更好地泛化到潜在的下游变化。


在推理阶段,I2CL以残差的形式将语境向量注入到每个transformer层的前向计算中。具体而言,语境向量中的MHA部分和query的MHA输出先进行线性组合,加入残差流;再对中间结果进行非线性变换;最后将语境向量中的MLP部分和变换后的结果线性组合,再次加入残差流,得到当前层的最终输出。值得一提的是,MHA和MLP部分的线性组合系数是可学习的参数,使模型能够自适应地调节语境信息在不同层的注入强度。这些参数通过在demonstration examples上的"自校准"过程来学习,同时引入轻微的高斯噪声以提高鲁棒性。



实验表明,I2CL在标准的文本分类任务上取得了瞩目的成果。在经典的few-shot设置下(如1-shot、5-shot),I2CL的性能显著优于传统的ICL方法和zero-shot基线。尤其令人印象深刻的是,I2CL在极低资源场景(如10-shot)下的表现,就已经超越了ICL的水平。这有力地证明了I2CL在小样本学习方面的巨大潜力。通过语境向量化,I2CL能够最大限度地挖掘极少量样本蕴含的丰富语义信息;而语境注入的软性融合机制,又使得这些信息能够被灵活地嵌入到推理过程中,从而实现更强的泛化和任务适应能力。

但ICL在3-shot的表现也不错,您可以看一下这篇文章

谷歌最新《Prompt指南101》“三三制”战法惊现云端,代号101

I2CL的意义不仅限于在小样本学习任务上取得了新的性能水平,更重要的是,它为预训练语言模型的应用开辟了新的可能性。在实践中,我们往往面临标注数据稀缺的挑战,尤其是针对垂直领域的定制化任务。得益于I2CL优异的少样本学习能力,我们只需准备少量的高质量demonstration examples,就可以快速地适配预训练模型,构建出强大的自然语言处理系统,而无需大规模的人工标注和模型微调。这将极大地降低开发成本,缩短应用周期。

让我们以一个智能客服系统中的意图识别任务为例,详细说明如何使用I2CL来构建高质量的prompt。



假设我们的客服系统需要处理用户关于一家电商的各类咨询,其中涉及订单查询、物流跟踪、退换货等多个意图。传统的意图识别方法需要大量标注数据,覆盖各种意图的问法。但实际上,收集和标注如此多的训练数据非常耗时耗力。



现在,我们利用I2CL,仅需少数示例就能搭建一个强大的意图识别prompt。具体步骤如下:


1.定义意图类型及其示例



首先,我们定义几种主要的意图类型,并为每个意图准备1-3个典型问法作为demonstration。比如:


订单查询意图:"我昨天下的订单什么时候可以发货?" "怎么查看我的订单详情?"



物流跟踪意图:"我的快递到哪里了?怎么还没收到?" "能告诉我物流单号吗?我想查下快递进度。"



退换货意图:
"我收到的商品有质量问题,怎么申请退货?" "请问超过七天还能换货吗?"



账号问题意图:"我忘记登录密码了,如何重置?" "怎样修改账号绑定的手机号码?"



2.生成语境向量



我们把这些意图示例输入预训练的语言模型(如GPT-3),提取每条示例在模型末位的激活状态,然后聚合得到一个统一的语境向量。这个向量蕴含了不同意图在语义空间中的表征信息。



3.注入语境向量



在少数示例上,我们微调一组标量权重,用于控制语境向量在模型不同层的注入强度。微调过程会适当添加噪声,以提高泛化效果。现在,我们得到了一个蕴含丰富语境信息的意图识别prompt。



4.无标注意图推理



对于用户的新询问,我们将其输入到上述prompt中。预训练模型会在语境增强下直接预测该询问的意图标签,而无需额外的训练数据。



举个实际推理的例子,假设用户输入一条新询问:"我上周买的电脑坏了,可以换一台新的吗?"



意图识别prompt会附加语境信息,如图:


将用户输入的问题放入prompt,语言模型会综合示例语境,输出"退换货意图"作为预测结果。



我们可以看到,I2CL利用少数示例就搭建起了一个强大的意图识别器。其中的关键在于:


1.示例覆盖了主要的意图类型,蕴含丰富的语义信息;


2.语境向量将这些信息进行了精炼和融合;


3.标量权重控制了语境信息在模型不同层的注入强度;


4.注入噪声提高了prompt的泛化能力。



当新问题到来时,预训练模型在语境增强下可以直接对其意图进行精准判断,而无需重新训练。与传统的有监督学习相比,I2CL大大降低了意图识别任务对标注数据的依赖,为快速构建智能客服系统提供了一种灵活、高效的新思路。



你还可以用DSPy实现以上意图识别:


# 定义I2CL模型的DSPy实现
class GenerateIntentLabel(dspy.Signature):
    """Generate intent label from a given query."""
    
    context = dspy.InputField(desc="Demonstrations of intents and examples.")
    query = dspy.InputField(desc="The user query to classify.")
    intent = dspy.OutputField(desc="The predicted intent label.")

class I2CL(dspy.Module):
    def __init__(self):
        super().__init__()
        self.generate_intent_label = dspy.ChainOfThought(GenerateIntentLabel)
        
    def forward(self, query):
        context = self.retrieve_demonstrations()
        prediction = self.generate_intent_label(context=context, query=query)
        return dspy.Prediction(context=context, intent=prediction.intent)
    
    def retrieve_demonstrations(self):
        return demonstrations
    
    def generate_intent_label(self, context, query):
        prompt = f"{context}\n用户询问: {query}\n意图类别: "
        response = openai.ChatCompletion.create(model="deepseek-chat")
        return response.choices[0].message.content

以上完整Prompt和代码,我将来会放在赞赏群里。您加群后可以向我要,我在赞赏群里为你准备了开群以来近五十份资料,包括开群以来本公众号文章的Prompt模板、模块和一些DSPy的代码文件完整示例,还有部署一些AI应用的Dockerfile,等你来一起讨论!另外,如果你有更多关于论文里Prompt的问题也可以到群里来,我会耐心解答你的问题


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

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

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

联系我们

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

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询