这篇论文声称类似 Json 的这类结构化输出的指令,会导致大模型发生降智现象——
如上图所示,在表现最差的任务上,结构化生成(JSON 模式)的准确率甚至低于 10%,而非结构化 Natural Language (NL)结果的准确率约为 70%。
论文链接:
https://arxiv.org/abs/2408.02442
论文一经发出,在外网引起大量争议。
而小鲤也看着自己手头的一堆 JSON、XML、YAML 结构化输出的大模型陷入了沉思。
不过,很快就有大佬站出来了。
直接写了一篇名为"Say What You Mean: A Response to 'Let Me Speak Freely'"的长博文,对这篇论文的结论展开了不留情面、有理有据的炮轰,用铁证推翻“_Speak Freely_”论文的实验结论。证明了不是大模型效果不行,是你的 prompt 水平不太行。
博文链接:https://blog.dottxt.co/say-what-you-mean.html
下面就跟随笔者一起看下这篇牛逼的博文。
下文中我们用“博文”表示这篇博文,用“Speak Freely”表示论文。
先放打脸结论——博文的作者实验结果如下图所示,在论文中的三个任务上大模型的效果不仅没有受到结构化输出的影响,甚至还都略有提升。
糟糕的 prompt
“Speak Freely”中被发现最大的一个问题,就是文中对结构化生成和非结构化生成使用了不同的 prompt。我们一起来看看这个 prompt 到底有多糟糕。以下是一个示例:
阅读完这个 prompt,我们能够知道它想让模型干什么,但不够明确:
答案必须是 JSON,但根本没有提到 JSON
即使模型猜测回答应该是 JSON,应该使用什么架构来响应?
虽然提到了工具使用,但 prompt 没有提到要使用哪些工具!
诚然大模型很强大,结构化生成也很强大,但它毕竟不是我们肚子里的蛔虫,不能推测出我们想要什么。
一个完整的 prompt 应该是包含了足够多的信息,以便于一个正常的人类能够正确回答问题。于是,博文的作者 Will Kurt对这个 prompt 进行了重新改写!
为 JSON 编写正确的 prompt
改进之后的 prompt 长下面这个样子:
system
You are an expert in solving simple word puzzles using reasoning steps. Your specific
task is going to be to take a list of 4 names and reason about the last letter of each .,
then you will concatenate those letters into a word. The Question will be plaintest from the user
and response will be formatted as JSON below:
{"reasoning":
, "answer":
}user
Question: Take the last letters of each words in 'Ian Peter Bernard Stephen' and concatenate them.assistant
{"reasoning": "The last letter of 'Ian' is 'N', the last letter of 'Peter' is 'R', the last letter of 'Bernard' is 'D', and the last letter of 'Stephen' is 'N'. Therefore, the answer is 'NRDN'.", "answer": "NRDN"}user
Question: Take the last letters of each words in "Britt Tamara Elvis Nayeli" and concatenate them.",assistant
我们可以看到 Will Kurt改进了很多点:
使用了适合模型的指令格式。
提供一个有正确结构并且和任务相匹配的示例。
以一个空的“assistant”prompt 结束,以便以我们想要的结构开始生成输出。
定义自己的结构
接下来, Will Kurt还定义了一个自己的结构。对于论文中的Last Letter 任务,作者使用了一个简单的 Pydantic 模型:
在这里 Will Kurt 限制了推理步骤为 250 个字符,以确保推理不会花费太长时间,并且还将答案限制为 4 个有效字母。
过程中有一个重要步骤是验证 prompt 中是否包含了定义的结构。prompt 的重点是为大模型做好充分的准备,如果我们没有向它展示我们想要的确切结构,模型就不得不花更大的代价去学习。以下是确保 prompt 与结构匹配的代码:
验证后,终于可以进入正题了!
JSON 结果
现在,让我们看看结构化生成和非结构化生成进行公平对比之后的结果。
是好消息!结构化生成优于非结构化生成。上图可以看出,非结构化 JSON 结果(73% 的准确率)优于结构化 NL 的(68% 的准确率)结果,但最后的赢家还是准确率为 77% 的结构化 JSON!
当然啦,博文中 diss 的可不仅仅是 prompt 设置的不够合理这一个问题, Will Kurt认为“Speak Freely”中对结构化生成理解有些偏颇,导致整个实验过程逻辑不够流畅。
于是博文作者亲自下场,为我们演示了一场丝滑的结构化生成的实验过程。在我们观看这场盛宴之前,先一起来了解一下作者用来实验的任务叭。
任务概述——Last Letter
Will Kurt的实验实验都是在一个叫做Last Letter 的任务上完成的,因为它是“Speak Freely”中声称结构化生成表现最差的任务。差到什么程度呢?结构化生成(JSON 模式)的准确率低于 10%,而非结构化 Natural Language (NL)结果的准确率约为 70%。
为了方便下文的理解,小鲤对这个任务做一点简要的介绍。在这个任务中,模型会收到一个四个名字的列表,然后模型必须将每个名字的最后一个字母连接起来。例如:
上述示例的答案将是“NRDN”。评估由测试集中的 150 个问题和训练集中的 350 个问题组成。“Speak Freely”中仅使用了 150 个“测试”问题,为了保持一致,博文中也同样如此。
我们使用结构化生成与大模型一起工作的主要原因是保证输出的格式以便于解析。也就是说,解析和结构化生成是相辅相成的。
“Speak Freely”中一个有趣的部分,叫做“Perfect Text Parser”,用于从初始模型输出中提取答案。
通常,大多数评估框架在解析输出时会使用简单的、定义明确的正则表达式,但 Tam 等人使用 claude-3-haiku-20240307 来解析模型生成的输出。这意味着每个答案实际上都使用了两个模型。
Will Kurt觉得论文中“Perfect Text Parser”中“Perfect”这个词的表达有些误导,因此在下文中我们都将其称为“AI 解析器”。
AI 解析器
首先来看看让模型在 Natural Language (NL)也就是非结构化输出格式下表现最好的 prompt 长什么样:
注意,输出的格式被明确描述成了:“The final answer is”。这意味着,如果模型遵循这条 prompt,我们应该能够使用以下简单正则表达式解析所有答案:
通过查看实验记录的结果,Will Kurt发现了严格正则表达式解析与AI 解析之间的结果差异:
发生了什么?
这看起来 AI 解析器做了很多繁重的工作。检查了结果之后发现,严格正则表达式漏掉了很多模型的正确输出。以下是一些 AI 解析器能够识别正确但不符合正则表达式的示例:
“The answer is e-S-S-E.” → ESSE
“The answer is AAA R.” → AAAR
“The answer is 'reye'.” → REYE
“The final answer is: YOOI” → YOOI
显然,严格正则表达式看起来过于严格了。所有这些答案在小鲤看来都是合理的,可能会有个别案例不能够被认同,但总体而言,这些似乎是可以接受的结果。在没有额外调用更强大模型的情况下,一个合理的解决方案是简单地扩展正则表达式,以便覆盖这些情况。所以 Will Kurt 添加了以下替代正则表达式来解决被发现的样本案例:
在使用了更加完善的正则表达之后,他得到的结果是:
事实证明,根本不需要单独的模型!手工编写的这些正则表达式列表(并不需要花费太多时间编写)在这个数据集上表现甚至优于 AI 解析器!
其实结构化生成的主要卖点就是无需担心解析。这个实验向我们展示了 AI 解析器事实上并不是“完美”的文本解析器,运行我们手工编写的灵活正则表达式解析器比调用 Claude 更快、更便宜,而且效果更好!所以论文中这么做就略显画蛇添足了。
非结构化——复现结果
接下来,Will Kurt使用相同的 prompt 来运行模型。这里他对 prompt 中的 one-shot 示例进行了一些修改,使 prompt 示例中包含四个名字,而非 Tam 等人所使用的两个名字。
得到的结果与论文原始数据中报告的结果相比如下:
如你所见,Will Kurt 的结果略好一些,基本上与记录的结果一致。感觉稳稳的,很幸福。
结构化——你可以生成任何你能够解析的内容
以上 Will Kurt 在非结构化的输出上向我们展示了 AI 解析器的工作原理,如何解析大模型的输出,是真正理解结构化输出的关键。接下来我们来看看大模型的结构化输出。
诚然手工编写一些正则表达式并不会花费太多的时间,但想要真正的解放双手,就是我们能够解析什么,就让模型直接生成什么。结构化生成的要点就是不用担心输出解析!
这里有一个常见的误解,就是认为结构化生成只是 JSON 模式(或 YAML 模式、XML 模式等)的另一个名称。这些格式当然是结构化的,但我们也可以自由的定义自己的结构。
所以,Will Kurt 将非结构化输出的例子中解析输出的正则表达式加入了结构化输出的定义中,让模型的输出从:
The final answer is
进化成了:
Answer: T[\w \",\.]{30,250}. The answer is ([A-Za-z]{4}).
让模型“思考”30 到 250 个字符,然后开始其答案。这样,模型就只会输出满足严格正则表达式的答案,我们也无需再使用更灵活的正则表达式来解析模型的输出了。
使用默认的严格正则表达式解析后,让我们看看 Will Kurt 自己定义的结构化输出表现如何:
这样看起来,这个自定义的结构一点儿都没有影响模型的“智商”。
那么 JSON 呢?
用我们自己定义的结构输出并不会影响大模型的效果,就能代表所有的结构都不会吗?JSON 也不会吗?原论文中这张看起来十分不妙的图表仍然是我们心里的一块大石头,无法安然落地。
根本问题难道是要求模型以 JSON 格式输出吗?
当然不是!
文章的刚开始我们就已经证实过了,那只是 prompt 的问题!“Speak Freely” 里在理解结构化生成的性能时,比较的条件不平等,把 prompt 不相同的这口大锅甩给了结构化。就像用一段糟糕的 Rust 代码和 Python 比性能,最终显示 Rust 的性能比 Python 差一样。
所以不管是 JSON,还是其他什么形式的结构,只要你有合适的解析器和准确的 prompt,都不会使大模型降智,甚至还能提高大模型的成绩。那么,就继续放心大胆的享受结构化带来的便利叭~
4000520066 欢迎批评指正
All Rights Reserved 新浪公司 版权所有