采用 guidance 提高大模型输出的可靠性和稳定性

本文首发于博客 LLM 应用开发实践

在复杂的 LLM 应用开发中,特别涉及流程编排和多次 LLM 调用时,每次的 Prompt 设计都取决于前一个步骤的大模型输出。如何避免大语言模型的"胡说八道",以提高大语言模型输出的可靠性和稳定性,成为一个具有挑战性的问题。在开发应用的过程中,我发现了微软推出的开源项目 guidance,能够很好地解决这一繁琐问题,本篇文章对此进行详细说明。

场景说明

首先分享下实际遇到的问题,我在做一个科普类视频内容纠正小工具,大概流程就是从视频中提取关键概念,并调用维基百科进行交叉验证:

  1. 解析科普视频字幕内容
  2. 让 LLM 分析是否存在错误科普片段
  3. 从错误科普片段上下文中提取相关概念
  4. 调用维基百科做纠正
  5. 生成一篇纠正性文章

下面是我一部分的 Prompt(提示词)设计示例:

Please act as an encyclopaedic expert covering the fields of physics, mathematics, chemistry and biology. The captioned content of a science video will be provided below. Please ensure that you fully understand the content of the video and then correct any scientific errors in it from a professional point of view. The content of the subtoc: true
titles of the video to be analysed is as follows:```{context}```
Your return must be in the specified json format, with the special character backslash \ escaped, always make sure that the json format cannot be wrong, and the content must be in English, like the following:
{"Misconception 1": "Relevant context error content 1","Misconception 2": "Relevant context error content 1",...
}

针对语言模型返回的内容,首先进行 json 解析,如果出错,再次请求(重复 3 次);如果解析正常,转换为字典进行遍历,将维基百科搜索的内容结合错误片段组成 Prompt,让大语言模型生成一篇纠正性文章。

发现问题

即使在 Prompt 中强调了语言模型返回 json 格式,但是实际调用过程中还会有 20 %的概率返回的不是 json 格式,只能通过重试规避,但是重试会再次大量消耗 token,肯定不是一个可行的方案。所以我在想是否可以做一个类似的工具,将上述过程(检查返回结果+生成错误信息)进行封装,且发生错误时只将解析错误的部分内容告知 LLM(节省 token),进行下一次的生成,不断重复直到符合要求,然后发现了 guidance,完美契合了我的需求,这篇文章将详细介绍这个工具。

guidance

guidance 是一个 Python 库,相比提示词方式或链式调用方式,可以更有效地控制和利用大型语言模型(如 GPT、BART 等)。 简单直观的语法,基于 Handlebars 模板,丰富的输出结构,具有函数调用、逻辑判断、控制流等功能,它的主要作用和优点包括:

  1. 简化输出结构设计
  • 通过模板语法可以设计各种输出结构逻辑:

    {{#if}}...{{else}}...{{/if}}
    {{#each}}...{{/each}}
    
  • 插入生成文本(遇到 gen 关键字,请求 LLM,获得响应后,继续解析语法树):

    {{gen "变量名"}}
    
  • 选择最佳选项:

    {{#select "变量名"}}选项1{{or}}选项2{{/select}}
    
  1. 推理加速

    与单次生成相比,guidance 可以自动把已经生成过的结果缓存起来,提升速度。

  2. 支持聊天对话

    {{#user}}...{{/user}}
    {{#assistant}}...{{/assistant}}
    
  1. 保证特定语法格式

    guidance 可以通过正则表达式指导语言模型生成保证语法正确的文本,例如生成 JSON 对象:

    {
    "name": "{{gen "name"}}",
    "age": "{{gen "age"}}"
    }
    
  2. 消除 token 边界效应

    所谓 token 边界效应会导致语言模型在生成文本时产生非预期的停止,guidance 通过一种叫“token healing”的方法可以消除这种效应,使用{{gen token_healing=True}}即可开启。

  3. 集成 Transformer

    from guidance.llms import Transformersllm = Transformers("gpt2")
    guidance(llm=llm)
    

实时流式传输

guidance 具有明确定义的线性执行顺序,该顺序直接对应于大语言模型处理 token 的顺序。在执行过程中的任何时候,大语言模型都可用于生成文本(当调用到{{gen}}命令时,便会触发 LLM 的生成操作)或做出逻辑控制流决策,允许进行精确的输出结构设计,从而产生清晰可解析的结果。

import guidance
guidance.llm = guidance.llms.OpenAI("text-davinci-003")program = guidance("""Tweak this proverb to apply to model instructions instead.{{proverb}}
- {{book}} {{chapter}}:{{verse}}UPDATED
Where there is no guidance{{gen 'rewrite' stop="\\n-"}}
- GPT {{#select 'chapter'}}9{{or}}10{{or}}11{{/select}}:{{gen 'verse'}}""")executed_program = program(proverb="Where there is no guidance, a people falls,\nbut in an abundance of counselors there is safety.",book="Proverbs",chapter=11,verse=14
)

实时流式传输

程序执行后,所有生成的变量都可以轻松访问:

>> executed_program["rewrite"]
>> ', a model fails,\nbut in an abundance of instructions there is safety.'

聊天对话模式

通过基于角色标记(如 {{#system}}...{{/system}} )的统一 API,guidance 支持 GPT-4 等基于 API 的聊天模型,以及 Vicuna 等开源聊天模型。

gpt4 = guidance.llms.OpenAI("gpt-4")
# vicuna = guidance.llms.transformers.Vicuna("your_path/vicuna_13B", device_map="auto")
experts = guidance('''
{{#system~}}
You are a helpful and terse assistant.
{{~/system}}{{#user~}}
I want a response to the following question:
{{query}}
Name 3 world-class experts (past or present) who would be great at answering this?
Don't answer the question yet.
{{~/user}}{{#assistant~}}
{{gen 'expert_names' temperature=0 max_tokens=300}}
{{~/assistant}}{{#user~}}
Great, now please answer the question as if these experts had collaborated in writing a joint anonymous answer.
{{~/user}}{{#assistant~}}
{{gen 'answer' temperature=0 max_tokens=500}}
{{~/assistant}}
''', llm=gpt4)experts(query='How can I be more productive?')

聊天对话模式

加速推理

# we use LLaMA here, but any GPT-style model will do
llama = guidance.llms.Transformers("your_path/llama-7b", device=0)# we can pre-define valid option sets
valid_weapons = ["sword", "axe", "mace", "spear", "bow", "crossbow"]# define the prompt
character_maker = guidance("""The following is a character profile for an RPG game in JSON format.
```json
{"id": "{{id}}","description": "{{description}}","name": "{{gen 'name'}}","age": {{gen 'age' pattern='[0-9]+' stop=','}},"armor": "{{#select 'armor'}}leather{{or}}chainmail{{or}}plate{{/select}}","weapon": "{{select 'weapon' options=valid_weapons}}","class": "{{gen 'class'}}","mantra": "{{gen 'mantra' temperature=0.7}}","strength": {{gen 'strength' pattern='[0-9]+' stop=','}},"items": [{{#geneach 'items' num_iterations=5 join=', '}}"{{gen 'this' temperature=0.7}}"{{/geneach}}]
}```""")# generate a character
character_maker(id="e1f491f7-7ab8-4dac-8c20-c92b5e7d883d",description="A quick and nimble fighter.",valid_weapons=valid_weapons,llm=llama
)

img

按照我之前的做法整个 json 都需要由 LLM 来生成,guidance 的思路是,既然 json 的结构是预先定义的,那么字段声明,花括号等等,其实都不需要 LLM 来生成。这个示例中,蓝色部分是传入的变量,只有绿色部分才是真正调用了 LLM 来生成的。这样一方面保证了生成的 json 结构可控,不会出现格式错误,字段缺失等,一方面通过 LLM 生成的 token 数量减少了,节省成本,加速推理。

回顾

guidance 本质上是一种用于处理大语言模型交互的领域特定语言 (DSL),和大语言模型查询语言一样,旨在降低 LLM 交互的成本。guidance 可以加快推理速度,又可以确保生成的 json 始终有效,有效的提高了 LLM (大语言模型)输出的可靠性和稳定性。

更多内容在公号:LLM 应用全栈开发

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/105256.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[python] pytest

在写一个项目前, 可以先编写测试模块 测试模块中包含了一个个最小的功能 当每一个功能都完善正确时 再将这些功能转换成项目运行的功能 多个项目运行的功能就组成了一个模块 多个模块就组成了一个项目服务 pytest 是一个 Python 测试框架,它提供了简单易用的语…

竞赛选题 深度学习YOLOv5车辆颜色识别检测 - python opencv

文章目录 1 前言2 实现效果3 CNN卷积神经网络4 Yolov56 数据集处理及模型训练5 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 **基于深度学习YOLOv5车辆颜色识别检测 ** 该项目较为新颖,适合作为竞赛课题方向&#xff0…

React如何优化减少组件间的重新Render

目前写了不少React的项目,发现React有些特点更灵活和注重细节,很多东西需要有一定的内功才能掌握好;比如在项目中常常遇到的组件重复渲染,有时候组件重复渲染如果内容是纯文本,不打印日志就不容易发现重复渲染了&#…

AtCoder ABC239G 最小割集

题意 传送门 AtCoder ABC239G Builder Takahashi 题解 将原图中每个节点拆为入点 v v v 与出点 v ′ v v′,对于原图任一边 ( u , v ) (u,v) (u,v) 则 u ′ → v , v → u u\rightarrow v, v\rightarrow u u′→v,v→u 连一条容量为 ∞ \infty ∞ 的边&…

关于小编入坑第512天

​机缘 最初成为创作者的初心:总结记录整个学习前端的历程 日常学习过程中的记录: 先思考,整个程序逻辑流程是否出现问题 再文档,根据相关文档了解源头,学会看懂文档,是一个锻炼自学前端能力的关键一步 …

每日一题 136. 只出现一次的数字(简单,位运算)

异或运算性质,两个相等的数作异或运算得零,任何数与零作异或运算保持不变 所以整个数组的异或和就是答案 class Solution:def singleNumber(self, nums: List[int]) -> int:ans 0for i in nums:ans ^ ireturn ans一行代码,reduce作累积操…

RustDay04------Exercise[11-20]

11.函数原型有参数时需要填写对应参数进行调用 这里原先call_me函数没有填写参数导致报错 添加一个usize即可 // functions3.rs // Execute rustlings hint functions3 or use the hint watch subcommand for a hint.fn main() {call_me(10); }fn call_me(num: u32) {for i i…

亚马逊测评安全吗?

测评可以说是卖家非常宝贵的财富,通过测评和广告相结合,可以快速有效的提升店铺的产品销量,提高转化,提升listing权重,但现在很多卖家找真人测评补单后店铺出现问题导致大家对测评的安全性感到担忧,因为真人…

List 模拟实现

前言 本文将会向你介绍如何模拟实现list、iterator迭代器 模拟实现 引入 迭代器是一种用于访问容器中元素的对象,它封装了对容器中元素的访问方式。迭代器提供了一组操作接口,可以让我们通过迭代器对象来遍历容器中的元素。(iterator迭代器…

Lua调用C#类

先创建一个Main脚本作为主入口,挂载到摄像机上 public class Main : MonoBehaviour {// Start is called before the first frame updatevoid Start(){LuaMgr.GetInstance().Init();LuaMgr.GetInstance().DoLuaFile("Main");}// Update is called once p…

【WebRTC---源码篇】(十:零)WEBRTC/StreamStatisticianImpl持续更新中)

StreamStatisticianImpl是WebRTC的一个内部实现类,用于统计和管理媒体流的各种统计信息。 StreamStatisticianImpl负责记录和计算以下统计数据: 1. 带宽统计:记录媒体流的发送和接收带宽信息,包括发送比特率、接收比特率、发送丢…

关于SpringBoot2.x集成SpringSecurity+JJWT(0.7.0-->0.11.5)生成Token登录鉴权的问题

项目场景: 问题:遵循版本稳定的前提下,搭建权限认证框架,基于SpringBoot2.xSpringSecurity向上依赖jjwt0.7.0构建用户认证鉴权,起因是某L觉得jjwt0.7.0版本,官方已经放弃维护,且从maven仓库对0…

CocosCreator 面试题(十二)Cocos Creator Label 的原理以及如何减少Drawcall

在Cocos Creator中,Label是用于显示文本的组件。它的原理是通过将文本渲染到纹理上,并将纹理贴图显示在屏幕上来实现。 一、Label组件的工作原理 字体加载:首先,Label组件需要加载所需的字体文件。可以通过在编辑器中设置字体资源…

python二次开发CATIA:测量曲线长度

以下代码是使用Python语言通过win32com库来控制CATIA应用程序的一个示例。主要步骤包括创建一个新的Part文件,然后在其中创建一个新的几何图形集,并在这个集合中创建一个样条线。这个样条线是通过一组给定的坐标点来创建的,这些点被添加到集合…

【SQL】NodeJs 连接 MySql 、MySql 常见语句

1.安装 mysql npm install mysql 2.引入MySql import mysql from mysql 3.连接MySql const connection mysql.createConnection({host: yourServerip,user: yourUsername,password: yourPassword,database: yourDatabase })connection.connect(err > {if (err) {console…

SpringCloud-Config

一、介绍 (1)服务注册中心 (2)管理各个服务上的application.yml,支持动态修改,但不会影响客户端配置 (3)一般将application.yml文件放在git上,客户端通过http/https方式…

MyLife - Docker安装rabbitmq

Docker安装rabbitmq 个人觉得像rabbitmq之类的基础设施在线上环境直接物理机安装使用可能会好些。但是在开发测试环境用docker容器还是比较方便的。这里学习下docker安装rabbitmq使用。 1. rabbitmq 镜像库地址 rabbitmq 镜像库地址:https://hub.docker.com/_/rabbi…

介绍一款小巧的Excel比对工具-DiffExcel

【缘起:此前找了一通,没有找到免费又好用的Excel比对工具,而ExcelBDD需要把Excel文件存放到Git,因此迫切需要Excel比对工具。 最新升级到V1.3.3,因为git diff有变化,原来是git diff会修改文件名&#xff0…

Compose 组件 - 分页器 HorizontalPager、VerticalPager

一、概念 类似于 ViewPager,1.4 版本之前需要借助 accompanis 库,底层基于 LazyColumn、LazyRow 实现,在使用上也基本相同。默认情况下 HorizontalPager 占据屏幕的整个宽度,VerticalPager 会占据整个高度。 fun HorizontalPager(…

xshell使用方法(超详细)

一、安装 下载最新版安装即可,不需要做任何配置。 安装完成后输入账号名和邮箱,确认后邮箱会收到一条确认邮件,将里面的链接点开即可免费使用(仅安装后会出现,认证后以后再打开不需要重复操作,如果重新安…