从一年的基于大语言模型的建造工作中我们学到了什么(上篇)
为了直接从作者那里听取关于这一主题的意见,6 月 20 日的虚拟活动中请注册,6 月 12 日的生成式 AI 成功故事超级流会上了解更多。
系列的第二部分在这里找到,第三部分在这里找到。
在构建大型语言模型(LLMs)的激动人心时期。在过去的一年里,LLMs 已经“足够好”用于实际应用。LLMs 的改进速度,加上社交媒体上的一系列演示,将推动到 2025 年约 2000 亿美元的 AI 投资。LLMs 并非仅限于 AI 开发人员和科学家,这使得每个人,而不是仅仅这些人才,都能在产品中集成智能。 虽然构建 AI 产品的门槛有所降低,但创造出超越演示效果的真正有效产品,仍是一项看似困难的任务。
我们已经识别出一些关键但往往被忽视的教训和方法论,这些教训和方法论源自机器学习,对于基于大语言模型(LLMs)的产品开发至关重要。对这些概念的了解可以让你在大多数其他领域中脱颖而出,而无需具备机器学习专业知识!在过去的一年里,我们六位合伙人一直在利用大语言模型构建实际应用。我们意识到,需要将这些教训汇集到一个地方,以供整个社区受益。
我们来自不同的背景,担任不同的角色,但我们都亲身经历了使用这项新技术带来的挑战。其中两人是独立的顾问,帮助众多客户将LLM个项目从概念阶段推向成功的产品,亲眼见证了成功或失败的关键模式。其中一人是一名研究者,研究机器学习/人工智能团队的工作方式,并尝试改进他们的工作流程。 我们两人分别在应用人工智能的团队中担任领导角色:一位在科技巨头,另一位在初创公司。最终,其中一位已经向数千人教授了深度学习,并现在正在努力使 AI 工具和基础设施更加易于使用。尽管我们的经验背景不同,但我们被我们在学习中反复出现的主题所吸引,感到惊讶的是这些见解并没有得到更广泛的关注。
我们的目标是将此视为构建基于大语言模型成功产品的实用指南,借鉴我们自身的经验并指向行业内的示例。在过去的一年里,我们付出了辛勤的劳动,并从宝贵的经验中学习,有时甚至是在所料未及的情况下。虽然我们不声称代表整个行业,但在这里,我们将分享一些关于如何构建使用大语言模型的产品的建议和教训。
这项工作分为三个部分:战术、操作和战略。这是第三篇文章中的第一部分。它深入探讨了与大语言模型工作相关的战术细节。我们分享了关于提示、设置检索增强生成、应用流程工程以及评估和监控的最好实践和常见陷阱。无论你是使用大语言模型的实践者,还是在周末项目中工作的黑客,这一部分都是为你量身定制的。 接下来几周,注意关注运营和战略方面的内容。
准备好深入探索了吗?让我们开始吧。
战术
在这一部分,我们分享了关于新兴 LLM 栈的核心组件的最佳实践:提示技巧以提高质量和可靠性,评估策略以评估输出,检索增强生成思路以提高上下文基础,以及其他方面。我们还探讨了如何设计以人类为中心的工作流程。 尽管技术仍在迅速发展,但我们希望这些教训,是我们在集体实验中产生的成果的副产品,将经受时间的考验,并能帮助你构建和交付稳健的 LLM 应用程序。
刺激
我们建议在开发新应用时,从提示开始。低估和高估其重要性的情况都可能发生。低估是因为正确使用适当提示技术,当方法得当时,可以引领我们取得巨大进展。高估是因为即使基于提示的应用程序也需要在提示周围进行大量工程来运行良好。
专注于最大化基本提示技术的使用效果
几个提示技巧在各种模型和任务中持续帮助提高表现:n-shot 提示 + 在线上下文学习,链式思考,以及提供相关资源。
通过 n 技巧提示进行情境学习的概念是提供 LLM 一组示例,这些示例展示了任务,并使输出与我们的期望相匹配。一些建议:
如果 n 设置得太低,模型可能会过度锚定在那些特定的示例上,从而削弱其泛化能力。一般来说,目标是 n≥5。不要害怕设置得非常高,比如几十个。
例子应该代表预期的输入分布。如果你在构建一个电影摘要器,就在实际中大致以相同比例包含来自不同类型的样本。
你不一定非得提供完整的输入-输出对。在很多情况下,想要的输出的示例就足够了。
如果你的设备支持工具使用,那么你的一次性示例也应该使用你希望代理使用的工具。
在链式思维(CoT)提示中,我们鼓励LLM在返回最终答案前,先解释其思考过程。把它想象成为LLM提供了一个草稿本,这样它就不必在记忆中完成所有工作。最初的建议是简单地将“让我们一步一步思考”作为指导的一部分添加到提示中。然而,我们发现当通过增加一个额外的句子或两个句子的细节来增加 CoT 的特定性时,往往能显著减少幻觉率。例如,当我们要求LLM整理会议记录时,我们可以在明确说明步骤方面提供具体指导,例如:
首先,在草稿纸上列出关键决定,后续事项及相关负责人。
然后,检查草稿本中的细节是否与录音记录相符。
最后,提炼出关键点,形成简洁的总结。
最近,有人对这种方法是否像被认为的那样强大产生了怀疑。此外,当使用链式思维时,在推理过程中具体发生了什么,存在重大争议。无论如何,这种方法在可能的情况下,值得一试。
提供相关资源是扩展模型知识库、减少幻觉、增加用户信任的强大机制。通常通过检索增强生成 (RAG) 实现,为模型提供可以直接利用的文本片段,这对提高响应质量至关重要。 在提供相关资源时,仅仅包括它们是不够的;别忘了告诉模型优先使用它们,直接引用它们,有时甚至提到当所有资源都不充分时。这些有助于“确定”代理对资源库的响应。
结构化你的输入和输出
结构化的输入和输出有助于模型更好地理解输入,并能可靠地整合出下游系统的输出。在您的输入中添加序列化格式化,可以帮助模型提供更多的线索,以解释上下文中的令牌之间的关系,额外的元数据,如令牌的类型,或者与模型训练数据中类似的示例相关联的请求。
以一个例子来说明,互联网上关于编写 SQL 的问题,往往会在开始时就提到 SQL 数据库的结构。因此,你可能会预期,对于将文本转换为 SQL 的有效提示,应该包括结构化的数据库定义;确实如此。
结构化输出同样具有这样的功能,但它也简化了与系统下游组件的集成。对于结构化输出来说,Instructor 和 Outlines 工作得很好。(如果正在导入 LLM API SDK,使用 Instructor;如果正在使用 Huggingface 为自托管模型,使用 Outlines。)结构化输入清晰地表达任务,与其训练数据的格式相似,这增加了更好输出的几率。
在使用结构化输入时,请注意,每个LLM家庭都有自己独特的偏好。克劳德偏爱 xml
,而 GPT 更倾向于 Markdown 和 JSON。在 XML 中,你甚至可以提前填充克劳德的回复,通过提供 response
标签来实现。
</> python messages=[ { "role": "user", "content": """Extract the <name>, <size>, <price>, and <color>
from this product description into your <response>. <description>The SmartHome Mini
is a compact smart home assistant
available in black or white for only $49.99.
At just 5 inches wide, it lets you control
lights, thermostats, and other connected
devices via voice or app—no matter where you
place it in your home. This affordable little hub
brings convenient hands-free control to your
smart devices. </description>""" }, { "role": "assistant", "content": "<response><name>" } ]
有小提示,一项且只做一项
在软件中,一个常见的反模式或代码气味是“上帝对象”(God Object),我们有一个单个类或函数承担所有任务。同样适用于提示。
一个提示通常从简单的开始: 几句话的指导,几组示例,我们就可以开始了。但当我们试图提高性能,处理更多的边缘情况时,复杂性会逐渐出现。会有更多指导。多步骤推理。数十个示例。当我们意识到这一点时,我们最初简单提示的现在变成了 2000 个令牌的怪物。再加上侮辱,它在更常见的和直白的输入上表现得更差!GoDaddy 以他们的 No. 1 来分享这一挑战。 从使用大语言模型构建建筑中汲取的一课。
就像我们努力(读:挣扎)让我们的系统和代码保持简单一样,我们应该对提示进行同样的努力。对于会议摘要生成器的转录总结步骤,我们不仅仅是有一个统一的,涵盖所有情况的提示,我们可以将其拆分为几个步骤来完成。
提取关键决策、行动项目和负责人到结构化格式中
核对提取的细节与原始转录的一致性,以确保准确性
从结构性信息中生成简洁的摘要
结果,我们把单一的提示拆分成多个提示,每个提示都简单、聚焦且易于理解。通过拆分,我们现在可以逐个迭代和评估每个提示。
为您的上下文生成令牌
Rethink, and challenge your assumptions about how much context you actually need to send to the agent. Be like Michaelangelo, do not build up your context sculpture—chisel away the superfluous material until the sculpture is revealed. RAG is a popular way to collate all of the potentially relevant blocks of marble, but what are you doing to extract what’s necessary?
我们发现,将最后发送给模型的提示,包括上下文构建、元提示和 RAG 结果,放在一张空白页面上,然后只是阅读它,真的能帮助你重新思考你的上下文。我们发现使用这种方法,存在冗余、自相矛盾的语言和糟糕的格式。
另一个关键的优化在于你的上下文结构。你的文档包表示对人类没有帮助,不要假设它对代理有任何价值。仔细考虑你如何结构你的上下文,以突出它部分之间的关系,并尽量简化提取过程。
信息检索/大语言模型
除了提示之外,另一种有效的方法是将知识作为提示的一部分,以引导 LLM。这样,LLM 将基于提供背景信息而建立,然后用于上下文学习。这种方法被称为检索增强生成(RAG)。实践者发现 RAG 在提供知识和改进输出方面非常有效,而所需的工作量和成本远低于微调。RAG 的表现取决于检索文档的相关性、密度和详细程度。
你的 RAG(检索增强生成)输出质量取决于检索到的文档的质量,而后者又可以考虑几个因素。
最重要的、最直观的度量标准是相关性。这通常通过排名指标来量化,例如均值逆次方排名(MRR)或折现累积增益(NDCG)。MRR 评估系统在排序列表中将第一个相关结果排名在前面的程度,而 NDCG 则考虑所有结果的相关性和其位置。它们衡量系统在将相关文档排名更高、将不相关文档排名更低方面表现的优劣。 例如,如果我们从用户总结中生成电影评论总结,我们希望为特定电影的评论排名更高,同时排除其他电影的评论。
就像传统的推荐系统一样,检索到的项目排名会直接影响LLM在下游任务中的表现。为了衡量影响,运行一个基于 RAG 的任务,但将检索到的项目打乱顺序——RAG 输出的表现如何?
其次,我们也需要考虑信息密度。如果两份文档在相关性上相同,我们应该优先选择更简洁、含蓄的文档,且其附加细节较少。回到我们的电影例子中,我们可能认为电影转录和所有用户评论在广义上是相关的。然而,最被推荐的评论和编辑评论将更密集地包含信息。
最后,考虑文档中提供的详细程度。想象我们正在构建一个 RAG 系统,从自然语言生成 SQL 查询。我们可能只是提供表结构及其列名作为上下文。但,如果我们包括列描述和一些代表性的值呢?额外的细节可能有助于 LLM 更好地理解表的语义,并因此生成更正确的 SQL。
别忘了关键词搜索;将其作为基准,并在混合搜索中使用它。
鉴于嵌入式检索的 RAG 演示如此普遍,很容易忘记或忽视信息检索领域几十年的研究和解决方案。
然而,尽管嵌入确实是强大的工具,但它们并非万能之选。首先,尽管它们在捕捉高级语义相似性方面表现出色,但它们可能在处理更具体、关键字驱动的查询时,如用户搜索姓名(例如,Ilya),缩写词(例如,RAG),或 ID(例如,claude-3-sonnet)时,会遇到困难。基于关键字的搜索,如 BM25,是专门为此设计的。 经过多年基于关键词的搜索,用户可能已经习惯了这一模式,如果他们期望获得的文档没有被返回,可能会感到沮丧。
向量嵌入并不神奇地解决搜索问题。事实上,真正的工作是在你重新排名时,利用语义相似性搜索之前进行的。在 BM25 或全文搜索上取得真正的改进非常困难。
— 阿拉文·斯里尼瓦斯,Perplexity.ai 的首席执行官
我们已经向我们的客户和合作伙伴持续传达了这一信息数月之久。使用朴素嵌入的最近邻搜索结果非常嘈杂,你可能比从基于关键词的方法开始更合适。
— 贝亚朗•刘,源溯科技 CTO
其次,通过关键词搜索时,理解检索文档的原因更为直接——我们可以查看与查询匹配的关键字。相比之下,基于嵌入的检索则难以解释。最后,得益于像 Lucene 和 OpenSearch 这样的系统,经过几十年的优化和考验,关键词检索通常在计算效率上更为高效。
在大多数情况下,混合模型会表现最好:对于明显的匹配,使用关键词匹配;对于同义词、超类和拼写错误,使用嵌入表示;同时支持多模态(例如,文本与图像的组合)。短波分享了他们构建其检索增强阅读(RAG)管道的详细信息,包括查询重写、关键词+嵌入检索以及排序。
在建立新知识时,优先选择 RAG 而不是微调
两者 RAG 和微调都可以用于将新信息融入大语言模型中,并在特定任务上提高性能。因此,我们应该首先尝试哪一种?
最近的研究表明,RAG(零样本学习)可能具有优势。一项研究表明,RAG 与无监督微调(即继续预训练)进行了对比,评估了在 MMLU 和当前事件子集上。结果显示,RAG 在训练中遇到的知识以及新知识上均比无监督微调表现更优。在另一篇论文中,他们比较了 RAG 与在农业数据集上进行的有监督微调的表现。 同样,来自 RAG 的性能提升大于微调,特别是在 GPT-4 的情况下(参见论文中的表 20)。
除了性能提升,RAG 还带来了几个实际的便利和优势。首先,与持续预训练或微调相比,更新检索索引要容易得多且成本更低!其次,如果我们发现检索索引中的文档存在问题,包含有毒或偏见的内容,我们可以轻松地删除或修改这些文档。
此外,RAG 中的 R 为如何检索文档提供了更细致的控制。例如,如果我们在为多个组织建立 RAG 系统,通过分区检索索引,我们可以确保每个组织只能从自己的索引中检索文档。这确保了我们无意中将一个组织的信息暴露给另一个组织。
长文本模型不会使 RAG 一去不复返
Gemini 1.5 提供了高达 10M 令牌大小的上下文窗口,有人已经开始质疑 RAG 的未来。
— 姚福
我倾向于认为 Gemini 1.5 这个版本被 Sora 过度炒作。一个 10M 个令牌的上下文窗口实际上使大多数现有的 RAG 架构变得无足轻重——你只需把你的数据放入上下文中,就像平常那样与模型交流。想象一下,这对所有起步或代理/ LangChain 项目而言,工程努力主要集中在 RAG 上的情景是多么荒谬!或者用一句话总结:10M 的上下文就让 RAG 撒手了。Gemini 硬核的工作!
虽然确实认为长内容将为诸如分析多份文档或与 PDF 交谈的用例带来颠覆性变革,但关于 RAG 的死亡的谣言被大大夸大了。
首先,即使有一个 10M 个令牌的上下文窗口,我们仍然需要一种方法来选择信息以输入到模型中。其次,除了狭窄的 haystack 搜索评估之外,我们尚未见到有令人信服的数据表明模型能够有效地在如此大的上下文中推理。因此,如果没有良好的检索(以及排序),我们可能风险过度提供干扰因素,或者甚至可能导致上下文窗口被完全填充,包含完全不相关的信息。
最后,成本是一个重要因素。Transformer 的推理成本随着上下文长度呈平方(或在空间和时间上呈线性)增长。尽管存在一个模型可以在回答每个问题前读取你组织的整个 Google Drive 内容,但这并不意味着这是个好主意。让我们来以 RAM 的使用为例:我们仍然从磁盘读取和写入数据,尽管存在计算实例的 RAM 量级上达到了数十太字节。
所以别把你的 RAGs 投进垃圾桶了。即使上下文窗口变大,这种模式依然会保持有用的。
调优和优化工作流程
要求出一个 LLM 就是开始的一步。为了从这些任务中榨出最大价值,我们需要跳出单个提示的限制,拥抱工作流程。例如,我们如何将单个复杂的任务拆分成多个更简单的任务?在性能和延迟/成本增加时,微调或缓存如何变得有用?在这一部分,我们分享了证明有效的策略和实际案例,帮助你优化和构建可靠的工作流程 LLM。
逐步、多轮的“流程”能够产生显著的提升。
我们知道,通过将一个大的提示分解成多个较小的提示,我们可以获得更好的结果。这是一个例子是 AlphaCodium:通过从一个单一的提示切换到多步骤的工作流程,他们提高了在 CodeContests 上 GPT-4 准确度(5 分段通过率)从 19% 提高到 44%。工作流包括:
反思问题
在公共测试中进行推理
生成可能的解决方案
排名可能的解决方案
生成合成测试
在公开和合成测试上迭代解决方案。
有明确目标的小任务最适合作为代理或流程提示。虽然不是每个代理提示都必须要求结构化输出,但结构化输出对于与操控代理与环境互动的系统进行交互帮助很大。
试试以下内容:
1. 咨询专业人士,如医生或营养师。
2. 保持健康饮食,多吃蔬菜和水果。
3. 保持适量运动,如散步、跑步或瑜伽。
4. 睡眠充足,每天至少睡 7-8 小时。
5. 管理压力,尝试冥想或深呼吸。
6. 增强社交互动,与家人和朋友保持联系。
7. 保持积极心态,寻找生活中的乐趣
一个明确的规划步骤,尽可能地具体明确。考虑预先定义的计划来选择(参见:https://youtu.be/hGXhFa3gzBs?si=gNEGYzux6TuB1del)。
将原始的用户提示重写为代理提示。小心,这个过程是损失性的!
Agent 行为可以被视为线性链、有向无环图( DAG)或状态机;不同的依赖和逻辑关系在不同规模下可能更加或不那么得当。你能从不同的任务架构中挤出性能优化吗?
计划验证;你的计划可以包括如何评估来自其他代理的响应,以确保最终组装能够很好地协同工作。
在固定上游状态下的提示工程——确保你的代理提示被评估与一系列可能发生的情况的变体。
现在优先考虑确定性的工作流程
尽管智能代理能够动态地对用户请求和环境做出反应,但其非确定性特性使得部署它们成为一项挑战。每个代理采取的步骤都有失败的可能性,而从错误中恢复的几率极低。因此,随着步骤数量的增加,代理完成多步骤任务成功的可能性呈指数级减少。结果,正在构建智能代理的团队发现部署可靠的代理变得困难重重。
一种有前景的方法是,让代理系统生成确定性的计划,这些计划随后以结构化、可再现的方式执行。在第一步,给定一个高层次的目标或提示,代理生成计划。然后,执行这些计划是确定性的。这使得每个步骤更加可预测和可靠。好处包括:
生成的计划可以作为少量样本,以提示或微调代理。
确定性执行使系统更加可靠,因此更容易测试和调试。此外,失败可以追溯到计划中的具体步骤。
生成的计划可以表示为有向无环图(DAGs),相对于静态提示,这在理解和适应新情况方面更容易理解。
最成功的代理构建者可能是那些具备强大经验管理初级工程师的人,因为生成计划的过程类似于我们如何指导和管理初级员工。我们给初级员工明确的目标和具体计划,而不是模糊的开放式方向,我们应该同样对待我们的代理。
最终,可靠且运行良好的代理的关键可能在于采纳更具结构化和确定性的方法,同时收集数据以精炼提示并微调模型。如果没有这些,我们将构建那些在某些情况下工作出色,但平均而言,会让用户失望的代理,这导致了较差的保留率。
除了温度之外,获得更多样化的输出
假设你的任务要求输出具有多样性。可能你在编写一个LLM的管道,给定用户之前购买的产品列表,建议购买商品。当你多次运行你的提示时,你可能会注意到生成的推荐太相似,所以你可能在你的LLM请求中增加温度参数。
简而言之,增加温度参数会使LLM的响应更加多样化。在采样时,下个令牌的概率分布变得更加平坦,这意味着通常不太可能的令牌选择次数会增加。然而,当增加温度时,你可能会注意到与输出多样性相关的某些失败模式。例如,从商品目录中可能适合的商品,但最终可能未必会被LLM输出。同一些产品可能在输出中出现得过于频繁,如果它们基于在训练时 LLM 已经学习到的信息,非常有可能会按照提示出现。如果温度设置得太低,你可能会得到引用不存在的产品(或者可能是无意义的 gibberish!)。)
换句话说,增加温度并不保证LLM会从你期望的概率分布中采样输出(例如,均匀随机)。然而,我们还有其他方法来增加输出的多样性。最简单的方法就是调整提示中的元素。例如,如果提示模板包含一个物品列表,如历史购买,每次插入这些物品到提示中时,将它们的顺序打乱会带来显著的不同。
此外,保持一个简短的近期输出列表可以帮助防止冗余。在我们的推荐产品示例中,通过指示 LLM 避免建议这个近期列表中出现的项目,或者通过拒绝相似的输出并重新采样,我们可以在进一步多元化回答时进一步保持多样性。另一种有效策略是改变提示中使用的措辞。 例如,引入诸如“选择一个用户经常使用且爱好的产品”或“选择一个用户可能会推荐给朋友的产品”这样的短语,可以改变焦点,从而影响推荐的产品种类。
缓存被低估了。
缓存节省了成本,消除了重计算输入相同响应的生成滞后。此外,如果一个响应已被预审核,我们可以提供这些审核过的响应,并减少提供有害或不适当内容的风险。
一种简单的方式来缓存数据的方法是使用独特标识符(UDI),比如当我们处理新文章或产品评论时。当收到请求时,我们可以检查缓存中是否已经存在一个总结。如果存在,我们可以立即返回;如果不存在,我们可以生成、校验、并返回它,然后将其存储在缓存中以供未来请求。
对于更开放性的问题,我们可以借鉴搜索领域的方法,该领域也利用缓存来处理开放性输入。如自动完成功能和拼写更正等特性有助于规范化用户输入,从而提高缓存命中率。
何时微调
我们可能在某些任务中,即使是最精心设计的提示也可能无法满足需求。例如,即使经过了大量提示工程,我们的系统可能仍然距离返回可靠且高质量的输出还有一段距离。如果真是如此,那么可能需要为你的特定任务微调一个模型。
成功的例子包括:
蜂窝的自然语言查询助手:最初,“编程手册”与示例一起在提示中提供,用于进行上下文学习。虽然这在某种程度上有效,但微调模型则在特定领域的语言语法和规则上产生了更好的输出。
ReChat 的 Lucy:LLM需要生成一种非常特定的格式的响应,这种格式将结构化和非结构化数据结合在一起,以便前端能够正确渲染。精细调优是确保其在不同时期都能正常工作的关键。
然而,尽管微调可以有效,但带来巨大的成本。我们不得不标注微调数据,微调和评估模型,最终自托管。因此,考虑一下如果更高的初期成本值得付出。如果提示让你走到了 90%的路,那么微调可能并不值得投入。然而,如果我们决定微调,为了减少收集人工标注数据的成本,我们可以生成和微调合成数据,或在开源数据上进行 bootstrap。
评估与监测
评估大语言模型(LLM)可能是一片荆棘丛生之地。大语言模型的输入和输出都是随意的文本,而我们赋予它们的任务各不相同。然而,严谨且富有洞察力的评估对于其成功至关重要——这当然不是巧合,OpenAI 技术领导层正是在评估和给出具体评估反馈方面工作的。
评估 LLM 个申请项目,会邀请出各种定义和缩减:纯粹的单元测试,或者是类似于可观测性,也许仅仅是数据科学。我们发现这几种角度都非常有帮助。在以下部分,我们将提供关于在构建评估和监控管道中什么才是重要的话题的一些经验教训。
从实际的输入/输出样本创建几个基于断言的单元测试
创建单元测试(即断言)由生产环境的输入和输出样本组成,基于至少三个标准预期输出。虽然三个标准看起来有些随意,但这是一个起步时的合理数字;如果少于三个标准,则可能表明任务不够明确或太宽泛,如通用型对话机器人。 这些单元测试,或断言,应该由任何影响管道的更改触发,无论是编辑提示,通过大语言模型添加新上下文,还是其他任何修改。这篇文档中举了断言式测试的实际用例的一个例子。
考虑从声明开始,声明说明要包括或排除在所有响应中的短语或观念。此外,可以考虑进行检查以确保单词、项目或句子的计数处于合理范围内。对于其他类型的生成,声明可能有所不同。执行评估是一种强大的方法来评估代码生成,其中你运行生成的代码,确定运行时状态足以满足用户请求。
举个例子,如果用户请求一个新函数,名字为 foo;那么在执行代理生成的代码后, foo 应该可以调用!在执行-评估过程中存在一个挑战,即代理代码往往会在运行时处于与目标代码略有不同的形式。有时,对断言进行“放松”,以满足任何可行答案的最弱假设,可能是有效的。
最后,将产品按照客户预期使用(即“狗食”)可以为现实世界数据中的失败模式提供洞察。这种方法不仅有助于识别潜在弱点,而且还能提供生产样品的来源,这些样品可以转化为评估测试。
LLM-as-Judge 可以工作(某种程度上),但这并不是万无一失的解决方案
LLM-as-Judge,我们在评估其他大语言模型输出时使用了一种强大的LLM,被部分人质疑。(有些人起初是巨大的怀疑者。)然而,当实施得当时,LLM-as-Judge 与人类判断的关联度相当好,至少可以帮我们构建一些新提示或技术可能表现的先验知识。具体来说,当做配对比较(例如,控制组 vs. 治疗方面),LLM-as-Judge 通常能够把握方向,但比赛的输赢的规模可能有些波动。
以下是利用 LLM-作为法官获取最大收益的几点建议:
使用两两比较:而不是让 LLM 在一个 Likert 规则上给单一输出打分,而是把它们呈现给它们,让他们选择更好的一个。这通常会导致更稳定的结果。
控制因位置偏见的影响:选项呈现的顺序可能会影响LLM的决策。为了减少这种影响,每次交换选项的顺序,对每一项进行两次两两比较。在交换后,确保将胜利归功于正确的选项!
允许平局:在某些情况下,两者可能都很好。因此,允许LLM声明平局,这样它就不必随意选择一个赢家。
使用基于逻辑推理:在给出最终偏好之前,先询问 LLM 解释其决定,可以提高评估的可靠性。作为额外的好处,这使得你可以在较弱但更快的 LLM 上进行尝试,仍然能获得类似的结果。因为频繁地,这个流程的一部分在批处理模式下,CoT 引入的额外延迟并不是问题。
控制回复长度:大语言模型倾向于倾向于较长的回复。为了缓解这一倾向,确保回复对相似长度。
尤其强大应用之一的LLM-作为法官是检查新的提示策略是否有效的手段。如果你跟踪了一组生产结果,有时你可以重新运行那些生产示例,使用LLM-作为法官来快速评估新策略可能存在的缺陷。
这里提供了一个简单但有效的迭代 LLM 作为法官的方法,我们只需要记录 LLM 的响应,法官的评论(即 CoT),以及最终结果。这些信息随后与相关方进行审查,以识别改进的领域。经过三轮迭代,与人类和 LLM 的一致率从 68% 提高到了 94%!
LLM-作为法官并不是万能药。然而,语言中的微妙方面,即使是最强的模型也无法可靠地评估。此外,我们发现,传统的分类器和奖励模型可以实现比LLM-作为法官更高的准确率,同时成本更低、响应时间更短。对于代码生成,LLM-作为法官可能会弱于直接评估策略,如执行评估。
对评估代际的“实习生测试”
当我们评估不同代际时,我们喜欢使用以下“内部测试”:如果你把输入(包括上下文)完全交给语言模型,然后把它交给了相关专业的一般大学生作为任务,他们能成功完成吗?需要多长时间?
如果答案是否定的,因为 LLM 缺乏必要的知识,可以考虑增加上下文来解决问题。
如果答案是否定的,而我们无法改善上下文来解决问题,那么我们可能已经触及了一个超出了当代大语言模型能力的任务。
如果答案是是,但需要一段时间,我们可以尝试简化任务的复杂性。任务是否可以分解?任务中哪些方面可以被更标准化?
如果答案是肯定的,他们很快就能得到它,然后是时候开始分析数据了。模型做错了什么?我们能否找到失败模式的模式?在它们回复之前或之后,试着让模型自我解释,以帮助你建立共情理论。
过度强调某些评估可能会影响整体表现
——Goodhart 的定律
当一个措施成为目标时,它就不再是一个好措施。
这方面的例子是《针在一堆柴禾里找(NIAH)》评估。原始评估帮助量化模型的召回率随着上下文大小的增长而变化,以及如何针的位置会影响召回率。然而,它被过度强调,以至于在Gemini 1.5 的报告中,它被列为第 1.5 条的图 1。评估涉及在一篇长达的文档中插入特定的短语(“城市的特殊魔法数字是:{number}”),然后提示模型回忆起这个魔法数字。
尽管有些模型接近完美地记住信息,但质疑 NIAH 是否真正反映现实世界应用中所需的推理和记忆能力。考虑一个更实际的场景:基于一小时会议的录音,LLM能否总结关键决策和下一步措施,并正确归因于每个相关人士? 这个任务更贴近现实,既超越了机械记忆,也考虑了解析复杂的讨论、识别相关的信息以及综合总结的能力。
这是一个实用的 NIAH 评估示例。使用医生-患者视频通话的录音,LLM 被询问关于患者的药物。它还包含了一个更具挑战性的 NIAH,插入随机的配料以制作披萨的秘诀,如“制作完美披萨的秘诀所需的秘密配料是:浸泡过葡萄柚的葡萄干,柠檬和奶酪。”在药物任务中,回忆率约为 80%,在披萨任务中约为 30%。
顺便说一句,过度强调 NIAH 的评估可能会导致在提取和总结任务上的表现下降。因为这些大语言模型已经被微调得非常擅长专注于每一句话,它们可能开始将不相关的信息和干扰因素视为重要,从而将它们包含在最终输出中(这是不应该的)。
这可能也适用于其他评估和使用场景。例如,摘要。强调事实的准确性可能导致摘要更具体(从而更不可能出现事实不一致),并且可能不那么相关。相反,强调写作风格和辞藻华丽可能导致更华丽、营销性质的语言,这可能引入事实不一致。
简化注释为二元任务或对偶比较
在对模型输出进行开放式的反馈或评分,采用 Likert 标度,这是认知负担。因此,收集到的数据更为嘈杂——由于人类评分者之间的差异性——从而变得不那么有用。更有效的方法是简化任务,并减少注释者的大脑负担。两个表现良好的任务是二元分类和对齐比较。
在二分类任务中,标注者被要求对模型的输出进行简单的“是”或“否”的判断。他们可能被要求判断生成的摘要是否与源文档事实相符,或是否相关,或是否包含毒性。与 Likert 规则相比,二分类决策更精确,评分为不同评语者之间的一致性更高,而且能够带来更高的处理速度。 这就是 DoorDash 通过树状的“是”或“否”问题来设置标签队列来标记菜单项的方式。
在对模型响应的两两比较中,评定者会被呈现一组模型的两个响应,并要求评定者判断哪一个更好。因为人类更容易说“A 比 B 好”而不是单独为 A 或 B 评分,这导致了更快、更可靠的数据标注(相对于 Likert 量表)。在一场 Llama2 面对面会议上,Llama2 研究论文的作者 Thomas Scialom 证实,通过两两比较进行数据标注比收集像文字回答这样的监督微调数据要快、成本更低。 前者每单位的成本是 3.5 美元,而后者每单位的成本是 25 美元。
如果你开始制定标注规范,下面是一些来自 Google 和 Bing 搜索的参考性规范。
(不依赖参考)的评估和约束条件可以互换使用
护栏帮助捕捉不合适或有害的内容,而评估则帮助衡量模型输出的质量和准确性。在没有参考值的评估中,它们可能被视为同一事物的两个方面。没有参考值的评估是在不依赖“金标准”参考的情况下进行的评估,例如人类写下的答案,它可以基于输入提示和模型的响应来评估输出质量。
一些例子包括摘要评估,我们只需考虑输入文档来评估摘要的客观一致性和相关性。如果摘要在这些指标上表现不佳,我们可以选择不向用户展示它,实际上用评估作为防线。同样,无参考点的翻译评估可以评估翻译质量,而无需使用人类翻译的参考文件,同样允许我们用它作为防线。
大语言模型会返回不应该返回的输出
当处理大语言模型时,一个关键挑战是它们往往会在不应生成的情况下生成输出。这可能导致无害但不合理的回答,或更严重的问题如毒性或危险的内容。例如,当被要求从文档中提取特定属性或元数据时,LLM 可能会自信地返回不存在的值。另一方面,如果我们在上下文中提供了非英语文档,模型可能会用不同于英语的语言回应。
尽管我们可以通过提示LLM来尝试返回“不适用”或“未知”响应,但这并非绝对有效。即使在有日志概率的情况下,它们也并非输出质量的可靠指示。虽然日志概率能反映某个词在输出中出现的可能性,但它们并不必然反映生成文本的正确性。相反,对于训练用于回应查询并生成连贯回应的指令微调模型,日志概率可能未被正确校准。 因此,虽然高对数概率可能表明输出流畅且意义连贯,但这并不意味着它准确或相关。
虽然精妙的提示工程可以在这方面起到一定的作用,但我们还应该补充以更强大的约束机制,这些约束机制能够检测并过滤/重生成出错的输出。例如,OpenAI 提供了一个内容审核 API,能够识别出诸如仇恨言论、自残或色情输出等不安全的回复。此外,有许多工具包可以用于检测个人识别信息(PII)。 一个好处是,护栏对应用场景的依赖性较小,因此可以广泛应用于给定语言的所有输出。此外,通过精确检索,我们的系统可以确定性地回应“我不知道”,如果找不到相关的文档。
这里的一个推论是,大型语言模型可能会在预期的情况下无法产生输出。这种情况可能由多种原因引起,从简单的 API 提供商的长尾延迟到更复杂的情况,如内容审查过滤器阻止了输出。因此,重要的是要连续记录输入(包括潜在的输入缺失),以便于调试和监控。
幻觉是顽固的问题。
与内容安全或 PII 缺陷相比,事实不一致虽然在某些情况下得到了广泛关注,但仍然很少发生。事实不一致顽固地存在,并且更难检测出来。它们更常见,发生率在 5%-10%之间,从LLM提供商了解到,即使在简单的任务如摘要中,要将其降至 2%以下也是一项具有挑战性的工作。
为了解决这个问题,我们可以结合提示工程(在生成之前)和事实不一致的防护措施(在生成之后)。对于提示工程,如 CoT 技术,可以帮助减少幻觉,通过让LLM在最终返回输出前解释其推理来实现这一点。然后,我们可以应用事实不一致的防护措施来评估摘要的真伪,从而过滤或重新生成幻觉。在某些情况下,幻觉可以被确定地检测到。 在使用 RAG 搜索检索资源时,如果输出结构化且识别出资源的来源,你应该能够手动验证它们来自输入上下文。
关于作者们
Eugene Yan 设计、构建和运营服务于全球百万客户的大型机器学习系统。他目前在亚马逊担任高级应用科学家,负责开发推荐系统(RecSys),为全球数百万客户提供服务。RecSys 2022 的开幕演讲,以及他如何将大语言模型(LLMs)应用于为客户提供更好的服务,人工智能峰会 2023 的开幕演讲。他以前在 Lazada(阿里云收购)担任机器学习负责人,领导了一个健康科技系列 A 轮融资。他在 eugeneyan.com 和 ApplyingML.com 上撰写和讲授关于机器学习、推荐系统、大语言模型和工程的主题。
布莱恩·比肖夫是 Hex 的 AI 主管,他领导着开发魔力(数据科学和分析的飞行跟乘员)的工程师团队。布莱恩在数据栈的各个方面都带领过团队,包括数据分析、机器学习工程、数据平台工程和人工智能工程。他在蓝瓶咖啡创立了数据团队,在 Stitch Fix 领导了几项项目,还在 Weights and Biases 建立了数据团队。 本尼尔之前与奥里尔出版社共同撰写了一本书《使用 O'Reilly 建立生产推荐系统》,并教授数据科学与分析课程,位于罗格斯大学的研究生院。他的博士学位是纯数学。
查尔斯·弗雷德教授致力于让人们学习构建人工智能应用。在心理药理学和神经生物学领域的研究后,他获得了加州大学伯克利分校的博士学位,以神经网络优化作为其博士论文工作。他通过在 Weights and Biases、Full Stack Deep Learning 和 Modal 等公司进行教育和咨询服务,培训了几千人掌握人工智能应用开发的整个堆栈,从线性代数基础到 GPU 细节和构建有辩护力的业务。
Hamel Husain 是一位拥有超过 25 年经验的机器学习工程师。他在 Airbnb 和 GitHub 这些创新公司工作,这些公司涉及早期 LLM 研究,这些研究被 OpenAI 用于代码理解。他还领导并贡献了许多广受欢迎的开源机器学习工具。Hamel 目前是一位独立咨询顾问,帮助公司将大型语言模型(LLMs)运用于加速其人工智能产品之旅。
Jason Liu 是一位备受尊敬的机器学习咨询顾问,以其带领团队成功交付 AI 产品而闻名。Jason 的技术专长涵盖个性化算法、搜索优化、合成数据生成和 MLOps 系统。他的经验包括像 Stitch Fix 这样的公司,他在那里创建了一个推荐框架和可观测性工具,处理了每天 3500 万次请求。其他角色还包括 Meta、纽约大学和像 Limitless AI 和 Trunk Tools 这样的初创公司。
Shreya Shankar 是来自加州大学伯克利分校的计算机科学博士生和机器学习工程师。她在两家中,她是第一个为公司构建 AI 助推产品的机器学习工程师。她在每日服务于数千用户的产品中,从零开始构建 AI 助推产品。作为一名研究人员,她的工作集中在通过以人为中心的方法来解决生产式机器学习系统中的数据挑战。她的工作发表在顶级的数据管理与人机交互会议上,如 VLDB、SIGMOD、CIDR 和 CSCW。
联系我们
我们非常乐意向您分享对这篇帖子的想法。您可以联系 us 于 contact@applied-llms.org。我们许多人对各种形式的咨询和顾问服务持开放态度。如果适当,我们会在与我们联系后将您转接到正确的专家。
感谢شيرelle、thomas、andrew、andrew、susan、andrew 和 sam 都为这个项目做出的贡献
这个系列始于一个小组聊天中的对话,Bryan 开玩笑说他受到启发,想写《人工智能工程一年的回顾》。然后,✨魔法✨ 在小组聊天中发生了,我们都受到了启发,决定一起分享我们所知道的。
作者们想要感谢 Eugene,他不仅在文档集成和总体结构上主导了大部分工作,同时还负责了大量条目的编写。此外,他们还感谢 Bryan,因为他的灵感引导了这篇写稿的形成,将写稿重新组织成了战术、操作和战略部分,以及它们的自我介绍,并且还激发了我们思考如何更广泛地帮助社区。 作者们想感谢查尔斯对成本和 LLMOps 的深度探讨,以及他将这些教训编织在一起,使之更具连贯性和紧凑性,使得这本著作不是 40 页而是 30 页。他们也感谢哈莱姆和詹森,他们从为客户提供咨询和一线工作中的洞察,以及从客户那里获得的广泛可推广的学习,以及他们对工具的深邃了解。 最后,感谢 Shreya 强调评估的重要性以及严谨生产实践的必要性,并将她的研究和原创成果带到这篇作品中。
最后,作者们想感谢所有无私分享自己挑战和教训的团队,在本系列中我们已经多次引用,以及人工智能社区对这一群体的活跃参与和互动。