链载Ai

标题: 别再执着于大模型提示词技巧了,一起迈向program llms新时代! [打印本页]

作者: 链载Ai    时间: 前天 10:04
标题: 别再执着于大模型提示词技巧了,一起迈向program llms新时代!

在大模型之后,提示词工程师这个岗位开始在市场上出现,我司去年就设了这个岗位,虽然不知道他们具体的工作内容有哪些方向。提示词工程,实际上就是大量的玩家在试玩大模型之后总结出的技巧。互联网上搜一波可以看到大量的诸如50个大模型提示词技巧,100个提示词技巧。这些技巧本身都很不错,但是在试用之后,你可能发现,没有什么提示词策略是可以解决所有类型的问题的。

LLMs本身对提示词是非常敏感的,这意味着,在实际实验过程中,除了要求大模型输出某个内容,还需要约束它按照某种格式,各种条件约束下输出,以确保整体的稳定性。

今天分享的这个思路,是将prompt llms变成program llms,主要来源于斯坦福大学的DSPY框架。将大模型提示词工程转变成像写pytorch代码一样结构化。这个框架的首图如下:

在DSPY中,对应了3大核心模块,Signatures、Modules、Optimizers。如果还原到提示词工程中,Signatures相当于在书写提示词,而Modules就像你使用提示词技巧,比如思维链cot、react等,而Optimizers就像一步一步的去根据模型的生成结果调优提示词。

更具象化一点:

接下来举个具体的例子:

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

importdspy

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测试

fromdspy.datasetsimportHotPotQA

dataset=HotPotQA(train_seed=1,train_size=20,eval_seed=2023,dev_size=50,test_size=0)

trainset=[x.with_inputs('question')forxindataset.train]
devset=[x.with_inputs('question')forxindataset.dev]

len(trainset),len(devset)
#(20,50)

设置Signatures

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


classGenerateSearchQuery(dspy.Signature):

context=dspy.InputField()
question=dspy.InputField()
query=dspy.OutputField()

构建DSPY pipeline

fromdsp.utilsimportdeduplicate

classSimplifiedBaleen(dspy.Module):
def__init__(self,passages_per_hop=3,max_hops=2):
super().__init__()

self.generate_query=[dspy.ChainOfThought(GenerateSearchQuery)for_inrange(max_hops)]#多跳,每一跳都使用一个dspy.ChainOfThought
self.retrieve=dspy.Retrieve(k=passages_per_hop)
self.generate_answer=dspy.ChainOfThought(GenerateAnswer)
self.max_hops=max_hops

defforward(self,question):
context=[]

forhopinrange(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)
returndspy.Prediction(context=context,answer=pred.answer)

测试

my_question="HowmanystoreysareinthecastlethatDavidGregoryinherited?"

uncompiled_baleen=SimplifiedBaleen()
pred=uncompiled_baleen(my_question)

print(f"Question:{my_question}")
print(f"redictedAnswer:{pred.answer}")
print(f"RetrievedContexts(truncated):{[c[:200]+'...'forcinpred.context]}")

优化

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

defvalidate_context_and_answer_and_hops(example,pred,trace=None):
ifnotdspy.evaluate.answer_exact_match(example,pred):returnFalse
ifnotdspy.evaluate.answer_passage_match(example,pred):returnFalse

hops=[example.question]+[outputs.queryfor*_,outputsintraceif'query'inoutputs]

ifmax([len(h)forhinhops])>100:returnFalse
ifany(dspy.evaluate.answer_exact_match_str(hops[idx],hops[:idx],frac=0.8)foridxinrange(2,len(hops))):returnFalse

returnTrue

使用 DSPy 中的BootstrapFewShot,通过少量示例来优化流程的预测器。

fromdspy.telepromptimportBootstrapFewShot

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

评估

fromdspy.evaluate.evaluateimportEvaluate


defgold_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]forcinpred.context])
)
returngold_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"##RetrievalScoreforuncompiledBaleen:{uncompiled_baleen_retrieval_score}")
print(f"##RetrievalScoreforcompiledBaleen:{compiled_baleen_retrieval_score}")


#Output
##RetrievalScoreforuncompiledBaleen:36.0
##RetrievalScoreforcompiledBaleen:60.0

在 DSPy 中结合多跳设置甚至可以超越人类反馈。即使是很小的模型,在 DSPy 设置中使用时也可以与更大尺寸模型进行比较。项目框架中有很多的优秀示例,感兴趣的小伙伴可以学习一波。









欢迎光临 链载Ai (https://www.lianzai.com/) Powered by Discuz! X3.5