Created
Aug 14, 2024 01:40 AM
Favorite
Favorite
Priority
备注
推荐
类型
JSON 是全球使用最广泛的数据交换格式之一,支持我们的所有需求。 在构建人工智能驱动的应用程序时,工程师不可避免地需要将大型语言模型(LLM)的输出集成到他们的代码库中。
通过指示 LLM 使用特定的语法或模式,然后输出应用程序所需的生成结果,我们可以使应用程序的行为更加可预测。 简而言之,JSON 的互操作性使其成为数据交换的首选。

1、为什么让LLM 输出JSON数据如此困难?

语言模型擅长预测下一个标记并生成文本,但它们在产生文本之外的精确输出方面可能具有挑战性,因为它们并不总是精确地遵循指令
例如:对于 OpenAI,我希望 GPT-3.5-turbo 始终以以下形式响应
然而,它可能会以略微不同的方式响应:
  • message_type:message_content
  • message_type:"message_content"
  • (message_type): "message_content"

2、使用提示工程

Please provide the response in the form of a Python list. It should begin with “[“ and end with “]”.
Chatgpt (gpt4) 支持提示系统/用户 (gpt4 api) 将数据格式化为 csv。 通常工作完美。 虽然 gpt4 非常适合制作演示原型,但它相当昂贵,因此本地解决方案将是完美的。
有许多提示工程框架可以限制 json 格式的输出,请参阅此处的一个用于 LLM 输出的严格 JSON 框架。
虽然提示工程对于某些用例可能是有效的,但它有一个局限性—LLM所做的任何内部更改都可能导致意外的输出。 众所周知,这会在生产环境中引起问题,正如在线故事中所见,依赖 ChatGPT API 的 AI 应用程序由于不断的后台更新而失败。

3、约束LLM输出

这一领域已经有大量的创新工作,我有机会探索三个框架,它们都从不同的角度解决了这个问题。 尽管使用不同的方法,但每个框架如何达到相似的结果给我留下了深刻的印象。
  • GRAMMAR — 约束模型输出的语法。 例如,你可以强制模型仅输出 JSON:
  • KOR — 这是一个半成品原型,可以“帮助”你使用LLM从文本中提取结构化数据
  • LM-Format-Enforcer — 强制语言模型的输出格式(JSON Schema、Regex 等)
  • Finetune LLM 模型 — 教导模型根据输入数据输出 JSON

3.1 使用语法规则强制模型仅输出 JSON

在这种方法中,你需要使用 Llama.cpp 来运行模型并创建语法文件。 GBNF (GGML BNF) 是一种用于定义形式语法以约束 llama.cpp 中模型输出的格式。
这是我为基本测试创建的一个简单语法文件:
它更难理解,但是,可以从更容易理解的模式定义开始。 如下所示:
接下来将模式粘贴到这个在线工具以自动生成语法文件 - 省去很多麻烦。
现在,我们有了一个语法文件并准备好插入 Llama.cpp。 有关在你的计算机上本地运行的设置的更多详细信息,请参阅存储库。
搞定! 结果是合法的 json对象 {"id":1,"name":"Mercury"}
因此,语法可以灵活地创建复杂的对象。 这是我第二次尝试创建收据模式和语法文件。
对此收据生成的语法文件:
然后运行 llama.cpp:
输出结果:
到目前为止,语法可以控制输出始终生成 JSON 作为输出—看起来很有前途的解决方案。 请参阅我的存储库,了解我为此测试创建的架构和语法文件。

3.2 KOR — 使用LLM提取文本中的结构化数据

关于一些可以用 Kor 完成的事情的想法。
  • 从与提取模式匹配的文本中提取数据。
  • 通过精确理解用户请求,为人工智能助手提供技能。
  • 提供对现有 API 的自然语言访问。
请参阅此处的存储库链接,了解我为此测试创建的测试笔记本。
对于此测试,我将使用开源 LLama-2 模型,因为我们都喜欢节省不使用 ChatGPT api 的成本。
示例 1:模式和链 — 输出单个 Json 对象
结果看起来不错,与单个对象的架构定义匹配。 KOR 还支持更流行的 pydantic 模式定义。 这是创建 json 对象列表的第二个示例。
示例 2:Pydantic Schema — Json 对象的输出列表
嗯,结果与我对 json 对象列表的预期不符。 需要更多调查。 鉴于原始数据确实得出了正确的值。

3.3 LM-Format-Enforcer — 强制LLM的输出格式

LM-Format-Enforcer可以强制LLM的输出格式,例如JSON、Regex等,这是一个看起来很有希望成为最好的框架。 根据文档,框架根据架构设计操纵令牌的输出来生成 json。
请参阅我为此测试创建的笔记本。 与 KOR 测试类似,我将继续使用开源 LLama-2 模型,因为它受到框架的支持。
对于令牌的输出操作,它与 LLM 推理框架紧密耦合。 对于 Llama.cpp,它需要创建一个 LogitProcessor。 参见下面的代码:
现在,我们要运行一个简单的测试来返回单个 json 对象
所以,结果还不错,它包含一个json对象。 但是,对于要使用此输出的应用程序,它仍然需要额外的解析工作来删除不需要的文本。 所以这个框架正是在输出中保留不需要的文本—只返回一个 json 对象。
不错,干得好!
接下来,让我们测试一下json对象列表的生成,首先从标准LLM输出开始:
现在,让我们加入 LLM 输出强制以及一个简单的模式。
很棒的结果是我们在模式中定义的 json 对象列表。

3.4 微调LLM

请参阅我之前的文章,了解我尝试通过微调 LLM从OCR数据输出JSON格式作为输入以及使用图像作为输入,在这两种情况下,结果都很好。

4、结束语

虽然没有一种万能的解决方案,但对完美方法的探索仍在继续。 这些令人惊叹的框架是针对特定用例量身定制的,我发现对输出施加限制比即时工程产生更好的结果。
训练我自己的本地模型可以让我更好地控制输出,并且在使用模型之前测试模型非常重要,因为每个模型的输出可能会有所不同,并且生成 JSON 对象列表对于LLM来说可能具有挑战性。
Loading...