2024-07-17 11:35 湖北
OpenAI思维模型:提示工程、检索增强生成 (RAG) 和微调
如何在使用 LLM 时最大限度地提高正确性和一致性行为
优化 LLM 很难。
我们与初创企业和大型企业的许多开发人员合作过,优化之所以困难,可以归结为以下原因:
了解如何开始优化准确率
何时使用哪种优化方法
什么样的精度水平才适合生产
本文给出了一个关于如何优化 LLM 以提高准确性和行为的思维模型。我们将探讨诸如提示工程、检索增强生成 (RAG) 和微调等方法。我们还将重点介绍如何以及何时使用每种技术,并分享一些陷阱。
在您阅读时,重要的是在心理上将这些原则与准确性对您的特定用例的意义联系起来。这似乎很明显,但制作一份需要人工修复的糟糕副本与退还客户 1000 美元而不是 100 美元之间是有区别的。在讨论 LLM 准确性时,您应该大致了解 LLM 失败会让您付出多少代价,以及成功会为您节省或赚取多少 - 这一点将在最后重新讨论,届时我们将讨论多少准确性对于生产来说“足够好”。
LLM 优化上下文
许多关于优化的“操作指南”将其描绘成一个简单的线性流程 - 从提示工程开始,然后转到检索增强生成,然后进行微调。然而,情况往往并非如此 - 这些都是解决不同问题的杠杆,要想朝着正确的方向进行优化,你需要拉动正确的杠杆。
将 LLM 优化构建为一个矩阵很有用:
典型的 LLM 任务将从左下角的提示工程开始,我们在此进行测试、学习和评估以获得基准。一旦我们审查了这些基准示例并评估了它们不正确的原因,我们就可以采取其中一个措施:
上下文优化:当出现以下情况时,您需要针对上下文进行优化:1)模型缺乏上下文知识(因为它不在其训练集中);2)其知识已过时;或 3)它需要专有信息知识。此轴可最大限度地提高响应准确性。
LLM 优化:当 1) 模型产生的结果不一致且格式不正确、2) 语气或说话风格不正确,或 3) 推理没有得到一致遵循时,您需要优化 LLM。此轴最大化了行为的一致性。
实际上,这变成了一系列优化步骤,我们评估、提出如何优化的假设、应用它、评估并重新评估下一步。以下是一个相当典型的优化流程示例:
在此示例中,我们执行以下操作:
从提示开始,然后评估其表现
添加静态小样本,这应该可以提高结果的一致性
添加检索步骤,以便根据问题动态地引入少量样本,这可确保每个输入的相关上下文,从而提高性能
准备 50 多个示例的数据集并微调模型以提高一致性
调整检索并添加事实核查步骤来发现幻觉,从而实现更高的准确率
使用包含增强型 RAG 输入的新训练示例重新训练微调模型
这是针对棘手业务问题的典型优化流程 - 它帮助我们决定是否需要更多相关上下文,或者是否需要模型中更一致的行为。一旦我们做出决定,我们就知道要采取哪个杠杆作为优化的第一步。
现在我们有了思维模型,让我们深入研究针对所有这些领域采取行动的方法。我们将从左下角的“提示工程”开始。
提示工程
提示工程通常是最好的起点。它通常是摘要、翻译和代码生成等用例所需的唯一方法,在这些用例中,零样本方法可以达到生产级别的准确性和一致性。
这是因为它迫使您定义准确性对于您的用例意味着什么 - 您从最基本的层面开始,提供输入,因此您需要能够判断输出是否符合您的期望。如果它不是您想要的,那么原因将告诉您使用什么来推动进一步的优化。
为了实现这一点,您应该始终从一个简单的提示和预期的输出开始,然后通过添加上下文、说明或示例来优化提示,直到它满足您的要求。
优化
为了优化您的提示,我将主要依靠OpenAI API 文档中的“提示工程”指南中的策略。每种策略都可以帮助您调整上下文、LLM 或两者:
策略 | 上下文优化 | LLM 优化 |
---|---|---|
写下清晰的说明 | X | |
将复杂任务拆分为更简单的子任务 | X | X |
给 GPT 时间“思考” | X | |
系统地测试变化 | X | X |
提供参考文本 | X | |
使用外部工具 | X |
这些可能有点难以形象化,所以我们将通过一个实际示例来测试它们。让我们使用 gpt-4-turbo 来纠正冰岛语句子,看看它是如何工作的。
提示工程进行语言校正
冰岛语错误语料库包含带有错误的冰岛语句子和该句子的更正版本的组合。我们将使用基线 GPT-4 模型来尝试解决此任务,然后应用不同的优化技术来了解如何提高模型的性能。
给定一个冰岛语句子,我们希望模型返回该句子的更正版本。我们将使用 Bleu 分数来衡量翻译的相对质量。
系统 | 用户 | 事实 | 助手 | BLEU |
---|---|---|---|---|
以下句子包含冰岛语句子,可能包含错误。请尽可能少地更改单词以更正这些错误。 | Sörvistölur eru nær hálsi og skartgripir kvenna á brjótsti。 | Sörvistölur eru nær hálsi og skartgripir kvenna á brjósti。 | Sörvistölur eru nær hálsi og skartgripir kvenna á brjósti。 | 1.0 |
我们首次尝试使用 GPT-4,没有使用任何示例,它表现不错,BLEU 得分为 62。现在我们将添加一些少样本示例,看看我们是否可以通过展示而不是讲述来教会模型我们想要的风格。示例如下:
整体翻译质量更好,Bleu 评分提高到70 (+8%)。这相当不错,表明为模型提供任务示例有助于其学习。
这告诉我们,我们需要优化的是模型的行为——它已经拥有解决问题所需的知识,因此提供更多的示例可能是我们需要的优化。
我们已经看到,提示工程是一个很好的起点,并且通过正确的调整方法,我们可以将性能推向更高的水平。
然而,提示工程的最大问题是它通常无法扩展——我们要么需要输入动态上下文,以使模型能够处理比通过简单的上下文填充所能处理的更广泛的问题,要么我们需要比通过少量示例所能实现的更一致的行为。
使用长上下文来扩展提示工程
长上下文模型允许提示工程进一步扩展 - 但是,请注意,模型可能难以在非常大的提示和复杂的指令中保持注意力,
因此您应该始终将长上下文模型与不同上下文大小的评估配对,以确保您不会迷失在中间。
“迷失在中间”是一个术语,它描述了 LLM 如何无法同时平等地关注给它的所有标记。
这可能导致它似乎随机地丢失信息。
这并不意味着你不应该使用长上下文,但你需要将它与彻底的评估配对。
一位开源贡献者 Greg Kamradt 做了一个很有用的评估,
称为“大海捞针”(NITA),它将一条信息隐藏在长上下文文档的不同深度,
并评估检索质量。这说明了长上下文的问题 - 它承诺一个更简单的检索过程,
您可以在其中转储上下文中的所有内容,但代价是准确性。
那么,提示工程究竟能走多远呢?答案是,这要视情况而定,而决策的方式是通过评估。
评估
这就是为什么一个包含评估问题和基本事实答案的良好提示是此阶段的最佳输出。如果我们有一组 20 多个问题和答案,并且我们已经研究了失败的细节并假设了失败的原因,那么我们就有了采用更高级优化方法的正确基础。
在继续使用更复杂的优化方法之前,还值得考虑如何自动化此评估以加快迭代速度。我们发现一些有效的常见做法如下:
使用ROUGE或BERTScore等方法提供粗略判断。这与人工审阅者没有那么密切的关联,但可以快速有效地衡量迭代对模型输出的改变程度。
使用GPT-4作为 G-Eval 论文中概述的评估器,向 LLM 提供记分卡,以尽可能客观地评估输出。
如果您想深入了解这些内容,请查看如下指南,它将指导您在实践中完成所有这些操作。
指南:
How to evaluate a summarization task
https://cookbook.openai.com/examples/evaluation/how_to_eval_abstractive_summarization
理解工具
因此,您已完成提示工程,并获得了评估集,但您的模型仍未达到预期效果。接下来最重要的步骤是诊断模型失败之处,以及哪种工具最适合改进模型。
以下是实现此目的的基本框架:
你可以将每个失败的评估问题视为一个上下文或学习记忆问题。打个比方,想象一下参加考试。有两种方法可以确保你得到正确的答案:
在过去的 6 个月里,你上课时会看到很多重复的例子,说明某个概念是如何运作的。这是学习记忆 - 你可以在 LLM 中通过展示提示和你期望的响应的例子以及从中学习的模型来解决这个问题。
你手边有教科书,可以查找正确的信息来回答问题。这就是上下文记忆——我们在 LLM 中通过将相关信息填充到上下文窗口中来解决这个问题,要么使用提示工程以静态方式,要么使用 RAG 的工业方式。
这两种优化方法是附加的,而不是排斥的——它们可以叠加,并且某些用例将要求您将它们一起使用以获得最佳性能。
让我们假设我们面临一个短期记忆问题——为此我们将使用 RAG 来解决它。
检索增强生成 (RAG)
RAG 是在生成答案之前检索内容以补充LLM 提示的过程。它用于使模型能够访问特定领域的上下文来解决任务。
RAG 是一种非常有价值的工具,可以提高 LLM 的准确性和一致性——OpenAI 的许多最大客户部署都是仅使用快速工程和 RAG 完成的。
在这个例子中,我们嵌入了一个统计知识库。当用户提出问题时,我们会嵌入该问题并从知识库中检索最相关的内容。这些数据将呈现给模型,模型将回答该问题。
RAG 应用程序引入了我们需要优化的新轴,即检索。为了使 RAG 发挥作用,我们需要为模型提供正确的上下文,然后评估模型是否正确回答。我将在这里用网格框出这些内容,以展示一种使用 RAG 进行评估的简单方法:
您的 RAG 应用程序可能会在两个方面出现问题:
区域 | 问题 | 解决 |
---|---|---|
检索 | 您可以提供错误的上下文,这样模型就无法回答,或者您可以提供太多不相关的上下文,从而淹没真实信息并导致幻觉。 | 优化您的检索,其中包括: - 调整搜索以返回正确的结果。 - 调整搜索以包含更少的噪音。 - 在每个检索结果中提供更多信息 这些只是示例,因为调整 RAG 性能本身就是一个行业,而 LlamaIndex 和 LangChain 等库在此提供了许多调整方法。 |
LLM | 该模型还可以获取正确的上下文并利用它做出错误的事情。 | 通过改进模型使用的指令和方法来促进工程设计,如果展示示例可以提高准确性,则添加微调 |
这里需要记住的关键一点是,原则与我们一开始的思维模型是一样的——通过评估找出问题所在,然后采取优化措施来修复它。RAG 的唯一区别在于,现在需要考虑检索轴。
虽然 RAG 很有用,但它只能解决我们的上下文学习问题 - 对于许多用例来说,问题在于确保 LLM 能够学习一项任务,以便能够一致且可靠地执行该任务。对于这个问题,我们转向微调。
微调
为了解决学习记忆问题,许多开发人员会在较小的特定领域数据集上继续 LLM 的训练过程,以针对特定任务进行优化。这个过程称为微调。
进行微调通常出于以下两个原因之一:
提高特定任务的模型准确性:通过向模型展示许多正确执行该任务的示例,针对特定任务的数据对模型进行训练,以解决学习记忆问题。
提高模型效率:用更少的token或者更小的模型达到同样的准确率。
微调过程从准备训练示例数据集开始 - 这是最关键的一步,因为您的微调示例必须准确地代表模型在现实世界中看到的内容。
许多客户使用一种称为“提示烘焙”的流程,在试用期间,您可以广泛记录即时输入和输出。这些日志可以精简为包含实际示例的有效训练集。
一旦拥有了干净的数据集后,您可以通过执行训练运行来训练经过微调的模型 - 根据您用于训练的平台或框架,您可能有可以在此处调整的超参数,类似于任何其他机器学习模型。我们始终建议在训练后维护一个保留集以用于评估,以检测过度拟合。有关如何构建良好训练集的提示,您可以查看我们的微调文档中的指导,而有关如何准备和调整保留集的更多信息,请点击此处。训练完成后,新的经过微调的模型可用于推理。
为了优化微调,我们将重点关注我们在 OpenAI 模型定制产品中观察到的最佳实践,但这些原则也适用于其他提供商和 OSS 产品。这里要观察的关键实践是:
从提示工程开始:从提示工程中获得一套可靠的评估集,您可以将其用作基准。这允许采用低投资方法,直到您对基本提示有信心为止。
从小处着手,注重质量:在基础模型上进行微调时,训练数据的质量比数量更重要。从 50 多个示例开始,进行评估,然后如果尚未达到准确度要求,并且导致错误答案的问题是由于一致性/行为而不是上下文造成的,则增加训练集大小。
确保您的示例具有代表性:我们看到的最常见陷阱之一是非代表性的训练数据,用于微调的示例在格式或形式上与 LLM 在生产中看到的示例略有不同。例如,如果您有一个 RAG 应用程序,请使用其中的 RAG 示例对模型进行微调,这样它就不会学习如何使用上下文零样本。
总结
这些技术相互叠加 - 如果您的早期评估显示上下文和行为都存在问题,那么您最终可能会在生产解决方案中使用微调 + RAG。这没关系 - 这些技术可以平衡两种方法的弱点。一些主要好处是:
使用微调来最小化用于提示工程的token,因为您用许多训练示例替换指令和少量示例,从而在模型中根植一致的行为。
使用大量微调来教授复杂行为
使用 RAG注入上下文、最新内容或用例所需的任何其他专业上下文
使用这些工具来改进语言翻译
现在您应该了解 RAG 和微调,以及它们各自的适用性。您应该了解的最后一件事是,一旦引入它们,我们的迭代速度就会受到影响:
对于 RAG,您需要调整检索以及 LLM 行为
通过微调,您需要重新运行微调过程,并在进行额外调整时管理您的训练和验证集。
这两个过程都可能耗时且复杂,可能会随着你的LLM应用变得更加复杂而引入回归问题。如果从本文中你学到了一件事,那就是在进行更复杂的 RAG 或微调之前,尽可能地从基本方法中榨取尽可能多的准确性 - 让你的准确性目标成为目标,而不是因为它们被认为是最复杂的而跳到 RAG + FT。
对于生产来说,多少精度才算“足够好”
对于 LLM 来说,调整准确性可能是一场永无止境的战斗——它们不太可能使用现成的方法达到 99.999% 的准确性。本节将重点讨论多少准确性才足够——如何放心将 LLM 投入生产,以及如何管理您推出的解决方案的风险。
我们发现从业务和技术角度考虑这个问题很有帮助。将描述管理这两种情况的高级方法,并使用客户服务帮助台用例来说明我们如何在这两种情况下管理风险。
商业
对于企业来说,在基于规则或传统机器学习系统,甚至人类的确定性比较高之后,很难再信任大模型!一个失败是开放的且不可预测的系统是一个难以解决的问题。
我见过的一种成功方法是针对客户服务用例 - 为此,我们做了以下工作:
首先,我们确定主要的成功和失败案例,并为它们分配估计的成本。这为我们清晰地表达了解决方案可能基于试点性能节省或成本的预期。
例如,一个以前由人类解决的案件现在由人工智能解决,可以节省20 美元。
人工智能故障需要升级,可能需要花费40 美元
在最糟糕的情况下,客户对 AI 感到非常失望,因此流失了客户,这给我们造成了1000 美元的损失。我们假设这种情况发生的概率为 5%。
我们做的另一件事是测量流程周围的经验统计数据,这将有助于我们衡量解决方案的宏观影响。再次使用客户服务,这些可能是:
纯人类互动与人工智能互动的 CSAT 分数
人类与人工智能回顾性案例的决策准确性
人类与人工智能的解决时间
在客户服务示例中,这帮助我们在几次试点之后做出了两个关键决策以获取清晰的数据:
即使我们的 LLM 解决方案升级到人工的程度超出了我们的预期,它仍然在运营成本上节省了巨大的成本,超过了现有解决方案。这意味着即使准确度达到85%,如果那15%主要是早期升级,也是可以接受的
当失败成本非常高时,例如欺诈案件被错误解决,我们决定由人类驾驶人工智能充当助手。在这种情况下,决策准确性统计数据帮助我们判断,我们并不适合完全自动驾驶。
技术的
从技术方面来看,情况更加清楚——现在企业已经清楚了他们期望的价值以及可能出错的成本,您的角色就是构建一个解决方案,以不破坏用户体验的方式妥善处理故障。
让我们再一次使用客户服务示例来说明这一点,我们假设我们有一个在确定意图方面准确率为 85% 的模型。作为技术团队,我们可以通过以下几种方法将 15% 的错误影响降至最低:
如果客户不确定,我们可以快速设计模型来提示客户提供更多信息,因此我们的首次准确度可能会下降,但通过两次尝试来确定意图可能会更准确。
我们可以给第二线助手提供退回意图确定阶段的选项,再次给UX一种自我修复的方式,以牺牲一些额外的用户延迟为代价。
我们可以通过提示工程让模型在意图不明确时交给人类,这在短期内会让我们失去一些运营节省,但可能会抵消长期客户流失风险。
这些决策然后反馈到我们的UX中,以牺牲准确度为代价变慢,或者更多的人为干预,这些干预反馈到上述商业部分的成本模型中。
现在,您已经掌握了一种方法来分解涉及设定基于业务现实的准确性目标的业务和技术决策。
继续推进
这是一个高级思维模型,用于思考如何最大限度地提高 LLM 的准确性、可以使用哪些工具来实现这一点,以及决定生产是否足够的方法。您拥有持续投入生产所需的框架和工具,如果您想从其他人使用这些方法所取得的成就中获得启发,那么看看我们的客户案例就知道了,摩根士丹利和Klarna等用例展示了您可以通过利用这些技术实现的目标。
祝你好运,我们很高兴看到你用它建造的东西!
https://platform.openai.com/docs/guides/optimizing-llm-accuracy/how-much-accuracy-is-good-enough-for-production
推荐阅读
• 对齐LLM偏好的直接偏好优化方法:DPO、IPO、KTO
• RAG全景图:从RAG启蒙到高级RAG之36技,再到终章Agentic RAG!
• Agent到多模态Agent再到多模态Multi-Agents系统的发展与案例讲解(1.2万字,20+文献,27张图)
欢迎关注我的公众号“PaperAgent”,每天一篇大模型(LLM)文章来锻炼我们的思维,简单的例子,不简单的方法,提升自己。