大型语言模型 (LLM) 的普及彻底改变了我们人类解决问题的方式。在过去,用计算机解决任何任务(例如,重新格式化文档或对句子进行分类)都需要创建一个程序(即根据某种编程语言精确编写的一组命令)。使用 LLM,解决此类问题只需要一个文本提示。例如,我们可以通过类似于下面显示的提示来提示 LLM 重新格式化任何文档。
使用提示重新格式化 XML 文档(由作者创建)
如上例所示,LLM 的通用文本到文本格式让我们能够轻松解决各种各样的问题。我们首次看到了这种潜力,是因为GPT-3 [18] 的提议,它表明足够大的语言模型可以使用少样本学习以惊人的准确度解决许多任务。然而,随着围绕 LLM 的研究不断进展,我们开始超越这些基本的(但仍然非常有效!)提示技术,例如零样本/少样本学习。
遵循指令的 LLM(例如InstructGPT和ChatGPT)让我们开始探索语言模型是否可以解决真正困难的任务。也就是说,我们希望将 LLM 用于不仅仅是解决玩具问题。为了在实际中发挥作用,LLM 需要能够遵循复杂的指令并执行多步推理,以正确回答人类提出的难题。不幸的是,这些问题通常无法使用基本的提示技术来解决。为了从 LLM 中引出复杂的问题解决行为,我们需要更复杂的东西。
(来自 [1, 2, 4, 7])
扩大可能性的范围……
(作者创作)
在之前的文章中,我们了解了 LLM 的更基本提示方法,例如零/少样本学习和指导提示。了解这些实用的提示技术对于掌握这里将介绍的更高级的提示程序非常重要。有关这些技术的更多详细信息,请查看此处链接中的概述!
更好的提示 → 更好的结果。这些技术可用于在 LLM 中完成很多工作(假设它们应用正确)。但是,由于各种原因,它们可能会失败。小样本学习要求大多数 LLM 的有限上下文窗口被样例占据,如果没有采取保护措施,LLM 可能会被诱骗提供有害的输出,并且大多数模型不擅长解决推理任务或遵循多步骤指令。鉴于这些限制,我们应该如何尝试使用 LLM 解决困难任务?
一种方法是创建更强大的 LLM,无论是从头开始还是通过更好的细化程序。然而,这需要付出很多努力!如果我们能让现有模型更好地解决问题会怎么样?在这篇文章中,我们将探索更高级的提示工程形式(例如,思路链提示、自动提示工程、信息检索等),这些形式使我们能够提高 LLM 性能并引出更复杂的问题解决行为。这些想法很重要,因为它们拓宽了 LLM 的可能性范围。例如,使用这些技术,我们可以:
- 允许 LLM 访问外部知识数据库。
- 使得复杂的、基于推理的问题能够得到解决。
- 通过允许模型存储和访问对话中的先前信息,为 LLM 提供无限内存。
即时工程正在不断发展。本概述将重点介绍即时工程的最新进展。我们不会深入探索个别方法,而是专注于广泛了解可能有用的不同即时工程技术。然而,应该注意的是,即时工程这一主题既新颖又发展迅速。几乎每天都会发布新的研究,许多前沿想法只是在网上分享,而不是正式发表。因此,这个主题很可能在未来几个月发生重大转变,从而扩大 LLM 可以解决的问题。
了解法学硕士
由于本概述侧重于提示,因此不会解释语言模型的历史或机制。为了更好地了解语言模型(这是深入理解提示的重要先决条件),我撰写了各种可用的概述。这些概述如下(按重要性排序):
- 语言建模基础(GPT 和 GPT-2) [链接]
- 规模对于语言模型的重要性(GPT-3) [链接]
- 现代法学硕士 [链接] 和专业法学硕士 [链接]
- PaLM、T5 (第一部分和第二部分)、LLaMA (第一部分和第二部分)
高级提示技巧
现在,我们将介绍提示工程领域中的三个有影响力的主题。首先,我们将了解如何使用思路链提示(包括几个值得注意的扩展和变体)来提高 LLM 的推理能力。从这里开始,我们将讨论 LLM 与外部数据库的集成,从而将相关、准确的信息注入每个提示中。最后,我们将学习如何使用自动提示工程方法从数据中发现更好的提示。
思维链提示及其超越
我们在之前的文章中介绍了思路链 (CoT) 提示 [1] 背后的主要思想及其一些流行的变体。有关完整详细信息,请阅读此处链接中的概述。
什么是 CoT 提示? CoT 提示是一种简单的技术,可以提高 LLM 在常识或符号推理等推理任务上的表现。CoT 提示通过在提示中插入几个正在解决的推理问题示例来利用少样本学习。每个示例都与一个思路(或原理)配对,通过以文本方式解释如何逐步解决问题来增强问题的答案;见下文。
(摘自[1])
由于 LLM 具有少量学习能力,他们可以通过观察 CoT 提示中的范例来学习生成答案和基本原理。先前的研究表明,以这种方式生成准确的基本原理可以提高推理性能 [10, 11],我们在 CoT 提示实验中也看到了这种效果。也就是说,教 LLM 输出相关的思路来解释其最终答案可以大大提高算术、符号和常识推理等任务的表现;见下文。
(摘自[9])
流行的 CoT 变体。除了基本的 CoT 提示之外,还探索了该技术的几种变体,例如:
- 零样本 CoT 提示 [13]:替换所有示例理由,并在提示末尾注入“让我们一步一步思考”的语句。
- 自洽性[14]:利用LLM生成多个思路链,并将这些多个输出中的多数票作为最终答案。
- 从最少到最多提示[15]:将推理问题分解为更小的步骤,每次解决一个子问题,其中每个子问题的输出用作下一个子问题的输入。
这些技术(如下图所示)与 CoT 提示类似,可产生类似的结果,但它们各自具有独特的优势。例如,零样本 CoT 提示非常简单!我们只需要在提示中插入一个语句,而不是手写或整理几个相关的思路链示例。另一方面,从最少到最多提示比普通 CoT 提示稍微复杂一些,但这种技术也更能解决需要很多步骤的推理问题。因此,我们可以使用从最少到最多提示来解决 CoT 提示不足的最困难的任务。
(来自 [13, 14, 15])
在这些技巧中,我个人最喜欢的是自洽。为什么?因为它是一种简单、适用范围广且非常有效的技巧。事实上,这个想法甚至不仅限于 CoT 提示!自洽在许多情况下可以提高 LLM 应用程序的性能。我们不是使用 LLM 生成单个输出,而是生成多个输出并取其平均值作为最终答案,从而提高可靠性和准确性。
这个想法让我想起了深度学习中的模型集成,我们i)独立训练多个模型来解决某个任务,ii)在推理时取每个模型输出的平均值。虽然自洽只使用单个模型而不是集成,但类似的技术已应用于更广泛的深度学习文献中;例如,为了模拟集成,可以从包含非确定性模块(如 dropout)的神经网络中生成并平均多个输出 [19, 20]。
扩展 CoT 提示。CoT提示是否真的教会了 LLM 如何“推理”尚不清楚。尽管如此,CoT 提示具有重要的实际意义,因为它可用于解决 LLM 中复杂的多步骤问题。因此,最近围绕 CoT 提示探索了各种有趣的想法。在 [16] 中,探索了 CoT 提示的多模态版本,其中使用图像和文本模态来执行不同的推理任务;见下文。
(摘自[16])
除了探索多种数据模态(即图像和文本)之外,[16] 中的作者还稍微调整了 CoT 设置,将多步骤基本原理生成和答案推理视为解决基于推理的任务的两个不同步骤;见下文。
(摘自[16])
通过明确隔离这些组成部分,我们可以更轻松地分析 CoT 提示中的错误来源。因此,[16] 中的作者发现i)错误答案通常是由生成的理由中的幻觉引起的;ii)使用多模态数据可以生成更有效的理由。
(摘自[17])
更进一步,[17] 中的作者将 CoT 提示与主动学习的理念相结合(即使用模型本身来识别应包含在训练集中的数据)。LLM 首先使用 CoT 提示回答几个问题。从这里开始,输出“不确定性”(根据同一 LLM 生成的多个答案之间的分歧来衡量)用于识别模型理解不佳的问题。然后,该组中的问题由人工用正确的思路进行手动注释,并用作解决未来问题的示例。
在实践中应用 CoT 提示时,我们可能遇到的最大问题之一是缺乏与我们试图解决的任务很好地匹配的少样本样本。也许我们可以访问几个高质量的思路链来包含在我们的提示中,但如果我们试图解决的问题与这些示例中解决的问题略有不同,我们该怎么办?虽然这样的问题会导致性能下降,但 [17] 中提出的方法旨在解决这个问题。也就是说,我们可以使用主动学习来动态识别何时 CoT 提示的可用示例不足以解决某个问题。
知识增强
尽管 LLM 在预训练期间学习了大量信息,但用额外的相关信息来补充他们的提示往往很有帮助。这种方法可以通过在 LLM 的提示中提供准确的信息来源来帮助解决幻觉(即生成不正确的事实)等问题,这些信息可以在生成输出时用作上下文。虽然有几种方法可以实现这一点,但我们将重点介绍基于信息检索和生成知识的技术。
(摘自[2])
信息检索。LLM社区最近非常重视矢量数据库技术(例如Pinecone、Milvus、Weaviate等),因为它在执行信息检索方面发挥着重要作用;见上文。从高层次上讲,信息检索的目标是使 LLM 能够通过以下方式访问大量文本信息(超出最大上下文窗口):
- 将文本分成小部分。
- 为每个文本块生成一个嵌入。
- 将这些嵌入存储在矢量数据库中。
- 执行向量相似性搜索(基于这些嵌入)以找到要包含在提示中的相关文本块。
最终结果是,我们可以快速找到相关的文本信息,作为 LLM 提示中的额外背景信息。这种方法甚至可以与CoT 提示相结合,以引导检索过程找到新的有用信息 [2]。
(摘自[1])
生成的知识。信息检索功能非常强大(即,它可以访问几乎无限量的信息!),但我们可能会想:外部向量数据库是否完全必要?有趣的是,最近的研究 [1] 表明答案可能是否定的!我们可以通过提示单独的 LLM 生成信息来提高 LLM 性能,而不是存储和检索外部知识;见上文。具体来说,我们可以使用少样本学习,通过提示 LLM 生成有关各种主题的知识生成示例,最后要求生成有关所需主题的有用上下文;见下文。
(摘自[1])
从这里开始,我们可以在生成预测时将生成的信息作为额外的上下文。尽管不依赖任何外部数据库,但这种方法可以显著提高 LLM 在几个常识推理任务上的性能;见下文。
(摘自[1])
生成的知识对于需要理解世界常识的任务(如常识推理)最有帮助。简而言之,只要谨慎使用并用于正确的任务类型,法学硕士就是很好的信息来源。
“生成知识提示强调大型语言模型是提高常识推理能力的灵活外部知识来源” ——摘自[1]
自动提示
提示工程的目标是调整语言模型的输入,从而最大限度地提高模型提供正确结果的机会。考虑到这一点,我们甚至可以将提示视为一组可训练的参数,这些参数可以更新(例如,使用梯度下降或其他数据驱动的标准)以生成正确答案。根据数据自动更新提示的想法非常通用,但最近的研究已经成功探索了几种此类技术。
自动提示工程师 (APE) [4]提出了一种自动生成提示指令的简单方法。首先,使用 LLM 通过使用包含多个指令示例的少样本提示来提出一组潜在指令。探索了一些用于生成指令的提示模板;见下文。
(摘自[4])
然后,我们通过评估使用每条指令的 LLM 的零样本性能(即准确度或正确结果的对数概率)来搜索这个指令“候选”池。换句话说,每个提示的 LLM 性能被用作评估指令质量的指标。
(摘自[4])
进一步说,我们在 [4] 中看到,只需重复此过程,就可以迭代地完善指令。具体来说,我们可以 i) 提出一组候选,ii) 根据性能评估这些候选,iii) 选择最佳候选,以及 iv) 通过提示 LLM 生成类似指令(即重新采样)来生成表现最佳的候选的新变体。下图概述了此过程(以及相关提示)。
(摘自[4])
基于梯度的搜索。除了寻找更好的文本提示的技术之外,还有一系列有用的提示工程工作,它们探索提示嵌入的持续更新。首先,我们应该回想一下语言模型中的提示嵌入是什么。给定一个文本提示,我们通常会标记这个提示(即,将其分成单词或子单词),然后查找每个结果标记的嵌入。这个过程为我们提供了一个标记嵌入列表(即提示嵌入!),我们将其作为输入传递给语言模型;见下文。
语言模型中的提示和提示嵌入(由作者创建)
有几篇论文探讨了直接修改提示嵌入(即,每个标记的嵌入列表)的提示工程策略。换句话说,这些论文不会直接修改提示的单词,而是使用梯度下降之类的规则更新提示嵌入。该领域的主要论文概述如下:
- AutoPrompt [5]将原始提示输入与一组共享的(跨所有输入数据)“触发标记”相结合,这些“触发标记”通过基于梯度的搜索进行选择以提高性能。
- 前缀调整[6]在输入层和隐藏层的提示嵌入中添加几个“前缀”标记,然后使用梯度下降作为参数有效的微调策略来训练该前缀的参数(保持模型参数固定)。
- 即时调优 [7]与前缀调优类似,但前缀标记仅添加到输入层。这些标记会针对语言模型解决的每个任务进行微调,从而允许前缀标记针对给定任务调节模型。
- P-Tuning [8]将经过微调的针对特定任务的锚标记添加到模型的输入层,但允许这些标记放置在任意位置(例如,提示的中间),从而使该方法比前缀调整更灵活。
我们应该使用哪一个?所有这些方法(如下所示)都探索了在语言模型中添加“软”标记,这些标记在目标数据集上进行监督微调。值得注意的是,这些技术不能用于只能通过付费 API(例如OpenAI API)访问的语言模型。这是因为我们需要访问和修改提示嵌入的能力,而大多数 API 仅显示模型的文本输入和输出。目前,如果我们使用自己的自托管 LLM,我们只能使用基于梯度的自动提示技术。
(来自 [5, 6, 7, 8])
在这些方法中,Prompt Tuning 是最简单的,并且可带来令人印象深刻的性能优势。使用 Prompt Tuning,我们只需i)将一些前缀标记嵌入附加到输入中,ii)在各个下游任务上对这些嵌入执行参数高效的微调。[7] 中的方法通过将几个不同的任务混合到每次更新中并为每个任务提供唯一的学习前缀来执行多任务微调;见下文。
(摘自[7])
通常,微调语言模型意味着我们必须为每个任务存储一份单独的模型参数副本。相比之下,Prompt Tuning 只微调一小部分前缀标记嵌入,并保持其余模型参数不变。尽管只微调了一小组参数,但 Prompt Tuning 的性能非常接近端到端微调,如下图所示。
(摘自[7])
总结
“随着模型规模的扩大,我们还能期望推理能力提高多少?还有哪些其他提示方法可以扩大语言模型可以解决的任务范围?” ——摘自[9]
本概述的主要目的是探索可能对解决 LLM 难题有实际作用的不同提示技术。如果正确应用,零/少样本学习和指令提示等基本技术是有用且有效的。但是,可能需要一些更复杂的东西来使 LLM 能够解决基于推理的任务或遵循复杂的多步骤指令。虽然模型的质量可能会随着时间的推移而提高,并且更容易处理这些困难的情况,但本概述中涵盖的技术可用于扩展当前可用的 LLM 的可能性范围。下面概述了这些技术的一些基本要点。
解决难题。对 CoT 提示的分析表明,LLM 能够解决复杂的多步骤问题。但是,要做到这一点,需要将问题分解为更小的部分,以便 LLM 或由 LLM 完成。我们可以通过鼓励模型在给出答案之前生成解决问题的理由来隐式地做到这一点,或者通过使用从最少到最多的提示将问题分解为由 LLM 单独解决的小部分来明确做到这一点。无论哪种方式,我们通常都会看到鼓励 LLM 逐步解决问题而不是整体解决问题的好处。
学习提示。如果我们听到“提示工程”这个词,我们大多数人可能会想到调整提示的单词或结构,看看哪种方法最有效。然而,这并不是提示工程的唯一方法!也就是说,我们可以采用一种自动提示方法,通过梯度下降从数据中学习最佳提示。为此,我们使提示嵌入(即提示中每个标记的嵌入列表)可训练并执行微调。虽然这种方法很有趣也很有用,但需要记住一些注意事项:
- 学习到的提示嵌入不能映射回文本提示,因为模型词汇表中每个标记的嵌入都是离散的。
- 只有在可以访问语言模型的嵌入层时,我们才能使用这些方法。此类访问权限不通过付费 API(例如来自 OpenAI)提供。
简单但功能强大。尽管本概述侧重于高级提示工程技术,但仍有许多简单的技巧可以轻松应用于改进 LLM 应用程序。例如,自洽性可以通过生成多个答案并取其平均值来提高 LLM 的可靠性。零样本 CoT 提示可以通过在提示末尾附加单个语句来轻松提高 LLM 推理能力。最后,生成的知识可以通过简单地要求模型在生成最终答案之前列出有关主题的有用信息来提高 LLM 性能。在许多情况下,在我们的提示工程工具包中添加简单的技巧可以产生很大的不同!