
前言来重新看下大模型应用中最脆弱的一环Prompt Engineering有了哪些新的解决方案。这一章我们先看看大火的DSPy框架会先梳理DSPy相关的几篇核心论文了解下框架背后的设计思想和原理,然后以FinEval的单选题作为任务从简单指令COT指令到采样Few-shot和优化指令给出代码示例和效果评估。论文串烧DEMONSTRATE–SEARCH–PREDICT:Composing retrieval and language models for knowledge-intensive NLPDSPy: Compiling Declarative Language Model Calls into Self-Improving PipelinesIn-Context Learning for Extreme Multi-Label ClassificationOptimizing Instructions and Demonstrations for Multi-Stage Language Model ProgramsDSPy Assertions:Computational Constraints for Self-Refining Language Model PipelinesDSPY这个prompt框架着实火了一阵了项目也发了上面的许多论文每篇论文都对应了项目中的一个或几个模块。我们来串一遍以上论文的核心思想。DEMONSTRATE–SEARCH–PREDICT是DSPy的第一篇核心思想和现在coze这类流程控制软件很相似哈哈现在大模型领域的名词异常的多这个workflow其实和agentchainpipelinebot啥的意思也很相似。核心在固定流程模块化推理过程和指令few-shot生成过程。虽然是在RAG任务上提出的DSP框架但我们抛开RAG的searchpredict的流程论文的核心其实是把任务拆分成多个原子节点每个原子节点是一个不可再分割的function通过整体的control flow来串联原子节点。同时这种流程化的框架使得每个节点都可以基于训练数据生成demonstation并且可以通过不同的召回逻辑在推理时进行few-shot的动态选择来优化每一个节点的效果。以下是OpenQA任务上的一个workflow的示例整个流程有三个部分生成Demonstration并基于示例进行检索和推理。其中示例的生成会使用训练数据在相同的流程上取运行过程中每一步的结果作为实例这里选择了k3的3-shot示例在上面DSP的基础上DSPy: Compiling Declarative Language Model Calls into Self-Improving Pipelines对流程进一步做了抽象和重构提出了以三个核心模块为基础的prompt生成和优化框架Signature: 继承了pydantic的BaseModel定义任务的范式例如ContextQuestion - AnswerModule类似pytorch对模型定义的callable function定义了任务的workflow例如上面retrieve-then-read的RAG流程Teleprompter: 基于任务指标对流程进行优化的编译器这里的优化集中在few-shot的选择和动态流程选择这里流程选择主要是Ensemble而非直接对workflow进行修改。论文说还提供了微调能力其实也是基于流程生成的Demonstration作为样本来微调。其中Telepropmter提供了BootstrapFewShot, BootstrapFewShotWithRandomSearchEnsemble等prompt优化器。这篇论文的重心是放在prompt中few-shot选择和优化以BootstrapFewShotWithRandomSearch为例Teleprompter会先基于训练集生成一批Demonstration再基于指定任务的metric从中采样得到在验证集上效果表现最优的few-shot来构建最终的prompt。In-Context Learning for Extreme Multi-Label Classification其实是利用了DSPy的框架在标签超大(≥10,000)的分类任务上构建了一个新的workflow叫做Infer-Retrieve-Rank。也就是想让模型猜测N个可能的分类标签然后召回这些标签。Optimizing Instructions and Demonstrations for Multi-Stage Language Model Programs把重心放在了端到端的对任务prompt进行整体优化除了few-shot之外还包括对任务指令和任务条件的优化。这里有两个技术难点一个是prompt空间的搜索范围极大另一个是整体优化时指标的归因问题。为解决prompt搜索空间问题论文借鉴APE,也就是大模型基于input-output样本来分析任务本质生成任务指令的思路。并且在描述任务时除了必须的训练样本还提供了多个可选择的任务信息包括是否使用大模型生成的2~3句话的任务描述是否使用任务的流程代码是否使用历史已经尝试过的指令是否使用不同的指令风格(tips), 例如更有创意更简洁模型生成指令的代码如下TIPS{none:,creative:Dont be afraid to be creative when creating the new instruction!,simple:Keep the instruction clear and concise.,description:Make sure your instruction is very informative and descriptive.,high_stakes:The instruction should include a high stakes scenario in which the LM must solve the task!,persona:Include a persona that is relevant to the task in the instruction (ie. You are a ...),}classGenerateSingleModuleInstruction(dspy.Signature):(Use the information below to learn about a task that we are trying to solve using calls to an LM, then generate a new instruction that will be used to prompt a Language Model to better solve the task.)ifuse_dataset_summary:dataset_descriptiondspy.InputField(descA description of the dataset that we are using.,prefixDATASET SUMMARY:,)ifprogram_aware:program_codedspy.InputField(formatstr,descLanguage model program designed to solve a particular task.,prefixPROGRAM CODE:,)program_descriptiondspy.InputField(descSummary of the task the program is designed to solve, and how it goes about solving it.,prefixPROGRAM DESCRIPTION:,)moduledspy.InputField(descThe module to create an instruction for.,prefixMODULE:,)task_demosdspy.InputField(formatstr,descExample inputs/outputs of our module.,prefixTASK DEMO(S):,)ifuse_instruct_history:previous_instructionsdspy.InputField(formatstr,descPrevious instructions weve attempted, along with their associated scores.,prefixPREVIOUS INSTRUCTIONS:,)basic_instructiondspy.InputField(formatstr,descBasic instruction.,prefixBASIC INSTRUCTION:,)ifuse_tip:tipdspy.InputField(formatstr,descA suggestion for how to go about generating the new instruction.,prefixTIP:,)proposed_instructiondspy.OutputField(descPropose an instruction that will be used to prompt a Language Model to perform this task.,prefixPROPOSED INSTRUCTION:,)基于以上大模型生成的指令候选以及前面BootstrapFewShot生成的众多示例下一步就是基于训练集选择最优的指令。这里论文构建了包括randomSearch等多个优化器论文主推的MIPRO(Multi-prompt Instruction Proposal Optimizer)使用常见的超参优化的TPE算法来拟合以上指令中的多个超参对最终prompt效果的正负面影响基于训练集上的评估指标最终选出最优的指令。所以是生成指令的超参包括采样生成的指令选择并非直接去迭代更新指令本身。其实这里也可以使用各类模型可解释算法。核心难点是整个任务中有多个节点每个节点prompt有多个超参彼此间互相影响并最终影响任务的完成效果但我们只能拿到最终任务完成的标签无法获得中间节点的输出反馈。和决策树之类的归因算法难点相似。DSPy: Compiling Declarative Language Model Calls into Self-Improving Pipelines是DSPy新出的一个子功能-条件判断。考虑常见的prompt构成基本就包括三个部分任务描述few-shot示例还有针对任务完成细节的requirement前面两篇论文分别给出了生成优化任务描述和采样筛选few-shot的方案那Assert就是面向requirements的优化方案。而现实任务中requirement往往是最琐碎的部分例如像Query改写任务我们可能需要要求改写query和原始query相似度不能太高但又不能丢失核心主体不能丢失或者改写时间实体query不能太长不能对query中无关细节等等论文给出了硬性要求Assert和软性建议Suggest两种方法直接加入到前面编写的任务module中这样任务推理的过程会根据Assert和Suggest直接生成建议而使用也有两种一种是模型在推理时命中assert和suggest后对应建议会直接加入到prompt中用于模型self-refine另一种是assert可以直接打断模型施法进行重试。论文就简单说这么多下面我们以金融单选题任务为示例尝试对prompt进行优化。代码示例https://github.com/stanfordnlp/dspyhttps://dspy-docs.vercel.app/下面我们以FinEval的单选题作为任务尝试使用DSPy进行Prompt生成Prompt优化和效果评估。考虑成本这里只使用了100条样本。基础Prompt首先定义LLM模型,这里我使用的Azure的GPT4importdspy modeldspy.AzureOpenAI(**kwargs)dspy.settings.configure(lmmodel)使用DSPy定义prompt就是定义一个Pydantic模型包括任务描述输入描述和输出描述称之为Signature如下classSingleChoiceQA(dspy.Signature):单项选择题给定题目和ABCD四个选项输出正确的选项questiondspy.InputField(desc问题和选项)answerdspy.OutputField(desc[ABCD]之一的正确选项)然后我们把数据导入并转化成DSPy规定的样本格式同样只要注明输入Example会自动把剩余字段都当做输出defformat_example(line):inputline[question]forchoicein[A,B,C,D]:inputf\n{choice}.{line[f{choice}]}outputline[answer]exampledspy.Example(questioninput,answeroutput).with_inputs(question)returnexample下一步我们来定义任务DSPy称之为Module也就是定义任务流像RAG就是retrieve-readmultihop QA就是多轮的QA而这里因为是简单的单选题因此Module定义非常简单。classSQA(dspy.Module):def__init__(self):self.generate_answerdspy.Predict(SingleChoiceQA)defforward(self,question):returnself.generate_answer(questionquestion)singlechoice_qaSQA()predsinglechoice_qa(questionexamples[0][question])print(以下为DSPy生成Prompt)print(model.inspect_history(n1))同时我们可以使用inspect_history很方便的查看DSPy生成的具体Prompt和对应模型的推理效果如下COT优化和评估在上面基础任务定义的基础上下一步我们看看能否简单使用COT就能优化任务效果。加入COT定义的Module如下DSPy提供了常见的ReACTPOT等思考Prompt。classSQACOT(dspy.Module):def__init__(self):self.generate_answerdspy.ChainOfThought(SingleChoiceQA)defforward(self,question):returnself.generate_answer(questionquestion)singlechoice_qa_cotSQACOT()加入COT后的prompt和推理效果如下接下来我们来定义下任务的评估指标然后批量评估下使用基础Prompt和COT Prompt的效果差异。DSPy提供了一些Exact MatchPassage Match之类的指标但其实自己定义指标最方便。只要和DSPy Metric的输入输出对齐即可。这里我们简单抽取答案中的ABCD和标准答案计算Accuracy。评估代码如下DSPy支持在返回打分的同时返回每一条预测的具体结果fromdspy.evaluate.evaluateimportEvaluatedefchoice_match(example,pred,traceNone):defextract_choice(gen_ans):mre.findall(r[ABCD],gen_ans,re.M)iflen(m)1:answerm[0]returnanswerreturnrandom.choice(ABCD)returnextract_choice(pred.answer)example.answer evaluate_on_qaEvaluate(devsettest,num_threads1,display_progressTrue,display_tableTrue)output1evaluate_on_qa(singlechoice_qa,metricchoice_match,return_outputsTrue,return_all_scoresTrue)output2evaluate_on_qa(singlechoice_qa_cot,metricchoice_match,return_outputsTrue,return_all_scoresTrue)以上评估基础Prompt的准确率在50%而COT Prompt的准确率在60%FewShot优化再进一步我们使用DSPy最重点打造的FewShot采样优化看下能否进一步提升效果。这里DSPy提供了多种优化器适配不同的样本量级这里考虑成本我们使用了基础的BootstrapFewShot样本更多可以尝试BootstrapFewShotWithRandomSearch或者BootstrapFewShotWithOptuna。BootstrapFewShot可以指定few-shot中包含几个模型预测生成的样本(max_bootstrapped_demos)和几个真实标签的训练样本(max_labeld_demos)teleprompterBootstrapFewShot(metricchoice_match,max_bootstrapped_demos4,max_labeled_demos16)compiled_qateleprompter.compile(singlechoice_qa_cot,trainsettrain)score3,results3,output3,df3evaluate_on_qa(compiled_qa,metricchoice_match,return_outputsTrue,return_all_scoresTrue)加入采样Few-Shot后的推理准确率提升到了75%使用2个推理Demos和4个真实标签的Demos拼接而成的模型Prompt如下指令优化再看下指令优化这里使用的是COPRO优化器也就是使用prompt让大模型基于原有prompt优化生成新的prompt优化指令和第一轮优化生成的prompt如下第二轮之后指令优化会给出之前尝试过的所有指令和每个指令在验证集上的打分并让模型进行有针对性的优化称之为GenerateInstructionGivenAttempts指令如下在0.7的temperature下每一轮模型会基于上一轮的最优prompt生成breadth5个新的prompt并重复以上过程depth3轮最后选取在验证集上效果最优的prompt。COPRO_teleprompterCOPRO(prompt_modelmodel,metricchoice_match,breadth5,depth3,init_temperature0.7,track_statsTrue)kwargsdict(num_threads1,display_progressTrue,display_table5)COPRO_compiled_qaCOPRO_teleprompter.compile(singlechoice_qa_cot,trainsettrain,eval_kwargskwargs)print(model.inspect_history(n1))最终优化后的最优的prompt指令如下但在测试集上最终并没有提升准确率还是60%,其中一个主要原因也是单选QA任务本身比较基础在指令上可以优化的空间不算太大指令优化再更复杂非常规任务上的效果会更显著些。整体上DSPy确实提供了模块化标准化设计Prompt的方案但是在任务描述上的优化方案现在还比较有限上面GenerateInstructionGivenAttempts虽然提供了历史尝试过的指令和验证集打分但缺少了模型从历史prompt的回答中总结模型当前指令存在什么问题的步骤后面可能可以考虑更多reflection相关的指令优化方案像TextGrad这个等我玩过再来总结吧~最后的最后感谢你们的阅读和喜欢我收藏了很多技术干货可以共享给喜欢我文章的朋友们如果你肯花时间沉下心去学习它们一定能帮到你。因为这个行业不同于其他行业知识体系实在是过于庞大知识更新也非常快。作为一个普通人无法全部学完所以我们在提升技术的时候首先需要明确一个目标然后制定好完整的计划同时找到好的学习方法这样才能更快的提升自己。这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】大模型知识脑图为了成为更好的 AI大模型 开发者这里为大家提供了总的路线图。它的用处就在于你可以按照上面的知识点去找对应的学习资源保证自己学得较为全面。经典书籍阅读阅读AI大模型经典书籍可以帮助读者提高技术水平开拓视野掌握核心技术提高解决问题的能力同时也可以借鉴他人的经验。对于想要深入学习AI大模型开发的读者来说阅读经典书籍是非常有必要的。实战案例光学理论是没用的要学会跟着一起敲要动手实操才能将自己的所学运用到实际当中去这时候可以搞点实战案例来学习。面试资料我们学习AI大模型必然是想找到高薪的工作下面这些面试题都是总结当前最新、最热、最高频的面试题并且每道题都有详细的答案面试前刷完这套面试题资料小小offer不在话下640套AI大模型报告合集这套包含640份报告的合集涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师还是对AI大模型感兴趣的爱好者这套报告合集都将为您提供宝贵的信息和启示。这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】