Created
Aug 14, 2024 01:48 PM
Favorite
Favorite
Priority
备注
推荐
🌟🌟🌟🌟🌟
类型
DSPy
notion image
书接上文Prompt或许的新未来, DSPy使用从0到1快速上手,以示例驱动的方式,由浅入深的介绍DSPy框架自身的使用流程,并结合知名大模型应用框架LangChain,进一步介绍了两个框架结合的案例。本文将通过示例和源码解析的方式,解读DSPy运行原理。DSPy是斯坦福 NLP 组推出的一个用于优化和生成Prompt的框架,DSPy将传统手工编写提示词的方式抽象为高代码编程方式,其核心思路为:
(1)将整体流程与单步骤分开。每个步骤聚焦具体的工作,协同完成Prompt的优化。
(2)引入多样的优化器,这些优化器是由LM驱动的算法,可以根据定义的阈值来调整调用LM的提示及访问参数。
上述步骤主要由 Signature、Module、Optimizer三个核心模块实现。

DSPy 实现原理之Signature类

DSPy的Signature类,是DSPy核心模块之一,Signature是声明性的规范,定义了 DSPy 模块的输入/输出行为,用于告诉语言模型应执行哪些任务,而不是我们应如何设置 prompt 语言模型。一个签名包括三个基本元素:
  • 语言模型旨在解决的子任务的简洁描述。
  • 我们提供给语言模型的一个或多个输入字段的描述(例如,输入问题)。
  • 我们期望从语言模型得到的一个或多个输出字段的描述(例如,问题的答案)。
notion image
Signature的基本用法示例
首先来看一个示例来解释Signature的用法,需要准备签名所需的三要素,下面代码进行三步操作:
1、将子任务描述填入函数下面的注释中。
2、定义输入字段(必选),并对输入字段设置描述(可选)。
3、定义输出字段(必选),并对输出字段设置描述(可选)。
然后我们使用dspy.ChainOfThought 进行一次推理,并查看提示词最终的内容
提示词的内容如下,通过提示词内容,可以看出Signature可以将类定义中的注释内容,转换为对这个子任务的描述填写到提示词开头部分,然后将输入输出字段,分别以统一的格式(首字母大写,单词用空格分开)排布在 Reasoning的前后,其中Reasoning的内容为 CoT模式的固定提示词。
通过上面的例子,我们了解了如何通过写代码的方式,产生提示词,并使得提示词包括我们对任务描述和输入输出参数描述。此外,Signature还可以通过字符串定义输入输出方式,代替通过继承方式定义,代码如下:
但是这种方式只能定义输入输出的字段名,无法定义任务描述 和 字段描述,此时产生的提示词的任务描述是默认任务描述,提示词如下:
至此,我们介绍了Signature的两种用法。

Signature源码解析

那么,Signature类是如何实现上述功能的呢?我们将通过源码解释以下问题:
  • Signature执行流程
  • 字符串如何转换为Signature类
  • Signature的变量如何转换为提示词中的内容
我们深入Signature类的代码中进行简单的解释(文件位置:dspy\signatures):
1、执行流程从代码中代码中可以看出,Signature类集成了pydantic.BaseModel,并设置了元类 SignatureMeta;pydantic.BaseModel是格式校验的类;SignatureMeta是自定义类,Signature的大部分提示词逻辑都来自SignatureMeta类。 在Signature类及子类初始化时,首先会调用 SignatureMeta的__call__ 函数,__call__中调用了 make_signature函数,该函数主要是解析输出的字段,最终调用pydantic.create_model函数创建pydantic的格式类(__call__ -> make_signature -> pydantic.create_model),格式类中已经包含了输入输出字段以及对应的字段描述。然后调用SignatureMeta的 __new__函数,该函数将子任务描述,传入到 cls.__doc__变量中,并且利用infer_prefix函数,修改了输入输出字段的格式,使他们统一为首字母大写的形式,存入到 field.json_schema_extra["prefix"] 中,将字段的描述,存入 field.json_schema_extra["desc"] 字段中,并返回类。2、字符串如何转为Signature类如果输入为字符串类型,则 make_signature中的_parse_signature 函数会 格式化这个字符串并转换为 dspy.InputFiled 或 dspy.OutputField类型,至此,通过字符串和Signature类定义的方式都统一成了相同类型。3、Signature的变量如何转换为提示词中的内容
在初始化时,调用了SignatureMeta类的__call__ 函数和 __new__函数,两个函数创建了pydantic.BaseModal类,并将输入输出字段进行格式化,将任务描述存入 cls.__doc__,至此,所有代码描述的注释和变量,都转变为了提示词中将要用到的字符串内容,在 dspy.Module执行时,则会对提示词进行填充。
后续将会对Module(模块)类、Optimizer(优化)类进行源码解析,欢迎大家持续关注。下一篇将会解析Module(模块)类,敬请关注~感谢本文作者“阿拉赫莫拉”供稿
相关链接
1. dspy官网 https://dspy-docs.vercel.app
2. Dspy github仓库地址 https://github.com/stanfordnlp/dspy
更多DSPy技术前沿分享,欢迎扫描下方二维码进入技术交流群(或者添加群助手ID:qstarsky 邀请您进群交流)
DSPy
notion image
立即扫码
往期推荐
notion image
notion image
notion image
DSPy技术洞察10
DSPy技术洞察 · 目录
上一篇Prompt或许的新未来, DSPy使用从0到1快速上手下一篇
Loading...