使用 Cerebras 推理引入结构化输出
Cerebras 是什么?
Cerebras 提供市场上最快的推理,比 GPU 快 20 倍。
在此注册 Cerebras 推理 API 密钥:cloud.cerebras.ai。
基本用法
要使用 Cerebras 推理获得保证的结构化输出,你
Cerebras 提供市场上最快的推理,比 GPU 快 20 倍。
在此注册 Cerebras 推理 API 密钥:cloud.cerebras.ai。
要使用 Cerebras 推理获得保证的结构化输出,你
OpenAI 最近推出了一项名为 API 模型蒸馏 的新功能,它允许开发者创建针对特定用例定制的自定义模型。当与 Instructor 的结构化输出能力结合使用时,此功能尤其强大。在本文中,我们将探讨如何利用 API 模型蒸馏和 Instructor 来创建更高效、更专业的模型。
使用错误的响应模型,你可能会损失高达 60% 的性能提升。响应模型对 Claude 和 GPT-4o 的模型性能影响巨大,无论你使用的是 JSON 模式还是工具调用。
使用正确的响应模型有助于确保你的模型以正确的语言响应,或在提取视频时间戳时防止幻觉。
我们决定通过在 GSM8k 数据集上对 Claude 和 GPT-4o 进行基准测试来调查此事,发现
final_choice
更改为 answer
使模型准确率从 4.5% 提高到 95%。我们在响应模型中组织和命名字段的方式可以从根本上改变模型解释和响应查询的方式。reasoning
字段使模型在 GSM8k 数据集上的准确率提高了 60%。模型在逐步解释其逻辑时表现更好。Anthropic 的 上下文检索 技术通过保留关键上下文来增强 RAG 系统。
本文探讨了该方法,并展示了使用异步处理的高效实现。我们将基于我们的异步处理指南中的概念,探讨如何利用这种方法优化你的 RAG 应用。
Gemini 可以理解语言模型输出中的时间戳,但它们可能不一致。视频内容时间戳在 HH:MM:SS 和 MM:SS 格式之间变化,导致解析错误和计算问题。本文提出了一种处理剪辑和电影时间戳的技术,避免格式问题。
我们结合了 Pydantic 的数据验证和自定义解析,以实现一致的时间戳处理。你将学习处理任何格式的时间戳,减少视频内容工作流程中的错误。这有点像我们通过添加一个简单字段来确保多语言摘要中的语言匹配。
本文提供了一个使用 Pydantic 的解决方案,以改进语言模型项目中时间戳的处理。此方法解决了格式不一致问题,并支持时间戳处理。
作为 Instructor 的创建者,我一直致力于保持产品开发流程化,避免不必要的复杂性。然而,我现在确信是时候在我们的数据结构中加入更好的模板功能了,特别是集成 Jinja。
这个决定有多个目的
这改进了块生成、少样本学习和动态规则。
验证
Pydantic 的验证上下文允许在验证函数中访问模板变量。
版本控制和日志记录
通过将 Jinja 集成到 Instructor 中,我们不仅仅是添加一个功能;我们正在增强处理复杂格式化、改进验证流程以及简化版本控制和日志记录的能力。这一新增功能将显著提升 Instructor 的能力和灵活性,使其成为用户更强大的工具。
在 Instructor 中,我们建议在我们的创建方法中实现一个新的 context
关键字。此新增功能将允许用户使用提供的上下文渲染提示,利用 Jinja 的模板功能。以下是其工作原理
context
字典传递给创建方法。content
字段中定义。这种方法提供以下好处
让我们看一个例子来说明此功能
client.create(
model="gpt-4o",
messages=[
{
"role": "user",
"content": """
You are a {{ role }} tasks with the following question
<question>
{{ question }}
</question>
Use the following context to answer the question, make sure to return [id] for every citation:
<context>
{% for chunk in context %}
<context_chunk>
<id>{{ chunk.id }}</id>
<text>{{ chunk.text }}</text>
</context_chunk>
{% endfor %}
</context>
{% if rules %}
Make sure to follow these rules:
{% for rule in rules %}
* {{ rule }}
{% endfor %}
{% endif %}
""",
},
],
context={
"role": "professional educator",
"question": "What is the capital of France?",
"context": [
{"id": 1, "text": "Paris is the capital of France."},
{"id": 2, "text": "France is a country in Europe."},
],
"rules": ["Use markdown."],
},
)
让我们考虑一种从文本中编辑词语的场景。通过使用 ValidationInfo
访问上下文并将其传递给验证器和模板,我们可以实现一个处理敏感信息的系统。这种方法使我们能够
以下是使用 Pydantic 验证器演示此概念的示例
from pydantic import BaseModel, ValidationInfo, field_validator
class Response(BaseModel):
text: str
@field_validator('text')
@classmethod
def no_banned_words(cls, v: str, info: ValidationInfo):
context = info.context
if context:
banned_words = context.get('banned_words', set())
banned_words_found = [word for word in banned_words if word.lower() in v.lower()]
if banned_words_found:
raise ValueError(f"Banned words found in text: {', '.join(banned_words_found)}, rewrite it but just without the banned words")
return v
@field_validator('text')
@classmethod
def redact_regex(cls, v: str, info: ValidationInfo):
context = info.context
if context:
redact_patterns = context.get('redact_patterns', [])
for pattern in redact_patterns:
v = re.sub(pattern, '****', v)
return v
response = client.create(
model="gpt-4o",
response_model=Response,
messages=[
{
"role": "user",
"content": """
Write about a {{ topic }}
{% if banned_words %}
You must not use the following banned words:
<banned_words>
{% for word in banned_words %}
* {{ word }}
{% endfor %}
</banned_words>
{% endif %}
"""
},
],
context={
"topic": "jason and now his phone number is 123-456-7890"
"banned_words": ["jason"],
"redact_patterns": [
r"\b\d{3}[-.]?\d{3}[-.]?\d{4}\b", # Phone number pattern
r"\b\d{3}-\d{2}-\d{4}\b", # SSN pattern
],
},
max_retries=3,
)
print(response.text)
# > While i can't say his name anymore, his phone number is ****
通过将提示模板和变量分离,我们获得了几个优势
版本控制:我们现在可以对模板进行版本控制,并为给定的提示检索适当的模板。这有助于更好地管理模板历史记录、差异比对和比较。
增强的日志记录:这种分离有助于结构化日志记录,使得调试以及与各种日志接收器、数据库和 OpenTelemetry 等可观测性工具的集成更加容易。
安全性:变量中的敏感信息可以与模板分开处理,从而实现更好的访问控制和数据保护。
这种关注点分离符合软件设计的最佳实践,从而形成一个更易于维护、可扩展和稳健的系统,用于管理提示及其相关数据。
由于它们只是 Python 对象,我们可以使用 Pydantic 模型来验证上下文,并控制它们的渲染方式,这样即使是秘密信息也可以动态渲染!考虑使用密钥字符串将敏感信息传递给 LLM。
from pydantic import BaseModel, SecretStr
class UserContext(BaseModel):
name: str
address: SecretStr
class Address(BaseModel):
street: SecretStr
city: str
state: str
zipcode: str
def normalize_address(address: Address):
context = UserContext(username="scolvin", address=address)
address = client.create(
model="gpt-4o",
messages=[
{
"role": "user",
"content": "{{ user.name }} is `{{ user.address.get_secret_value() }}`, normalize it to an address object",
},
],
context={"user": context},
)
print(context)
#> UserContext(username='jliu', address="******")
print(address)
#> Address(street='******', city="Toronto", state="Ontario", zipcode="M5A 0J3")
logger.info(
f"Normalized address: {address}",
extra={"user_context": context, "address": address},
)
return address
这种方法提供几个优势
开发者在使用大上下文时经常面临两个主要挑战——响应时间慢和成本高。当我们需要随着时间推移进行多次此类调用时,情况尤其如此,这严重影响了我们应用的成本和延迟。借助 Anthropic 新的提示缓存功能,我们可以轻松解决这两个问题。
由于新功能仍在测试阶段,我们将在其普遍可用后才将其集成到 instructor 中。在此期间,我们整理了一份关于如何在你的应用中使用此功能的快速入门指南。
一年前,我做了一个题为“Pydantic:你所需的一切”的演讲,这开启了我的 Twitter 生涯。今天,我重申那个信息,并分享过去一年在使用语言模型进行结构化输出方面学到的东西。
我们很高兴地宣布,instructor
现在支持使用工具调用对 Gemini SDK 和 VertexAI SDK 进行结构化输出。
特别鸣谢 Sonal 对 Gemini 工具调用支持的贡献。
让我们通过一个简单示例来了解如何使用这些新功能
开始之前,安装最新版本的 instructor
。根据你使用的是 Gemini 还是 VertexAI,你应该安装以下内容
这确保你拥有使用 Gemini 或 VertexAI SDK 与 instructor 所需的依赖项。
基于两个主要原因,我们推荐使用 Gemini SDK 而不是 VertexAI SDK。
GOOGLE_API_KEY
。另一方面,VertexAI SDK 需要一个 credentials.json 文件或 OAuth 集成才能使用。借助我们提供商无关的 API,你可以使用相同的接口与两个 SDK 交互,唯一改变的是我们如何初始化客户端本身。
在运行以下代码之前,你需要确保已在你的 shell 中将 Gemini API 密钥设置为别名 GOOGLE_API_KEY
。
import instructor
import google.generativeai as genai
from pydantic import BaseModel
class User(BaseModel):
name: str
age: int
client = instructor.from_gemini(
client=genai.GenerativeModel(
model_name="models/gemini-1.5-flash-latest", # (1)!
)
)
resp = client.chat.completions.create(
messages=[
{
"role": "user",
"content": "Extract Jason is 25 years old.",
}
],
response_model=User,
)
print(resp)
#> name='Jason' age=25
gemini-1.5-flash-latest
和 gemini-1.5-pro-latest
。我们可以使用 VertexAI SDK 实现类似的功能。为此,你需要对 VertexAI 进行身份验证。
此处有一些说明,但我发现最简单的方法是直接下载 GCloud CLI 并运行 gcloud auth application-default login
。
import instructor
import vertexai # type: ignore
from vertexai.generative_models import GenerativeModel # type: ignore
from pydantic import BaseModel
vertexai.init()
class User(BaseModel):
name: str
age: int
client = instructor.from_vertexai(
client=GenerativeModel("gemini-1.5-pro-preview-0409"), # (1)!
)
resp = client.chat.completions.create(
messages=[
{
"role": "user",
"content": "Extract Jason is 25 years old.",
}
],
response_model=User,
)
print(resp)
#> name='Jason' age=25
gemini-1.5-flash-latest
和 gemini-1.5-pro-latest
。OpenAI 最近宣布了结构化输出功能,可确保生成的响应匹配任何任意提供的 JSON Schema。在他们的公告文章中,他们承认该功能受到了 instructor
等库的启发。
如果你正在构建复杂的 LLM 工作流程,你很可能已经考虑将 OpenAI 的结构化输出作为 instructor
的潜在替代方案。
但在此之前,还有三个关键挑战
此外,采用结构化输出会将你锁定在 OpenAI 的生态系统中,限制你试验更适合特定用例的各种模型或提供商的能力。
这种供应商锁定增加了对提供商中断的脆弱性,可能导致应用程序停机和 SLA 违规,从而损害用户信任并影响你的商业声誉。
在本文中,我们将展示 instructor
如何通过验证失败时的自动重新请求、对经验证流式数据的自动支持等功能来解决其中许多挑战。