你还在为写好Prompt而头疼吗,带你走进DSPy-Program LLMs之初体验

前言

随着大模型的使用和应用越来越频繁,也越来越广泛,大家有没有陷入到无限制的研究、调优自己的prompt。

随之,市面上也出现了提示词工程师,更有专门的提示工程一说。

现在网上搜一搜,有各种各样的写提示词的技巧,包括我自己也专门写过相关的文章。

再聊prompt

不知道大家有没有感受,prompt的技巧和调优效果很明显,但是没有什么提示词策略是可以解决所有类型的问题的。

LLMs本身对提示词是非常敏感的,这意味着,在实际实验过程中,除了要求大模型输出某个内容,还需要约束它按照某种格式,各种条件约束下输出,以确保整体的稳定性。你稍微改变条件或者数据,都会导致结果的返回发生变化,甚至有时候天差地别,你又需要重新调整或者优化prompt。

关于prompt我有两个问题:

  1. 根据OpenAI的工程师自述,起先在开发大模型的过程中,并没有提示工程这一说,而是后来在使用过程中大家发现通过一些技巧可以提高大模型的涌现能力。实际上就是大量的玩家在试玩大模型之后总结出的技巧。

我什么时候能不费劲巴拉的写各种各样的prompt。

  1. 都说我们看待LLM要像对待“人”一样,什么时候我真正能像和一个“人”沟通,能理解我在说什么和我需要什么 。

Hello Programming-DSPy

在这个过程中,DSPy一种program的全新的大模型应用方式出现了。

在这里我们不讨论两者的好与坏,随着LLM的多模态能力的发展和Multil Agents的发展,没准哪天就可以傻瓜式的提问了。

DSPy是什么

DSPy [1] 是斯坦福大学 NLP 研究人员开发的 "基础模型编程 "框架, 是一个旨在解决基于语言模型(LM)的应用程序脆弱性问题的框架,它优先考虑编程而不是提示。它允许您重新编译整个流水线,以便根据您的特定任务进行优化,而不是每当您更改一个组件时,就重复一轮人工提示工程。

DSPy 还将程序的信息流与每一步的参数(提示和 LM 权重)分离开来,为构建基于 LM 的应用程序提供了更系统的方法。然后,DSPy 将根据您的程序,自动优化如何针对您的特定任务提示(或微调)LM。

DSPy的核心思想

  • Signatures:手动设计的提示 -> 用签名取代

是我们告诉DSPY需要做什么,而不是告诉他应该如何做。例如:输入是文档,输出是摘要;输入是上下文+问题,输出是问题回复。

  • Modules:提示技巧 -> 转变为模块化

在DSPY是一些模块化的组件,比如说:dspy.ChainOfThought、dspy.ProgramOfThought,类似于一些可调用的函数

  • Optimizers:复杂的提示工程 -> 通过提词器和DSPy编译器自动完成

根据某个指标对整个流程自动优化。

DSPy是如何工作的

image.png

使用DSPy构建基于LM的应用的工作流程如上图所示,与训练神经网络的工作流程类似。

  1. 收集数据集:收集一些程序输入和输出的示例(例如,问答对),这些示例将用于优化pipeline。
  2. 编写DSPy程序:用签名(signature)和模块(module)以及组件之间的信息流定义程序的逻辑,以解决你的任务。
  3. 定义验证逻辑:使用验证度量和优化器(teleprompter)定义优化程序的逻辑。
  4. 编译DSPy程序:DSPy编译器考虑训练数据、编写程序、优化器和验证度量,以优化程序(例如,提示或微调)。
  5. 迭代:通过改进数据、编写程序或验证来重复该过程,直到对pipeline的性能感到满意为止。

进一步了解DSPy请参考以下链接:

  • DSPy Paper: [DSPy: Compiling Declarative Language Model Calls into Self-Improving Pipelines]
  • DSPy GitHub: [github.com/stanfordnlp…]

举个例子

可能理解起来还有点抽象,我们再举一个例子:

比如说,我们想解决“姚明的妻子的出生年龄?”这个问题。看到这个问题,大家脑子里肯定蹦出了一堆的解决方案。这是个多跳问题,几乎不可能通过单轮搜索来解决这个问题,大多数系统可以得出“姚明的妻子是谁?”,但是无法回答后续的年龄问题。多轮搜索的系统,通过生成额外的搜索,收集必要的信息,可以得出最终答案,整体上还是蛮复杂的。但是这里举个例子,如何用DSPY只需要几行代码来实现并优化这个问题。

import dspy      

turbo = dspy.OpenAI(model='gpt-3.5-turbo')   
colbertv2 = dspy.ColBERTv2(url='http://20.102.90.50:2017/wiki17_abstracts')      
dspy.settings.configure(lm=turbo, rm=colbertv2 )   


加载测试数据,多跳问题,可以使用HotPotQA测试

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]      
len(trainset), 
len(devset)   
#(20, 50)   


设置Signatures

签名是最小形式的输入和输出字段的元组。下面,您可以看到一些简写语法签名的示例。

与手写提示相比,签名可以通过为每个签名引导示例编译成自完善和自适应管道的prompt或fine-tune。

"question -> answer"

"long-document -> summary"

"context, question -> answer"

class GenerateAnswer(dspy.Signature):       
context = dspy.InputField()       
question = dspy.InputField()       
answer = dspy.OutputField()         

class GenerateSearchQuery(dspy.Signature):          
context = dspy.InputField()       
question = dspy.InputField()       
query = dspy.OutputField()   


构建DSPY pipeline

您可能熟悉几种不同的提示技巧,例如添加Your task is to …之类的句子。或“You are a …”在提示开头,思维链(“让我们一步一步地思考”),或者在提示结尾添加 “Don’t make anything up” 或“Only use the provided context”这样的句子。

对DSPy中的模块进行模板化和参数化,以抽象这些提示技术。这意味着它们用于通过应用提示、微调、增强和推理技术使DSPy签名适应任务。

将签名传递给ChainOfThought模块,然后使用输入字段contextquestion的值进行调用。

使用ChainOfThought初步实施签名“context, question -> answer”

在撰写本文时,DSPy实现了以下六个Module:

  • dspy.Predict:处理输入和输出字段,生成指令,并为指定的signature创建模板。
  • dspy.ChainOfThought:继承了Predict模块,并增加了“ Chain of Thought “处理的功能。
  • dspy.ChainOfThoughtWithHint:继承了Predict模块,并增强了ChainOfThought模块,增加了提供推理提示的选项。
  • dspy.MultiChainComparison:继承了Predict模块,并增加了多链比较的功能。
  • dspy.Retrieve:从检索器模块检索段落。
  • dspy.ReAct:旨在组成思想,行动和观察的交错步骤。
from dsp.utils import deduplicate      

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)]  
# 多跳,每一跳都使用一个dspy.ChainOfThought           
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)   


测试

my_question = "How many storeys are in the castle that David Gregory inherited?"  
uncompiled_baleen = SimplifiedBaleen()     
pred = uncompiled_baleen(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]}")   


优化

上面提到过,可以用某个打分来优化DSPY的结果,定义一个评估函数

  • 预测答案与真实答案相符。
  • 检索到的上下文包含真实答案
  • 生成的搜索查询不能太杂乱,小于100个字符
  • 生成的搜索查询尽量不要重复(跟历史的相比,不能超过0.8)。
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   


使用 DSPy 中的BootstrapFewShot,通过少量示例来优化流程的预测器。 在撰写本文时,DSPy实现了以下五个提词器:

  • dspy.LabeledFewShot:定义预测器使用的k个样本数。
  • dspy.BootstrapFewShot:引导Few-Shot。
  • dspy.BootstrapFewShotWithRandomSearch:继承了BootstrapFewShot提词器,并为随机搜索过程引入了额外的属性。
  • dspy.BootstrapFinetune:t将提词器定义为用于微调编译的BootstrapFewShot实例。
  • dspy.Ensemble:创建多个程序的集成版本,将不同程序的各种输出减少到单个输出。 还有SignatureOptimizer和BayesianSignatureOptimizer,它们在zero/few-shot 设置中改善模块中签名的输出前缀和指令。

不同的提词器在优化成本和质量等方面提供了不同的权衡。

from dspy.teleprompt import BootstrapFewShot      
teleprompter = BootstrapFewShot(metric=validate_context_and_answer_and_hops)   
compiled_baleen = teleprompter.compile(SimplifiedBaleen(), teacher=SimplifiedBaleen(passages_per_hop=2), trainset=trainset)   


评估

from dspy.evaluate.evaluate import Evaluate         
def gold_passages_retrieved(example, pred, trace=None):       
gold_titles = set(map(dspy.evaluate.normalize_text, example["gold_titles"]))       
found_titles = set(           
map(dspy.evaluate.normalize_text, [c.split(" | ")[0] for c in pred.context])       
)       
return gold_titles.issubset(found_titles)      
evaluate_on_hotpotqa = Evaluate(devset=devset, num_threads=1, display_progress=True, display_table=5)      
uncompiled_baleen_retrieval_score = evaluate_on_hotpotqa(uncompiled_baleen, metric=gold_passages_retrieved, display=False)      
compiled_baleen_retrieval_score = evaluate_on_hotpotqa(compiled_baleen, metric=gold_passages_retrieved)      
print(f"## Retrieval Score for uncompiled Baleen: {uncompiled_baleen_retrieval_score}")   
print(f"## Retrieval Score for compiled Baleen: {compiled_baleen_retrieval_score}")         
#Output   
## Retrieval Score for uncompiled Baleen: 36.0   
## Retrieval Score for compiled Baleen: 60.0   



DSPy与LangChain或LlamaIndex有何不同?

LangChain、LlamaIndex和DSPy都是帮助开发人员轻松构建基于LM的应用的框架。使用LangChain和LlamaIndex的典型pipeline通常使用prompt template来实现,这使得整个pipeline对组件更改非常敏感。相比之下,DSPy将构建基于LM的管道从操作prompt 转移到更贴近编程。

DSPy中新引入的编译器在更改基于LM的应用程序(如LM或数据)中的部件时,消除了任何额外的Prompt工程或微调工作。相反,开发人员可以简单地重新编译程序,以优化pipeline适应新添加的更改。因此,与LangChain或LlamaIndex相比,DSPy可以帮助开发人员以更少的努力获得pipeline的性能。

总结

本文我们一是回顾了prompt使用过程中的痛点和问题,同时介绍了DSPy一种program的全新的大模型应用方式,并通过一个例子初步了解了DSPy是如何工作的,目前生成式人工智能社区对该框架非常感兴趣。DSPy 框架引入了一系列概念,将构建基于 LM 的应用程序从手动提示工程转向编程。

如何学习AI大模型?

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

在这里插入图片描述

第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;

第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;

第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;

第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;

第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;

第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;

第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。

在这里插入图片描述

👉学会后的收获:👈
• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。

在这里插入图片描述

1.AI大模型学习路线图
2.100套AI大模型商业化落地方案
3.100集大模型视频教程
4.200本大模型PDF书籍
5.LLM面试题合集
6.AI产品经理资源合集

👉获取方式:
😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓

在这里插入图片描述

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值