前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >斯坦福NLP实验室重磅开源:DSPy,让大模型开发更简单,附代码

斯坦福NLP实验室重磅开源:DSPy,让大模型开发更简单,附代码

作者头像
统计学家
发布2024-10-23 16:54:35
发布2024-10-23 16:54:35
26100
代码可运行
举报
运行总次数:0
代码可运行

DSPy: 编程而非提示工程的基础模型框架

DSPy是斯坦福大学自然语言处理实验室开发的一个开源框架,旨在为基础模型提供一种新的编程范式,取代传统的提示工程方法。

DSPy的核心理念

DSPy的核心理念是"编程而非提示工程"(Programming—not prompting)。

它提供了一套声明式的API,让开发者可以像编写普通Python程序一样构建复杂的语言模型应用,而无需手动编写和调试繁琐的提示词。

DSPy引入了两个关键概念:

  1. 签名(Signature):用于声明性地指定语言模型输入输出的行为。
  2. 优化器(Optimizer,原名Teleprompter):自动优化程序中的提示词或模型权重。

DSPy的主要特性

  • 提供了通用的模块(如ChainOfThought、ReAct等),可以替代特定的提示工程技巧。
  • 引入了优化器,可以自动生成和选择有效的提示词。
  • 支持在Python控制流中自由使用DSPy模块。
  • 只需少量标注数据即可工作,框架会自动引导生成中间标签。
  • 可以针对不同的语言模型、数据集和管道自动优化提示词或微调权重。

使用DSPy的优势

使用DSPy进行开发相比传统方法有以下优势:

  1. 更加模块化和可维护的代码结构。
  2. 无需手动编写和维护复杂的提示词字符串。
  3. 当更改数据、流程或目标模型时,可以自动重新优化提示词。
  4. 可以更专注于系统设计,而非繁琐的提示词工程。

安装和使用

可以通过pip安装DSPy:

代码语言:javascript
代码运行次数:0
复制
pip install dspy-ai

实践示例

让我们通过两个简单的示例来展示DSPy的使用方法。

示例1: 最小工作示例

这个示例使用GSM8K数据集和OpenAI的GPT-3.5-turbo模型来演示DSPy的基本用法。

  1. 首先,我们设置环境并导入必要的模块:
代码语言:javascript
代码运行次数:0
复制
import dspy
from dspy.datasets.gsm8k import GSM8K, gsm8k_metric

# 设置语言模型
turbo = dspy.OpenAI(model='gpt-3.5-turbo-instruct', max_tokens=250)
dspy.settings.configure(lm=turbo)

# 加载GSM8K数据集
gsm8k = GSM8K()
gsm8k_trainset, gsm8k_devset = gsm8k.train[:10], gsm8k.dev[:10]
  1. 定义一个使用ChainOfThought模块的自定义程序:
代码语言:javascript
代码运行次数:0
复制
class CoT(dspy.Module):
    def __init__(self):
        super().__init__()
        self.prog = dspy.ChainOfThought("question -> answer")
    
    def forward(self, question):
        return self.prog(question=question)
  1. 使用BootstrapFewShot优化器编译模型:
代码语言:javascript
代码运行次数:0
复制
from dspy.teleprompt import BootstrapFewShot

config = dict(max_bootstrapped_demos=4, max_labeled_demos=4)
teleprompter = BootstrapFewShot(metric=gsm8k_metric, **config)
optimized_cot = teleprompter.compile(CoT(), trainset=gsm8k_trainset)
  1. 评估模型性能:
代码语言:javascript
代码运行次数:0
复制
from dspy.evaluate import Evaluate

evaluate = Evaluate(devset=gsm8k_devset, metric=gsm8k_metric, num_threads=4, display_progress=True, display_table=0)
evaluate(optimized_cot)
  1. 查看模型的最近生成:
代码语言:javascript
代码运行次数:0
复制
turbo.inspect_history(n=1)

示例2: RAG (检索增强生成)

这个示例展示了如何使用DSPy构建一个RAG (Retrieval-Augmented Generation) 管道。

  1. 配置语言模型和检索模型:
代码语言:javascript
代码运行次数:0
复制
import dspy

turbo = dspy.OpenAI(model='gpt-3.5-turbo')
colbertv2_wiki17_abstracts = dspy.ColBERTv2(url='http://20.102.90.50:2017/wiki17_abstracts')

dspy.settings.configure(lm=turbo, rm=colbertv2_wiki17_abstracts)
  1. 加载数据集:
代码语言:javascript
代码运行次数:0
复制
from dspy.datasets import HotPotQA

dataset = HotPotQA(train_seed=1, train_size=20, eval_seed=2023, dev_size=50, test_size=0)
trainset = [x.with_inputs('question') for x in dataset.train]
devset = [x.with_inputs('question') for x in dataset.dev]
  1. 定义签名和RAG管道:
代码语言:javascript
代码运行次数:0
复制
class GenerateAnswer(dspy.Signature):
    """Answer questions with short factoid answers."""

    context = dspy.InputField(desc="may contain relevant facts")
    question = dspy.InputField()
    answer = dspy.OutputField(desc="often between 1 and 5 words")

class RAG(dspy.Module):
    def __init__(self, num_passages=3):
        super().__init__()

        self.retrieve = dspy.Retrieve(k=num_passages)
        self.generate_answer = dspy.ChainOfThought(GenerateAnswer)
    
    def forward(self, question):
        context = self.retrieve(question).passages
        prediction = self.generate_answer(context=context, question=question)
        return dspy.Prediction(context=context, answer=prediction.answer)
  1. 编译和优化RAG程序:
代码语言:javascript
代码运行次数:0
复制
from dspy.teleprompt import BootstrapFewShot

def validate_context_and_answer(example, pred, trace=None):
    answer_EM = dspy.evaluate.answer_exact_match(example, pred)
    answer_PM = dspy.evaluate.answer_passage_match(example, pred)
    return answer_EM and answer_PM

teleprompter = BootstrapFewShot(metric=validate_context_and_answer)
compiled_rag = teleprompter.compile(RAG(), trainset=trainset)
  1. 执行和评估RAG管道:
代码语言:javascript
代码运行次数:0
复制
my_question = "What castle did David Gregory inherit?"
pred = compiled_rag(my_question)

print(f"Question: {my_question}")
print(f"Predicted Answer: {pred.answer}")
print(f"Retrieved Contexts (truncated): {[c[:200] + '...' for c in pred.context]}")

from dspy.evaluate.evaluate import Evaluate

evaluate_on_hotpotqa = Evaluate(devset=devset, num_threads=1, display_progress=False, display_table=5)
metric = dspy.evaluate.answer_exact_match
evaluate_on_hotpotqa(compiled_rag, metric=metric)

这些示例展示了DSPy如何简化复杂语言模型应用的开发过程,使得开发者可以更专注于系统设计而非繁琐的提示词工程。

结语

DSPy为基础模型应用开发提供了一种全新的范式,有望大幅提高开发效率和应用质量。通过上述示例,我们可以看到DSPy如何简化了复杂语言模型应用的开发过程。

reference

文档:https://dspy-docs.vercel.app/

论文:https://arxiv.org/abs/2310.03714

项目:https://github.com/stanfordnlp/dspy

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-10-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 机器学习与统计学 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • DSPy: 编程而非提示工程的基础模型框架
    • DSPy的核心理念
    • DSPy的主要特性
    • 使用DSPy的优势
    • 安装和使用
    • 实践示例
      • 示例1: 最小工作示例
      • 示例2: RAG (检索增强生成)
    • 结语
    • reference
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档