提升大语言模型应用能力:Outlines结构化文本生成库

综合介绍

Outlines 是由 dottxt-ai 开发的开源库,致力于通过结构化文本生成来增强大语言模型(LLM)的应用能力。该库支持多种模型集成,包括 OpenAI、transformers、llama.cpp 等,提供简单但强大的提示原语,基于 Jinja 模板引擎。Outlines 允许用户通过正则表达式、JSON 模式或 Pydantic 模型快速生成,并支持多种采样算法,如贪婪算法、多项式采样和束搜索。该项目还提供了缓存生成和批量推理等功能,旨在提高模型的推理速度和性能。Outlines 已被主流推理框架(如 VLLM、TGI)用于函数调用。

Outlines:通过正则表达式、JSON或Pydantic模型生成结构化文本输出-1


(adsbygoogle=window.adsbygoogle||[]).push({});

 

功能列表

  • 多模型集成:支持 OpenAI、transformers、llama.cpp 等模型
  • 简单但强大的提示原语:基于 Jinja 模板引擎
  • 正则表达式结构生成:快速生成符合正则表达式的文本
  • JSON 生成:根据 JSON 模式或 Pydantic 模型生成文本
  • 语法结构生成:支持循环、条件和自定义 Python 函数的生成
  • 生成缓存:缓存生成结果,提高效率
  • 批量推理:支持批量处理,提高推理速度
  • 多种采样算法:支持贪婪、多项式和束搜索等采样算法
  • Docker 支持:提供官方 Docker 镜像,方便部署

 

使用帮助

安装流程

  1. 确保已安装 Python 环境。
  2. 使用 pip 安装 Outlines:
   pip install outlines
  1. 如果需要使用 Rust 版本的核心功能,可以安装 outlines-core:
   pip install outlines-core

使用指南

基本使用

  1. 导入 Outlines 库:
   import outlines
  1. 选择并加载模型:
   model = outlines.models.transformers("openai/gpt-3.5-turbo")
  1. 创建提示并生成文本:
   prompt = "生成一个关于AI技术的简短介绍。"
generated_text = model.generate(prompt)
print(generated_text)

高级功能

  1. 使用正则表达式生成结构化文本:
   import outlines
generator = outlines.generate.regex("^[A-Z][a-z]+$")
result = generator("生成一个符合正则表达式的单词")
print(result)
  1. 使用 JSON 模式生成文本:
   import outlines
from pydantic import BaseModel
class Person(BaseModel):
name: str
age: int
generator = outlines.generate.json(Person)
result = generator({"name": "Alice", "age": 30})
print(result)
  1. 使用多种采样算法:
   import outlines
generator = outlines.generate.choice(model, ["选项1", "选项2", "选项3"])
result = generator("请选择一个选项:")
print(result)
  1. 部署 Docker 镜像:
   docker pull outlinesdev/outlines
docker run -p 8000:8000 outlinesdev/outlines

常见问题

  • 如何提高生成速度? 使用批量推理和生成缓存功能可以显著提高生成速度。
  • 如何集成自定义函数? 可以在生成过程中使用自定义 Python 函数来处理复杂逻辑。

 

大模型的非结构化输出带来的问题

问题

大语言模型(LLM)具有强大的文本生成能力,但在生成结构化数据时表现不够可靠,给以 Agent 为核心的 AI 应用带来严重困扰。

核心问题

  • 输出不一致性:当从邮件中提取航班信息时,理想情况下应该输出一致的 JSON 对象,但 LLM 通常失败,导致出现 "JSON decode errors" 等问题。
  • 缺乏可靠性:这种不可预测性使得基于 LLM 构建复杂模块化系统变得困难。

影响

没有可靠的结构化输出,开发者需要通过繁琐的后处理(如正则表达式)提取信息,导致开发效率低下且易出错。

结构化输出的好处

数据的普遍结构性

即使是看似无结构的数据(如 GSM 数据集),也常常有内在的结构可利用。

保证输出格式

通过定义特定的结构(如 JSON 或正则表达式),可以保证输出的有效性,避免繁琐的后处理。

提升性能与效率

  • 提升 JSON 有效率:使用结构化生成后,JSON 有效率从 17.7% 提升至 99.9%。
  • 减少示例需求:在 GSM8K 基准测试中,一次性结构化生成的性能几乎与八次非结构化生成相当。
  • 提升开放模型性能:在函数调用基准测试中,性能从 86% 提升至 96.5%,甚至超越 GPT-4。

结构化输出与非结构化输出的对比

为了更好地理解结构化输出的优势,我们可以通过以下例子来对比结构化与非结构化输出的差异。

假设我们需要从一封电子邮件中提取航班信息:

非结构化输出

当大模型生成的输出没有严格的格式时,可能会得到如下文本:

飞往巴黎的航班在下周二,可能是早上10点,飞机是法国航空。

这个输出包含了我们需要的信息(目的地、日期、时间、航空公司等),但没有明确的结构。要提取信息,开发者需要使用正则表达式或其他方法解析每个字段,这既繁琐又容易出错。模型在不同输入中可能输出不同格式,导致系统出错或出现 "JSON decode errors"。

结构化输出

使用结构化生成,模型将返回预定义格式的数据,如:

{
  "destination": "巴黎",
  "departure_date": "2024-11-25",
  "time": "10:00",
  "airline": "法国航空"
}

输出是统一的、标准化的。开发者无需额外处理或解析信息,因为关键字段按预期格式返回。节省开发时间,减少错误的几率。

结构化输出保证了数据的一致性和可靠性,提高处理效率,特别是处理大量信息时。

 

使用 Outlines 会给大模型带来性能问题吗?

Outlines 是如何工作的?

基本原理

  • Logit 处理:生成 logits 后,Outlines 检查每个可能的下一个 token,屏蔽违反定义结构的 token。
  • 效率优化:通过高效的屏蔽实现极低的额外开销。

示例

"如果生成的 token 会破坏结构,则立即屏蔽,确保生成过程严格遵循预定义结构。"

结构化输出会减慢输出速度吗?

不会。结构化生成通常加速生成过程:

  • 减少无用 token:提前定义结构,避免生成多余字段名或括号。
  • 减少生成长度:结构化输出的 token 数通常更少,速度更快且更清晰。

Outlines 与其他结构化生成库的对比

  • 与 Guidance 比较:Outlines 在推理阶段开销几乎为零,而 Guidance 在生成大量 token 时可能减慢。
  • 与 LMQL 比较:Outlines 的优势在于轻量化设计和效率。

代码示例

以下是使用 Outlines 生成结构化事件数据的示例:

from datetime import datetime
from pydantic import BaseModel, Field
from outlines import generate, models

# 加载模型
model = models.mlxlm("mlx-community/Hermes-3-Llama-3.1-8B-8bit")

# 使用 Pydantic 定义事件结构
class Event(BaseModel):
    title: str = Field(description="title of the event")
    location: str
    start: datetime = Field(
        default=None, description="date of the event if available in iso format"
    )

# 获取当前时间
now = datetime.now().strftime("%A %d %B %Y and it's %H:%M")

# 定义提示
prompt = f"""
Today's date and time are {now}
Given a user message, extract information of the event like date and time in iso format, location and title.
If the given date is relative, think step by step to find the right date.
Here is the message:
"""

# 示例消息
message = """Hello Kitty, my grandmother will be here , I think it's better to postpone our
appointment to review math lessons to next Friday at 2pm at the same place, 3 avenue des tanneurs, I think that one hour will be enough
see you 😘 """

# 创建生成器
generator = generate.json(model, Event)

# 提取事件信息
event = generator(prompt + message)

# 输出结果
print(f"Today: {now}")
print(event.json())

生成的事件信息如下:

{
  "title": "Math Review",
  "location": "3 avenue des tanneurs",
  "start": "2024-11-22T14:00:00Z"
}

结论与展望

结构化生成不再仅是利基功能,而是大模型应用的未来:

  • 更高的可靠性与效率:通过结构化生成,LLM 的性能得到显著提升。
  • 开源的潜力:Outlines 的成功证明了开源模型在与专有模型竞争中的潜力。

未来,随着结构化生成的普及,Outlines 有望成为开发者工具箱中的关键组件。

相关推荐

CommandR7B发布:高效企业级大语言模型,优化性能与速度

Command R7B是Cohere推出的最新大语言模型,结合高效的速度、成本效益和出色的上下文处理能力,适用于低端GPU和边缘设备。该模型在数学、推理和代码任务中表现出色,支持多语言和富有竞争力的工具使用能力,尤其适合企业级AI应用,降低生产成本并提升效率。可通过Cohere Platform和HuggingFace访问。

暂无评论

发表评论