戰(zhàn)指南:用 BootstrapFewShot 自動(dòng)優(yōu)化你的程序)
DSPy Teleprompter / Optimizer 實(shí)戰(zhàn)指南用 BootstrapFewShot 自動(dòng)優(yōu)化你的程序【免費(fèi)下載鏈接】Tutorial-Codebase-KnowledgePocket Flow: Codebase to Tutorial項(xiàng)目地址: https://gitcode.com/gh_mirrors/tu/Tutorial-Codebase-Knowledge導(dǎo)讀在 DSPy 教程 的完整技術(shù)棧中構(gòu)建程序、定義簽名、接入 LM/RM 之后評(píng)估Evaluate負(fù)責(zé)回答程序表現(xiàn)如何而Teleprompter又名 Optimizer優(yōu)化器則負(fù)責(zé)回答程序表現(xiàn)不夠好時(shí)如何自動(dòng)變好。它把傳統(tǒng)上靠人工反復(fù)試錯(cuò)的prompt engineering提示詞工程自動(dòng)化你只需提供學(xué)生程序、訓(xùn)練數(shù)據(jù)集和度量函數(shù)DSPy 就會(huì)自動(dòng)搜索更優(yōu)的指令與 few-shot 示例甚至可以對(duì) LM 權(quán)重做微調(diào)。讀完本文你將掌握 Teleprompter 的核心三要素、用BootstrapFewShot一鍵自動(dòng)挑選 few-shot 示例的完整實(shí)戰(zhàn)流程以及其底層教師-學(xué)生引導(dǎo)式優(yōu)化原理。Teleprompter 是什么程序的教練假設(shè)你構(gòu)建了BasicQA程序在上一章的評(píng)估中只有 75% 的準(zhǔn)確率。傳統(tǒng)做法是開始手動(dòng)微調(diào)提示詞要不要改改指令的措辭要不要加一些 few-shot 示例哪些示例效果最好這種手工過(guò)程緩慢、繁瑣且充滿猜測(cè)。Teleprompters正是 DSPy 內(nèi)置的自動(dòng)化提示詞工程師和程序調(diào)優(yōu)器。它像一個(gè)教練對(duì)待你的 DSPy 程序?qū)W生教練觀察學(xué)生在練習(xí)數(shù)據(jù)集上的表現(xiàn)用反饋度量函數(shù)找出弱點(diǎn)提出新策略更好的指令、更好的示例來(lái)提升表現(xiàn)不斷重復(fù)直到學(xué)生表現(xiàn)大幅改善。一個(gè)Teleprompter在 DSPy 中是一個(gè)算法它接收你的 DSPy Program學(xué)生自動(dòng)調(diào)整其內(nèi)部參數(shù)以在目標(biāo)任務(wù)上最大化性能。這些參數(shù)通常是指令I(lǐng)nstructions程序中各模塊如dspy.Predict內(nèi)提供給 LM 的自然語(yǔ)言指引。Few-Shot 示例Demos提示詞中用于向 LM 演示任務(wù)的 dspy.Example 對(duì)象。部分高級(jí) Teleprompter 甚至可以直接微調(diào) LM 自身的權(quán)重。正如 DSPy 教程首頁(yè)架構(gòu)圖 所示Teleprompter 一方面優(yōu)化程序Program一方面可以微調(diào)LM 客戶端同時(shí)從示例Example中獲取訓(xùn)練數(shù)據(jù)、從評(píng)估Evaluate中獲取度量標(biāo)準(zhǔn)。Teleprompter 工作的三大要素要施展魔法一個(gè) Teleprompter 需要三樣?xùn)|西和評(píng)估所需的要素非常相似學(xué)生程序The Student Program你想要改進(jìn)的 DSPy 程序。訓(xùn)練數(shù)據(jù)集trainset一組 dspy.Example 對(duì)象代表目標(biāo)任務(wù)。Teleprompter 會(huì)用這些數(shù)據(jù)來(lái)練習(xí)和學(xué)習(xí)。度量函數(shù)metric與 Evaluate 章節(jié) 中使用的同類函數(shù)用于告訴 Teleprompter 學(xué)生程序在trainset的每個(gè)示例上表現(xiàn)如何。Teleprompter 使用metric來(lái)引導(dǎo)搜索更好的指令或示例嘗試不同的組合保留在trainset上得分最高的那一組。輸出是學(xué)生程序的一個(gè)優(yōu)化版本。實(shí)戰(zhàn)用 BootstrapFewShot 自動(dòng)尋找優(yōu)質(zhì) Few-Shot 示例沿用上一章的BasicQA程序和評(píng)估設(shè)置我們從 75% 的初始成績(jī)出發(fā)。import dspy from dspy.evaluate import Evaluate # 假設(shè) LM 已配置例如 dspy.settings.configure(lm...) # 我們的簡(jiǎn)單程序 class BasicQA(dspy.Module): def __init__(self): super().__init__() self.predictor dspy.Predict(question - answer) def forward(self, question): return self.predictor(questionquestion) # 來(lái)自第 7 章的度量函數(shù) def simple_exact_match_metric(gold, prediction, traceNone): return prediction.answer.lower() gold.answer.lower() # 來(lái)自第 7 章的數(shù)據(jù)集這次當(dāng)作 trainset 使用 dev_example1 dspy.Example(questionWhat color is the sky?, answerblue) dev_example2 dspy.Example(questionWhat is 2 2?, answer4) dev_example3 dspy.Example(questionWhat is the capital of France?, answerParis) # 程序最初可能答錯(cuò)的示例 dev_example_hard dspy.Example(questionWho painted the Mona Lisa?, answerLeonardo da Vinci) trainset [dev_example1, dev_example2, dev_example3, dev_example_hard] trainset [d.with_inputs(question) for d in trainset] # 先評(píng)估初始程序大概率不完美 initial_program BasicQA() evaluator Evaluate(devsettrainset, metricsimple_exact_match_metric, display_progressFalse) initial_score evaluator(initial_program) print(fInitial Score (on trainset): {initial_score}%) # 可能輸出: Initial Score (on trainset): 75.0% 假設(shè)最后一個(gè)答錯(cuò)初始程序只有 75%。手動(dòng)加 few-shot 示例的話該加哪些、加多少這正是dspy.teleprompt.BootstrapFewShot的用武之地——它自動(dòng)為程序中的每個(gè)預(yù)測(cè)器創(chuàng)建并挑選 few-shot 演示。第 1 步導(dǎo)入 Teleprompterfrom dspy.teleprompt import BootstrapFewShot第 2 步實(shí)例化 Teleprompter需要給它用于判斷成功與否的metric函數(shù)還可以指定每個(gè)預(yù)測(cè)器最多嘗試尋找多少條候選演示max_bootstrapped_demos。# 配置 BootstrapFewShot 優(yōu)化器 # 它使用 metric 尋找成功的演示 # max_bootstrapped_demos4 表示它為每個(gè)預(yù)測(cè)器最多尋找 4 個(gè)好示例 config dict(max_bootstrapped_demos4, metricsimple_exact_match_metric) teleprompter BootstrapFewShot(**config)第 3 步編譯程序compile這是核心步驟調(diào)用 Teleprompter 的compile方法傳入初始student程序和trainset。它返回一個(gè)全新的、經(jīng)過(guò)優(yōu)化的程序。# 編譯程序 # 這一步使用 trainset 運(yùn)行優(yōu)化過(guò)程 # 用一個(gè) teacher 模型通常就是學(xué)生自身或其副本生成 trace # 通過(guò) metric 找出成功的 trace # 并把它們作為 demos 添加到學(xué)生程序的預(yù)測(cè)器中。 compiled_program teleprompter.compile(studentinitial_program, trainsettrainset) # compiled_program 是 BasicQA 的新實(shí)例 # 但其內(nèi)部預(yù)測(cè)器現(xiàn)在已經(jīng)帶上了 few-shot 示例剛才到底發(fā)生了什么在幕后BootstrapFewShot概念上做了這些事使用一個(gè) teacher 程序通常是學(xué)生的副本或另一個(gè)指定的 LM 配置運(yùn)行trainset中的每個(gè)示例對(duì)每個(gè)示例用我們的simple_exact_match_metric檢查 teacher 的輸出是否正確如果示例被正確完成Teleprompter 就把這組輸入/輸出保存為一條潛在的演示好示例收集所有成功的演示把挑選出的一組好演示數(shù)量受max_bootstrapped_demos限制賦值給compiled_program內(nèi)對(duì)應(yīng)預(yù)測(cè)器的demos屬性。第 4 步評(píng)估編譯后的程序# 評(píng)估編譯后的程序 compiled_score evaluator(compiled_program) print(fCompiled Score (on trainset): {compiled_score}%) # 如果優(yōu)化生效分?jǐn)?shù)應(yīng)該更高 # 可能輸出: Compiled Score (on trainset): 100.0%如果BootstrapFewShot找到了好示例比如 teacher 模型成功回答蒙娜麗莎后得到的那個(gè)示例compiled_program的提示詞中就會(huì)內(nèi)嵌這些示例幫助 LM 在相似問(wèn)題上表現(xiàn)得更好。我們就這樣把尋找有效 few-shot 示例的過(guò)程自動(dòng)化了。優(yōu)化如何工作概念層面不同 Teleprompter 采用不同策略但核心思路通常是目標(biāo)Goal找到能在trainset上最大化metric分?jǐn)?shù)的程序參數(shù)指令、演示。搜索空間Search Space所有可能指令或演示組合構(gòu)成的空間。搜索策略Search StrategyTeleprompter 如何探索這個(gè)空間BootstrapFewShot基于 teacher 的成功執(zhí)行來(lái)生成候選演示其他優(yōu)化器如代碼片段中提到的COPRO、MIPROv2可能讓 LM提出新指令、評(píng)估并迭代有些使用貝葉斯優(yōu)化或隨機(jī)搜索等更復(fù)雜的搜索算法。評(píng)估Evaluation用metric和trainset給每個(gè)候選配置例如帶特定演示或指令的程序打分。選擇Selection保留得分最高的配置。類比回顧概念對(duì)應(yīng)物教練Teleprompter 算法BootstrapFewShot學(xué)生你的 DSPy 程序initial_program練習(xí)trainset評(píng)分metric函數(shù)simple_exact_match_metric嘗試技巧生成/挑選不同的演示或指令采用最佳技巧生成帶有最高分演示/指令的compiled_program源碼級(jí)剖析BootstrapFewShot 的內(nèi)部流程來(lái)看BootstrapFewShot.compile()的內(nèi)部流程準(zhǔn)備 Teacher設(shè)置一個(gè) teacher 程序通常是學(xué)生程序的副本有時(shí)會(huì)配置特定設(shè)置如更高溫度以鼓勵(lì)探索若提供了標(biāo)注數(shù)據(jù)也可能使用LabeledFewShot參與 teacher 的搭建。遍歷 Trainset逐個(gè)處理trainset中的每個(gè)example。Teacher 執(zhí)行對(duì)每個(gè)example運(yùn)行 teacher 程序teacher(**example.inputs())。這一步發(fā)生在dspy.settings.context塊內(nèi)以便捕獲執(zhí)行trace。度量檢查用metric(example, prediction, trace)將 teacher 的預(yù)測(cè)與example的金標(biāo)準(zhǔn)標(biāo)簽比較。收集 Demos如果metric返回成功如True或超過(guò)閾值Teleprompter 從執(zhí)行trace中提取輸入/輸出步驟每個(gè)成功的 trace 步驟都可以成為一條候選dspy.Example演示。分配 Demos遍歷完trainset后把收集到的成功演示最多max_bootstrapped_demos條賦值給學(xué)生程序?qū)嵗袑?duì)應(yīng)預(yù)測(cè)器的demos屬性。返回編譯后的學(xué)生返回修改后的學(xué)生程序——現(xiàn)在它已攜帶 bootstrapped few-shot 示例。相關(guān)源碼文件dspy/teleprompt/teleprompt.py定義基類Teleprompter。dspy/teleprompt/bootstrap.py包含BootstrapFewShot的實(shí)現(xiàn)關(guān)鍵方法compile編排整個(gè)流程和_bootstrap_one_example負(fù)責(zé)對(duì)單個(gè)訓(xùn)練示例運(yùn)行 teacher 并檢查 metric。以下是從dspy/teleprompt/bootstrap.py提煉的簡(jiǎn)化視角展示了這個(gè)核心循環(huán)運(yùn)行 teacher → 檢查 metric → 把成功的 trace 收集為 demos → 最終把 demos 賦值給學(xué)生程序。# Simplified view from dspy/teleprompt/bootstrap.py # ... imports ... from .teleprompt import Teleprompter from .vanilla import LabeledFewShot # Used for teacher setup if labeled demos are needed import dspy class BootstrapFewShot(Teleprompter): def __init__(self, metricNone, max_bootstrapped_demos4, ...): self.metric metric self.max_bootstrapped_demos max_bootstrapped_demos # ... other initializations ... def compile(self, student, *, teacherNone, trainset): self.trainset trainset self._prepare_student_and_teacher(student, teacher) # Sets up self.student and self.teacher self._prepare_predictor_mappings() # Links student predictors to teacher predictors self._bootstrap() # Runs the core bootstrapping logic self.student self._train() # Assigns collected demos to the student self.student._compiled True return self.student def _bootstrap(self): # ... setup ... self.name2traces {name: [] for name in self.name2predictor} # Store successful traces per predictor for example_idx, example in enumerate(tqdm.tqdm(self.trainset)): # ... logic to stop early if enough demos found ... success self._bootstrap_one_example(example, round_idx0) # Try to get a demo from this example # ... potentially multiple rounds ... # ... logging ... def _bootstrap_one_example(self, example, round_idx0): # ... setup teacher context (e.g., temperature) ... try: with dspy.settings.context(trace[], **self.teacher_settings): # Optionally modify teacher LM settings for exploration # ... # Run the teacher program prediction self.teacher(**example.inputs()) trace dspy.settings.trace # Get the execution trace # Evaluate the prediction using the metric if self.metric: metric_val self.metric(example, prediction, trace) # Determine success based on metric value/threshold success bool(metric_val) # Simplified else: success True # Assume success if no metric provided except Exception: success False # ... error handling ... if success: # If successful, extract demos from the trace for step in trace: predictor, inputs, outputs step demo dspy.Example(augmentedTrue, **inputs, **outputs) try: predictor_name self.predictor2name[id(predictor)] # Store the successful demo example self.name2traces[predictor_name].append(demo) except KeyError: continue # Handle potential issues finding the predictor return success def _train(self): # Assign the collected demos to the students predictors for name, predictor in self.student.named_predictors(): demos_for_predictor self.name2traces[name][:self.max_bootstrapped_demos] # Potentially mix with labeled demos if configured # ... predictor.demos demos_for_predictor # Assign the demos! return self.student這段簡(jiǎn)化代碼揭示了幾個(gè)值得注意的工程細(xì)節(jié)teacher 設(shè)置compile的teacher參數(shù)允許你顯式指定教師程序_prepare_student_and_teacher與_prepare_predictor_mappings負(fù)責(zé)在學(xué)生與教師之間建立預(yù)測(cè)器級(jí)別的映射確保教師 trace 中的每一步都能定位到學(xué)生程序中對(duì)應(yīng)的預(yù)測(cè)器。trace 捕獲_bootstrap_one_example在dspy.settings.context(trace[], **self.teacher_settings)中運(yùn)行教師程序執(zhí)行完成后通過(guò)dspy.settings.trace拿到完整調(diào)用鏈每個(gè) trace 步驟形如(predictor, inputs, outputs)這正是從成功的執(zhí)行中提取演示的原料。演示構(gòu)造成功的 trace 步驟被包裝為dspy.Example(augmentedTrue, **inputs, **outputs)其中augmentedTrue標(biāo)記這是引導(dǎo)生成的演示區(qū)別于原始標(biāo)注數(shù)據(jù)。異常兜底teacher 執(zhí)行或 metric 拋異常時(shí)_bootstrap_one_example直接判定失敗success False保證單個(gè)壞樣本不會(huì)中斷整個(gè)優(yōu)化循環(huán)。demos 賦值_train通過(guò)student.named_predictors()遍歷學(xué)生程序的所有預(yù)測(cè)器把收集到的演示截取前max_bootstrapped_demos條寫入predictor.demos。這些 demos 在后續(xù)推理時(shí)會(huì)被 Adapter 格式化為提示詞中的 few-shot 片段最終送達(dá) LM??偨Y(jié)至此你已掌握 DSPyTeleprompters / Optimizers——自動(dòng)化提示詞工程的強(qiáng)大工具Teleprompter 像教練一樣自動(dòng)調(diào)優(yōu)你的 DSPy 程序?qū)W生它們優(yōu)化指令與**few-shot 示例demos**等參數(shù)高級(jí)優(yōu)化器還可微調(diào) LM 權(quán)重它們需要學(xué)生程序、訓(xùn)練數(shù)據(jù)集和度量函數(shù)三樣輸入我們看到BootstrapFewShot如何通過(guò)運(yùn)行 teacher 模型、收集成功執(zhí)行 trace 來(lái)自動(dòng)找到有效的 few-shot 示例teleprompter.compile()的產(chǎn)物是一個(gè)優(yōu)化后的程序?qū)嵗芍苯邮褂没蚶^續(xù)評(píng)估。Teleprompter 讓你免于繁瑣的手工調(diào)參從而更高效地構(gòu)建高性能的 LM 程序。理解了如何構(gòu)建、評(píng)估并自動(dòng)優(yōu)化 DSPy 程序之后下一步就是解決優(yōu)化后的程序如何與不同數(shù)據(jù)格式、不同模型尤其是聊天模型順暢交互的問(wèn)題——這正是 Adapter第 9 章 的主題?!久赓M(fèi)下載鏈接】Tutorial-Codebase-KnowledgePocket Flow: Codebase to Tutorial項(xiàng)目地址: https://gitcode.com/gh_mirrors/tu/Tutorial-Codebase-Knowledge創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考