Press "Enter" to skip to content

创造一台由维基百科知识赋能的 LLaMa 2 代理人

用检索增强生成的方式提升 LLaMa 2,寻找并利用来自维基百科的信息。

Photo by Lysander Yuen on Unsplash

介绍

大型语言模型(LLM)是人工智能领域中最火热的趋势之一。它们展示了令人印象深刻的文本生成能力,从与人类用户进行对话到编写代码的能力。开源的LLM,如LLama、Falcon、稳定Beluga等,以及针对开发更小、更高效模型的关注,使其潜力可用于广大的人工智能社区,并且能够在消费级硬件上运行。

促成LLM成功的关键因素之一是在革命性论文《Attention Is All You Need》中引入的著名Transformer架构。当将这个架构扩展到数十亿个参数并在包含数万亿个令牌的数据集上进行训练时,最先进的LLM展现了令人印象深刻的性能。通过这种预训练,LLM可以理解人类语言并进一步进行特定用途的微调,形成强大的基础模型。

大型语言模型的预训练是以自我监督的方式进行的。它需要大量的文本语料库,但不需要人工标注。这使得训练可以扩展到可以自动创建的大型数据集上。在将输入文本转换为一系列令牌后,预训练是通过预测每个令牌的概率来进行的,条件是所有先前的令牌。这样,在训练后,模型能够通过在所有已抽样令牌的条件下逐个抽样一个令牌来自动生成文本。仅通过这种预训练,大型语言模型已经显示出令人印象深刻的语言能力。然而,通过根据训练数据学习到的条件概率抽样令牌,生成的文本通常与人类偏好不一致,LLM难以遵循特定的指令或人类意图。

在将LLM生成的文本与人类偏好对齐方面,人类反馈增强强化学习(RLHF)取得了显著进展。这种技术是最先进的聊天模型(如ChatGPT)的核心。通过RLHF,在初始的自我监督预训练阶段后,通过强化学习算法对大型语言模型进行进一步微调,以最大化根据人类偏好校准的奖励。为了获取奖励函数,通常会训练一个辅助模型来学习反映人类偏好的标量奖励。通过这种方式,用于强化学习阶段的实际人工标记数据量可以最小化。奖励模型的训练数据由人类根据其偏好对生成的文本进行排名而成。该模型旨在预测较高的奖励来为排名较高的文本。使用旨在最大化反映人类偏好的奖励进行大型语言模型的训练应该会产生更符合人类意图的生成文本。事实上,已经证明,通过从人类反馈中进行强化学习进行微调的大型语言模型在遵循用户指令方面效果更好,同时也更少有有害内容,更真实。

检索增强生成

大型语言模型的一个典型缺点是它们是离线训练的,因此不具有在训练数据收集之后发生的事件的信息。同样,它们也无法使用在训练数据中不存在的任何特定知识。这对特定领域可能是有问题的,因为用于训练LLM的数据通常来自通用领域的语料库。一种避免这些问题的方法,而不需要昂贵的微调,是使用检索增强生成(RAG)。RAG通过将馈送给LLM的提示与外部文本信息进行增强来工作。通常,这些文本信息是根据与当前提示相关性从外部数据源中检索的。在实践中,首先,这涉及将提示和外部文本转换为向量嵌入。可以通过汇聚训练用于将具有相似含义的文本映射为按适当度量标准接近的嵌入的变声器编码器模型(如BERT)的输出来获得后者。对于长文本,可以将其拆分为逐个嵌入的块,从而检索到最相关的段落。接下来,通过与提示嵌入最接近的文本嵌入进行检索。在适当的格式化之后,将提示与检索到的文本进行拼接,并作为语言模型的输入。

通过检索增强生成,模型可以访问在训练期间不可用的信息,并根据选择的文本语料库进行回答。RAG还可以检查模型用来回答问题所使用的源,这使得人类用户对模型输出的评估更加直接。

在本博客文章中,我将解释如何创建一个简单的代理人,能够基于从维基百科中检索到的内容来进行回答,以展示LLMs寻找和使用外部信息的能力。在用户提供提示的情况下,模型将搜索适当的维基百科页面,并根据其内容进行回答。我已经在此GitHub存储库中提供了完整的代码。

一个以维基百科内容增强的Llama 2代理人

在这一部分中,我将描述创建一个简单的Llama 2代理人的步骤,该代理人基于从维基百科中检索到的信息来回答问题。特别是,该代理人将:

  • 创建适当的查询以搜索与用户问题相关的维基百科页面。
  • 从在维基百科上找到的页面中检索出与用户问题最相关的页面。
  • 从检索到的页面中提取出与用户提示最相关的段落。
  • 基于页面中的摘录回答用户的问题。

请注意,更一般地,模型可以接收一个提示,该提示以最相关页面的完整内容或排名与用户提示相关性最高的多个摘录为基础进行增强。虽然这可能会提高模型的回应质量,但会增加所需的内存,因为这不可避免地会导致更长的提示。为了简单起见,并且为了在免费版Google Colab GPU上运行一个最小的示例,我限制了该代理人只使用来自最相关文章的几个摘录。

现在让我们更详细地了解各个步骤。代理人需要执行的第一步是创建一个合适的搜索查询,以检索维基百科中包含回答用户提示所需信息的内容。为了做到这一点,我们将提示一个Llama 2聊天模型,并要求其返回代表用户提示的关键词。在进入具体使用的提示之前,我将简要回顾Llama 2聊天模型的一般提示格式。

在Llama 2聊天模型的训练过程中使用的模板具有以下结构:

<s>[INST] <<SYS>>{{ system_prompt }}<</SYS>>{{ user_message }} [/INST]

{{ system_prompt }}指定了聊天模型对后续提示的行为,并且对于调整模型对不同任务的响应很有用。{{ user_message }}是用户的提示,模型需要回答。

回到获取维基百科搜索查询的问题上,我们的代理人将使用以下提示的Llama 2模型:

<s>[INST] <<SYS>>你是一个返回文本查询以搜索维基百科文章的助手,该文章包含有关提示的相关信息。只写查询,不写其他内容。示例:[prompt] 告诉我关于2023年夏季欧洲的热浪 [query] 热浪、天气、温度、欧洲、夏季2023. <</SYS>>[prompt] {prompt} [/INST] [query]

{prompt}会在生成之前由用户的输入替换。系统提示中提供的示例旨在利用模型的上下文学习能力。上下文学习指的是模型根据提示中提供的一些示例演示的能力,解决新任务的能力。通过这种方式,模型可以学习到,在文本 [query] 后的逗号分隔的关键词是我们期望它提供的与提示相关的关键词。后者用作限定符,用于区分提示和示例中的答案,从模型的输出中提取查询也很有用。它已经作为输入的一部分提供,因此模型只需要生成它之后的内容。

一旦从模型输出中获取了查询,就可以使用它们来搜索维基百科并检索返回页面的元数据和文本数据。在本文附带的代码中,我使用了简单的Python包 wikipedia package,它是一个包装了 MediaWiki API 的简单 Python 包,用于搜索和检索维基百科的数据。

从搜索结果中提取文本后,选择与初始用户提示最相关的页面。这将使检索到的信息重新对齐到原始用户提示的方式,有可能消除由模型生成的搜索查询所导致的分歧。为了实现这一点,将用户的提示和搜索结果页面的摘要嵌入并存储在一个向量数据库中。然后检索与用户的提示嵌入最接近的文章。我使用了sentence transformers all-MiniLM-L6-v2模型作为嵌入模型,以及由langchain软件包提供的FAISS向量数据库的集成。

找到来自维基百科的相关页面后,由于将其整个文本添加到提示中可能需要大量的内存(或超过上下文长度的模型标记限制),我们的助手将找到最相关的摘录以补充提示。首先将页面的文本分成块,然后像之前一样将它们嵌入到矢量空间中,并检索与提示嵌入最接近的块。我再次使用了all-MiniLM-L6-v2模型来嵌入这些块,并使用FAISS向量数据库来存储和检索它们。

现在我们从文章中获取了检索到的段落,我们可以将它们与用户的提示结合起来,然后将它们输入到Llama 2模型中获取答案。输入的模板如下:

<s>[INST] <<SYS>>您是一位乐于助人且诚实的助手。您的回答不应包含任何有害、不道德、种族主义、性别歧视、有毒、危险或非法内容。您从维基百科页面{title}中检索到以下摘录:{extracts}。您应基于之前的摘录提供真实的答案。如果没有相关信息满足请求,请直接说出来,不要编造虚假信息。<</SYS>>{prompt} [/INST]

变量{prompt}在生成之前将被用户提示替换,{title}将替换为维基百科页面的标题,{extracts}将被提取的段落替换。您还可以提供一些示例来再次利用模型的上下文学习能力,但这将使提示显著变长,增加内存要求。

现在,让我们检查模型是否能够利用从维基百科中提取的最新信息进行回答,而这些信息在其训练期间并不存在。以下示例使用了在Google Colab免费版GPU上运行的LLaMa 2最小聊天版本,参数为70亿个。

我给模型提供了以下提示:

提示:"告诉我有关马拉喀什地震的情况"

模型创建了以下搜索维基百科的查询:

"地震,马拉喀什,摩洛哥,最近的地震,地震活动。"

在从最相关页面中提取段落后,模型返回了以下答案:

2023年9月8日发生在马拉喀什的地震是一场灾难性事件,造成了该地区广泛的破坏和生命损失。根据维基百科提供的信息,这次地震的瞬时矩震级为6.8-6.9,最大马加利强度为VIII级(严重),使其成为摩洛哥有记录以来最强的工程地震,也是自1960年阿加迪尔地震以来最致命的地震。地震的震中位于马拉喀什西南约45英里(73.4公里)处,靠近Ighil镇和阿特拉斯山脉中的Oukaïmeden滑雪度假村。这次地震是由山脉下的浅向斜逆冲断层活动引起的。根据世界卫生组织的数据,马拉喀什及周边地区约有30万人受地震影响,其中包括10万名儿童。地震导致至少2,946人死亡,其中大多数发生在马拉喀什以外的地区。需要注意的是,维基百科所提供的信息基于可用数据,可能不是详尽或最新的。如果您有任何特定问题

助手还返回了页面的元数据和用于答案的摘录,使用户可以检查其正确性,并通过阅读原始页面深入了解更多细节。以下是上一个答案的元数据:

检索到的维基百科页面:标题:2023年马拉喀什-撒菲地震,网址:https://en.wikipedia.org/wiki/2023_Marrakesh%E2%80%93Safi_earthquake检索到的摘录:摘录_0:马拉喀什和穆拉伊·布拉欣的地震后果 摘录_1:破坏范围广泛,马拉喀什的历史地标遭到破坏。这次地震在西班牙、葡萄牙和阿尔及利亚也有感觉。这是摩洛哥有记录以来最强烈的工程地震,自1960年阿加迪尔地震以来该国最致命的地震,也是2023年土耳其-叙利亚地震之后第二致命的地震。世界卫生组织估计,马拉喀什及周边地区约有30万人受到影响,其中包括10万名儿童 摘录_2:2023年9月8日23:11 DST(协调世界时间22:11),在摩洛哥的马拉喀什-撒菲地区发生了一次地震,瞬时矩震级为6.8-6.9,最大马加利强度为VIII级(严重)。地震的震中位于马拉喀什西南73.4公里(45.6英里)处,在Ighil镇和Oukaïmeden滑雪度假村附近。这是由山脉下浅向斜逆冲断层活动引起的。据报道,至少有2,946人死亡,其中大多数发生在马拉喀什以外。

结论

在本篇文章中,我解释了如何创建一个简单的代理程序,该程序可以通过在维基百科上搜索并根据所检索到的页面来回应用户的提示。尽管它很简单,但即使使用最小的 Llama 2 7B 模型,该代理也能够提供最新和准确的答案。该代理还返回用于生成答案的页面摘录,使用户能够检查模型提供的信息的正确性,并通过阅读完整的原始页面来深入了解。

维基百科是一个有趣的游乐场,可以展示 LLM 代理寻找和使用在训练数据中不存在的外部信息的能力,但是相同的方法也可以应用于其他需要外部知识的情境。例如,对于需要最新答案的应用程序、需要训练数据中不存在的特定知识的领域,或需要从私有文件中提取信息的情况,这种方法同样适用。这种方法还突显了 LLM 和人类之间合作的潜力。模型可以快速从非常庞大的外部知识库中搜索相关信息并返回有意义的答案,而人类用户则可以检查模型答案的有效性,并通过检查原始来源深入研究问题。

可以通过从不同页面中组合多个摘录以向模型提供更多信息来直接改进本文中描述的代理程序。事实上,在复杂提示的情况下,从多个维基百科页面提取信息可能会很有用。由于上下文更长所导致的内存需求的增加可以通过实施量化技术(例如 GPTQ)来部分补偿。通过在向用户提供最终答案之前让模型在搜索结果和检索内容上进行推理(例如根据论文 “ReAct: Synergizing Reasoning and Acting in Language Models” 中所描述的 ReAct 框架),可以进一步改进结果。这样,可以构建一个模型,该模型可以迭代地收集来自不同页面的最相关段落,并剔除不需要的段落,将来自不同主题的信息相结合。

感谢阅读!

Leave a Reply

Your email address will not be published. Required fields are marked *