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

2023-10-14 21:28

本文主要是介绍采用 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 应用全栈开发

这篇关于采用 guidance 提高大模型输出的可靠性和稳定性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/213256

相关文章

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

python多种数据类型输出为Excel文件

《python多种数据类型输出为Excel文件》本文主要介绍了将Python中的列表、元组、字典和集合等数据类型输出到Excel文件中,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录一.列表List二.字典dict三.集合set四.元组tuplepython中的列表、元组、字典

Spring AI集成DeepSeek实现流式输出的操作方法

《SpringAI集成DeepSeek实现流式输出的操作方法》本文介绍了如何在SpringBoot中使用Sse(Server-SentEvents)技术实现流式输出,后端使用SpringMVC中的S... 目录一、后端代码二、前端代码三、运行项目小天有话说题外话参考资料前面一篇文章我们实现了《Spring

C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)

《C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)》本文主要介绍了C#集成DeepSeek模型实现AI私有化的方法,包括搭建基础环境,如安装Ollama和下载DeepS... 目录前言搭建基础环境1、安装 Ollama2、下载 DeepSeek R1 模型客户端 ChatBo

SpringBoot快速接入OpenAI大模型的方法(JDK8)

《SpringBoot快速接入OpenAI大模型的方法(JDK8)》本文介绍了如何使用AI4J快速接入OpenAI大模型,并展示了如何实现流式与非流式的输出,以及对函数调用的使用,AI4J支持JDK8... 目录使用AI4J快速接入OpenAI大模型介绍AI4J-github快速使用创建SpringBoot

Rust格式化输出方式总结

《Rust格式化输出方式总结》Rust提供了强大的格式化输出功能,通过std::fmt模块和相关的宏来实现,主要的输出宏包括println!和format!,它们支持多种格式化占位符,如{}、{:?}... 目录Rust格式化输出方式基本的格式化输出格式化占位符Format 特性总结Rust格式化输出方式

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll