跳到内容

命名实体提取

命名实体提取是自然语言处理(NLP)中的一个基本问题。它涉及识别文档中的命名实体并对其进行分类:人物、组织、日期、地点等。它通常是更复杂的自然语言处理工作流程中的第一步。这里我们将使用一个披萨餐厅的例子,该餐厅通过网站接收订单,需要识别订购披萨的数量和类型。

让大型语言模型(LLMs)以结构化格式输出提取的实体可能具有挑战性。在本教程中,我们将看到如何使用 Outlines 的 JSON 结构化生成功能从文档中提取实体,并百分之百地将它们以有效的 JSON 数据结构返回。

像往常一样,我们从初始化模型开始。我们将使用 Mistral-7B-v0.1 的量化版本(我们 GPU 资源不足)

import outlines

model = outlines.models.transformers("TheBloke/Mistral-7B-OpenOrca-AWQ", device="cuda")

我们将使用以下提示模板

from outlines import Template


take_order = Template.from_string(
    """You are the owner of a pizza parlor. Customers \
    send you orders from which you need to extract:

    1. The pizza that is ordered
    2. The number of pizzas

    # EXAMPLE

    ORDER: I would like one Margherita pizza
    RESULT: {"pizza": "Margherita", "number": 1}

    # OUTPUT INSTRUCTIONS

    Answer in valid JSON. Here are the different objects relevant for the output:

    Order:
        pizza (str): name of the pizza
        number (int): number of pizzas

    Return a valid JSON of type "Order"

    # OUTPUT

    ORDER: {{ order }}
    RESULT: """
)

我们现在使用 Pydantic 定义我们的数据模型

from enum import Enum
from pydantic import BaseModel

class Pizza(str, Enum):
    margherita = "Margherita"
    pepperonni = "Pepperoni"
    calzone = "Calzone"

class Order(BaseModel):
    pizza: Pizza
    number: int

我们现在可以定义我们的生成器,并在几个传入订单上调用它

orders = [
    "Hi! I would like to order two pepperonni pizzas and would like them in 30mins.",
    "Is it possible to get 12 margheritas?"
]
prompts = [take_order(order) for order in orders]

generator = outlines.generate.json(model, Order)

results = generator(prompts)
print(results)
# [Order(pizza=<Pizza.pepperonni: 'Pepperoni'>, number=2),
#  Order(pizza=<Pizza.margherita: 'Margherita'>, number=12)]

有几种方法可以改进此示例

  • 客户可能会订购几种不同类型的披萨。
  • 客户也可能订购饮料。
  • 如果这家披萨店提供送餐服务,我们需要提取客户的地址和电话号码
  • 客户可能会指定他们想要披萨的时间。然后我们可以对照排队系统进行检查,并回复他们预计的送达时间。

您会如何修改 Pydantic 模型来考虑这些用例?