标签: LLMs

  • 毕业生职位分类案例研究

    Clavié等人(2023)提供了一项关于提示工程应用于生产系统中中等规模文本分类用例的案例研究。通过使用将工作分类为真正的“初级职位”(是否适合应届毕业生的任务),他们评估了一系列提示工程技术,并使用GPT-3.5 (gpt-3.5-turbo)报告了他们的结果。

    该研究表明,LLMs在所有经过测试的模型中表现最佳,包括DeBERTa-V3中的一个极强的基准模型。gpt-3.5-turbo在所有关键指标上也明显优于早期的GPT3变体,但需要进行额外的输出解析,因为其遵循模板的能力似乎不如其他变体。

    他们的提示工程方法的关键发现是:

    • 对于像这样不需要专业知识的任务,Few-shot CoT提示在所有实验中的表现都不如Zero-shot提示。
    • 提示对于引导正确推理的影响非常巨大。简单地要求模型对给定的工作进行分类会得到65.6的F1分数,而后提示工程模型的F1分数为91.7。
    • 试图强制模型遵循模板会降低所有情况下的性能(这种行为在GPT-4的早期测试中消失,这项测试在该论文之后进行)。
    • 许多小的修改对性能产生了巨大的影响。
      • 下面的表格显示了所有经过测试的修改。
      • 正确地给出指令并重复关键点似乎是最有效的提升性能的方法。
      • 简单地给模型一个(人类的)名字并这样称呼它,可以将F1分数提高0.6个百分点。

    经本文测试的 Prompt策略

    Short nameDescription
    Baseline提供一个职位招聘信息并询问它是否适合毕业生。
    CoT在查询之前给出几个准确分类的示例。
    Zero-CoT要求模型一步步推理后再给出答案。
    rawinst通过添加到用户消息中, 来给出有关其角色和任务的说明。
    sysinst作为系统消息给出有关其角色和任务的说明。
    bothinst将角色作为系统消息和任务作为用户消息拆分说明。
    mock通过模拟讨论来给出任务说明,其中模型确认了它们。
    reit通过重复强调关键要素来加强说明。
    strict要求模型严格按照给定模板回答。
    loose要求仅根据给定模板给出最终答案。
    right要求模型得出正确的结论。
    info提供额外的信息以解决常见的推理失败。
    name为模型取一个我们在对话中称呼它的名称。
    pos在查询之前向模型提供正面反馈。

    所有Prompt性能策略对性能的影响

    PrecisionRecallF1Template Stickiness
    Baseline61.270.665.679%
    CoT72.685.178.487%
    Zero-CoT75.588.381.465%
    +rawinst8092.485.868%
    +sysinst77.790.983.869%
    +bothinst81.993.987.571%
    +bothinst+mock83.395.188.874%
    +bothinst+mock+reit83.895.589.375%
    +bothinst+mock+reit+strict79.993.786.398%
    +bothinst+mock+reit+loose80.594.887.195%
    +bothinst+mock+reit+right8495.989.677%
    +bothinst+mock+reit+right+info84.996.590.377%
    +bothinst+mock+reit+right+info+name85.796.890.979%
    +bothinst+mock+reit+right+info+name+pos86.99791.781%

    “Template stickiness” 指的是模型多频繁地按照所期望的格式作答。

  • 偏见

    LLMs可能会产生问题的生成结果,这些结果可能会对模型在下游任务上的性能产生负面影响,并显示可能会恶化模型性能的偏见。其中一些可以通过有效的提示策略来缓解,但可能需要更高级的解决方案,如调节和过滤。

    范例的分布

    在进行少样本学习时,范例的分布是否会影响模型的性能或以某种方式使模型产生偏见?我们可以在这里进行简单的测试。

    提示:

    Q: 我刚刚得到了最好的消息!
    A: 积极
    Q: 我们刚刚在工作中得到了加薪!
    A: 积极
    Q: 我为今天所取得的成就感到非常自豪。
    A: 积极
    Q: 我今天过得非常愉快!
    A: 积极
    Q: 我真的很期待周末。
    A: 积极
    Q: 我刚刚得到了最好的礼物!
    A: 积极
    Q: 我现在非常开心。
    A: 积极
    Q: 我很幸运拥有如此出色的家庭。
    A: 积极
    Q: 外面的天气非常阴沉。
    A: 消极
    Q: 我刚刚听到了一些可怕的消息。
    A: 消极
    Q: 那让人感到不愉快。
    A:

    输出:

    消极

    在上面的例子中,范例的分布似乎不会使模型产生偏见。这很好。让我们尝试另一个更难分类的例子,看看模型的表现如何:

    提示:

    Q: 这里的食物很美味!
    A: 积极 
    Q: 我已经厌倦了这门课程。
    A: 消极
    Q: 我不敢相信我考试不及格了。
    A: 消极
    Q: 我今天过得很愉快!
    A: 积极 
    Q: 我讨厌这份工作。
    A: 消极
    Q: 这里的服务很糟糕。
    A: 消极
    Q: 我对自己的生活感到非常沮丧。
    A: 消极
    Q: 我从来没有休息过。
    A: 消极
    Q: 这顿饭尝起来很糟糕。
    A: 消极
    Q: 我受不了我的老板。
    A: 消极
    Q: 我感觉到了一些东西。
    A:

    输出:

    消极

    虽然最后一句话有点主观,但我翻转了分布,使用了8个积极的例子和2个消极的例子,然后再次尝试了完全相同的句子。你猜模型的回答是什么?它回答“积极”。对于这个问题,模型可能有很多关于情感分类的知识,因此很难让它显示出偏见。这里的建议是避免偏斜分布,而是为每个标签提供更平衡的例子数量。对于模型没有太多知识的更难的任务,它可能会更加困难。

    范例的顺序

    在进行少样本学习时,范例的顺序是否会影响模型的性能或以某种方式使模型产生偏见?

    你可以尝试上面的例子,看看是否可以通过改变顺序使模型对某个标签产生偏见。建议随机排序范例。例如,避免先放所有的积极例子,然后最后放消极例子。如果标签的分布偏斜,这个问题会进一步放大。一定要进行大量实验,以减少这种类型的偏见。

  • 生成数据

    生成数据

    LLMs具有生成连贯文本的强大能力。使用有效的提示策略可以引导模型产生更好、更一致和更真实的响应。LLMs还可以特别有用地生成数据,这对于运行各种实验和评估非常有用。例如,我们可以使用它来为情感分类器生成快速样本,如下所示:

    LLMs生成数据图

    提示:

    生成10个情感分析的范例。示例被归类为正面或负面。生成2个负面示例和8个正面示例。使用以下格式的示例:Q:<句子>A:<情感>

    输出:

    Q:我刚刚得到了最好的消息!
    A:正面
    Q:我们刚刚在工作中得到了加薪!
    A:正面
    Q:我为今天所取得的成就感到非常自豪。
    A:正面
    Q:我度过了最美好的一天!
    A:正面
    Q:我真的很期待周末。
    A:正面
    Q:我刚刚得到了最好的礼物!
    A:正面
    Q:我现在感到非常快乐。
    A:正面
    Q:我很幸运有这么棒的家人。
    A:正面
    Q:外面的天气很阴沉。
    A:负面
    Q:我刚刚得到了一些可怕的消息。
    A:负面

    这非常有用。我们实际上在指南的另一个部分中使用了这个示例进行不同的测试。

  • PAL(程序辅助语言模型)

    PAL(程序辅助语言模型)

    Gao等人(2022)(opens in a new tab)提出了一种使用LLMs读取自然语言问题并生成程序作为中间推理步骤的方法。被称为程序辅助语言模型(PAL),它与思维链提示不同,因为它不是使用自由形式文本来获得解决方案,而是将解决步骤卸载到类似Python解释器的编程运行时中。

    图片来源:Gao等人(2022)(opens in a new tab)

    图片来源:Gao等人(2022)(opens in a new tab)

    让我们以LangChain和OpenAI GPT-3为例。我们有兴趣开发一个简单的应用程序,它能够解释所提出的问题,并利用Python解释器提供答案。

    具体来说,我们有兴趣创建一个功能,允许使用LLM回答需要日期理解的问题。我们将为LLM提供一个提示,其中包括一些示例,这些示例是从这里(opens in a new tab)采用的。

    这是我们需要导入的包:

    import openaifrom datetime import datetimefrom dateutil.relativedelta import relativedeltaimport osfrom langchain.llms import OpenAIfrom dotenv import load_dotenv

    让我们先配置一些环境:

    load_dotenv() # API configurationopenai.api_key = os.getenv("OPENAI_API_KEY") # for LangChainos.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")

    设置模型实例:

    llm = OpenAI(model_name='text-davinci-003', temperature=0)

    设置提示+问题:

    question = "Today is 27 February 2023. I was born exactly 25 years ago. What is the date I was born in MM/DD/YYYY?" DATE_UNDERSTANDING_PROMPT = """# Q: 2015 is coming in 36 hours. What is the date one week from today in MM/DD/YYYY?# If 2015 is coming in 36 hours, then today is 36 hours before.today = datetime(2015, 1, 1) - relativedelta(hours=36)# One week from today,one_week_from_today = today + relativedelta(weeks=1)# The answer formatted with %m/%d/%Y isone_week_from_today.strftime('%m/%d/%Y')# Q: The first day of 2019 is a Tuesday, and today is the first Monday of 2019. What is the date today in MM/DD/YYYY?# If the first day of 2019 is a Tuesday, and today is the first Monday of 2019, then today is 6 days later.today = datetime(2019, 1, 1) + relativedelta(days=6)# The answer formatted with %m/%d/%Y istoday.strftime('%m/%d/%Y')# Q: The concert was scheduled to be on 06/01/1943, but was delayed by one day to today. What is the date 10 days ago in MM/DD/YYYY?# If the concert was scheduled to be on 06/01/1943, but was delayed by one day to today, then today is one day later.today = datetime(1943, 6, 1) + relativedelta(days=1)# 10 days ago,ten_days_ago = today - relativedelta(days=10)# The answer formatted with %m/%d/%Y isten_days_ago.strftime('%m/%d/%Y')# Q: It is 4/19/1969 today. What is the date 24 hours later in MM/DD/YYYY?# It is 4/19/1969 today.today = datetime(1969, 4, 19)# 24 hours later,later = today + relativedelta(hours=24)# The answer formatted with %m/%d/%Y istoday.strftime('%m/%d/%Y')# Q: Jane thought today is 3/11/2002, but today is in fact Mar 12, which is 1 day later. What is the date 24 hours later in MM/DD/YYYY?# If Jane thought today is 3/11/2002, but today is in fact Mar 12, then today is 3/1/2002.today = datetime(2002, 3, 12)# 24 hours later,later = today + relativedelta(hours=24)# The answer formatted with %m/%d/%Y islater.strftime('%m/%d/%Y')# Q: Jane was born on the last day of Feburary in 2001. Today is her 16-year-old birthday. What is the date yesterday in MM/DD/YYYY?# If Jane was born on the last day of Feburary in 2001 and today is her 16-year-old birthday, then today is 16 years later.today = datetime(2001, 2, 28) + relativedelta(years=16)# Yesterday,yesterday = today - relativedelta(days=1)# The answer formatted with %m/%d/%Y isyesterday.strftime('%m/%d/%Y')# Q: {question}""".strip() + '\n'
    llm_out = llm(DATE_UNDERSTANDING_PROMPT.format(question=question))print(llm_out)
    exec(llm_out)print(born)

    这将输出以下内容:02/27/1998