Large Language Models as Optimizers
文章链接
总体架构Optimization by PROmpting (OPRO):最开始输入meta-prompt,这个初始的meta-prompt基本上只是对优化任务进行了描述(也会有few-shot example)。输入后LLM便会生成一个solution,这个solution由objective function评估并打分。(solution, score)组合成一对添加到meta-prompt中,如此完成一个循环。多次循环后取分数最高的solution作为优化结果。
meta-prompt design
meta-prompt分为两部分,问题描述和优化轨迹,问题描述就是用自然语言描述想要优化的问题,比如“generate a new instruction that achieves a higher accuracy”。而优化弹道(Optimization trajectory)则是指之前提到的(solution, score)对,即之前生成的解决方案和对应的分数,可以看作优化的“日志”。但是要注意这个弹道不是按时间顺序排的,而是按照打分升序排的。因为之前的研究也发现,越靠后的样例对输出的影响越大,所以把分数高的排在后面有利于LLM向其学习。
下图是一个meta-prompt的示例:
solution generation
稳定性:由于生成的solution并不一定就是好的,特别是在优化的初期,将这些烂solution加入meta-prompt可能对后续优化产生负面影响,这也会导致整个优化过程不稳定。所以作者让每个优化步生成多个solution,这样可以更好的explore找到好的方向。
explore-exploit tradeoff: 温度低的时候LLM倾向于exploit,而温度高的时候模型倾向于explore。
Application
整个优化框架甚至可以优化数值问题,比如线性回归和旅行商问题,在这里我们着重说一下其在prompt优化上的应用。
还是如上面贴的图所示,这基本上就是作者给LLM的meta-prompt的全部组成部分了。橙色的为meta-instruction,第一段告诉LLM prompt中的优化弹道是什么意思,第二段告诉LLM输入输出的格式,第三段则告知LLM它的任务是什么。蓝色的部分就是优化弹道没啥好说的,紫色的部分则是一些few-shot examples,配合第二段meta-instruction让LLM明白数据集是什么以及输入输出格式。这个样例可以是每个优化步随机采样得到的,也可以是上一个instruction做错的。
这个优化任务的打分就很简单了,直接用prompt在数据集上的正确率。优化弹道按照分数升序排列,在prompt的长度限制内,每次优化完更新并保留得分高的instruction。
测试的时候还比较了这个优化出来的instruction放在不同位置对表现的影响,分为Q_begin(放在问题前面), Q_end(放在问题后面), A_begin(放在答案第一句话)如下图:
实验结果如下:
可以看到基本上还是同种模型来自己优化自己效果好,跨模型的提升没有那么明显。
作者在GSM8K上做优化只用了3.5%的样例,整个GSM8K的训练集有7473条数据,也就是说只用了261条左右个问题就把prompt优化出来了。整个迭代次数也就80-200次,在BBH上则是20%的样例150-200次,整个收敛还是很快的,主要取决的LLM的速度。
消融实验
meta-prompt design
分析了meta-prompt中可能影响表现的因素
-
优化弹道的顺序
显然升序效果比较好,降序最差,随机介于两者之间。 -
打分的呈现形式
有百分制、二十分制和不给打分默认升序排列,可以看到效果没有那么明显,但基本上还是百分制有优势,说明给分给细一点更能让LLM明白不同问题的优劣区别。 -
样例数量
从图上看,3个样例的效果最好,10个样例和无样例效果都远不如3个样例的效果好,作者分析说example很重要,因为它提供了有关任务的信息,并帮助优化器模型更好优化指令。 然而,更多的示例并不一定会提高性能,因为几个示例通常足以描述任务。 此外,包含更多样本会稀释meta-prompt的其他部分,分散 LLM 对其他重要部分(如优化弹道)的注意力。
初始prompt
影响不是很大,200轮基本都能收敛,起点好的要收敛的更快一些。
温度
跟前面分析的差不多,温度高explore多exploit少,温度低exploit多explore少,温度为1最好。