DSPy是斯坦福大学自然语言处理实验室开发的一个框架,全称是”Programming with Foundation Models”(使用基础模型编程)。它的核心理念是将提示工程(Prompting)、微调(Fine-tuning)、推理增强(Reasoning)和工具/检索增强(Tool/Retrieval Augmentation)等技术统一起来,通过一组简洁的Python操作来表达和学习。
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 GenerateSearchQuery(dspy.Signature):
"""Write a simple search query that will help answer a complex question."""
context = dspy.InputField(desc="may contain relevant facts")
question = dspy.InputField()
query = dspy.OutputField()
然后,我们定义多跳问答的主程序:
class SimplifiedBaleen(dspy.Module):
def __init__(self, passages_per_hop=3, max_hops=2):
super().__init__()
self.generate_query = [dspy.ChainOfThought(GenerateSearchQuery) for _ in range(max_hops)]
self.retrieve = dspy.Retrieve(k=passages_per_hop)
self.generate_answer = dspy.ChainOfThought(GenerateAnswer)
self.max_hops = max_hops
def forward(self, question):
context = []
for hop in range(self.max_hops):
query = self.generate_query[hop](context=context, question=question).query
passages = self.retrieve(query).passages
context = deduplicate(context + passages)
pred = self.generate_answer(context=context, question=question)
return dspy.Prediction(context=context, answer=pred.answer)
这个程序的核心逻辑是:
根据问题生成搜索查询
使用查询检索相关段落
将检索到的信息加入上下文
重复上述步骤,直到达到最大跳数
根据收集到的上下文生成最终答案
接下来,我们定义验证逻辑和使用编译器优化程序:
def validate_context_and_answer_and_hops(example, pred, trace=None):
if not dspy.evaluate.answer_exact_match(example, pred): return False
if not dspy.evaluate.answer_passage_match(example, pred): return False
hops = [example.question] + [outputs.query for *_, outputs in trace if 'query' in outputs]
if max([len(h) for h in hops]) > 100: return False
if any(dspy.evaluate.answer_exact_match_str(hops[idx], hops[:idx], frac=0.8) for idx in range(2, len(hops))): return False
return True
teleprompter = BootstrapFewShot(metric=validate_context_and_answer_and_hops)
compiled_baleen = teleprompter.compile(SimplifiedBaleen(), teacher=SimplifiedBaleen(passages_per_hop=2), trainset=trainset)
经过编译后,我们的程序就可以回答复杂的多跳问题了。例如:
question = "How many storeys are in the castle that David Gregory inherited?"
pred = compiled_baleen(question)
print(f"Question: {question}")
print(f"Predicted Answer: {pred.answer}")
print(f"Retrieved Contexts: {[c[:200] + '...' for c in pred.context]}")
输出结果:
Question: How many storeys are in the castle that David Gregory inherited?
Predicted Answer: Five
Retrieved Contexts: ['David Gregory (physician) | David Gregory (20 December 1625 – 1720) was a Scottish physician and inventor. His surname is sometimes spelt as Gregorie, the original Scottish spelling. He inherited Kinn...', 'Kinnairdy Castle | Kinnairdy Castle is a tower house, having five storeys and a garret, two miles south of Aberchirder, Aberdeenshire, Scotland. The alternative name is Old Kinnairdy....', ...]
Khattab, O. , Santhanam, K., Li, X., Hall, D., Liang, P., Potts, C., & Callison-Burch, C. (2023). Demonstrate-Search-Predict: Composing retrieval and language models for knowledge-intensive NLP. arXiv preprint arXiv:2212.14024.✅
Khattab, O. , & Zaharia, M. (2020). ColBERT: Efficient and Effective Passage Search via Contextualized Late Interaction over BERT. In Proceedings of the 43rd International ACM SIGIR Conference on Research and Development in Information Retrieval (pp. 39-48).✅
Brown, T. , Mann, B., Ryder, N., Subbiah, M., Kaplan, J. D., Dhariwal, P., … & Amodei, D. (2020). Language models are few-shot learners. Advances in neural information processing systems, 33, 1877-1901.✅
Raffel, C. , Shazeer, N., Roberts, A., Lee, K., Narang, S., Matena, M., … & Liu, P. J. (2020). Exploring the limits of transfer learning with a unified text-to-text transformer. Journal of Machine Learning Research, 21(140), 1-67.✅
Devlin, J. , Chang, M. W., Lee, K., & Toutanova, K. (2018). Bert: Pre-training of deep bidirectional transformers for language understanding. arXiv preprint arXiv:1810.04805.✅
在人工智能和大语言模型席卷全球的今天,如何更好地利用这些强大的工具来解决实际问题,成为了许多开发者和研究人员关注的焦点。今天要介绍的DSPy框架,为我们提供了一个全新的视角和方法,让我们能够像编写传统程序一样,轻松地”编程”大语言模型,构建复杂的AI应用。让我们一起来探索这个激动人心的新领域吧!
🌟 什么是DSPy?
DSPy是斯坦福大学自然语言处理实验室开发的一个框架,全称是”Programming with Foundation Models”(使用基础模型编程)。它的核心理念是将提示工程(Prompting)、微调(Fine-tuning)、推理增强(Reasoning)和工具/检索增强(Tool/Retrieval Augmentation)等技术统一起来,通过一组简洁的Python操作来表达和学习。
简单来说,DSPy让我们能够像编写普通Python程序一样,定义和组合各种AI模块,然后通过自动化的编译和优化过程,生成高质量的提示或微调模型,以完成复杂的任务。
🔍 DSPy的核心概念
要理解DSPy,我们需要先了解几个关键概念:
🚀 DSPy的工作流程
使用DSPy构建AI应用的一般流程如下:
💡 DSPy实战:多跳问答系统
为了更直观地理解DSPy的强大之处,让我们来看一个具体的例子:构建一个多跳问答系统。这个系统能够回答需要多步推理的复杂问题,比如”David Gregory继承的城堡有几层?”
首先,我们定义问答和搜索查询的签名:
然后,我们定义多跳问答的主程序:
这个程序的核心逻辑是:
接下来,我们定义验证逻辑和使用编译器优化程序:
经过编译后,我们的程序就可以回答复杂的多跳问题了。例如:
输出结果:
🌈 DSPy的优势
🔮 未来展望
DSPy的出现,标志着AI应用开发正在向更加系统化、工程化的方向发展。它为我们提供了一种新的范式,让我们能够更加高效、可靠地构建复杂的AI系统。
随着DSPy的不断发展和完善,我们可以期待:
📚 结语
DSPy为我们开启了一个崭新的AI编程世界。它不仅简化了复杂AI应用的开发过程,还为我们提供了一种全新的思考方式,让我们能够更好地利用和组合各种AI能力。无论你是AI研究人员、软件工程师,还是对AI应用感兴趣的爱好者,DSPy都值得你深入探索和尝试。
让我们一起拥抱这个AI编程的新时代,用DSPy构建更智能、更强大的应用吧!
参考文献