翻译 What We Learned from a Year of Building with LLMs (Part I)

我们从一年构建大型语言模型(LLMs)中学到了什么(第一部分)

Eugene YanBryan BischofCharles FryeHamel HusainJason Liu 和Shreya Shankar 著作 2024年5月28日

          本文由六位不同背景和专业领域的一线AI作者共同撰写,分享了他们使用大型语言模型(LLMs)构建实际应用一年来的经验教训。文章分为战术、运营和战略三部分,讨论了如何有效地使用提示(prompting)、改进信息检索(RAG)、设计人工在环工作流程,并强调了评估和监控LLMs的重要性。

        作者们提供了丰富的最佳实践、常见陷阱和实用建议,旨在帮助读者构建成功的LLM应用,并指出了在构建过程中保持输出多样性、减少错误和提升性能的关键策略。  
        这篇长文干货满满,一时间成为开发者社区热议的话题。
        有网友评价为,大模型领域少有的“有操作性”的实用见解,非常值得一读。👍


目录

从一年构建大型语言模型(LLMs)中学到的内容(第一部分)

目录

        战术

        提示

        注重充分利用基本提示技巧

结构化输入和输出

保持提示简短,让它们做好一件事

打造您的上下文token

信息检索/RAG

一些有用的尝试

超越温度获取更多样化的输出

缓存被低估了

何时微调

评估与监控

从真实的输入/输出样本中创建一些基于断言的单元测试

LLM-as-Judge 可以工作(有点),但它不是万能的

评估生成的“实习生测试”

过分强调某些评估可能会损害整体性能

简化注释为二元任务或成对比较

LLMs 甚至在不应该的时候也会返回输出

幻觉是一个棘手的问题。

关于作者

联系我们

致谢


        现在正是使用大语言模型 (LLMs) 构建产品激动人心的时刻。在过去的一年里,LLMs 已经变得足够“好”,可以用于现实世界的应用。LLMs 的改进速度,加上社交媒体上的一系列演示,将推动到 2025 年 AI 投资估计达到 2000 亿美元。LLMs 也可广泛获取,允许每个人,不仅仅是机器学习工程师和科学家,将智能构建到他们的产品中。尽管构建 AI 产品的入门门槛已经降低,但创建超出演示的有效产品仍然是一个具有欺骗性的困难尝试。

        我们已经确定了一些关键的,却常被忽视的课程和方法论,这些由机器学习提供的信息对于基于 LLMs 开发产品至关重要。对这些概念的认识可以在不需要 ML 专业知识的情况下,为您提供比该领域大多数人更强的竞争优势!在过去的一年里,我们六个人一直在 LLMs 之上构建现实世界的应用。我们意识到有必要将这些课程提炼在一个地方,以造福社区。

        我们来自不同的背景,担任不同的职务,但我们都亲身经历了使用这项新技术带来的挑战。我们中有两人是独立顾问,帮助众多客户将 LLM 项目从最初的概念成功地发展到产品,看到了决定成功或失败的模式。我们中的一位是研究 ML/AI 团队如何工作以及如何改进他们的工作流程的研究者。我们中的两位是应用 AI 团队的领导者:一位在科技巨头公司,一位在初创公司。最后,我们中的一位曾教授了数千人深度学习,现在致力于使 AI 工具和基础设施更易于使用。尽管我们的经历各不相同,但我们对学到的一致的经验教训感到惊讶,我们惊讶于这些见解没有被更广泛地讨论。

        我们的目标是使这成为一个实用的指南,围绕 LLMs 构建成功的产品,借鉴我们自己的经验,并指向行业周围的例子。在过去的一年里,我们亲力亲为,积累了宝贵的经验,其中不乏艰辛。虽然我们并不代表整个行业,但我们在此分享一些建议和经验,供任何使用 LLMs 构建产品的人参考。

        这项工作分为三个部分:战术、运营和战略。这是三部分中的第一部分。它深入到与 LLMs 合作的战术细节。我们分享了最佳实践和常见陷阱,围绕提示、设置增强检索的生成、应用流程工程以及评估和监控。无论您是使用 LLMs 构建的从业者,还是周末项目上工作的黑客,这一部分都是为您写的。请期待未来几周的运营和战略部分。

        准备好扎猛子(划掉)深入研究了吗?我们开始吧。

        战术

        在这一部分,我们分享了新兴的LLM技术栈核心组件的最佳实践:提高质量和可靠性的提示技巧、评估输出的评估策略、增强基础的检索增强生成思想等。我们还探讨了如何设计人工参与的流程。虽然这项技术仍在快速发展,但我们希望这些经验,作为我们集体进行的无数实验的副产品,能够经得起时间的考验,帮助您构建和发布健壮的LLM应用。

        提示

        我们建议在开发新应用程序时从提示开始。我们既容易低估也容易高估提示功能的重要性。低估是因为正确的提示技术如果使用得当,可以让我们走得更远。高估的原因是,即使是基于提示的应用程序,也需要围绕提示进行大量的工程设计才能运行良好。

        

        注重充分利用基本提示技巧

        在各种模型和任务中,有几种提示技巧始终有助于提高成绩:N-shot 提示 + 情境学习、思维链和提供相关资源。

        通过 "n-shot 提示 "进行 "情境学习 "的想法是,为 LLM 提供一些演示任务的例子,并使输出结果与我们的期望相一致。一些提示:

  • 如果n太低,模型可能会过度依赖这些特定示例,损害其泛化能力。通常,目标是n ≥ 5。不要害怕高达几十个。
  • 示例应该是预期输入分布的代表。如果您正在构建电影摘要器,请按预期在实践中看到的比例包括不同流派的样本。
  • 您不一定需要提供完整的输入输出对。在许多情况下,期望输出的示例就足够了。
  • 如果您使用的LLM支持工具使用,您的n-shot示例也应该使用您希望代理使用的工具。

        在思维链(CoT)提示中,我们鼓励LLM在返回最终答案之前解释其思考过程。将其视为为LLM提供一个素描本,这样它就不必全部记在记忆中。最初的方法是简单地添加短语“让我们逐步思考”作为指令的一部分。然而,我们发现使CoT更具体更有帮助,通过额外的一两句增加具体性通常可以显著降低幻觉率。例如,当要求LLM总结会议记录时,我们可以明确步骤,例如:

  • 首先,在素描本中列出关键决策、后续项目和相关所有者。
  • 然后,检查素描本中的细节是否与记录事实一致。
  • 最后,将关键点综合成简洁的摘要。

        最近,有人对这种技术是否像认为的那样强大表示怀疑。此外,关于在使用思维链时的推理过程中究竟发生了什么,还有相当大的争论。无论如何,这种技术是在可能的情况下尝试的一种技术。

        提供相关资源是扩大模型知识库、减少幻觉和增加用户信任的强大机制。通常通过检索增强生成(RAG)完成,为模型提供它可以在响应中直接使用的文本片段是必不可少的技术。在提供相关资源时,仅仅包含它们是不够的;不要忘记告诉模型优先使用它们,直接引用它们,有时提到当没有任何资源足够时要提及。这些帮助“定位”代理响应到资源语料库。

结构化输入和输出


        结构化输入和输出有助于模型更好地理解输入,并且返回可以可靠地与下游系统集成的输出。在输入中添加序列化格式可以为模型提供更多关于上下文中标记之间关系、特定标记的附加元数据(如类型)或者将请求与模型训练数据中类似示例关联的线索。

        例如,互联网上许多关于编写 SQL 的问题首先会指定 SQL 模式。因此,您可能会期望有效的针对文本到 SQL 的提示应该包括结构化的模式定义;确实如此。

        结构化输出具有类似的目的,但它还简化了与系统下游组件的集成。Instructor 和 Outlines 对于结构化输出效果很好。(如果您正在导入 LLM API SDK,请使用 Instructor;如果您正在导入 Huggingface 的自托管模型,请使用 Outlines。)结构化输入清晰地表达任务,并类似于训练数据的格式,增加了更好输出的可能性。

        使用结构化输入时,请注意每个 LLM 系列都有自己的偏好。Claude 偏好 xml,而 GPT 偏好 Markdown 和 JSON。使用 XML,您甚至可以通过提供如下的响应标签来预填充 Claude 的响应。

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>"     
   } 
]

保持提示简短,让它们做好一件事


        软件中常见的一个反模式/代码异味是“上帝对象”,我们有一个单一的类或函数来做所有事情。同样的规则也适用于提示。

        提示通常从简单开始:几句说明,几个示例,我们就可以开始了。但是,随着我们试图提高性能并处理更多的边缘情况,复杂性悄然进入。更多的说明。多步骤的推理。几十个示例。在我们意识到之前,我们最初简单的提示现在已经是一个2000个token的怪物。并且,为了增加伤害,它在更常见和更直接的输入上的性能更差!GoDaddy 将这一挑战作为他们使用 LLMs 构建时的头号教训

        正如我们努力(阅读:挣扎)保持我们的系统和代码简单一样,我们的提示也应该如此。与其有一个单一的、包罗万象的提示用于会议记录摘要生成器,我们可以将其分解为以下步骤:

  • 将关键决策、行动项目和所有者提取到结构化格式中
  • 检查提取的细节是否与原始转录一致
  • 从结构化细节生成简洁的摘要

        因此,我们将单一提示拆分为多个提示,每个提示都简单、专注且易于理解。并且通过拆分它们,我们现在可以单独迭代和评估每个提示。

打造您的上下文token


        重新思考并挑战您关于实际需要发送多少上下文给代理的假设。像米开朗基罗一样,不要构建上下文雕塑——而是凿去多余的材料,直到雕塑显现出来。RAG 是一种流行的整理所有可能相关的大理石块的方式,但是您如何提取所需的内容呢?

        我们发现,将发送给模型的最终提示——包括所有的上下文构建、元提示和 RAG 结果——放在一张空白页面上,只是阅读它,真的有助于您重新思考上下文。我们使用这种方法发现了冗余、自相矛盾的语言和糟糕的格式。

        另一个关键的优化是您的上下文结构。您的文档袋表示对人类没有帮助,不要假设它对代理有好处。仔细考虑如何构建您的上下文,以强调其各部分之间的关系,并使提取尽可能简单。

信息检索/RAG

        除了提示之外,通过在提示中提供知识来引导LLM的另一种有效方法是检索增强生成(RAG)。这将基于提供的上下文为LLM提供知识,然后用于上下文学习。实践者发现RAG在提供知识和改进输出方面非常有效,同时所需的努力和成本远低于微调(fine-tuning)。RAG的好坏取决于检索文档的相关性、密度和细节。

        您的RAG输出的质量取决于检索文档的质量,这反过来可以通过几个因素来考虑。

        最明显的第一个指标是相关性。这通常通过排名指标如平均倒数排名(MRR)归一化折扣累积增益(NDCG)来量化。MRR评估系统将第一个相关结果放置在排名列表中的表现,而NDCG考虑所有结果的相关性和它们的位置。它们衡量系统将相关文档排名更高,不相关文档排名更低的能力。例如,如果我们检索用户摘要以生成电影评论摘要,我们将希望将特定电影的评论排名更高,同时排除其他电影的评论。

        像传统的推荐系统一样,检索项目的排名将对LLM在下游任务上的表现产生重大影响。为了衡量影响,运行一个基于RAG的任务,但是将检索的项目打乱——RAG输出的表现如何?

        其次,我们还要考虑信息密度。如果两个文档具有相同的相关性,我们应该偏向于选择更简洁、包含较少无关细节的文档。回到我们的电影示例,我们可能会认为电影剧本和所有用户评论在广义上是相关的。尽管如此,评分最高的评论和编辑评论可能在信息上更加密集。

        最后,考虑文档提供的细节水平。想象我们正在构建一个RAG系统,从自然语言生成SQL查询。我们可以简单地提供带有列名的表模式作为上下文。但是,如果我们包括列描述和一些代表性值呢?额外的细节可能有助于LLM更好地理解表的语义,从而生成更正确的SQL。

        不要忘了关键词搜索;将其用作基线,并在混合搜索中使用。

        鉴于基于嵌入的RAG演示非常普遍,人们很容易忘记或忽视在信息检索领域数十年的研究和解决方案。

        尽管如此,虽然嵌入无疑是一个强大的工具,但它们并非万能的。首先,尽管它们在捕获高层次的语义相似性方面表现出色,但它们可能难以处理更具体的基于关键词的查询,比如当用户搜索名称(例如,Ilya)、缩写(例如,RAG)或ID(例如,claude-3-sonnet)时。基于关键词的搜索,如BM25,就是为此明确设计的。经过多年的基于关键词的搜索,用户可能已经认为它是理所当然的,如果他们期望检索的文档没有被返回,可能会感到沮丧。

        向量嵌入并不能神奇地解决搜索问题。事实上,在您使用语义相似性搜索重新排名之前的步骤中,才是真正需要付出努力的地方。与BM25或全文搜索相比,取得真正的改进是很难的。

——Aravind Srinivas, Perplexity.ai 首席执行官

        我们几个月来一直在向客户和合作伙伴传达这一点。使用简单的嵌入进行最近邻搜索会产生非常嘈杂的结果,您最好从基于关键词的方法开始。

——Beyang Liu, Sourcegraph 首席技术官

        其次,使用关键词搜索更容易理解为什么检索到某个文档——我们可以查看与查询匹配的关键词。相比之下,基于嵌入的检索不太可解释。最后,由于像Lucene和OpenSearch这样的系统经过数十年的优化和实战测试,关键词搜索通常更具计算效率。

        在大多数情况下,混合方法效果最佳:关键词匹配用于明显匹配,嵌入用于同义词、上下位词和拼写错误,以及多模态(例如,图像和文本)。Shortwave分享了他们如何构建RAG管道,包括查询重写、关键词+嵌入检索和排名。

        对于新知识,优先选择RAG而不是微调

        RAG和微调都可以用来将新信息纳入LLMs并提高特定任务的性能。那么,我们应该先尝试哪一个呢?

        最近的研究表明,RAG可能具有优势。一项研究比较了RAG和无监督微调(即继续预训练),在MMLU的一个子集和当前事件上评估了两者。他们发现RAG在训练期间遇到的知识以及完全新的知识方面,始终优于微调。在另一篇论文中,他们在一个农业数据集上比较了RAG和有监督微调。类似地,RAG的性能提升大于微调,特别是对于GPT-4(见论文的表20)。

        除了提高性能外,RAG还带来了几个实际优势。首先,与持续预训练或微调相比,保持检索索引的最新状态更容易——也更便宜!其次,如果我们的检索索引有问题文档包含有毒或有偏见的内容,我们可以轻松地丢弃或修改这些冒犯性文档。

        此外,RAG中的R提供了更细粒度的控制,关于我们如何检索文档。例如,如果我们为多个组织托管RAG系统,通过划分检索索引,我们可以确保每个组织只能从自己的索引中检索文档。这确保我们不会无意中将一个组织的信息暴露给另一个组织。

        长上下文模型不会使RAG过时

        随着Gemini 1.5提供高达10M个token的上下文窗口,一些人开始质疑RAG的未来。

        我认为Gemini 1.5被Sora过度炒作了。一个10M个token的上下文窗口实际上使大多数现有的RAG框架变得不必要——你只需将任何数据放入上下文并像平常一样与模型对话。想象一下,这对所有将大部分工程努力投入到RAG的初创公司/代理/LangChain项目会有什么影响 😅 或用一句话来说:10M上下文杀死了RAG。Gemini干得好。

——Yao Fu

        虽然长上下文将改变游戏规则,用于分析多个文档或与PDF聊天等用例,但RAG消亡的传言被极大地夸大了。

        首先,即使有10M个token的上下文窗口,我们仍然需要一种方法来选择要输入模型的信息。其次,除了狭窄的针头评估之外,我们还没有看到令人信服的数据,证明模型可以有效地推理如此大的上下文。因此,没有良好的检索(和排名),我们冒着用干扰物压倒模型的风险,或者甚至可能用完全无关的信息填满上下文窗口。

        最后,还有成本问题。Transformer的推理成本随着上下文长度的增加而呈二次方(或在空间和时间上呈线性)增加。仅仅因为存在一个模型,可以在回答每个问题之前读取您组织的全部Google Drive内容,并不意味着这是一个好主意。考虑一个类比,就像我们如何使用RAM:尽管存在具有数十TB RAM的计算实例,我们仍然从磁盘读取和写入。

        所以,不要把你的RAG扔进垃圾桶。即使上下文窗口变大,这种模式仍然有用。

        调整和优化工作流程 提示LLM只是开始。

        要充分利用它们,我们需要超越单个提示,接受工作流程。例如,我们如何将一个复杂的任务分解为多个更简单的任务?什么时候微调或缓存有助于提高性能并降低延迟/成本?在这一部分,我们分享经过验证的策略和现实世界的例子,帮助您优化和构建可靠的LLM工作流程。

        一步一步的,多轮“流程”可以带来很大的提升。

         我们已经知道,通过将单个大提示分解为多个小提示,我们可以取得更好的结果。一个例子是AlphaCodium:通过从单个提示切换到多步骤工作流程,他们将CodeContests上GPT-4的准确性(pass@5)从19%提高到44%。工作流程包括:

  • 反思问题
  • 对公共测试进行推理
  • 生成可能的解决方案
  • 对可能的解决方案进行排名
  • 生成合成测试 在公共和合成测试上迭代解决方案。

        具有清晰目标的小任务构成最佳的代理或流程提示。并非每个代理提示都需要请求结构化输出,但结构化输出有助于与协调代理与环境交互的系统接口。

一些有用的尝试

        尽可能明确地制定一个明确的计划步骤。考虑有预定义的计划可供选择(参见 https://youtu.be/hGXhFa3gzBs?si=gNEGYzux6TuB1del)。 将原始用户提示重写成代理提示。小心,这个过程是有损耗的! 代理行为作为线性链、DAGs和状态机;不同的依赖和逻辑关系可能对不同规模更合适或不合适。你能从不同的任务架构中挤出性能优化吗? 计划验证;你的计划可以包括如何评估其他代理的响应的说明,以确保最终组装协同工作。 具有固定上游状态的提示工程——确保你的代理提示针对可能出现的变体集合进行评估。

        目前优先考虑确定性工作流程

        虽然AI代理可以动态响应用户请求和环境,但它们的不确定性质使它们成为一个部署上的挑战。代理采取的每一步都有可能失败,而且从错误中恢复的机会很小。因此,代理成功完成多步骤任务的可能性随着步骤数量的增加呈指数级下降。结果,构建代理的团队发现很难部署可靠的代理。

        一个有希望的方法是让代理系统产生确定性的计划,然后以结构化、可复制的方式执行。第一步,给定一个高层次的目标或提示,代理生成一个计划。然后,计划以确定性方式执行。这使得每一步都更加可预测和可靠。好处包括:

        生成的计划可以作为少量样本提示或微调代理。 确定性执行使系统更可靠,因此更容易测试和调试。此外,失败可以追溯到计划中的特定步骤。 生成的计划可以表示为有向无环图(DAGs),相对于静态提示,更容易理解和适应新情况。

        最成功的代理构建者可能是那些有管理初级工程师经验的人,因为生成计划的过程类似于我们如何指导和管理初级人员。我们给初级人员明确的目标和具体的计划,而不是模糊的开放式方向,我们也应该为我们的代理这样做。

        最终,可靠、工作代理的关键可能在于采用更多结构化、确定性的方法,以及收集数据以改进提示和微调模型。没有这些,我们将构建的代理可能有时表现得非常好,但平均而言,会让用户失望,这会导致留存率差。

超越温度获取更多样化的输出

译注:

        "temperature" 并不是指字面上的温度,而是一个用于控制语言模型输出创造性和多样性的参数。在大型语言模型(LLMs)中,temperature 参数影响着生成文本的随机性。较低的温度值会使模型倾向于生成更常见、概率更高的词,而较高的温度值则会使模型生成更多样化、更不常见的词。

        假设您的任务需要 LLM 输出的多样性。也许您正在编写一个 LLM 流程,根据用户之前购买的产品列表推荐目录中的产品。当您多次运行提示时,您可能会注意到结果推荐过于相似——所以您可能会增加 LLM 请求中的温度参数。

        简而言之,增加温度参数会使 LLM 响应更加多样化。在采样时,下一个 token 的概率分布变得更加平坦,这意味着通常不太可能被选择的 token 会更经常被选中。然而,当增加温度时,您可能会注意到与输出多样性相关的一些失败模式。例如,目录中可能适合的某些产品可能永远不会被 LLM 输出。如果它们根据 LLM 在训练时学到的内容,很可能会跟随提示,那么相同的少数产品可能会在输出中过度表示。如果温度过高,您可能会得到引用不存在的产品(或胡言乱语!)的输出。

        换句话说,增加温度并不能保证 LLM 会从您期望的概率分布中采样输出(例如,均匀随机)。尽管如此,我们有其他技巧来增加输出多样性。最简单的方法是调整提示内的元素。例如,如果提示模板包括一个项目列表,比如历史购买,每次将这些项目插入提示时,改变它们的顺序可以产生显著差异。

        此外,保留一个最近的输出列表可以帮助防止冗余。在我们的推荐产品示例中,通过指示 LLM 避免建议这个最近的列表中的物品,或者通过拒绝和重新采样与最近建议相似的输出,我们可以进一步多样化响应。另一个有效的策略是改变提示中使用的措辞。例如,加入像“选择一个用户会喜欢经常使用的物品”或“选择一个用户可能会推荐给朋友的产品”这样的短语可以转移焦点,从而影响推荐产品的种类。

缓存被低估了

         缓存通过消除对相同输入重新计算响应的需要,节省成本并消除生成延迟。此外,如果响应以前已经被审查过,我们可以提供这些经过审查的响应,并减少提供有害或不适当内容的风险。

        一种直接的缓存方法是为正在处理的项目使用唯一 ID,比如我们正在总结新文章或产品评论。当一个请求进来时,我们可以检查缓存中是否已经有摘要存在。如果有,我们可以立即返回它;如果没有,我们生成、审查并提供它,然后将其存储在缓存中以供将来的请求使用。

        对于更开放式的查询,我们可以借鉴搜索领域的技术,该领域也利用缓存来处理开放式输入。自动完成和拼写更正等功能也有助于规范化用户输入,从而提高缓存命中率。

何时微调

        我们可能有一些任务,即使设计得最巧妙的提示也不足以满足需求。例如,即使在显著的提示工程之后,我们的系统可能仍然无法返回可靠、高质量的输出。如果是这样,那么可能需要针对您的特定任务微调模型。

        成功的例子包括:

        Honeycomb 的自然语言查询助手:最初,在提示中提供了“编程手册”以及 n-shot 示例用于上下文学习。虽然这种方法效果还不错,但微调模型可以更好地输出特定领域的语言的语法和规则。

        ReChat 的 Lucy:LLM 需要以一种非常特定的格式生成响应,这种格式结合了结构化和非结构化数据,以便前端正确渲染。微调对于它的一致工作至关重要。

        然而,尽管微调可能有效,但它伴随着显著的成本。我们必须注释微调数据,微调和评估模型,并最终自行托管它们。因此,请考虑较高的前期成本是否值得。如果提示可以让您达到 90% 的目标,那么微调可能不值得投资。然而,如果我们确实决定微调,为了减少收集人工注释数据的成本,我们可以生成并微调合成数据,或者在开源数据上进行引导。

评估与监控

        评估 LLM 可能是个雷区。LLM 的输入和输出是任意文本,我们为它们设定的任务也各不相同。尽管如此,严格而周到的评估至关重要——OpenAI 的技术领导者从事评估工作并在个人评估上提供反馈,这并非巧合。

        评估 LLM 应用引发了多种定义和简化:它只是单元测试,或者更像可观测性,或者可能只是数据科学。我们发现所有这些观点都很有用。在接下来的部分中,我们将提供一些我们学到的经验教训,关于构建评估和监控流程的重要性。

从真实的输入/输出样本中创建一些基于断言的单元测试

        创建由生产环境中的输入和输出样本组成的单元测试(即断言),并根据至少三个标准对输出设定期望。虽然三个标准看起来可能是随意的,但这是一个实际的起点;如果更少,可能表明您的任务没有足够定义或者太开放,比如一个通用聊天机器人。这些单元测试或断言应在对流程进行任何更改时触发,无论是编辑提示、通过 RAG 添加新上下文还是其他修改。本文有一个实际用例的基于断言的测试示例。

        考虑从指定在所有响应中包含或排除的短语或想法的断言开始。还要考虑检查单词、项目或句子计数是否在一定范围内。对于其他类型的生成,断言可能看起来不同。执行评估是一种强大的代码生成评估方法,其中您运行生成的代码,并确定运行时状态是否满足用户请求。

        例如,如果用户请求一个名为 foo 的新函数;那么在执行代理生成的代码之后,foo 应该是可调用的!执行评估中的一个挑战是,代理代码经常使运行时处于与目标代码略有不同的状态。有效地“放宽”断言到任何可行答案都会满足的绝对最弱假设可能会很有用。

        最后,像客户一样使用您的产品(即,“内部测试”)可以提供对真实世界数据上故障模式的见解。这种方法不仅有助于识别潜在的弱点,而且还提供了可以转换为评估的生产样本的有用来源。

LLM-as-Judge 可以工作(有点),但它不是万能的

        LLM-as-Judge,我们用一个强大的 LLM 来评估其他 LLM 的输出,有些人对此持怀疑态度。(我们中的一些人最初是巨大的怀疑者。)尽管如此,当实施得当时,LLM-as-Judge 与人类判断的相关性相当不错,至少可以帮助建立关于新提示或技术可能表现如何的先验知识。

具体来说,在进行成对比较时(例如,控制对比治疗),LLM-as-Judge 通常可以正确判断方向,尽管胜负的幅度可能存在噪声。

以下是一些建议,以充分利用 LLM-as-Judge:

  • 使用成对比较:而不是要求 LLM 在 Likert 量表上对单个输出进行评分,给它两个选项并要求它选择更好的一个。这往往会导致更稳定的结果。
  • 控制位置偏差:呈现选项的顺序可以影响 LLM 的决策。为了缓解这一点,每次都要进行两次成对比较,每次都交换配对的顺序。只是在交换后要确保将胜利归因于正确的选项!
  • 允许平局:在某些情况下,两个选项可能同样好。因此,允许 LLM 宣布平局,这样它就不必任意选择一个赢家。
  • 使用思维链:在给出最终偏好之前,要求 LLM 解释其决策可以增加评估的可靠性。作为一个额外的好处,这允许您使用一个较弱但更快的 LLM 并仍然获得类似的结果。因为通常这部分流水线是批量模式,思维链的额外延迟不是问题。
  • 控制响应长度:LLM 倾向于偏向于更长的响应。为了缓解这一点,请确保响应对的长度相似。

        LLM-as-Judge 的一个特别强大的应用是检查新提示策略是否存在退步。如果您已经跟踪了一系列生产结果,有时您可以使用新的提示策略重新运行这些生产示例,并使用 LLM-as-Judge 快速评估新策略可能存在问题的地方。

        这里有一个简单但有效的迭代 LLM-as-Judge 的方法,我们只是记录 LLM 响应、法官的批评(即思维链)和最终结果。然后与利益相关者一起审查,以确定改进的领域。经过三次迭代,与人类和 LLM 的一致性从 68% 提高到 94%!

        然而,LLM-as-Judge 并不是万能的。即使是最强大的模型,在语言的微妙方面也可能无法可靠地评估。此外,我们发现传统的分类器和奖励模型比 LLM-as-Judge 实现更高的准确性,并且成本和延迟更低。对于代码生成,LLM-as-Judge 可能比更直接的评估策略如执行评估更弱。

评估生成的“实习生测试”

        我们喜欢在评估生成时使用以下“实习生测试”:如果您将输入到语言模型的确切内容(包括上下文)交给一个相关领域的普通大学生作为任务,他们能成功吗?需要多长时间?

        如果答案是不,因为 LLM 缺乏所需的知识,请考虑如何丰富上下文。

        如果答案是不,我们也无法通过改善上下文来解决,那么可能我们已经遇到了对当代 LLM 来说太难的任务。

        如果答案是肯定的,但需要一段时间,我们可以尝试减少任务的复杂性。它是否可以分解?是否有任务的方面可以更加模板化?

        如果答案是肯定的,他们会很快得到它,那么是时候深入研究数据了。模型做错了什么?我们能找到失败的模式吗?尝试在模型响应前后要求模型自我解释,以帮助您建立心理理论。

过分强调某些评估可能会损害整体性能

        “当一个度量成为目标时,它就不再是一个好的度量。” ——古德哈特定律

        一个例子是“大海捞针”(NIAH)评估。原始评估帮助量化了随着上下文大小增长模型的召回率,以及针的位置如何影响召回率。然而,它被过分强调,以至于它被作为 Gemini 1.5 报告的图 1。评估涉及将特定短语(“特殊的魔法{城市}数字是:{数字}”)插入到重复 Paul Graham 的文章的长文档中,然后提示模型回忆魔法数字。

        虽然一些模型实现了接近完美的召回率,但 NIAH 是否真正反映了现实世界应用中所需的推理和回忆能力值得怀疑。考虑一个更实际的场景:给定一个小时长的会议记录,LLM 是否能总结关键决策和下一步行动,并且正确地将每个项目归因于相关的人?这个任务更加现实,超越了死记硬背,还考虑了解析复杂讨论、识别相关信息和综合摘要的能力。

        这里有一个实际 NIAH 评估的例子。使用医生-患者视频通话的记录,LLM 被询问有关患者的用药情况。它还包括一个更具挑战性的 NIAH,插入一个用于比萨饼配料的随机短语,如“制作完美比萨所需的秘密配料有:浸泡在浓缩咖啡中的枣、柠檬和山羊奶酪。”在用药任务上的召回率约为 80%,在比萨任务上为 30%。

        另外,过分强调 NIAH 评估可能会导致提取和总结任务的性能下降。**因为这些大型语言模型(LLMs)被如此精细地调整以关注每一个句子,它们可能开始将不相关的细节和干扰因素视为重要,因此将它们包含在最终输出中(当它们不应该这么做的时候!)

        这同样适用于其他评估和用例。例如,总结。过分强调事实一致性可能导致总结不够具体(因此不太可能事实上的不一致),可能也不够相关。相反,过分强调写作风格和口才可能会导致更多华丽的、营销型的语言,这可能会引入事实上的不一致性。

简化注释为二元任务或成对比较

        提供开放式反馈或对模型输出进行评分在认知上要求很高。结果,收集到的数据更加嘈杂——由于评估者之间的差异——因此不太有用。一种更有效的方法简化任务,减少评估者的认知负担。两种有效的任务是二元分类和成对比较。

        在二元分类中,评估者被要求对模型的输出进行简单的是否判断。他们可能被问及生成的摘要是否与源文档在事实上一致,或者所提出的回答是否相关,或者是否包含有毒内容。与李克特量表相比,二元决策更精确,评估者之间的一致性更高,并且通量更高。这是 Doordash 通过一系列是非问题设置他们的标签队列来标记菜单项的方式。

        在成对比较中,评估者面对一对模型响应,并被要求选择哪一个更好。因为对于人类来说,“A 比 B 更好” 比单独给 A 或 B 分配一个分数更容易,这导致更快和更可靠的注释(超过李克特量表)。在 Llama2 聚会上,Llama2 论文的作者之一 Thomas Scialom 确认,成对比较比收集监督微调数据(如书面回答)更快、更便宜。前者的成本是每个单位 3.5 美元,后者的成本是每个单位 25 美元。

        如果您开始编写标签指南,这里有一些来自 Google 和 Bing 搜索的参考指南。

(无参考)评估和护栏可以互换使用

        护栏有助于捕获不适当或有害的内容,而评估有助于衡量模型输出的质量和准确性。在无参考评估的情况下,它们可能被视为同一枚硬币的两面。无参考评估是不依赖于“黄金”参考,例如人类编写的答案,并且可以仅基于输入提示和模型的响应来评估输出的质量。

        其中一些例子是摘要评估,我们只需要考虑输入文档就可以根据事实一致性和相关性来评估摘要。如果摘要在这些指标上得分很低,我们可以选择不向用户显示它,有效地将评估用作护栏。类似地,无参考翻译评估可以在不需要人类翻译参考的情况下评估翻译的质量,再次允许我们将其用作护栏。

LLMs 甚至在不应该的时候也会返回输出

        使用 LLMs 的一个关键挑战是,它们经常在不应该的时候生成输出。这可能导致无害但无意义的响应,或者更严重的缺陷,如毒性或危险内容。例如,当被要求从文档中提取特定属性或元数据时,LLM 可能会自信地返回值,即使这些值实际上并不存在。或者,模型可能会用非英语回应,因为我们在上下文中提供了非英语文档。

        虽然我们可以尝试提示 LLM 返回“不适用”或“未知”的响应,但这并不是万无一失的。即使有日志概率可用,它们也是输出质量的差指标。虽然日志概率表明了令牌出现在输出中的可能性,但它们并不一定反映了生成文本的正确性。相反,对于经过指令调整的模型,它们被训练为响应查询并生成连贯的响应,日志概率可能没有很好地校准。因此,尽管高日志概率可能表明输出是流畅和连贯的,但这并不意味着它是准确或相关的。

        虽然仔细的提示工程在一定程度上有所帮助,但我们应该用强大的护栏补充它,以检测和过滤/重新生成不想要的输出。例如,OpenAI 提供了一个内容审核 API,可以识别不安全的回答,例如仇恨言论、自我伤害或性内容。类似地,还有许多用于检测个人身份信息(PII)的软件包。一个好处是,护栏在很大程度上与用例无关,因此可以广泛地应用于给定语言的所有输出。此外,通过精确检索,如果没有任何相关文档,我们的系统可以确定性地响应“我不知道”。

        这里有一个推论,即 LLMs 可能会在预期时失败,不产生输出。这可能由于各种原因发生,从 API 提供者的长尾延迟等简单问题,到更复杂的问题,如输出被内容审核过滤器阻止。因此,持续记录输入和(可能的)输出缺失对于调试和监控非常重要。

幻觉是一个棘手的问题。

        与内容安全或 PII 缺陷不同,这些问题得到了很多关注,因此很少发生,事实上的不一致却顽固地持续存在,更难以检测。它们更常见,发生在 5% 到 10% 的基线率上,根据我们从 LLM 提供商那里了解到的,即使在像摘要这样的简单任务中,也很难将其降至 2% 以下。

        为了解决这个问题,我们可以结合提示工程(生成上游)和事实不一致护栏(生成下游)。对于提示工程,像思维链这样的技术通过让 LLM 在最终返回输出之前解释其推理,有助于减少幻觉。然后,我们可以应用事实不一致护栏来评估摘要的事实性,并过滤或重新生成幻觉。在某些情况下,幻觉可以被确定性地检测到。当使用 RAG 检索的资源时,如果输出是有结构的,并确定所使用的资源,您应该能够手动验证它们是否来源于输入上下文。

关于作者

        Eugene Yan 设计、构建并运营大规模服务客户的机器学习系统。他目前在亚马逊担任高级应用科学家,构建服务于全球数百万客户的推荐系统(RecSys)并应用大型语言模型(LLMs)来更好地服务客户。之前,他领导了 Lazada(被阿里巴巴收购)和一家健康科技 A 系列公司的机器学习。他在 eugeneyan.com 和 ApplyingML.com 上写作和演讲有关机器学习、推荐系统、大型语言模型和工程的话题。

        Bryan Bischof 是 Hex 的 AI 负责人,他领导着一支工程师团队,负责构建 Magic —— 数据科学和分析的辅助工具。Bryan 在数据分析、机器学习工程、数据平台工程和 AI 工程等领域的团队中都有工作经验。他在 Blue Bottle Coffee 开始了数据团队,在 Stitch Fix 领导了多个项目,并在 Weights and Biases 建立了数据团队。Bryan 之前与 O’Reilly 合著了《构建生产推荐系统》一书,并在罗格斯大学的研究生院教授数据科学和分析。他拥有纯数学博士学位。

        Charles Frye 教授人们构建 AI 应用。在发表了有关精神药理学和神经生物学的研究后,他在加州大学伯克利分校获得了博士学位,其论文工作涉及神经网络优化。他通过 Weights and Biases、Full Stack Deep Learning 和 Modal 的教育和咨询工作,教授了数千人整个 AI 应用开发栈,从线性代数基础到 GPU 奥秘和构建可防御的业务。

        Hamel Husain 是一位拥有超过 25 年经验的机器学习工程师。他曾与 Airbnb 和 GitHub 等创新公司合作,其中包括 OpenAI 用于代码理解的早期 LLM 研究。他还领导并贡献了众多流行的开源机器学习工具。Hamel 目前是一位独立顾问,帮助公司实现大型语言模型(LLMs)的运营化,以加速他们的 AI 产品旅程。

        Jason Liu 是一位杰出的机器学习顾问,以带领团队成功推出 AI 产品而闻名。Jason 的技术专长涵盖个性化算法、搜索优化、合成数据生成和 MLOps 系统。他的经验包括 Stitchfix,他在那里创建了一个处理每天 3.5 亿次请求的推荐框架和可观测性工具。其他角色包括 Meta、NYU 以及像 Limitless AI 和 Trunk Tools 这样的初创公司。

        Shreya Shankar 是加州大学伯克利分校计算机科学博士生,也是一位机器学习工程师。她在两家初创公司担任首位机器学习工程师,从零开始构建服务于数千用户的 AI 驱动产品。作为一名研究者,她的工作侧重于通过以人为本的方法解决生产 ML 系统中的数据挑战。她的作品出现在顶级数据管理和人机交互场所,如 VLDB、SIGMOD、CIDR 和 CSCW。

联系我们

        我们很乐意听到您对这篇文章的看法。您可以通过 contact@applied-llms.org 与我们联系。我们中的许多人都愿意提供各种形式的咨询和指导。如果我们认为合适,我们会在您联系我们后将您引导到正确的专家。

致谢

        这个系列最初是在群聊中的一次对话,Bryan 开玩笑说他受到启发要写“一年的 AI 工程”。然后,在群聊中发生了 ✨magic✨,我们所有人都受到启发,投入进来分享我们到目前为止学到的东西。

        作者要感谢 Eugene 领导了大部分文档整合和整体结构,以及大部分课程。此外,还要感谢他承担主要的编辑责任和文档方向。作者要感谢 Bryan 引发了这次写作的火花,将写作重构为战术、运营和战略部分及其介绍,并推动我们思考如何更广泛地触及和帮助社区。作者要感谢 Charles 对成本和 LLMOps 的深入研究,以及将课程编织得更加连贯和紧凑——感谢他让这篇文章只有 30 页而不是 40 页!作者感谢 Hamel 和 Jason 从客户咨询和一线工作中提供的见解,感谢他们从客户那里获得的广泛通用的学习,以及对工具的深入了解。最后,感谢 Shreya 提醒我们评估和严格的生产实践的重要性,并将她的研究和原始结果带到这篇文章中。

        最后,作者要感谢所有团队,他们慷慨地分享了你们自己的写作中的挑战和教训,我们在本系列中引用了这些内容,以及 AI 社区对你们充满活力的参与和与这个群体的互动。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Sure, I can help you with that. First, let me briefly explain what a snowball option is. It is a type of option where the strike price is set at the beginning of the option period but the payoff is based on the cumulative return of an underlying asset over a fixed period of time. In other words, the payoff of a snowball option depends on the performance of the underlying asset over the option period. To price a snowball option, we need to use a simulation approach. One common method is to use Monte Carlo simulation. The steps are as follows: 1. Generate random paths for the underlying asset based on a given stochastic process (e.g. geometric Brownian motion). 2. Calculate the cumulative return for each path over the option period. 3. Calculate the payoff of the option based on the cumulative returns. 4. Repeat steps 1-3 many times to obtain a distribution of payoffs. 5. Discount the expected payoff to obtain the option price. Here is an example Python code to price a snowball option: ```python import numpy as np # Parameters S0 = 100 # initial stock price T = 1 # option period (in years) r = 0.05 # risk-free rate sigma = 0.2 # volatility K = 100 # strike price n_sim = 100000 # number of simulations # Simulation dt = 1/252 # time step (in years) n_steps = int(T/dt) # number of time steps S = np.zeros((n_sim, n_steps+1)) S[:,0] = S0 for i in range(n_steps): dW = np.random.normal(0, np.sqrt(dt), size=n_sim) S[:,i+1] = S[:,i] * np.exp((r - 0.5*sigma**2)*dt + sigma*dW) # Cumulative returns R = np.cumprod(S, axis=1)[:,-1] # Payoff P = np.maximum(R - K, 0) # Option price C = np.exp(-r*T) * np.mean(P) print("Option price:", C) ``` In this example, I have assumed a geometric Brownian motion process for the underlying asset. The simulation generates 100,000 random paths for the stock price over the option period, and calculates the cumulative return for each path. The payoff of the option is the maximum of the cumulative return minus the strike price, or zero if the cumulative return is less than the strike price. The option price is the discounted expected payoff. Note that this is just a simple example, and there are many ways to modify or improve the simulation approach depending on the specific requirements of the snowball option.
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值