Transformers 文档

Prompt engineering

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

Prompt engineering

Prompt engineering 或 prompting,使用自然语言来提高大型语言模型 (LLM) 在各种任务上的性能。Prompt 可以引导模型生成期望的输出。在许多情况下,您甚至不需要为任务进行 微调 的模型。您只需要一个好的 Prompt。

尝试使用 Prompt 来让 LLM 对文本进行分类。创建 Prompt 时,提供关于任务和期望结果的具体说明非常重要。

from transformers import pipeline
import torch

pipeline = pipeline(task="text-generation", model="mistralai/Mistal-7B-Instruct-v0.1", dtype=torch.bfloat16, device_map="auto")
prompt = """Classify the text into neutral, negative or positive.
Text: This movie is definitely one of my favorite movies of its kind. The interaction between respectable and morally strong characters is an ode to chivalry and the honor code amongst thieves and policemen.
Sentiment:
"""

outputs = pipeline(prompt, max_new_tokens=10)
for output in outputs:
    print(f"Result: {output['generated_text']}")
Result: Classify the text into neutral, negative or positive. 
Text: This movie is definitely one of my favorite movies of its kind. The interaction between respectable and morally strong characters is an ode to chivalry and the honor code amongst thieves and policemen.
Sentiment:
Positive

挑战在于设计能够产生您预期结果的 Prompt,因为语言如此极其微妙和富有表现力。

本指南涵盖了 Prompt engineering 的最佳实践、技术以及用于解决语言和推理任务的示例。

最佳实践

  1. 尝试选择最新的模型以获得最佳性能。请记住,LLM 可以有两种变体:基础模型指令微调模型(或聊天模型)。

    基础模型非常擅长根据初始 Prompt 完成文本,但它们不擅长遵循指令。指令微调模型是经过专门训练的基础模型版本,使用指令或对话数据进行训练。这使得指令微调模型更适合 Prompt。

    现代 LLM 通常是仅解码器模型,但也有一些编码器-解码器 LLM,如 Flan-T5BART,可用于 Prompt。对于编码器-解码器模型,请确保将管道任务标识符设置为 text2text-generation 而不是 text-generation

  2. 从一个简短简单的 Prompt 开始,并对其进行迭代以获得更好的结果。

  3. 将指令放在 Prompt 的开头或结尾。对于较长的 Prompt,模型可能会应用优化来防止注意力呈二次方扩展,这会更加强调 Prompt 的开头和结尾。

  4. 清楚地将指令与感兴趣的文本分开。

  5. 关于任务和期望的输出要具体和描述性,例如包括其格式、长度、风格和语言。避免模糊的描述和说明。

  6. 指令应侧重于“做什么”而不是“不要做什么”。

  7. 通过写下第一个词甚至第一个句子来引导模型生成正确的输出。

  8. 尝试其他技术,如 少样本学习思维链 来提高结果。

  9. 使用不同的模型测试您的 Prompt,以评估它们的鲁棒性。

  10. 版本化并跟踪您的 Prompt 性能。

技术

仅凭一个好的 Prompt,即所谓的零样本 Prompt,可能不足以获得您想要的结果。您可能需要尝试一些 Prompt 技术来获得最佳性能。

本节介绍了几种 Prompt 技术。

少样本 Prompt

少样本 Prompt 通过包含模型应根据输入生成的具体示例来提高准确性和性能。这些明确的示例使模型能更好地理解您正在寻找的任务和输出格式。尝试用不同数量的示例(2、4、8 等)进行实验,看看它如何影响性能。下面的示例为模型提供了 1 个示例(1-shot)的输出格式(MM/DD/YYYY 格式的日期)它应该返回。

from transformers import pipeline
import torch

pipeline = pipeline(model="mistralai/Mistral-7B-Instruct-v0.1", dtype=torch.bfloat16, device_map="auto")
prompt = """Text: The first human went into space and orbited the Earth on April 12, 1961.
Date: 04/12/1961
Text: The first-ever televised presidential debate in the United States took place on September 28, 1960, between presidential candidates John F. Kennedy and Richard Nixon.
Date:"""

outputs = pipeline(prompt, max_new_tokens=12, do_sample=True, top_k=10)
for output in outputs:
    print(f"Result: {output['generated_text']}")
# Result: Text: The first human went into space and orbited the Earth on April 12, 1961.
# Date: 04/12/1961
# Text: The first-ever televised presidential debate in the United States took place on September 28, 1960, between presidential candidates John F. Kennedy and Richard Nixon.
# Date: 09/28/1960

少样本 Prompt 的缺点是您需要创建更长的 Prompt,这会增加计算量和延迟。Prompt 长度也有限制。最后,模型可以从您的示例中学习到非预期的模式,并且在复杂的推理任务上可能效果不佳。

为了改进现代指令微调 LLM 的少样本 Prompt,请使用模型特定的 聊天模板。这些模型在“用户”和“助手”之间的回合制对话数据集上进行了训练。将您的 Prompt 与此对齐可以提高性能。

将您的 Prompt 结构化为回合制对话,并使用 apply_chat_template 方法对其进行标记和格式化。

from transformers import pipeline
import torch

pipeline = pipeline(model="mistralai/Mistral-7B-Instruct-v0.1", dtype=torch.bfloat16, device_map="auto")

messages = [
    {"role": "user", "content": "Text: The first human went into space and orbited the Earth on April 12, 1961."},
    {"role": "assistant", "content": "Date: 04/12/1961"},
    {"role": "user", "content": "Text: The first-ever televised presidential debate in the United States took place on September 28, 1960, between presidential candidates John F. Kennedy and Richard Nixon."}
]

prompt = pipeline.tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)

outputs = pipeline(prompt, max_new_tokens=12, do_sample=True, top_k=10)

for output in outputs:
    print(f"Result: {output['generated_text']}")

虽然基本的少样本 Prompt 方法将示例嵌入到单个文本字符串中,但聊天模板格式提供了以下好处。

  • 模型可能具有更好的理解能力,因为它能更好地识别模式以及用户输入和助手输出的预期角色。
  • 模型可能更一致地输出所需的输出格式,因为它在训练期间的结构类似于其输入。

始终查阅特定指令微调模型的文档,以了解其聊天模板的格式,以便您可以相应地构建您的少样本 Prompt。

思维链

思维链 (CoT) 通过提供一系列有助于模型更深入地“思考”某个主题的 Prompt,从而有效地生成更连贯、更有推理能力的输出。

下面的示例为模型提供了几个 Prompt 来逐步进行中间推理。

from transformers import pipeline
import torch

pipeline = pipeline(model="mistralai/Mistral-7B-Instruct-v0.1", dtype=torch.bfloat16, device_map="auto")
prompt = """Let's go through this step-by-step:
1. You start with 15 muffins.
2. You eat 2 muffins, leaving you with 13 muffins.
3. You give 5 muffins to your neighbor, leaving you with 8 muffins.
4. Your partner buys 6 more muffins, bringing the total number of muffins to 14.
5. Your partner eats 2 muffins, leaving you with 12 muffins.
If you eat 6 muffins, how many are left?"""

outputs = pipeline(prompt, max_new_tokens=20, do_sample=True, top_k=10)
for output in outputs:
    print(f"Result: {output['generated_text']}")
Result: Let's go through this step-by-step:
1. You start with 15 muffins.
2. You eat 2 muffins, leaving you with 13 muffins.
3. You give 5 muffins to your neighbor, leaving you with 8 muffins.
4. Your partner buys 6 more muffins, bringing the total number of muffins to 14.
5. Your partner eats 2 muffins, leaving you with 12 muffins.
If you eat 6 muffins, how many are left?
Answer: 6

少样本 Prompt 类似,CoT 的缺点是它需要更多的工作来设计一系列 Prompt,以帮助模型推理复杂的任务,并且 Prompt 长度会增加延迟。

微调

虽然 Prompt 是与 LLM 合作的强大方式,但在某些情况下,微调模型或甚至微调模型效果更好。

以下是一些需要微调模型的示例场景。

  • 您的领域与 LLM 预训练的领域截然不同,并且大量的 Prompt 都没有产生您想要的结果。
  • 您的模型需要在低资源语言中表现良好。
  • 您的模型需要处理具有严格监管要求的敏感数据。
  • 由于成本、隐私、基础设施或其他限制,您正在使用小型模型。

在所有这些场景中,请确保您拥有足够大的特定领域数据集来训练您的模型,拥有足够的时间和资源,并且微调的成本是值得的。否则,您最好尝试优化您的 Prompt。

示例

下面的示例演示了为不同任务 Prompt LLM。

命名实体识别
翻译
摘要
问答
from transformers import pipeline
import torch

pipeline = pipeline(model="mistralai/Mistral-7B-Instruct-v0.1", dtype=torch.bfloat16, device_map="auto")
prompt = """Return a list of named entities in the text.
Text: The company was founded in 2016 by French entrepreneurs Clément Delangue, Julien Chaumond, and Thomas Wolf in New York City, originally as a company that developed a chatbot app targeted at teenagers.
Named entities:
"""

outputs = pipeline(prompt, max_new_tokens=50, return_full_text=False)
for output in outputs:
    print(f"Result: {output['generated_text']}")
Result:  [Clément Delangue, Julien Chaumond, Thomas Wolf, company, New York City, chatbot app, teenagers]
在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.