Multi-Stage Language Model Programs:提升语言模型程序的新策略 原创
在自然语言处理(NLP)领域,语言模型程序(Language Model Programs)正逐渐成为推动任务进展的关键力量。这些由多个模块化语言模型(LM)调用组成的复杂管道,为解决复杂的NLP任务提供了新的思路和方法。然而,构建这些管道并非易事,其中一个关键挑战就是如何优化提示(prompts),使得所有模块都能高效协同工作。今天我们就来介绍一篇来自DSPy一作、斯坦福大学博士生、并且即将成为MIT助理教授的Omar Khattab领导的一项有意思的工作!
一、研究背景
(一)语言模型程序的发展与挑战
随着技术的发展,语言模型在解决复杂任务时,常常需要运用复杂的提示技术,并将其组合成多阶段的管道。例如在问答系统、文本生成、信息检索等任务中,通过将多个语言模型按特定顺序和方式组合,可以实现更强大的功能。但是,目前构建这些管道大多依赖于手动的“提示工程”(prompt engineering),即通过反复试验来设计提示,以促使特定的语言模型在特定的管道步骤中运行。这种方法不仅耗时费力,而且难以保证效果的最优性。
(二)现有提示优化方法的局限性
近年来,虽然出现了一些提示优化器(prompt optimizers),如APE、OPRO和EvoPrompt等,但它们大多针对单个语言模型的提示优化,无法直接应用于多阶段的语言模型程序。在多阶段程序中,由于缺乏对单个语言模型调用的黄金标签或评估指标,使得提示优化变得更加困难。
图1:优化问题的一个示例,以一个多跳检索语言模型程序展示。给定一些问答对和一个度量标准,优化器为每个阶段提出新的指令并引导新的演示(未图示)。
二、问题定义与挑战分析
(一)问题正式化
考虑一个由m个模块组成的语言模型程序Φ,每个模块使用一个语言模型,并由一个包含一组变量(开放插槽)v的提示模板pi定义。我们的目标是找到一个变量到字符串的总分配,使得程序在给定的训练集D上,根据评估指标μ达到最优性能。这个问题面临着诸多挑战,例如每个字符串可以取任意值,评估指标只能在整个任务层面提供监督,无法获取语言模型的梯度或嵌入,以及通常只有小数据集和有限的语言模型调用预算等。
(二)主要挑战
- 提案挑战(Proposal Challenge) 可能的提示空间非常大,而且随着模块数量的增加,这个问题更加严重。因此,提出一些高质量的指令就变得至关重要。
- 信用分配挑战(Credit Assignment Challenge) 需要联合优化许多不同的变量,这些变量用于参数化所有模块的提示。为了合理分配搜索努力,我们必须有效地推断每个变量配置的影响。
三、解决策略
(一)应对提案挑战的策略
- 引导演示(Bootstrapping Demonstrations)一种简单而有效的策略是通过从训练集中采样输入,运行程序Φ生成输入/输出轨迹,将成功的轨迹作为潜在的标记演示(即有效输入/输出示例)。然后,从这些潜在演示中选择组合作为有效的少样本示例用于提示。
- 基础设定(Grounding)为了引导提案语言模型为给定模块生成高效的指令,我们为其提供相关的上下文信息,如数据的属性、程序的控制流以及成功任务完成的示例等。通过构建一个零样本语言模型程序来描述原始数据集的模式、总结程序的控制流、引导程序演示以及收集每个阶段的提示及其评估分数,并将这些信息作为上下文提供给提案语言模型。
- 学习提案(Learning To Propose)每个提案策略都有一些超参数,如指令生成的温度以及是否使用数据摘要、程序控制流等来设定提案语言模型的基础。由于这些超参数的最优配置可能因任务、程序和提案语言模型而异,我们通过参数化提案超参数,并在多次试验中学习一个贝叶斯模型,以找到适合给定任务、程序和语言模型设置的提案策略。
图2:引导随机搜索。在第1步中,通过将训练输入在程序Φ中运行,并保留根据度量标准µ判断能产生足够高得分输出的轨迹,来引导演示。在第2步中,使用随机搜索对这些引导出的演示集进行搜索,并返回性能最佳的集合。
(二)应对信用分配挑战的策略
- 贪婪策略(Greedy)分别对语言模型程序的单阶段变化进行提案和评估。虽然这种方法可以避免将错误错误地归因到不正确的阶段,但它效率低下,因为每次只能应用一个变化,而且某些阶段的变化可能要在其他阶段先改进后才能对程序级性能产生影响。
- 替代策略(Surrogate)利用贝叶斯学习构建一个替代模型,通过学习从先前评估中预测不同参数组合的质量,使我们能够聚焦于搜索空间中有希望的区域。这种基于替代的优化方法可以有效地优化离散的现有参数提案集,但它的缺点是只能对固定的提案集进行优化,无法利用过去的评估结果来改进提案本身。
- 基于历史的策略(History - Based)假设给定过去评估的历史,一个足够强大的语言模型可以进行信用分配。通过将评估过的指令及其分数包含在上下文中,让提案语言模型学习分配信用并输出新的指令。
四、算法实例与实验
(一)算法实例
- 引导随机搜索(Bootstrap Random Search)首先通过引导演示过程为每个模块引导出一定数量的少样本示例,然后使用随机搜索在这些引导出的演示集上进行搜索,返回性能最佳的集合。
- 模块级OPRO(Module - Level OPRO)将模块级指令和程序分数对的历史作为输入提供给提案语言模型,为每个模块生成新的指令,然后在程序中评估这些指令,并将结果分数与每个模块的指令一起添加回模块的历史中,重复这个过程直到达到最大迭代次数,最后返回得分最高的程序参数化。
- MIPRO(Multiprompt Instruction PRoposal Optimizer)首先通过引导演示和基础设定策略为每个模块引导出少样本示例和指令,并初始化潜在的分类变量。然后使用树结构的Parzen估计器的采样规则选择用于参数化Φ的指令和少样本示例。接着在随机选择的小批量样本上对参数化的Φ进行评分,并使用这些分数更新估计器对参数质量的先验。最后,每隔一定步骤,在整个训练集上评估具有最高平均分数的候选参数化,返回最优的分配。
图3:模块级OPRO优化器。模块级指令和程序分数对的历史作为输入提供给提案语言模型,以便为每个模块生成一条新指令。然后在程序中对这些指令进行评估,并将所得分数与每个模块的指令一起添加回模块的历史记录中。这个过程重复I次。
图4:MIPRO优化器。在第1步中,使用与引导随机搜索第1步相同的过程引导演示。在第2步中,使用3.1节中描述的基础设定策略提出指令。在第3步中,使用贝叶斯优化来找到指令和演示候选的最佳性能组合。
(二)实验设置
- 基准测试(Benchmark)开发了七个任务来评估语言模型程序优化器,包括四个多阶段程序和两个单阶段程序,涵盖了问答、分类、自然语言推理等多种任务类型。使用500个示例进行训练,500个用于开发,2000个(或更小的完整测试集)用于测试。
- 方法与模型(Methods & Models)对指令仅优化、少样本优化以及指令和少样本联合优化三种情况进行了评估。在不同的优化场景下,比较了多种优化器的性能,如Module - Level OPRO、0 - Shot MIPRO、0 - Shot MIPRO++、Bootstrap Random Search、Bayesian Bootstrap等,并使用未优化的语言模型程序作为基线。同时,为了评估基础设定的效用,还比较了带有和不带有基础设定的Module - Level OPRO。在实验中,使用GPT - 3.5作为提案语言模型,Llama3 - 8B作为任务模型,并根据任务的不同,在引导少样本演示时可能会切换使用的模型。
表1:DSPy优化器基准测试和相关程序。我们在七个不同的程序上对我们的优化器进行基准测试。
(三)实验结果与讨论
- 引导演示的重要性对于大多数任务,优化引导的演示作为少样本示例对于实现最佳性能至关重要。通过实验证明,即使是简单的引导随机搜索,在除了一个任务之外的所有任务中,都比最佳的仅指令优化器表现更好。
- MIPRO的优势使用MIPRO联合优化指令和少样本示例通常能获得最佳的整体性能。但也存在一些例外情况,对于某些任务,如HotPotQA和Heart Disease等,可能由于任务本身的特点,指令优化的价值相对较小。
- 指令优化的适用场景对于具有条件规则且这些规则对语言模型不明显且无法通过有限的少样本示例表达的任务,指令优化最为重要。例如在HotPotQA Conditional任务中,即使是0 - shot指令优化也优于仅演示优化。
- 基础设定的效果基础设定对于指令提案总体上是有帮助的,但最佳的提案策略因任务而异。在某些任务中,如HotPotQA和HoVer,基础设定对性能提升至关重要,而在ScoNe任务中,似乎会损害性能。这也促使了像MIPRO++这样能够针对给定任务学习自定义提案策略的方法的出现。
- 进一步探索的空间通过比较不同优化器的性能,发现结果是复杂的。不同的优化器在不同的任务和场景下各有优劣,未来还需要进一步研究在不同优化预算下这些优化器的性能差异,以及探索如何让优化器在不依赖手写输入的情况下学习任务动态等问题。
表2:5次运行的平均结果,分为仅优化指令(即“0 - shot”提示)、仅优化演示以及两者同时优化。每列中性能最佳的值用粗体突出显示。这些粗体值表示与第二高值相比的最高平均分数,相应运行平均值之间的威尔科克森符号秩检验(p <.05)支持其显著性。如果显著性未得到确认,则多个结果用粗体表示它们具有可比的性能。
五、研究贡献与局限
(一)贡献
- 对语言模型程序的提示优化问题进行了形式化定义,并提出了一个算法设计空间,包括三种应对提示提案挑战的策略和三种解决信用分配问题的策略。
- 发布了一个涵盖七个任务的语言模型程序优化器基准测试套件,为评估不同优化器的性能提供了统一的标准。
- 构建并评估了一组可能的提示优化算法,其中MIPRO优化器在七个任务中的五个任务上优于基线优化器,为实际应用提供了有效的优化方法。
- 为从业者提供了五条关于优化语言模型程序的关键经验教训,有助于指导实践操作。
(二)局限
- 研究是在固定预算下进行的,没有探讨在极低或极高预算场景下优化动态的差异。
- 在实验中使用了固定的提案语言模型和任务语言模型,未来需要评估在使用不同模型时方法的一致性表现。
- 优化器在推断复杂任务的规则方面能力有限,尤其是在没有手写种子提示的情况下。
- 虽然建立了一个涵盖多种任务和程序的基准,但对于日益复杂的任务和程序,优化器方法的性能还有待进一步研究和完善。
总的来说,这项研究在语言模型程序提示优化方面取得了重要进展,为未来的研究和实践提供了有价值的参考和方向。尽管存在一些局限,但也为进一步的探索和改进提供了空间。
本文转载自公众号AIGC最前线 作者:不是小马哥啊