Medium 好读版: https://bit.ly/4fpxwdn
大型语言模型 (LLM) 为自动化工作流程提供了很多帮助,
很多新的应用因为大型语言模型的出现,从不可能变为可能。
而为了使用模型的回答来串接不同的工作,
结构化输出 (Structured Output) 几乎不可或缺。
目前热门的模型都有支援输出特定的 JSON 格式,来方便程式处理模型的回答。
不过平常可能不太容易察觉,结构化输出其实有它的缺点。
要求模型输出特定的格式有机会降低模型的表现,甚至增加幻觉发生的机率。
大型语言模型如何产生结构化输出?
想要让模型照着我们的要求回答问题并不是一件简单的事情,
资料科学家和工程师们为此提出了很多不同的解决方案。
而目前被广泛应用到实际产品的方式,
是透过建立目标格式的语法树来限制模型每一次输出的 token。
知名的实作有开源的 lm-format-enforcer (LMFE)
或是 Google DeepMind 基于 OpenFST 的实作。
虽然在名词的使用上各家并没有统一,但概念上是相似的。
大方向就是强迫模型输出符合当前语法状态的 token,遍历目标语法树直到结束状态。
这个方法的可靠性和效率非常高,几乎可以确保输出的格式符合规范。
但,最重要的永远是这个但是,
强迫模型输出特定的格式意味着每一次输出的 token
不一定是能够回答问题的的最佳解。
模型极有可能为了符合格式,让下一个产生的 token 偏离了正确答案。
随着任务的复杂度和输出的增加,这样的偏差最终就可能导致幻觉或错误的回答。
让模型先好好说话!
要解决这样的问题,有一个容易且直觉的方法:
不要限制模型输出的格式,让它好好回答问题。
取得答案之后,我们再要求模型将答案转换成我们要的格式。
这个方法适用在有较长前后文 (Context) 的复杂任务,
因为输出的内容通常较精简,模型便可以正确的转换格式。
但这个方法具体倒底能改进多少输出的品质呢?
来作个实验!
为了量化结构化输出对模型表现的影响,
笔者收集了一周份来自立法院的会议纪录和质询逐字稿,
总计约 400,000 个 tokens 的文字资料来设计实验。
完整的资料可以在立院知更的每周新闻下载。
https://lyrobin.com/news
任务目标是请模型整理出当周立法院讨论的议题,并做成新闻标题。
在选题上,我们要求模型尽可能的挑选不同领域的议题,
并希望可以避免标题间太过相似。
因此若是模型输出的标题重复性越高,则输出的品质越低。
我们将输出的标题透过 text embedding 输出成 embedding vectors,
透过两两配对标题并计算彼此的相似度后取平均值,
就可以评估模型的表现。
以下的程式码分别实作了两个不同的方法:
1. 立即使用结构化输出
2. 先不使用结构化输出,后续多用一个提示来整理输出格式。
以下我们称前后者分别为一步和二步骤提示。
程式的输出和标题相似度的范例如下。
最后我们用标题间的相似度画出分布图,可以得到以下的结果。
可以看到二步骤提示得到的标题彼此间相以度较低,
因此议题的差异较高,更符合我们设定的目标。
总结
从我们的实验可以观察出,
透过二步骤提示先让模型好好针对问题回答,
再修改成特定格式有助于提升模型的表现。
因此若是输入的前后文较长,且任务要求比较复杂,
可以透过这个方法来有效的改善输出的品质。
希望这个小技巧能对你有一点帮助,
有任何的问题或指教都欢迎留言和我讨论。
===========================
最后小小的宣传一下我开发的服务:立院知更。
https://lyrobin.com/
这是一个使用大型语言模型实作的立法院搜寻引擎,
我们希望透过建立更加直觉且便利的立院搜寻引擎,
让所有人能够轻易地使用关键字搜寻到立院中各种相关文档及影音资料,
进而提升公民参与。
有任何的想法或意见,都欢迎来信讨论!
参考资料
1. Automata-based constraints for language model decoding
https://arxiv.org/abs/2407.08103v1
2. lm-format-enforcer
https://github.com/noamgat/lm-format-enforcer