此页面已过时,在 DSPy 2.5 和 2.6 版本中可能不完全准确
常见问题解答
DSPy适合我吗?DSPy与其他框架的对比
DSPy 的哲学理念和抽象方式与其他库和框架有显著不同,因此通常很容易判断 DSPy 是否适合您的用例。如果您是 NLP/AI 研究人员(或正在探索新流程或新任务的从业者),答案通常是肯定的 是。如果您是从事其他工作的从业者,请继续阅读。
DSPy 与提示词轻量封装(OpenAI API、MiniChain、基础模板)的对比 换句话说:为什么我不能直接用字符串模板编写提示词? 对于极其简单的场景,这种方式或许完全可行。(如果你熟悉神经网络,这就像用 Python 的 for 循环实现一个微型两层神经网络。勉强能用。)然而,当你需要更高品质(或可控成本)时,就需要迭代探索多阶段分解、改进提示词、数据自举、精细调优、检索增强,和/或使用更小(或更便宜,或本地)的模型。基于基础模型构建的真正表达能力在于这些组件之间的交互。但每次修改一个组件时,很可能破坏(或削弱)其他多个组件。DSPy 清晰抽象了(并高效优化了)这些交互中与实际系统设计无关的部分。它让你专注于设计模块级交互:用 10 到 20 行 DSPy 编写的同一程序,可轻松编译为针对 GPT-4 的多阶段指令、针对 Llama2-13b 的详细提示词,或针对 T5-base 的微调方案。哦,你也不再需要在项目核心维护冗长脆弱、模型特定的字符串了。
DSPy vs. 应用开发库如 LangChain, LlamaIndex LangChain 和 LlamaIndex 针对高层次应用开发;它们提供开箱即用的预制应用模块,可与您的数据或配置进行集成。如果您愿意使用通用、现成的提示来处理 PDF 问答或标准文本转 SQL,您将在这些库中找到丰富的生态系统。DSPy 内部不包含针对特定应用的手工制作的提示。相反,DSPy 引入了一小组更强大且通用的模块,可以在您的流水线中根据您的数据学习如何提示(或微调)您的语言模型。当您更改数据、调整程序的控制流或更改目标语言模型时,DSPy 编译器可以将您的程序映射为一组新的提示(或微调),这些提示专门针对此流水线进行了优化。因此,您可能会发现,DSPy 以最少的努力为您的任务获得最高质量的结果,前提是您愿意实现(或扩展)自己的简短程序。简而言之,DSPy 适用于需要轻量级但自动优化的编程模型的情况,而不是预定义提示和集成的库。如果您熟悉神经网络:这类似于 PyTorch(即代表DSPy)和 HuggingFace Transformers(即代表更高层次的库)之间的区别。
DSPy vs. 生成控制库(如Guidance、LMQL、RELM、Outlines) 这些都是令人兴奋的新库,用于控制语言模型的单个补全结果,例如,如果你想强制JSON输出模式或将采样约束到特定的正则表达式。这在许多场景中非常有用,但它通常侧重于对单个语言模型调用的低级结构化控制。它并不能确保你获得的JSON(或结构化输出)对于你的任务是正确或有用的。相比之下,DSPy 自动优化程序中的提示,使其与各种任务需求对齐,这也可能包括生成有效的结构化输出。也就是说,我们正在考虑允许DSPy中的Signatures来表达由这些库实现的正则表达式类约束。
基本用法
我应该如何为我的任务使用DSPy? 我们为此编写了一份八步指南。简而言之,使用DSPy是一个迭代过程。你首先定义你的任务和想要最大化的指标,并准备一些示例输入——通常不带标签(或者如果指标需要,仅对最终输出带标签)。然后,通过选择内置层(modules)来构建你的流水线,为每个层赋予一个signature(输入/输出规范),然后在你的Python代码中自由调用这些模块。最后,使用DSPy的optimizer将你的代码编译成高质量的指令、自动的少样本示例或更新你的LM权重。
如何将我的复杂提示转换为DSPy流水线? 请参考上述相同答案。
DSPy优化器调整什么? 或者说,编译实际上做了什么? 每个优化器都不同,但它们都通过更新提示或语言模型权重来最大化程序的度量指标。当前的DSPy optimizers 可以检查您的数据,通过程序模拟追踪来生成每个步骤的好/坏示例,根据过去的结果提出或改进每个步骤的指令,在自生成的示例上微调语言模型的权重,或者结合其中几种方法来提高质量或降低成本。我们很乐意合并探索更丰富空间的新优化器:您目前为提示工程、"合成数据"生成或自我改进所进行的大多数手动步骤,很可能可以泛化为作用于任意语言模型程序的DSPy优化器。
其他常见问题。我们欢迎提交PR来为这些问题添加正式解答。您可以在现有问题、教程或论文中找到所有或大部分问题的答案。
- 如何获取多个输出?
您可以指定多个输出字段。对于短格式签名,您可以在"->"指示符后列出多个逗号分隔的输出值(例如"inputs -> output1, output2")。对于长格式签名,您可以包含多个dspy.OutputField。
- 如何定义自己的指标?指标可以返回浮点数吗?
您可以将指标定义为简单的Python函数,这些函数处理模型生成并根据用户定义的需求进行评估。指标可以将现有数据(例如黄金标签)与模型预测进行比较,或者使用来自语言模型的验证反馈(例如LLMs-as-Judges)来评估输出的各个组成部分。指标可以返回bool、int和float类型的分数。查看官方Metrics文档以了解更多关于定义自定义指标和使用AI反馈和/或dspy程序进行高级评估的信息。
- 编译的成本有多高或者速度有多慢?
为了反映编译指标,我们重点展示一个实验以供参考,使用BootstrapFewShotWithRandomSearch优化器在gpt-3.5-turbo-1106模型上编译一个程序,涉及7个候选程序和10个线程。我们报告显示,编译该程序大约需要6分钟,进行3200次API调用,输入270万个令牌,输出15.6万个令牌,总成本为3美元(按当前OpenAI模型定价计算)。
编译DSPy optimizers自然会带来额外的语言模型调用,但我们通过最小化执行来证实这一开销,目标是最大化性能。这为提升较小模型的性能开辟了途径,即通过使用较大模型编译DSPy程序,在编译时学习增强行为,并在推理时将这种行为传播到被测试的较小模型。
部署或可重现性问题
- 如何保存我编译程序的检查点?
以下是一个保存/加载已编译模块的示例:
cot_compiled = teleprompter.compile(CoT(), trainset=trainset, valset=devset)
#Saving
cot_compiled.save('compiled_cot_gsm8k.json')
#Loading:
cot = CoT()
cot.load('compiled_cot_gsm8k.json')
- 如何导出用于部署?
导出DSPy程序只需如上所示保存它们!
- 如何搜索我自己的数据?
开源库如 RAGautouille 使你能够通过像ColBERT这样的高级检索模型搜索自己的数据,并配备嵌入和索引文档的工具。在开发你的DSPy程序时,可以自由集成这些库来创建可搜索的数据集!
- 如何关闭缓存?如何导出缓存?
从 v2.5 版本开始,你可以通过在 dspy.LM 中设置 cache 参数为 False 来关闭缓存:
您的本地缓存将被保存到全局环境目录 os.environ["DSP_CACHEDIR"] 或对于笔记本环境为 os.environ["DSP_NOTEBOOK_CACHEDIR"]。您通常可以将缓存目录设置为 os.path.join(repo_path, 'cache') 并从这里导出此缓存:
重要
DSP_CACHEDIR 负责旧客户端(包括 dspy.OpenAI、dspy.ColBERTv2 等),而 DSPY_CACHEDIR 负责新的 dspy.LM 客户端。
在AWS lambda部署中,您应该禁用DSP_*和DSPY_*。
高级用法
-
如何实现并行化? 您可以在编译和评估期间通过分别在DSPy
optimizers中或dspy.Evaluate实用函数内指定多线程设置来并行化DSPy程序。 -
如何冻结模块?
模块可以通过设置其._compiled属性为True来冻结,表示该模块已经过优化器编译,不应再调整其参数。这在优化器内部处理,例如dspy.BootstrapFewShot中,确保在教师传播引导过程中收集的少样本演示之前,学生程序已被冻结。
-
如何使用DSPy断言?
a) 如何向程序添加断言: - 定义约束条件:使用
dspy.Assert和/或dspy.Suggest在DSPy程序中定义约束条件。这些约束基于您想要强制执行的布尔验证检查,可以简单地使用Python函数来验证模型输出。 - 集成断言:将断言语句保持在模型生成之后(提示:跟随模块层之后)b) 如何激活断言: 1. 使用
assert_transform_module: - 使用assert_transform_module函数以及backtrack_handler来包装带有断言的DSPy模块。此函数会转换您的程序以包含内部断言回溯和重试逻辑,这些逻辑也可以自定义:program_with_assertions = assert_transform_module(ProgramWithAssertions(), backtrack_handler)2. 激活断言: - 直接在带有断言的DSPy程序上调用activate_assertions:program_with_assertions = ProgramWithAssertions().activate_assertions()注意:要正确使用断言,您必须通过上述任一方法激活包含
dspy.Assert或dspy.Suggest语句的DSPy程序。
错误
- 如何处理"上下文过长"错误?
如果你在DSPy中遇到"上下文过长"错误,很可能是因为你使用了DSPy优化器在提示中包含演示,这超出了你当前的上下文窗口限制。尝试减少这些参数(例如max_bootstrapped_demos和max_labeled_demos)。此外,你也可以减少检索到的段落/文档/嵌入数量,以确保你的提示能够适应模型的上下文长度限制。
一个更通用的修复方法是简单地增加指定给LM请求的max_tokens数量(例如lm = dspy.OpenAI(model = ..., max_tokens = ...)。
设置详细级别
DSPy 使用 logging library 来打印日志。如果你想调试你的 DSPy 代码,请使用以下示例代码将日志级别设置为 DEBUG。
Alternatively, if you want to reduce the amount of logs, set the logging level to WARNING or ERROR.