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

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

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

亚马逊测评安全吗?

测评可以说是卖家非常宝贵的财富,通过测评和广告相结合,可以快速有效的提升店铺的产品销量,提高转化,提升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…

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

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

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

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

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使用方法(超详细)

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

【MySQL】索引的作用及知识储备

为什么要有索引 索引可以提高数据库的性能。不用加内存,不用改程序,不用调sql,只要执行正确的create indix,查询的速度就可能提高成百上千倍。但相应的代价是,插入,更新,删除的速度有所减弱。 …

[论文分享] EnBinDiff: Identifying Data-Only Patches for Binaries

EnBinDiff: Identifying Data-Only Patches for Binaries [TDSC 2021] 在本文中,我们将重点介绍纯数据补丁,这是一种不会引起任何结构更改的特定类型的安全补丁。作为导致假阴性的最重要原因之一,纯数据补丁成为影响所有最先进的二进制差分方…

切换npm的版本

1、在配置环境变量的地址中,多准备几个已解压版本的node 2、要想升降版本直接更改该文件中的文件夹名称就行 环境变量中的path的值是不用变的C:\Program Files\nodejs

Ubuntu22安装Docker engine(apt安装方式)

一、准备工作 新创建一个虚拟机。 进入虚拟机: 二、安装docker docker现在对用不同主机提供了不同安装包:docker engine 和 docker desktop。 docker desktop适用于图形化的桌面电脑,docker engine适用于服务器。我们这里当然是安装docker…

SpringCloud-Gateway

一、介绍 (1)网关服务 (2)功能:断言、路由、过滤 (3)能避免用户直接访问到业务主机 二、项目搭建 a、编写pom.xml(注意移除web框架,gateway中自带有) &l…

7.定时器

定时器资源 CC2530有四个定时器TIM1~TIM4和休眠定时器 TIM1 定时器1 是一个独立的16 位定时器,支持典型的定时/计数功能,比如输入捕获,输出比较和PWM 功能。定时器有五个独立的捕获/比较通道。每个通道定时器使用一个I/O 引脚。定时器用于…