❤️ 如果你也关注 AI 的发展现状,且对 AI 应用开发非常感兴趣,我会每日跟你分享最新的 AI 资讯和开源应用,也会不定期分享自己的想法和开源实例,欢迎关注我哦!
🥦 微信公众号|搜一搜:蚝油菜花 🥦
🚀 快速阅读
- 功能:自动化优化提示词,提升 LLMs 在特定任务中的表现。
- 机制:通过反馈驱动的批评和合成过程,迭代优化提示指令和示例。
- 应用:适用于情感分析、智能教育助手、医疗诊断支持等多个领域。
正文(附运行示例)
PromptWizard 是什么
PromptWizard 是微软推出的自动化提示优化框架,旨在改进大型语言模型(LLMs)在特定任务中的表现。该框架基于自我演变和自我适应机制,通过反馈驱动的批评和合成过程,在探索和利用之间找到平衡,迭代地优化提示指令和上下文示例,从而提高模型的准确性和效率,减少 API 调用和令牌使用,降低成本。
PromptWizard 在多个任务和数据集上展现了卓越的性能,即使在训练数据有限或使用较小模型的情况下也能保持高效。
PromptWizard 的主要功能
- 自动化提示优化:自动优化 LLMs 的提示,提高特定任务的性能。
- 自我演变和自我适应:框架能自我演变和适应,生成更好的任务特定提示。
- 反馈驱动的批评和合成:基于反馈机制,不断改进提示和示例。
- 迭代细化:框架迭代地细化提示指令和上下文示例,提升模型输出的质量。
PromptWizard 的技术原理
- 问题表述:用问题描述和初始提示指令开始,为后续优化提供基础。
- 迭代细化提示指令:通过变异、评分、批评和合成组件,生成更具体和有效的指令。
- 识别多样化示例:从训练数据中选择正例和负例,优化提示。
- 顺序优化:同时优化提示指令和少量示例,基于迭代反馈循环进行。
- 自我生成的推理和验证:自动为每个示例生成详细的推理链,验证示例的一致性和相关性。
- 任务意图和专家角色的整合:将任务意图和专家角色整合到提示中,提高模型性能和解释性。
如何运行 PromptWizard
安装
克隆仓库:
git clone https://github.com/microsoft/PromptWizard cd PromptWizard
创建并激活虚拟环境:
在 Windows 上:
python -m venv venv venv\Scripts\activate
在 macOS/Linux 上:
python -m venv venv source venv/bin/activate
- 安装包:
pip install -e .
快速开始
PromptWizard 提供了三种主要的使用场景:
- 优化提示而不使用示例。
- 生成合成示例并使用它们优化提示。
- 使用训练数据优化提示。
运行 PromptWizard 的示例
以下是使用 PromptWizard 优化提示的简单示例:
设置环境变量
from dotenv import load_dotenv load_dotenv(override=True)
导入依赖
import sys sys.path.insert(0, "../../") import promptwizard from promptwizard.glue.promptopt.instantiate import GluePromptOpt from promptwizard.glue.promptopt.techniques.common_logic import DatasetSpecificProcessing from promptwizard.glue.common.utils.file import save_jsonlist from typing import Any from tqdm import tqdm from re import compile, findall import os from datasets import load_dataset import yaml
更新 YAML 文件
def update_yaml_file(file_path, config_dict): with open(file_path, 'r') as file: data = yaml.safe_load(file) for field, value in config_dict.items(): data[field] = value with open(file_path, 'w') as file: yaml.dump(data, file, default_flow_style=False) print("YAML file updated successfully!")
设置路径
path_to_config = "configs" promptopt_config_path = os.path.join(path_to_config, "promptopt_config.yaml") setup_config_path = os.path.join(path_to_config, "setup_config.yaml")
优化提示的三种情景
情景 1:无训练数据,且不想在最终提示中使用上下文示例
file_path = 'configs/promptopt_config.yaml'
config_dict = {
"task_description": "You are a mathematics expert. You will be given a mathematics problem which you need to solve",
"base_instruction": "Lets think step by step.",
"mutation_rounds": 5
}
update_yaml_file(file_path, config_dict)
gp = GluePromptOpt(promptopt_config_path, setup_config_path, dataset_jsonl=None, data_processor=None)
best_prompt, expert_profile = gp.get_best_prompt(use_examples=False, run_without_train_examples=True, generate_synthetic_examples=False)
情景 2:无训练数据,但在最终提示中使用上下文示例
- 步骤 1:生成合成数据
```python
file_path = 'configs/promptopt_config.yaml'
config_dict = {
"num_train_examples": 20
}
update_yaml_file(file_path, config_dict)
gp = GluePromptOpt(promptopt_config_path, setup_config_path, dataset_jsonl=None, data_processor=None)
best_prompt, expert_profile = gp.get_best_prompt(use_examples=False, run_without_train_examples=False, generate_synthetic_examples=True)
- **步骤 2:使用合成数据优化提示**
```python
class GSM8k(DatasetSpecificProcessing):
def dataset_to_jsonl(self, dataset_jsonl: str, **kwargs: Any) -> None:
def extract_answer_from_output(completion):
ans_re = compile(r"#### (-?[0-9\.,]+)")
self.INVALID_ANS = "[invalid]"
match = ans_re.search(completion)
if match:
match_str = match.group(1).strip()
match_str = match_str.replace(",", "")
return match_str
else:
return self.INVALID_ANS
examples_set = []
for _, sample in tqdm(enumerate(kwargs["dataset"]), desc="Evaluating samples"):
example = {
DatasetSpecificProcessing.QUESTION_LITERAL: sample['question'],
DatasetSpecificProcessing.ANSWER_WITH_REASON_LITERAL: sample['answer'],
DatasetSpecificProcessing.FINAL_ANSWER_LITERAL: extract_answer_from_output(sample["answer"])
}
examples_set.append(example)
save_jsonlist(dataset_jsonl, examples_set, "w")
def extract_final_answer(self, answer: str):
if not answer:
return self.INVALID_ANS
model_pred = answer.lower()
preds = model_pred.split(self.ANSWER_START.lower())
answer_flag = True if len(preds) > 1 else False
pred = preds[-1].replace(",", "")
pred = [s for s in findall(r'-?\d+\.?\d*', pred)]
if len(pred) == 0:
return self.INVALID_ANS
if answer_flag:
pred = pred[0]
else:
pred = pred[-1]
if pred[-1] == ".":
pred = pred[:-1]
return pred
gsm8k_processor = GSM8k()
file_path = 'configs/promptopt_config.yaml'
config_dict = {
"task_description": "You are a mathematics expert. You will be given a mathematics problem which you need to solve",
"base_instruction": "Lets think step by step.",
"mutation_rounds": 2,
"few_shot_count": 5,
"generate_reasoning": True,
"mutate_refine_iterations": 3,
"seen_set_size": 20
}
update_yaml_file(file_path, config_dict)
gp = GluePromptOpt(promptopt_config_path, setup_config_path, dataset_jsonl="train_synthetic.jsonl", data_processor=gsm8k_processor)
best_prompt, expert_profile = gp.get_best_prompt(use_examples=True, run_without_train_examples=False, generate_synthetic_examples=False)
情景 3:有训练数据,并在最终提示中使用上下文示例
if not os.path.exists("data"):
os.mkdir("data")
dataset = load_dataset("openai/gsm8k", "main")
num_samples = 0
for dataset_type in ['train', 'test']:
data_list = []
for data in dataset[dataset_type]:
data_list.append({
"question": data['question'], "answer": data['answer']})
if num_samples == 100 and dataset_type == 'train':
break
num_samples += 1
gsm8k_processor.dataset_to_jsonl(f"data/{dataset_type}.jsonl", dataset=data_list)
file_path = 'configs/promptopt_config.yaml'
config_dict = {
"task_description": "You are a mathematics expert. You will be given a mathematics problem which you need to solve",
"base_instruction": "Lets think step by step.",
"mutation_rounds": 2,
"few_shot_count": 5,
"generate_reasoning": True,
"mutate_refine_iterations": 3,
"seen_set_size": 20
}
update_yaml_file(file_path, config_dict)
gp = GluePromptOpt(promptopt_config_path, setup_config_path, dataset_jsonl=os.path.join("data", "train.jsonl"), data_processor=gsm8k_processor)
best_prompt, expert_profile = gp.get_best_prompt(use_examples=True, run_without_train_examples=False, generate_synthetic_examples=False)
资源
- 项目官网:https://microsoft.github.io/PromptWizard
- GitHub 仓库:https://github.com/microsoft/PromptWizard
- arXiv 技术论文:https://arxiv.org/pdf/2405.18369
❤️ 如果你也关注 AI 的发展现状,且对 AI 应用开发非常感兴趣,我会每日跟你分享最新的 AI 资讯和开源应用,也会不定期分享自己的想法和开源实例,欢迎关注我哦!
🥦 微信公众号|搜一搜:蚝油菜花 🥦