模块
一个DSPy模块是使用语言模型的程序构建块。
-
每个内置模块抽象化一种提示技术(如思维链或ReAct)。关键的是,它们被通用化以处理任何签名。
-
一个DSPy模块具有可学习参数(即构成提示和语言模型权重的小片段),并且可以被调用(调用)以处理输入并返回输出。
-
多个模块可以组合成更大的模块(程序)。DSPy模块直接受到PyTorch中神经网络模块的启发,但应用于语言模型程序。
如何使用内置模块,比如 dspy.Predict
或 dspy.ChainOfThought
?
让我们从最基础的模块开始,dspy.Predict
。在内部,所有其他DSPy模块都是使用dspy.Predict
构建的。我们假设你已经至少对DSPy签名有了一些了解,这些是用于定义我们在DSPy中使用的任何模块行为的声明式规范。
要使用一个模块,我们首先通过赋予它一个签名来声明它。然后我们用输入参数调用该模块,并提取输出字段!
sentence = "it's a charming and often affecting journey." # SST-2数据集中的示例。
# 1) 使用签名声明。
classify = dspy.Predict('sentence -> sentiment: bool')
# 2) 使用输入参数调用。
response = classify(sentence=sentence)
# 3) 访问输出。
print(response.sentiment)
当我们声明一个模块时,可以向它传递配置键。
下面,我们将传递 n=5
来请求五个补全。我们也可以传递 temperature
或 max_len
等参数。
让我们使用dspy.ChainOfThought
。在许多情况下,只需将dspy.ChainOfThought
替换dspy.Predict
就能提高质量。
question = "关于ColBERT检索模型有什么优点?"
# 1) 使用签名声明,并传递一些配置。
classify = dspy.ChainOfThought('question -> answer', n=5)
# 2) 使用输入参数调用。
response = classify(question=question)
# 3) 访问输出结果。
response.completions.answer
['ColBERT检索模型的一大优点是与其他模型相比具有更高的效率和效果。',
'它能够从大型文档集合中高效检索相关信息。',
'ColBERT检索模型的一大优点是与其他模型相比具有更优越的性能,并且有效利用了预训练语言模型。',
'ColBERT检索模型的一大优点是与其他模型相比具有更高的效率和准确性。',
'ColBERT检索模型的一大优点是能够整合用户反馈并支持复杂查询。']
让我们在这里讨论输出对象。dspy.ChainOfThought
模块通常会在你的签名输出字段前注入一个reasoning
。
让我们检查(第一个)推理和答案!
可能的输出:推理过程: 我们可以考虑到ColBERT在效率和效果方面已证明优于其他最先进的检索模型。它使用上下文嵌入并以既准确又可扩展的方式执行文档检索。
答案: ColBERT检索模型的一个很棒的特点是它相比其他模型具有卓越的效率和效果。
无论我们请求一个还是多个完成项,这都可以访问。
我们也可以将不同的补全结果作为Prediction
列表访问,或者作为多个列表访问,每个字段一个列表。
还有哪些其他DSPy模块?我该如何使用它们?
其他的都非常相似。它们主要改变实现你签名时的内部行为!
-
dspy.Predict
: 基础预测器。不修改签名。处理关键形式的学习(即存储指令和演示以及对LM的更新)。 -
dspy.ChainOfThought
: 教导语言模型在确定签名响应之前进行逐步思考。 -
dspy.ProgramOfThought
: 教导语言模型输出代码,其执行结果将决定响应内容。 -
dspy.ReAct
: 一个可以使用工具来实现给定签名的智能体。 -
dspy.MultiChainComparison
: 可以比较来自ChainOfThought
的多个输出,以生成最终预测。
我们还有一些函数式模块:
dspy.majority
: 可以进行基本投票,从一组预测中返回最受欢迎的响应。
DSPy 模块在简单任务上的几个示例。
配置好你的lm
后,尝试下面的示例。调整字段以探索你的语言模型开箱即用能胜任哪些任务。
可能输出:
可能的输出:
可能的输出:
可能的输出:
可能的输出:
如何将多个模块组合成一个更大的程序?
DSPy 只是使用模块的 Python 代码,你可以按任意控制流编写,内部在 compile
时使用一点魔法来追踪你的 LM 调用。这意味着你可以自由调用这些模块。
查看教程,如多跳搜索,其模块作为示例在下方重现。
然后你可以创建一个自定义模块类 Hop
的实例,然后通过 __call__
方法调用它:
hop = Hop()
print(hop(claim="Stephen Curry is the best 3 pointer shooter ever in the human history"))
如何追踪语言模型使用情况?
版本要求
LM 使用追踪功能在 DSPy 版本 2.6.16 及之后可用。
DSPy 提供内置的语言模型使用情况跟踪功能,适用于所有模块调用。要启用跟踪:
一旦启用,您可以从任何 dspy.Prediction
对象中访问使用统计信息:
使用数据以字典形式返回,将每个语言模型名称映射到其使用统计信息。以下是一个完整示例:
import dspy
# Configure DSPy with tracking enabled
dspy.settings.configure(
lm=dspy.LM("openai/gpt-4o-mini", cache=False),
track_usage=True
)
# Define a simple program that makes multiple LM calls
class MyProgram(dspy.Module):
def __init__(self):
self.predict1 = dspy.ChainOfThought("question -> answer")
self.predict2 = dspy.ChainOfThought("question, answer -> score")
def __call__(self, question: str) -> str:
answer = self.predict1(question=question)
score = self.predict2(question=question, answer=answer)
return score
# Run the program and check usage
program = MyProgram()
output = program(question="What is the capital of France?")
print(output.get_lm_usage())
这将输出使用统计信息,例如:
{
'openai/gpt-4o-mini': {
'completion_tokens': 61,
'prompt_tokens': 260,
'total_tokens': 321,
'completion_tokens_details': {
'accepted_prediction_tokens': 0,
'audio_tokens': 0,
'reasoning_tokens': 0,
'rejected_prediction_tokens': 0,
'text_tokens': None
},
'prompt_tokens_details': {
'audio_tokens': 0,
'cached_tokens': 0,
'text_tokens': None,
'image_tokens': None
}
}
}
使用DSPy的缓存功能时(无论是通过litellm在内存中还是磁盘上),缓存的响应不会计入使用统计。例如:
# Enable caching
dspy.settings.configure(
lm=dspy.LM("openai/gpt-4o-mini", cache=True),
track_usage=True
)
program = MyProgram()
# First call - will show usage statistics
output = program(question="What is the capital of Zambia?")
print(output.get_lm_usage()) # Shows token usage
# Second call - same question, will use cache
output = program(question="What is the capital of Zambia?")
print(output.get_lm_usage()) # Shows empty dict: {}