这篇文章是关于将大型语言模型集成到系统和产品中的实际模式。我们将借鉴学术研究、行业资源和从业者专业知识,并尝试将它们提炼成关键想法和实践。

本文摘自亚马逊科学家Eugene Yan 的个人博客

原文地址:https://eugeneyan.com/writing/llm-patterns/

 

 

有一大批问题很容易想象和构建演示,但很难制造出产品。例如,自动驾驶:在一个街区周围演示汽车自动驾驶很容易,但将其制作成产品需要十年的时间。”- Karpathy

有七个关键模式。我还按照提高性能与降低成本/风险的范围,以及更接近数据与更接近用户来组织它们。

以下为机器翻译,查看原文请点击这里


评估:衡量绩效

评估是一组用于评估模型在任务中表现的测量。它们包括基准数据和指标。来自HackerNews的评论:

评估对团队的重要性是运送热垃圾的人和那些在太空中认真制造产品的人之间的主要区别。

为什么要评估?

评估使我们能够衡量我们的系统或产品表现如何,并检测任何回归。(系统或产品可以由多个组件组成,如LLM、提示模板、检索到的上下文和温度等参数。)一套具有代表性的评估让我们朝着大规模测量系统变化迈出了一步。如果没有评估,我们将盲目飞行,或者每次更改都必须目视检查LLM输出。

关于evals的更多信息

语言建模领域有许多基准。一些值得注意的是:

  • MMLU:一套57项任务,涵盖小学数学、美国历史、计算机科学、法律等。为了表现良好,模型必须具备广泛的世界知识和解决问题的能力。
  • EleutherAI Eval:统一框架,通过200个任务的零/很少拍摄设置来测试模型。包含大量评估,包括BigBench、MMLU等。
  • HELM:HELM不是具体的任务和指标,而是通过跨领域评估LLM来全面评估LLM。指标包括准确性、校准、稳健性、公平性、偏差、毒性等。任务包括问答、信息检索、总结、文本分类等。
  • AlpacaEval:自动评估框架,用于衡量一个强大的LLM(例如GPT-4)更喜欢一个模型的输出而不是参考模型的频率。指标包括胜率、偏差、延迟、价格、方差等。经验证与2万份人类注释高度一致。

我们可以将指标分为两类:上下文依赖性或上下文无关。

  • 上下文相关:这些考虑了上下文。它们通常被提议用于特定任务;将它们重新用于其他任务需要一些调整。
  • 无上下文:在评估生成的输出时,这些与上下文无关;它们只将输出与提供的黄金引用进行比较。由于它们是任务不可知论者,因此更容易应用于各种任务。

为了更好地了解这些指标(及其潜在不足),我们将探索一些常用的指标,如BLEU、ROUGE、BERTScore和MoverScore。

BLEU(双语评估代读)是一个基于精度的度量:它计算生成的输出中也显示在参考中的n克数,然后将其除以输出中的单词总数。它主要用于机器翻译,由于其成本效益,它仍然是一个受欢迎的指标。

首先,各种值的精度第十四个英文字母计算:

精度第十四个英文字母=∑P∈输出信息∑n-克∈P总数夹子(n-克)∑P∈输出信息∑n-克∈P总数(n-克)

字母C字母O第二十一个罗马字母第十四个英文字母字母T字母C字母l我P(n-克)被n-gram在任何相应的引用句子中出现的最大次数剪切。

总数夹子(第十四个英文字母-克)=部长(匹配第十四个英文字母-克计数,马克斯字母R∈字母R(第十四个英文字母-克计数字母R))

一旦我们计算了各种精度第十四个英文字母,最终的BLEU-N分数被计算为所有P字母Re字母C我罗马字母的第十九个我字母O第十四个英文字母第十四个英文字母分数。

然而,由于精度完全依赖于n克,并且不考虑生成输出的长度,因此仅包含一个通用单词(如停止单词)的输出将实现完美的精度。这可能会产生误导,并鼓励包含较少单词的输出,以提高BLEU分数。为了应对这种情况,增加了简短的惩罚,以惩罚过短的句子。

字母bP={1如果|p|>|r|e1−|字母R||P|否则

因此,最终公式是:

BLEU-N=字母bP⋅经验⁡(∑第十四个英文字母=1第十四个英文字母罗马字母的第23个字母第十四个英文字母日志⁡(精度第十四个英文字母))

ROUGE(以召回为导向的Gisting评估副手语):与BLEU相反,ROUGE以召回为导向。它计算了引用中也出现在输出中的单词数。它通常用于评估自动总结任务。

有几种ROUGE变体。ROUGE-N与BLEU最相似,因为它还计算了输出和引用之间的n-gram匹配数。

ROUGE-N=∑罗马字母的第十九个字母R∈参考文献∑第十四个英文字母-克∈罗马字母的第十九个字母R总数比赛(第十四个英文字母-克)∑罗马字母的第十九个字母R∈参考文献∑第十四个英文字母-克∈罗马字母的第十九个字母R总数(第十四个英文字母-克)

其他变体包括:

  • ROUGE-L:这测量输出和参考值之间最长的通用子序列(LCS)。它考虑了句子级结构的相似性,并在最长的序列中并发生n克的零。
  • ROUGE-S:这测量了输出和参考之间的跳过比格拉姆。Skip-bigrams是一对保持句子顺序的单词,无论它们之间可能夹着的单词。

BERTScore是一个基于嵌入的度量,它使用余弦相似性将生成的输出中的每个令牌或n-gram与参考句进行比较。BERTScore有三个组成部分:

  • 回忆:引用中每个令牌与生成输出中最接近的匹配之间的平均余弦相似性。
  • 精度:生成输出中的每个令牌与引用中最近的匹配之间的平均余弦相似性。
  • F1:召回和精度的谐波平均值

字母Re字母C罗马字母的第一个字母字母l字母l伯特=1|字母R|∑我∈字母R马克斯第十个英文字母J∈P我→字母T第十个英文字母J→,P字母Re字母C我罗马字母的第十九个我字母O第十四个英文字母伯特=1|P|∑第十个英文字母J∈P马克斯我∈字母R我→字母T第十个英文字母J→伯特得分=第六个罗马字母伯特=2⋅P伯特⋅字母R伯特P伯特+字母R伯特

BERTScore很有用,因为它可以解释同义词和释义。像BLEU和ROUGE这样的简单指标无法做到这一点,因为它们依赖于精确匹配。事实证明,BERTScore在图像字幕和机器翻译等任务中具有更好的相关性。

MoverScore还使用上下文嵌入来计算生成的输出和引用中令牌之间的距离。但与基于令牌一对一匹配(或“高对齐”)的BERTScore不同,MoverScore允许多对一匹配(或“软对齐”)。

BERTScore(左)与MoverScore(右)

BERTScore(左)与MoverScore(右;来源

MoverScore允许将一个序列中的语义相关单词映射到另一个序列中的对应词。它通过解决受限的优化问题来做到这一点,该问题找到将一个文本转换为另一个文本的最小努力。这个想法是测量单词将一个序列转换为另一个序列所必须移动的距离。

然而,使用这些传统的基准和指标有几个陷阱。

首先,这些指标和人类的判断之间的相关性很差。BLEU、ROUGE、METEOR等有时与人类评估流利度的方式负相关。特别是,BLEU和ROUGE与需要创造力和多样性的任务相关性很低。此外,即使对于相同的指标,不同研究之间也报告了高方差。这可能是由于收集人类判断的方法不同或不同的度量参数设置。

其次,这些指标通常对更广泛的任务的适应性。对另一项任务采用为一项任务提出的指标并不总是谨慎的。例如,BLEU和ROUGE等精确匹配指标不适合抽象总结或对话等任务。由于它们基于输出和引用之间的n-gram重叠,因此对于可能有各种响应的对话任务来说,它们没有意义。输出可以与引用有零n-gram重叠,但又是一个很好的响应。

第三,即使有最近的基准,如MMLU,相同的模型也可以根据评估的实现获得显著不同的分数Huggingface将最初的MMLU实现与HELM和EleutherAI实现进行了比较,发现同一示例在各种实现中可能具有不同的提示。

MMLU实现中同一问题的不同提示

MMLU实现中同一问题的不同提示(来源

此外,评估方法在所有三个基准上都有所不同:

  • 原始MMLU:仅比较答案(A、B、C、D)的预测概率
  • HELM:使用模型中的下一个令牌概率,并以最高的概率选择令牌,即使它不是选项之一。
  • EleutherAI:计算每个答案的完整答案序列(即一个字母后跟答案文本)的概率。然后,以最高的概率选择答案。

MMLU实现中同一问题的不同评估

MMLU实现中同一问题的不同评估(来源

因此,即使对于相同的评估,绝对分数和模型排名也会根据评估的实施情况而大幅波动。这意味着模型指标没有真正的可比性,即使对于相同的评估,除非eval的实现在提示和标记化等微小细节上是相同的。

除了上述传统评估外,一个新兴趋势是使用强大的LLM作为其他LLM几代人的无参考指标。这意味着我们可能不需要人类的判断或黄金参考来评估。

G-Eval是一个框架,它应用了带有Though链(CoT)的LLM和表单填充范式来评估LLM输出。首先,他们为LLM提供任务介绍和评估标准,并要求其生成评估步骤的CoT。然后,为了评估新闻总结的一致性,他们连接提示、CoT、新闻文章和摘要,并要求LLM输出1到5的分数。最后,他们使用LLM输出令牌的概率来规范分数,并将其加权求和作为最终结果。

G-Eval概述

G-Eval概述(来源

他们发现,作为评估者的GPT-4与人类判断(0.514)具有很高的斯皮尔曼相关性,优于之前的所有方法。在一致性、一致性、流畅性和相关性等方面,它的表现也优于传统指标。在专题聊天中,它在自然性、连贯性、吸引力和接地性等几个标准上比ROUGE-L、BLEU-4和BERTScore等传统指标做得更好。

Vicuna论文采用了类似的方法。他们首先定义了八个类别(写作、角色扮演、提取、推理、数学、编码、STEM和人文/社会科学),然后为每个类别开发10个问题。接下来,他们从五个聊天机器人中生成了答案:LLaMA、Alpaca、ChatGPT、Bard和Vicuna。最后,他们要求GPT-4根据帮助性、相关性、准确性和细节对答案的质量进行评分。

总体而言,他们发现GPT-4不仅提供了一致的分数,还可以为这些分数提供详细的解释。在单一答案分级范式下,GPT-4与人类的一致性(85%)高于人类之间的一致性(81%)。这表明GPT-4的判断与人类评估者非常一致。

QLoRA还使用LLM来评估另一个LLM的输出。他们要求GPT-4在Vijun基准上对各种型号的性能进行评级,以对照gpt-3.5-turbo进行评级。鉴于gpt-3.5-turbo和另一款型号的响应,GPT-4被提示在10分中得分,并解释其评级。他们还通过模型之间的直接比较来衡量性能,将任务简化为包括领带在内的三类评级方案。

为了验证自动评估,他们收集了关于Vicuna基准的人类判断。使用Mechanical Turk,他们招募了两个注释器与gpt-3.5-turbo进行比较,三个注释器进行配对比较。他们发现,模型的人类和GPT-4排名在很大程度上是一致的,在模型级别上,Spearman排名相关性为0.55。这提供了一个额外的数据点,表明基于LLM的自动评估可能是人类评估的具有成本效益和合理的替代方案。

如何应用评估?

建立坚实的评估应该是任何基于LLM的系统或产品(以及传统的机器学习系统)的起点

不幸的是,BLEU和ROUGE等经典指标对于抽象总结或对话等更复杂的任务来说没有意义。此外,我们已经看到,像MMLU这样的基准对它们的实施和衡量方式很敏感。坦率地说,除非你的大模型系统正在为学校考试而学习,否则使用MMLU作为评估是没有意义的。

因此,我们可以从收集一组特定于任务的评估(即提示、上下文、预期输出作为参考)开始,而不是使用现成的基准。然后,这些评估将指导快速工程、模型选择、微调等。当我们调整系统时,我们可以运行这些评估来快速测量改进或回归。将其视为评估驱动开发(EDD)。

除了评估数据集外,我们还需要有用的指标。它们帮助我们将性能变化提炼成一个数字,该数字在评估运行中具有可比性。如果我们能简化问题,我们可以选择更易于计算和解释的指标。

最简单的任务可能是分类:如果我们使用LLM进行类似分类的任务(例如毒性检测、文档分类)或没有对话的采掘QA,我们可以依靠标准分类指标,如召回、精度、PRAUC等。如果我们的任务没有正确答案,但我们有参考(例如,机器翻译,提取总结),我们可能不得不依赖基于匹配(BLEU,ROUGE)或语义相似性(BERTScore,MoverScore)的损失参考指标。

然而,这些指标可能不适用于更开放式的任务,如抽象总结、对话等。此外,收集人类的判断可能既缓慢又昂贵。因此,我们可能会选择通过强大的大模型来依靠自动评估。相对于通常嘈杂的人类判断(由于注释员之间的偏见不同),大模型判断往往不那么嘈杂(因为偏见更系统化),但更有偏见。但是,如果我们意识到这些大模型偏见,我们可以相应地减轻它们:

  • 位置偏差:像GPT-4这样的LLM倾向于在第一个位置上做出回应。为了缓解这种情况,我们可以在交换订单时两次评估同一对响应。如果两个订单都倾向于相同的响应,我们将其标记为胜利。否则,这是一条领带。
  • 详细性偏见:大模型倾向于更长、更冗长、更冗长的回答,而不是更简洁的回复,即使后者更清晰、质量更高。一个可能的解决方案是确保比较响应的长度相似。
  • 自我增强偏见:大模型对自己的答案有轻微的偏见。GPT-4以高出10%的胜率偏爱自己,而Claude-v1以高出25%的胜率偏爱自己。为了应对这种情况,不要使用相同的LLM进行评估任务。

另一个提示:与其要求LLM进行直接评估(通过给出分数),不如尝试给它一个参考并要求进行比较。这有助于减少噪音。

最后,有时最好的评估是人类评估,又名氛围检查。(不要与名称不佳的代码评估基准HumanEval混淆。)正如MosaicML的潜在空间播客(第34分钟)中提到的:

基于氛围的评估不能被低估。...我们的一个评估只是有一堆提示,在模型训练时观察答案,看看它们是否改变。老实说,我真的不相信这些评估指标能捕捉到我们关心的东西。我们的提示之一是“建议一个3岁的孩子和一个7岁的孩子玩比赛”,这更有价值的是看看在训练过程中答案是如何变化的。——乔纳森·弗兰克尔

检索增强生成:增加知识

检索增强生成(RAG)从基础模型外部获取相关数据,并增强这些数据的输入,提供更丰富的上下文来改善输出。

为什么是RAG?

RAG通过将模型基于检索到的上下文来帮助减少幻觉,从而增加事实性。此外,保持检索索引更新比持续预培训大模型更便宜。这种成本效率使LLM更容易通过RAG访问最新数据。最后,如果我们需要更新或删除有偏见或有毒文档等数据,更新检索索引会更直接。

简而言之,RAG应用了信息检索领域成熟而简单的想法来支持LLM的生成。在最近的红杉调查中,88%的受访者认为检索将是他们堆栈的关键组成部分。

关于RAG的更多信息

在深入研究RAG之前,对文本嵌入有基本的了解是有帮助的。(如果您熟悉该主题,请随意跳过本节。)

文本嵌入是文本数据的压缩、抽象表示,其中任意长度的文本可以表示为数字的矢量。它通常从维基百科等文本语料库中学习。把它们想象成文本的通用编码,其中类似的项目彼此接近,而不同的项目相距更远

良好的嵌入是在下游任务上做得很好,例如检索类似项目。Huggingface的Massive Text Embedding Benchmark(MTEB)对分类、聚类、检索、总结等各种任务的模型进行评分。

快速说明:虽然我们在这里主要讨论文本嵌入,但嵌入可能需要多种方式。例如,CLIP是多模态的,将图像和文本嵌入到同一空间中,允许我们找到与输入文本最相似的图像。我们还可以根据用户行为(例如点击、购买)或图形关系嵌入产品

RAG起源于开放领域问答。早期的一篇元论文显示,通过TF-IDF检索相关文档并将其作为语言模型(BERT)的上下文提供,提高了开放域QA任务的性能。他们把每个任务转换为完形语句,并查询了丢失令牌的语言模型。

随后,密集通道检索(DPR)表明,使用密集嵌入(而不是稀疏的矢量空间,如TF-IDF)进行文档检索可以超过Lucene BM25等强基线(65.2%对42.9%的top-5精度)。他们还表明,更高的检索精度转化为更高的端到端QA准确性,突显了上游检索的重要性。

为了学习DPR嵌入,他们在现有的问答对上微调了两个独立的基于BERT的编码器。通道编码器(eP)将文本段落嵌入到向量中,而查询编码器(eq)将问题嵌入到向量中。然后,查询嵌入用于检索K最接近问题的段落。

他们训练了编码器,使点积相似性具有良好的排名函数,并将损失函数优化为正通道的负对数似然。DPR嵌入针对问题和相关段落向量之间的最大内积进行了优化。目标是学习一个向量空间,使成对的问题及其相关段落紧密结合在一起。

为了推断,他们嵌入了所有段落(通过eP)并在FAISS离线中索引它们。然后,给定查询时的问题,他们计算问题嵌入(通过eq),找回顶部K通过近似最近的邻居的通道,并将其提供给输出问题答案的语言模型(BERT)。

检索增强生成(RAG)因此而得名,它强调了预训练的LLM的缺点。这些缺点包括无法扩展或修改内存,无法提供对生成输出的见解,以及幻觉。

为了解决这些缺点,他们引入了RAG(又名半参数模型)。密集矢量检索作为非参数分量,而预训练的LLM作为参数分量。他们重用DPR编码器来初始化检索器并构建文档索引。对于LLM,他们使用了BART,一个400M参数seq2seq模型。

检索增强生成概述

检索增强生成概述(来源

在推理过程中,他们将输入与检索到的文档连接。然后,LLM生成代币我基于原始输入、检索到的文档和之前的我−1代币。对于生成,他们提出了两种方法,这两种方法在使用检索到的段落来生成输出方面有所不同。

在第一种方法RAG-Sequence中,模型使用相同的文档来生成完整的序列。因此,因为K检索到的文档,生成器为每个文档生成一个输出。然后将每个输出序列的概率边缘化(每个输出序列的概率之和K并按检索每个文档的概率来权衡)。最后,选择概率最高的输出序列。

另一方面,RAG-Token可以根据不同的文档生成每个令牌。给定K检索到的文档,生成器在边缘化之前为每个文档的下一个输出令牌生成分布(聚合所有单个令牌分布)。然后为下一个令牌重复该过程。这意味着,对于每个令牌生成,它可以检索一组不同的K基于原始输入之前生成的令牌的相关文档。因此,文档可以具有不同的检索概率,并对下一个生成的令牌做出不同的贡献。

解码器中的融合器(FiD)还使用带有生成模型的检索来进行开放域QA。它支持两种检索方法,BM25(默认参数为Lucene)和DPR。FiD仅因其在解码器中对检索到的文档执行融合的方式而命名。

解码器中融合概述

解码器中融合概述(来源

对于每个检索到的段落,标题和段落都与问题串联在一起。这些对在编码器中独立处理。他们还在相应的部分之前添加特殊令牌,如question:title:context:。解码器负责连接这些检索到的段落。

因为它在编码器中独立处理段落,因此它可以扩展到大量段落,因为它一次只需要对一个上下文进行自我关注。因此,计算随着检索通道的数量而线性增长(而不是二次增长),使其比RAG-Token等替代品更具可扩展性。然后,在解码过程中,解码器共同处理编码的段落,使其能够更好地在多个检索到的段落中聚合上下文。

检索增强变压器(RETRO)采用类似的模式,它结合了冻结的BERT检索器、可微编码器和分块交叉注意力来生成输出。不同的是,RETRO在整个训练前阶段进行检索,而不仅仅是在推理期间。此外,他们根据输入的块获取相关文档。这允许在生成过程中进行更细粒度的重复检索,而不是每次查询只检索一次。

对于每个输入块(字母C第二十一个罗马字母),K检索到的块字母Re字母T(字母C第二十一个罗马字母)被输入编码器。输出是编码的邻居e第二十一个罗马字母第十个英文字母J地点e第二十一个罗马字母第十个英文字母J=编码器(RET(字母C第二十一个罗马字母)第十个英文字母J,h第二十一个罗马字母)∈字母R字母R×d0。在这里,每个块编码都取决于h第二十一个罗马字母(中间激活)和块的激活字母C第二十一个罗马字母通过交叉注意力层。简而言之,检索到的块的编码取决于输入块的参与激活。e第二十一个罗马字母第十个英文字母J然后用于条件下一个块的生成。

复古概述

RETRO概述(来源

在检索过程中,RETRO将输入序列拆分为64个令牌的块。然后,它找到与上一个块相似的文本,为当前块提供上下文。检索索引由两个连续的令牌块组成,第十四个英文字母和第六个罗马字母。前者是用于计算密钥的邻块(64个令牌),而后者是原始文档中的延续块(64个令牌)。

检索基于近似值K-最近的邻居通过字母l2BERT嵌入上的距离(欧几里得)。(有趣的偏离通常的余弦或点积相似性。)基于SCaNN构建的检索索引可以在10毫秒内查询2T令牌数据库。

他们还演示了如何改造现有的基线模型。通过冻结预训练的砝码,只训练分块交叉注意力和邻居编码器参数(7B模型的砝码的10%),它们可以通过检索来增强变压器,而只需要6M训练序列(训练前序列的3%)。RETRO安装的模型能够超越基线模型的性能,并实现了接近RETRO从头开始训练的性能。

RETRO拟合预训练模型的性能

RETRO安装预训练模型的性能(来源

互联网增强的LM建议使用不起眼的“现成”搜索引擎来增强LLM。首先,他们通过谷歌搜索检索一组相关文档。由于这些检索到的文件往往很长(平均长度为2056字),它们将它们分成每段六句话。最后,他们通过TF-IDF嵌入问题和段落,并应用余弦相似性对每个查询最相关的段落进行排名。

互联网增强的法学硕士概述

互联网增强大模型概述(来源

检索到的段落用于通过少量提示来调节LLM。他们采用传统K-射击提示(K=15)用于闭簿QA(仅限问题和答案),并用证据段落扩展,以便每个上下文都是证据、问题和答案。

对于生成器,他们使用了Gopher,这是一个在300B令牌上训练的280B参数模型。对于每个问题,他们根据检索到的50个段落中的每个段落生成了四个候选答案。最后,他们通过几种方法估计答案概率来选择最佳答案,包括直接推断、RAG、噪声通道推断和专家产品(PoE)。PoE始终表现最好。

RAG也适用于非QA任务,如代码生成。虽然CodeT5+可以用作独立的生成器,但当与RAG结合使用时,它在代码生成方面明显优于类似模型。

为了评估RAG对代码生成的影响,他们在三种情况下评估模型:

  • 基于检索:获取前1名代码样本作为预测
  • 仅生成:仅基于解码器的输出代码
  • 检索增强:在通过解码器生成代码之前,将top-1代码样本附加到编码器输入中。

>CodeT5+的RAG概述

CodeT5+的RAG概述(来源

作为一个定性的例子,他们表明,检索到的代码提供了关键的上下文(例如,HTTP请求的useurlliburllib3),并引导生成过程进行更正确的预测。相比之下,仅生成的方法返回不正确的输出,只捕获“下载”和“压缩”的概念。

如果我们没有查询-传递对的相关性判断呢?没有它们,我们将无法训练将查询和文档嵌入到同一嵌入空间的双编码器,其中相关性由内部产品表示。假设文档嵌入(HyDE)提出了一个解决方案。

HyDE概述

HyDE概述(来源

给定一个查询,HyDE首先提示LLM,如InstructGPT,以生成一个假设的文档。然后,无监督编码器,如Contriver,将文档编码为嵌入向量。最后,在假设文档和语料库之间计算内积,并检索最相似的真实文档。

期望编码器的密集瓶颈作为有损压缩机,并通过嵌入排除无关的、非事实的细节。这重新定义了相关性建模问题,从表示学习任务到生成任务。

如何应用RAG

根据我与黑曜石副驾驶的经验,我发现混合检索(传统搜索索引+基于嵌入的搜索)比单独搜索效果更好。在那个项目中,我结合了经典检索(通过OpenSearch的BM25)和语义搜索(e5-small-v2)。

为什么不只进行基于嵌入的搜索?虽然在许多情况下它很棒,但在某些情况下它不尽如人入,例如:

  • 搜索人员或物体的名称(例如,Eugene,Kaptir 2.0)
  • 搜索首字母缩略词或短语(例如,RAG、RLHF)
  • 搜索ID(例如,gpt-3.5-turbotitan-xlarge-v1.01

但关键词搜索也有其局限性。它只模拟简单的单词频率,不捕获语义或相关性信息。因此,它不能很好地处理同义词或超音名称(即代表概括的单词)。这就是将其与语义搜索相结合是互补的地方。

此外,使用传统的搜索索引,我们可以使用元数据来细化结果。例如,我们可以使用日期过滤器来优先处理较新的文档,或将搜索范围缩小到特定时间段。如果搜索与电子商务有关,平均评级或类别的过滤器会很有帮助。拥有元数据对于下游排名也很有用,例如对引用更多的文档进行优先排序,或通过销售量提高产品。

关于嵌入,看似流行的方法是使用text-embedding-ada-002。它的好处包括通过API易于使用,而不必维护我们自己的嵌入基础设施或自主机嵌入模型。尽管如此,经验和轶事表明,它不适合检索。

OG嵌入方法包括Word2vec和fastText。FastText是一个开源的轻量级库,使用户能够利用预训练的嵌入或训练新的嵌入模型。它带有157种语言的预训练嵌入,即使没有GPU,速度也非常快。这是我早期概念验证的首选。

另一个好的基线是句子变换器。它使计算句子、段落甚至图像的嵌入变得简单。它基于BERT和RoBERTa等主力变压器,有100多种语言版本。

最近,讲师模型展示了SOTA的表现。在培训期间,这些模型将任务描述添加到文本的前置。然后,在嵌入新文本时,我们只需描述任务即可获得特定于任务的嵌入。(恕我直言,与嵌入模型的指令调整没有太大区别。)

E5系列模型为例。对于开放的QA和信息检索,我们只需在索引中用passage:将文档放在前,用query:放在查询前。如果任务是对称的(例如,语义相似性,释义检索),或者如果我们想使用嵌入作为特征(例如,分类,聚类),我们只需使用query:前缀。

The Instructor model takes it a step further, allowing users to customize the prepended prompt: “Represent the domain task_type for the task_objective:” For example, “Represent the Wikipedia document for retrieval:”. (The domain and task objective are optional). This brings the concept of prompt tuning into the field of text embedding.

最后,截至8月1日,MTEB排行榜上的顶级嵌入模型是阿里巴巴DAMO学院的GTE系列模型。性能最佳的型号的尺寸是下一个最佳型号e5-large-v2的一半(0.67GB与1.34GB)。第2位是gte-base,模型尺寸仅为0.22GB,嵌入尺寸为768。(H/T Nirant。)

为了大规模检索低延迟的文档,我们使用近似最近邻居(ANN)。它针对检索速度进行优化,并返回近似(而不是精确的)顶部K大多数相似的邻居,用一点精度损失换取了大幅加速。

ANN嵌入索引是数据结构,让我们高效地进行ANN搜索。在高层次上,他们在嵌入空间上构建分区,这样我们就可以快速进入查询向量所在的特定空间。一些流行的技术包括:

  • 局部敏感散列(LSH):核心思想是创建散列函数,使类似的项目最终可能会出现在同一个散列桶中。只需检查相关桶,我们就可以高效地执行ANN查询。
  • Facebook AI相似性搜索(FAISS):它使用量化和索引的组合进行高效检索,同时支持CPU和GPU,并且由于其对内存的有效使用,可以处理数十亿个向量。
  • 分层可导航小世界(HNSW):受“六度分离”的启发,它构建了一个体现小世界现象的分层图结构。在这里,大多数节点可以通过最小跳跃数从任何其他节点到达。这种结构允许HNSW从更广泛、更粗略的近似中发起查询,并在较低级别逐步缩小搜索范围。
  • 可扩展的最近邻居(ScaNN):ANN通过两步过程完成。首先,粗量化减少了搜索空间。然后,在简化的集合中进行细粒度搜索。我见过的最好的召回/延迟权衡。

在评估ANN指数时,需要考虑的一些因素包括:

  • 回想一下:它与最近的邻居相比如何?
  • 延迟/吞吐量:每秒可以处理多少查询?
  • 内存占用:需要多少RAM来服务于索引?
  • 添加新项目的便利性:无需重新索引所有文档(LSH)即可添加新项目,还是需要重建索引(ScaNN)?

没有一个框架在各个方面都比所有其他框架更好。因此,在基准测试之前,首先定义您的功能和非功能要求。就我个人而言,我发现ScaNN在召回-延迟权衡方面非常出色(请参阅此处的基准图表)。

微调:在特定任务中做得更好

微调是指采取预训练模型(已经使用大量数据训练)并进一步完善特定任务的过程。其目的是利用模型在预培训期间已经获得的知识,并将其应用于特定任务,通常涉及一个较小的、特定任务的数据集。

“微调”一词相当宽泛,可以指几个概念,例如:

  • 继续预训练:使用特定领域的数据,在基础模型上应用相同的预训练制度(下一个令牌预测,掩码语言建模)。
  • 指令微调:根据指令-输出对的示例对进行预训练(基础)模型进行微调,以遵循指令、回答问题、成为waifu等。
  • 单任务微调:预训练模型用于狭义和特定的任务,如毒性检测或总结,类似于BERT和T5。
  • 人类反馈强化学习(RLHF):这结合了教学微调和强化学习。它需要收集人类的偏好(例如,成对比较),然后用于训练奖励模型。然后,奖励模型用于通过RL技术(如近端策略优化(PPO))进一步微调指示的LLM。

我们在这里将主要关注单项任务和指令微调。

为什么要微调?

由于几个原因,微调开放式LLM正在成为使用第三方基于云的LLM的越来越可行的替代方案。

性能和控制:微调可以提高现成基础模型的性能,甚至可能超过第三方大模型。它还为LLM行为提供了更大的控制,从而形成了一个更强大的系统或产品。总的来说,微调使我们能够构建不同于简单使用第三方或开放式LLM的产品。

模块化:单任务微调使我们能够使用一支由小型模型组成的大军,每个模型都专注于自己的任务。通过此设置,系统可以模块化为单个模型,用于内容审核、提取、总结等任务。此外,鉴于每个模型只需要专注于一组狭窄的任务,因此对对调整税的担忧减少了,即对一项任务的微调模型会降低其他任务的性能。

减少依赖性:通过微调和托管我们自己的模型,我们可以减少对专有数据(例如PII、内部文档和代码)暴露于外部API的法律担忧。它还可以绕过第三方LLM带来的限制,如费率限制、高成本或过度限制的安全过滤器。通过微调和托管我们自己的LLM,我们可以确保数据不会离开我们的网络,并可以根据需要扩展吞吐量。

更多关于微调的信息

为什么我们需要微调基础模型?冒着过度简化的风险,基础模型主要经过优化,以根据他们训练的语料库来预测下一个单词。因此,他们天生不擅长遵循指示或回答问题。当提出问题时,他们往往会用进一步的问题来回答。因此,我们进行指令微调,以便他们学会做出适当的反应。

然而,微调并非没有挑战。首先,我们需要大量的演示数据。例如,在InstructGPT论文中,他们使用13k指令输出样本进行监督微调,使用33k输出比较进行奖励建模,以及31k没有人工标签的提示作为RLHF的输入。

此外,微调附带调整税——该过程可能导致某些关键任务的性能下降。(毕竟没有免费的午餐。)同一篇InstructGPT论文发现,RLHF导致SQuAD、HellaSwag和WMT 2015法语到英语等公共NLP任务的性能回归(相对于GPT-3基础模型)。(变通办法是拥有几个更小、更专业的模型,这些模型擅长狭窄的任务。)

微调类似于转移学习的概念。正如维基百科所定义的:“转移学习是机器学习中的一种技术,从任务中学到的知识被重复使用,以提高相关任务的性能。”几年前,转移学习使我能够轻松地应用在ImageNet上训练的ResNet模型来对时尚产品进行分类构建图像搜索

ULMFit是将转移学习应用于文本的早期论文之一。他们建立了自我监督的预培训协议(在未标记的数据上),然后进行微调(在标记的数据上)。他们使用AWS-LSTM,这是一种LSTM变体,在各种门都有辍学。

ULMFit概述

ULMFit概述(来源

在预培训(下一个单词预测)期间,该模型在wikitext-103上进行训练,其中包含28.6篇维基百科文章和1.03亿个单词。然后,在目标任务微调期间,LM会使用来自特定任务域的数据进行微调。最后,在分类器微调期间,模型增加了两个额外的线性块,并对目标分类任务进行了微调,包括情绪分析、问题分类和主题分类。

从那时起,经过微调范式的预培训推动了语言建模的很大进展。来自变形金刚的双向编码器表示(BERT;仅限编码器)是通过屏蔽语言建模和英语维基百科和BooksCorpus上的下一句预测进行预训练的。然后对特定任务的输入和标签进行了微调,用于单句分类、句子对分类、单句标签和问答。

BERT概述

BERT概述(来源

生成预训练的变压器(GPT;仅限解码器)首先通过下一个令牌预测在BooksCorpus上进行预训练。随后是文本分类、文本蕴涵、相似性和问答等任务的单任务微调。有趣的是,他们发现将语言建模作为辅助目标有助于模型在训练期间更快地推广和收敛。

GPT概述

GPT概述(来源

文本到文本传输变压器(T5;编码器-解码器)在Colossal Clean Crawled Corpus(C4)上进行了预训练,这是从2019年4月开始Common Crawl的清理版本。它采用了与BERT相同的去噪目标,即掩蔽语言建模。然后对文本分类、抽象总结、问答和机器翻译等任务进行了微调。

T5概述

T5概述(来源

But unlike ULMFIt, BERT, and GPT which used different classifier heads for downstream tasks, T5 represented downstream tasks as text-to-text only. For example, a translation task would have input text starting with Translation English to German:, while a summarization task might start with Summarize: or TL;DR:. The prefix essentially became a hyperparameter (first instance of prompt engineering?) This design choice allowed them to use a single fine-tuned model across a variety of downstream tasks.

InstructGPT将单任务微调的想法扩展到指令微调。基本模型是GPT-3,在互联网数据上进行了预训练,包括Common Crawl、WebText、Books和Wikipedia。然后,它对预期行为(指令和输出)的演示进行了监督微调。接下来,它在比较数据集上训练了一个奖励模型。最后,它通过PPO根据奖励模型优化了指示模型,最后一个阶段更侧重于对齐,而不是特定任务性能。

InstructGPT中的微调步骤概述

InstructGPT中的微调步骤概述(来源

接下来,让我们从微调模型转向微调技术。

软提示调优在模型的输入嵌入之前添加可训练的张量,本质上创建一个软提示。与离散文本提示不同,软提示可以通过反向传播来学习,这意味着它们可以微调以合并来自任何数量的标记示例的信号。

接下来,还有前缀调音。它没有在模型输入中添加软提示,而是将可训练参数添加到所有变压器块的隐藏状态。在微调期间,LM的原始参数被冻结,而前缀参数被更新。

前缀调谐概述

前缀调整概述(来源

该论文表明,尽管只需要对0.1%的参数进行更新,但性能仍可与完全微调相媲美。此外,在数据有限和对新主题进行外推的设置中,它的表现优于完全微调。一个假设是,涉及的参数较少有助于减少对较小的目标数据集的过拟合。

还有适配器技术。这种方法将完全连接的网络层添加到每个变压器块两次,在注意力层之后和向前馈网络层之后。在GLUE上,只需为每个任务添加3.6%的参数,它就能够实现完全微调性能的0.4%。

适配器概述

适配器概述(来源

低级适应(LoRA)是一种技术,其中适配器被设计为两个低级矩阵的产物。它受到Aghajanyan等人的启发,该研究表明,当适应特定任务时,预训练的语言模型具有较低的内在维度,尽管随机投影到更小的子空间中,仍然可以有效地学习。因此,他们假设适应期间的体重更新也具有较低的内在等级。

LoRA概述

LoRA概述(来源

与前缀调整类似,他们发现LoRA的表现优于几个基线,包括完全微调。同样,假设是,由于其等级降低,LoRA提供了隐性正则化。相比之下,更新所有重量的完全微调可能容易过度拟合。

QLoRA建立在LoRA理念的基础上。但它没有在微调期间使用完整的16位模型,而是应用了4位量化模型。它引入了几项创新,如4位NormalFloat(量化模型)、双量化(用于额外的内存节省)和分页优化器(在GPU内存耗尽时通过将数据传输到CPU RAM来防止OOM错误)。

QLoRA概述

QLoRA概述(来源

因此,与16位完全微调的基线相比,QLoRA将65B型号微调的平均内存需求从>780GB内存降低到更易于管理的48B,而不会降低运行时或预测性能。

(有趣的事实:在与Tim Dettmers的会面中,他打趣说,双重量化是“有点愚蠢的想法,但效果很好”。嘿,如果行得通,就行得通。)

如何应用微调?

第一步是收集演示数据/标签。这些可以用于直接的任务,如文档分类、实体提取或总结,也可以更复杂,如问答或对话。收集这些数据的一些方法包括:

  • 通过专家或众包人类注释员:虽然这既昂贵又缓慢,但它通常会导致具有良好指南的更高质量的数据。
  • 通过用户反馈:这可以很简单,要求用户选择描述产品的属性,用大拇指向上或向下对模型响应进行评级(例如,ChatGPT),或记录用户选择下载的图像(例如,Midjourney)。
  • 使用允许许可证查询较大的开放模型:通过快速工程,我们也许能够从较大的模型(Falcon 40B Instruct)中获取合理的演示数据,这些数据可用于微调较小的模型。
  • 重复使用开源数据:如果您的任务可以作为自然语言推理(NLI)任务,我们可以微调模型,使用MNLI数据执行NLI。然后,我们可以继续微调内部数据的模型,将输入归类为蕴涵、中性或矛盾。

注意:一些LLM术语阻止用户使用其输出来训练其他模型。

  • OpenAI使用条款(第2c、iii节):您不得使用服务的输出来开发与OpenAI竞争的模型。
  • LLaMA 2社区许可协议(第1b-v节):您不会使用Llama材料或Llama材料的任何输出或结果来改进任何其他大型语言模型(不包括Llama 2或其衍生作品)。

下一步是定义评估指标。我们在上一节中讨论过这个问题。然后,选择一个预先训练的模型。几种具有许可许可证的开源预训练模型可供选择。不包括Llama 2(因为它不是完全商业用途),Falcon-40B是众所周知的性能最好的型号。尽管如此,鉴于它的重量,我发现在生产中进行微调和服务是难以负担的。

相反,我倾向于使用较小的型号,如Falcon-7B。如果我们能更简化和狭义地构建任务,BERT、RoBERTA和BART是分类和自然语言推理任务的可靠选择。除此之外,Flan-T5是翻译、总结、标题生成等的可靠基线。

我们可能还需要更新模型架构。当预训练模型的架构与任务不一致时,需要这样做。例如,我们可能需要更新BERT或T5上的分类头,以匹配我们的任务。提示:如果任务是简单的二进制分类任务,NLI模型可以开箱即用。内容映射为正,矛盾映射为负,而神经标签可以指示不确定性。

然后,选择一个微调方法。LoRA和QLoRA是开始的好地方。但是,如果您的微调更加密集,例如继续对新领域知识进行预培训,您可能会发现需要进行全面微调。

最后,基本的超参数调谐。一般来说,大多数论文侧重于学习率、批次大小和纪元数(见LoRA、QLoRA)。如果我们使用LoRA,我们可能想要调整排名参数(尽管QLoRA论文发现,不同的排名和alpha导致了类似的结果。)其他超参数包括输入序列长度、损失类型(对比损失与令牌匹配)和数据比率(如预训练或演示数据的混合,或正负示例的比率等)。

缓存:减少延迟和成本

缓存是一种存储之前检索或计算的数据的技术。这样,未来对相同数据的请求可以更快地得到满足。在为LLM世代提供服务的空间中,普及的方法是在输入请求的嵌入上缓存LLM响应。然后,对于每个新请求,如果收到语义上相似的请求,我们可以提供缓存的响应。

对于一些从业者来说,这听起来像是“一场等待发生的灾难”。我倾向于同意。因此,我认为采用这种模式的关键是弄清楚如何安全缓存,而不是仅仅依赖于语义相似性。

为什么要缓存?

缓存可以显著减少之前已提供的响应的延迟。此外,通过消除对相同输入反复计算响应的需要,我们可以减少LLM请求的数量,从而节省成本。此外,某些用例不支持秒数的延迟。因此,预计算和缓存可能是服务于这些用例的唯一方法。

关于缓存的更多信息

缓存是一种高速存储层,它存储了更频繁访问的数据子集。这使我们能够通过缓存而不是数据的主要存储(例如搜索索引、关系数据库)更快地满足这些请求。总体而言,缓存可以高效重用以前获取或计算的数据。(更多关于缓存最佳实践的信息。)

LLM缓存的一个例子是GPTCache

GPTCache概述

GPTCache概述(来源

当收到新请求时:

  • 嵌入生成器:通过各种模型嵌入请求,如OpenAI的text-embedding-ada-002、FastText、句子变压器等。
  • 相似性评估器:这通过向量存储计算请求的相似性,然后提供距离度量。矢量存储可以是本地的(FAISS,Hnswlib)或基于云的。它也可以通过模型计算相似性。
  • 缓存存储:如果请求相似,则会获取并送达缓存的响应。
  • LLM:如果请求不够相似,它将被传递给LLM,然后生成结果。最后,响应被提供和缓存,以备将来使用。

Redis也分享了一个类似的例子。一些团队甚至会预先计算他们预计收到的所有查询。然后,他们设置了一个相似性阈值,其中查询足够相似,以保证缓存响应。

如何应用缓存?

我们应该从很好地理解用户请求模式开始。这使我们能够深思熟虑地设计缓存,以便可靠地应用它。

首先,让我们考虑一个非LLM的例子。想象一下,我们正在为电子商务网站缓存产品价格。在结账时,显示(可能过时的)缓存价格是否安全?可能不会,因为客户在结账时看到的价格应该与他们收取的最终金额相同。缓存在这里不合适,因为我们需要确保客户的一致性。

现在,把它带回大模型的回应。想象一下,我们收到了“碟中谍2”摘要的请求,该摘要在语义上与“碟中谍3”足够相似。如果我们基于语义相似性查找缓存,我们可能会提供错误的响应。

我们还需要考虑缓存对使用模式是否有效。量化这一点的一种方法是通过缓存命中率(直接从缓存提供的请求的百分比)。如果使用模式是统一随机的,缓存将需要频繁更新。因此,努力使缓存保持最新状态可能会抵消缓存提供的任何好处。另一方面,如果用法遵循权力法则,其中一小部分独特的请求占了大部分流量(例如,搜索查询、产品视图),那么缓存可能是一种有效的策略。

除了语义相似性,我们还可以根据以下方式探索缓存:

  • 项目ID:这适用于我们预先计算产品评论摘要或生成整个电影三部曲的摘要时。
  • 项目ID对:例如当我们在两部电影之间进行比较时。虽然这似乎是字母O(第十四个英文字母2),在实践中,少量的组合驱动了大部分流量,例如三部曲中电影之间的比较。
  • 约束输入:例如电影类型、导演或男主角等变量。例如,如果用户向特定导演寻求电影推荐,我们可以执行结构化查询,并通过LLM运行它,以更雄辩地构建响应。另一个例子是基于下拉选项生成代码——如果代码已验证工作,我们可以将其缓存以进行可靠的重用。

此外,缓存不仅需要实时进行。正如Redis共享的那样,我们可以在提供服务之前离线或异步预计算LLM世代。通过从缓存提供服务,我们将延迟从生成(通常为秒)转移到缓存查找(毫秒)。批量预计算也有助于降低与实时服务相关的成本。

虽然这里列出的方法可能不像在自然语言输入上的语义缓存那样灵活,但我认为它在效率和可靠性之间提供了良好的平衡。

护栏:确保输出质量

在LLM的背景下,护栏验证LLM的输出,确保输出不仅听起来不错,而且在语法上正确,符合事实,并且没有有害内容。它还包括防范对抗性投入。

为什么是护栏?

它们确保模型输出足够可靠和一致,可以在生产中使用。例如,我们可能会要求输出在特定的JSON模式中,以便其机器可读,或者我们需要生成的代码是可执行的。护栏可以帮助进行这种句法验证。

它们还提供了额外的安全层,并保持对LLM输出的质量控制。例如,为了验证生成的内容是否适合服务,我们可能需要检查输出是否有害,验证其事实准确性,或确保与提供的上下文一致。

关于护栏的更多信息

一种方法是通过提示控制模型的响应。例如,Anthropic分享了旨在引导模型产生有帮助、无害和诚实的响应(HHH)的提示。他们发现,与RLHF的微调相比,Python使用HHH提示符进行微调可以带来更好的性能。

HHH提示示例

HHH提示示例(来源

更常见的方法是验证输出。一个例子是护栏包。它允许用户通过Pydantic风格的验证在LLM输出上添加结构、类型和质量要求。如果检查失败,它可以触发纠正措施,例如过滤违规输出或重新生成另一个响应。

大多数验证逻辑都在validators.py中。看看它们是如何实施的很有趣。广义上讲,护栏分为以下几类:

  • 单一输出值验证:这包括确保输出(i)是预定义的选择之一,(ii)在一定范围内有长度,(iii)如果是数字,则在预期范围内,以及(iv)是一个完整的句子。
  • 语法检查:这包括确保生成的URL是有效和可访问的,以及Python和SQL代码没有错误。
  • 语义检查:这验证了输出是否与参考文档对齐,或者提取摘要是否与源文档密切匹配。这些检查可以通过余弦相似性或模糊匹配技术来完成。
  • 安全检查:这确保生成的输出没有不适当的语言,或者翻译文本的质量很高。

Nvidia的NeMo-Guardrails遵循类似的原则,但旨在指导基于LLM的对话系统。它不是专注于句法护栏,而是强调语义栏。这包括确保助理避开带有政治色彩的话题,提供事实正确的信息,并能发现越狱企图。

因此,NeMo的方法有些不同:NeMo没有使用更确定性的检查,如验证列表中是否存在值或检查代码中是否有错误,而是大量依赖使用另一个LLM来验证输出(灵感来自SelfCheckGPT)。

在他们关于事实核查和预防幻觉的例子中,他们要求大模型本身检查最新的输出是否与给定的上下文一致。为了进行事实核查,根据从知识库中检索的文档,查询LLM的响应是否为真。为了防止幻觉,由于没有可用的知识库,他们让LLM生成多个替代完成,作为上下文。基本的假设是,如果大模型产生了多个彼此不一致的完成,那么最初的完成可能是幻觉。

审核示例遵循一个简单的方法:通过大模型对响应进行有害和不道德内容的筛选。鉴于道德和有害内容的细微差别,启发式和传统的机器学习技术是不够的。因此,需要大模型来更深入地了解对话的意图和结构。

除了使用护栏来验证LLM的输出外,我们还可以直接引导输出以遵守特定的语法。这方面的一个例子是微软的指南。与通过提示符强加JSON模式的护栏不同,Guidance通过注入构成结构的令牌来强制执行模式。

我们可以将指导视为一种特定领域语言,用于大模型互动和输出。它从Handlebars中汲取灵感,Handlebars是一种流行的模板语言,用于Web应用程序,使用户能够执行变量插值和逻辑控制。

然而,指导通过线性执行将自己与常规模板语言区分开来。这意味着它保持生成的令牌的顺序。因此,通过插入作为结构一部分的令牌,而不是依靠LLM来正确生成它们,指南可以规定特定的输出格式。在他们的示例中,他们展示了如何生成始终有效的JSON生成具有多个键的复杂输出格式,确保LLM发挥正确的角色,并让代理相互交互

他们还引入了一个称为令牌愈合的概念,这是一个有用的功能,可以帮助我们避免因令牌化而出现的微妙错误。简而言之,它在提示符结束前将生成一个令牌倒带,然后限制第一个生成的令牌具有与提示符中最后一个令牌匹配的前缀。这消除了在制作提示时对令牌边界的担忧。

如何应用护栏?

虽然工业中的护栏概念还处于萌芽阶段,但我们可以考虑一些立即有用和实用的策略。

结构指导:尽可能应用指导。它提供了对输出的直接控制,并提供了一种更精确的方法来确保输出符合特定的结构或格式。

语法护栏:这些包括检查分类输出是否在一组可接受的选择范围内,或者数字输出是否在预期范围内。此外,如果我们生成SQL,这些可以验证其正确性,并确保查询中的所有列都与模式匹配。同上Python代码。

内容安全护栏:这些保证输出没有有害或不适当的内容。它可以很简单,只需对照肮脏、淘气、淫秽和其他坏话列表或使用脏话检测模型。(在输出上运行审核分类器常见。)更复杂和细致入微的输出可以依靠大模型评估员。

语义/事实护栏:这些确认输出在语义上与输入相关。假设我们正在根据剧情简介生成一部电影的两句话摘要。我们可以验证生成的摘要在语义上是否与输出相似,或者让(另一个)LLM确定摘要是否准确代表了提供的概要。

输入护栏:这些限制了模型将响应的输入类型,有助于降低模型响应不适当或敌对的提示的风险,这会导致产生有害内容。例如,如果您要求Midjourney生成NSFW内容,您将收到错误。这可以像与字符串列表进行比较或使用适度分类器一样简单。

中途输入护栏的例子

中途输入护栏的例子

防御性用户体验:优雅地预测和处理错误

防御性用户体验是一种设计策略,它承认在用户与机器学习或基于LLM的产品交互过程中可能会发生坏事,如不准确或幻觉。因此,其目的是提前预测和管理这些,主要是通过指导用户行为、避免误用和优雅地处理错误。

为什么是防御性用户体验?

机器学习和大模型并不完美——它们可能会产生不准确的输出。此外,随着时间的推移,他们对相同输入的反应不同,例如搜索引擎因个性化而显示不同的结果,或者LLM在更具创意的设置中产生不同的输出。这可能违反倡导一致的用户界面和可预测行为的一致性原则。

防御性用户体验可以通过提供以下内容来帮助缓解上述情况:

  • 提高可访问性:通过帮助用户了解ML/LLM功能的工作原理及其局限性,防御性UX使其更易于访问和用户友好。
  • 增加信任度:当用户看到该功能可以优雅地处理困难场景并且不会产生有害的输出时,他们可能会更信任它。
  • 更好的用户体验:通过设计模型和用户体验来处理模棱两可的情况和错误,防御性用户体验为更流畅、更愉快的用户体验铺平了道路。

更多关于防御性用户体验的信息

要了解有关防御性用户体验的更多信息,我们可以查看微软、谷歌和苹果的Human-AI指南。

微软的人类-人工智能互动指南基于对168项潜在指南的调查,这些指南从内部和外部行业来源、学术文献和公共文章中收集。在对类似的指南进行聚类、过于模糊或过于具体或不特定于人工智能的过滤指南以及一轮启发式评估后,他们将其缩小到18条指南。

这些准则遵循某种风格:每个准则都是3-10个单词的简洁动作规则,以动词开头。每条规则都附有一条解决潜在模糊性的一句话。它们是根据用户交互期间可能的应用程序组织的:

  • 最初:明确系统能做什么(G1),明确系统能做什么(G2)
  • 互动期间:基于上下文的时间服务(G3),缓解社会偏见(G6)
  • 错误时:支持高效解雇(G8),支持高效纠正(G9)
  • 随着时间的推移:从用户行为中学习(G13),提供全局控制(G17)

谷歌的《人物+人工智能指南》植根于来自谷歌产品团队和学术研究的数据和见解。与微软围绕用户组织的指导方针相反,谷歌将其指导方针组织成开发人员需要记住的概念。

有23种模式围绕产品开发过程中遇到的常见问题分组,包括:

  • 我如何开始使用以人为本的人工智能:确定人工智能是否增加了价值,尽早投资于良好的数据实践(例如,评估)
  • 我如何让用户使用新的人工智能功能:安全地探索,固定熟悉度,分阶段自动化
  • 我如何帮助用户建立对我产品的信任:设定正确的期望,保持透明,在风险低时实现更多自动化。

苹果的机器学习人机界面指南与学术文献和用户研究的自下而上的方法不同。相反,它的主要来源是从业者的知识和经验。因此,它不包含许多参考资料或数据点,而是专注于苹果的长期设计原则。这产生了一个独特的视角,将其与其他两个准则区分开来。

该文件重点介绍了苹果的设计原则如何应用于注入ML的产品,强调UI的各个方面,而不是模型功能。它首先要求开发人员考虑ML在其应用程序中的作用,并从用户体验中向后工作。这包括诸如ML是否:

  • 关键或互补:例如,没有ML,Face ID无法工作,但没有QuickType,键盘仍然可以工作。
  • 主动或被动:Siri建议是主动的,而自动更正是被动的。
  • 动态或静态:建议是动态的,而照片中的对象检测仅随着每个iOS版本而改进。

然后,它深入研究几种模式,分为系统的输入和输出。输入侧重于显式反馈、隐式反馈、校准和校正。本节指导人工智能产品如何请求和处理用户数据和交互的设计。输出集中在错误、多种选择、信心、归因和局限性上。其目的是确保模型的输出以可理解和有用的方式呈现。

这三条准则之间的差异很有见地。谷歌更重视培训数据和模型开发的考虑因素,这可能受到其工程驱动文化的影响。微软更关注心理模型,这可能是HCI学术研究的产物。最后,苹果的方法围绕着提供无缝的用户体验,这可能是由于其文化价值观和原则。

如何应用防御性用户体验?

以下是一些基于上述指南的模式。(免责声明:我不是设计师。)

设定正确的期望。这一原则在所有三项准则中都是一致的:

  • 微软:明确系统能做它能做的事情(帮助用户了解人工智能系统可能犯错的频率)
  • 谷歌:设定正确的期望(对用户透明地说明您的人工智能产品能做什么和不能做什么)
  • 苹果:帮助人们建立现实的期望(描述营销材料或功能上下文中的局限性)

这可以很简单,只需在人工智能生成的结果上方添加一个简短的免责声明,如Bard的结果,或者在其登录页面上突出显示我们应用程序的局限性,例如ChatGPT如何做到这一点。

Google Bard结果的免责声明示例(注:提供的代码将不起作用。)

Google Bard结果的免责声明示例(注:nrows不是有效的参数。)

通过对我们产品的功能和局限性保持透明,我们帮助用户校准其功能和输出的期望。虽然这可能会导致用户在短期内不太信任它,但从长远来看,它有助于培养信任——用户不太可能高估我们的产品,并随后面临失望。

实现高效解雇。这被明确称为微软的准则8:支持高效解雇(使解雇或忽略不需要的人工智能系统服务变得容易)。

例如,如果用户正在浏览我们的网站,并且弹出一个聊天机器人询问他们是否需要帮助,那么用户应该很容易关闭聊天机器人。这确保了聊天机器人不会碍事,特别是在屏幕较小的设备上。同样,GitHub Copilot允许用户通过继续键入来方便地忽略其代码建议。虽然这可能会在短期内减少人工智能功能的使用,但它可以防止它成为一种滋扰,并可能长期降低客户满意度。

提供归属。这列在所有三个指南中:

  • 微软:明确系统为什么会这样做(使用户能够访问人工智能系统为什么会这样做的解释)
  • 谷歌:添加来自人类来源的上下文(帮助用户使用第三方来源的输入来评估您的建议)
  • 苹果:考虑使用属性来帮助人们区分结果

引文正成为越来越受欢迎的设计元素。以BingChat为例。当您进行查询时,其回复中包含通常来自信誉良好的来源的引文。这不仅显示了信息的来源,还允许用户评估来源的质量。同样,想象一下我们正在使用LLM来解释为什么用户可能喜欢一个产品。除了LLM生成的解释外,我们还可以引用实际评论或提及产品评级。

来自专家和社区的背景也增强了用户的信任。例如,如果用户正在寻求远足小径的建议,提到相关社区强烈推荐建议的小径可能会大有帮助。它不仅为推荐增加了价值,还帮助用户通过人与人之间的联系来校准信任。

通过社会证明归属的示例

通过社会证明归属的示例(来源

最后,苹果的指导方针包括流行的归因,如“因为你读过非小说类作品”、“你读过的作者的新书”。这些描述符不仅个性化体验,还提供上下文,增强用户的理解和信任。

锚定在熟悉上。当向用户介绍新的人工智能产品或功能时,这有助于引导他们使用熟悉的用户体验模式和功能。这使得用户更容易专注于主要任务,并开始对我们的新产品建立信任。抵制通过异国情调的UI元素展示新的“神奇”功能的诱惑。

同样,基于聊天的功能正变得越来越普遍,这主要是由于ChatGPT的流行。例如,与您的文档聊天,聊天查询您的数据,聊天购买杂货。然而,我质疑聊天是否是大多数用户体验的正确用户体验——相对于熟悉的点击文本和图像的用户体验来说,它只是花费了太多的精力。

增加用户的努力导致更高的期望,而这些期望更难满足。Netflix分享说,用户对搜索等显式操作所产生的建议更高的期望。一般来说,用户付出的努力越多(例如聊天、搜索),他们的期望就越高。将此与低费力的互动(如滚动推荐石板或单击产品)进行对比。

因此,虽然聊天提供了更大的灵活性,但它也需要更多的用户努力。此外,使用聊天框不太直观,因为它缺乏用户如何调整输出的指示。总的来说,我认为坚持熟悉和受约束的用户界面使用户更容易浏览我们的产品;聊天只应被视为次要或三级选项。

收集用户反馈:构建我们的数据飞轮

来自用户的反馈有助于我们了解他们的偏好。特定于LLM产品,用户反馈有助于构建评估、微调和护栏。如果我们想一想,数据——用于预培训的语料库、专家制作的演示、人类对奖励建模的偏好——是为数不多的大模型产品的护城河之一。因此,我们希望在设计用户体验时刻意考虑收集用户反馈。

反馈可以是明确的,也可以是隐含的。显式反馈是用户响应我们产品请求提供的信息;隐式反馈是我们从用户互动中学习的信息,而不需要用户故意提供反馈。

为什么要收集用户反馈

用户反馈有助于我们的模型改进。通过了解用户喜欢、不喜欢或抱怨什么,我们可以改进我们的模式和服务,以更好地满足他们的需求。

用户反馈还允许我们适应个人喜好。推荐系统就是一个例子。当用户与物品互动时,我们可以了解他们喜欢什么和不喜欢什么,并随着时间的推移更好地迎合他们的口味。

最后,反馈循环帮助我们评估系统的整体性能。虽然评估可以帮助我们衡量模型/系统性能,但用户反馈提供了用户满意度和产品有效性的具体衡量标准。

如何收集用户反馈

让用户轻松提供反馈。这在所有三个准则中都得到了回应:

  • 微软:鼓励粒度反馈(使用户能够在与人工智能系统的定期互动期间提供反馈,表明他们的偏好)
  • 谷歌:让用户提供反馈(为用户提供实时教学、反馈和纠错的机会)
  • 苹果:提供您的应用程序可用于改善其向人们呈现的内容和体验的可操作信息

ChatGPT就是这样一个例子。用户可以在响应上竖起/向下竖起大拇指,或者如果回复真的很糟糕或没有帮助,可以选择重新生成响应。这是对人类偏好的有用反馈,然后可用于微调LLM。

中途旅行是另一个好例子。生成图像后,用户可以生成一组新的图像(负反馈),通过要求变化(积极反馈)来调整图像,或升级并下载图像(强烈的积极反馈)。这使得Midjourney能够收集有关生成输出的丰富比较数据。

>作为用户体验的一部分收集用户反馈的例子

作为用户体验的一部分收集用户反馈的示例

也考虑隐含反馈。隐式反馈是用户与我们的产品互动时产生的信息。与我们从显式反馈中获得的具体响应不同,隐式反馈可以提供有关用户行为和偏好的广泛数据。

像副驾驶一样的助手就是一个最好的例子。用户通过完全接受建议(强烈的积极反馈)、接受并进行小幅调整(积极反馈)或忽略它(中性/负面反馈)来表明建议是否有用。或者,他们可能会更新导致生成代码的评论,这表明初始代码生成没有满足他们的需求。

ChatGPT和BingChat等聊天机器人是另一个例子。随着时间的推移,日常使用情况发生了怎样的变化?如果产品是粘性的,这表明用户喜欢它。此外,平均对话有多长?这可能会很棘手解释:因为对话引人入胜且富有成效,所以更长的对话会更好吗?还是更糟糕,因为用户花了更长的时间才得到他们需要的东西?

机器学习中常见的其他模式

除了我们探索的七种模式外,机器学习中还有其他几种模式也与大模型系统和产品相关。它们包括:

  • 数据飞轮:持续的数据收集改善了模型,并带来了更好的用户体验。这反过来又促进了更多的使用,为进一步评估和微调模型提供了更多的数据,创造了一个良性循环。
  • Cascade:与其将单个复杂的任务分配给LLM,我们可以简化和分解它,这样它只需要处理它擅长的任务,例如推理或雄辩沟通。RAG就是一个例子。我们可以利用外部知识来增强LLM,并专注于应用LLM的推理能力,而不是依靠LLM来根据其内部知识检索和排名项目。
  • 监控:这有助于证明人工智能系统的附加值,或缺乏它。有人分享了在停止之前在prod中运行基于LLM的客户支持解决方案两周的轶事——A/B测试显示,当使用LLM作为支持团队的替代品时,损失会增加12倍!

(阅读更多关于机器学习代码系统的设计模式。)

此外,其他人也是这么说的:

关注/任务分解的分离-对不同的子任务有不同的提示,并将它们链接在一起,有助于注意力和可靠性(伤害延迟)。我们在指定刚性输出结构和可变响应内容时遇到了问题,所以我们拆分了任务——Erick Enriquez

其他一些需要:基于角色的访问控制:谁可以访问什么;安全:如果我使用带有LLM的DB,我如何确保我有合适的保安——克里希纳

一致的输出格式:将输出设置为标准化格式,如JSON;工具增强:将任务卸载到更专业、更成熟、更可靠的模型——Paul Tune

安全:缓解缓存中毒,输入验证,缓解提示注入,训练数据来源,使用非易受攻击的代码输出,缓解旨在影响工具(AI代理)使用的请求的恶意输入,缓解拒绝服务(压力测试llm),仅举几例:)——Anderson Darario

另一个与ux/ui相关的:激励用户对生成的答案(隐式或显式)提供反馈。隐含的可能是像副驾驶的幽灵文本风格,如果被TAB接受,意味着积极的反馈等。——温阳

很棒的清单。我会添加一致性检查,如自一致性采样、任务的链和分解,以及多个模型输出的模拟。几乎每天都要应用这些。丹·怀特

护栏与构建分析工具非常相关,其中llm是从自然语言到编程语言的翻译器——m_voitko

结论

这是我迄今为止写的最长的帖子。如果你还和我在一起,谢谢!我希望您发现阅读这些模式很有帮助,并且下面的2x2有意义。

跨数据軸的法学硕士模式对用户,防御对进攻。

跨数据轴的大模型模式对用户,防御对进攻。

 

内容中包含的图片若涉及版权问题,请及时与我们联系删除