通过 Amazon SageMaker JumpStart 构建基于知识库的问答应用

GitHub
JSON
Amazon SageMaker
大语言模型
Amazon SageMaker Jumpstart
0
0
从海量文本中解锁准确以及富有洞察力的内容是大语言模型 (LLM) 所赋予的一种令人兴奋的能力。在构建 LLM 的相关应用时,通常需要连接和查询外部数据源来为模型提供相关的上下文。一种流行的方法是使用检索增强生成 (RAG) 来创建能够理解复杂信息并对查询提供自然响应的问答系统。RAG 允许模型利用庞大的知识库,为诸如聊天机器人和企业搜索助手等应用提供仿人类的对话。 本文将探讨**如何借助 [LlamaIndex](https://www.llamaindex.ai/?trk=cndc-detail)、[Llama 2-70B-Chat](https://llama.meta.com/?trk=cndc-detail) 和 [LangChain](https://www.langchain.com/?trk=cndc-detail) 的力量来构建强大的问答应用**。通过这些最先进的技术,您可以**摄取文本语料库、为关键的知识创建索引,以及生成能够准确、清晰地回答用户问题的文本**。 #### **Llama 2-70B-Chat** Llama 2-70B-Chat 是一个强大的 LLM,可与众多领先的模型相媲美。它是**在两万亿个文本标记上进行了预训练,并且其主要被用于为用户提供聊天辅助**。预训练数据来源于公开可用的数据,截止于 2022 年 9 月;而微调数据则截止于 2023 年 7 月。有关模型的训练过程、安全考虑、经验教训和预期用途的更多详细信息,请参阅论文 “[Llama 2: Open Foundation and Fine-Tuned Chat Models](http://arxiv.org/pdf/2307.09288?trk=cndc-detail)”。Llama 2 模型可在 [Amazon SageMaker JumpStart](https://aws.amazon.com/sagemaker/jumpstart/?trk=cndc-detail) 上获得,以实现快速和直观的部署。 #### **LlamaIndex** LlamaIndex 是一个数据框架,可用于构建 LLM 应用程序。它提供了数据连接工具,可以从各种来源和格式(PDF、docs、API、SQL 等)的文件摄取您的数据。无论您的数据存储在数据库中还是 PDF 文件中,LlamaIndex 都可以轻松地将这些数据用于 LLM。正如本文所演示的例子,LlamaIndex API 使数据访问变得轻而易举,同时使您能够创建强大的自定义 LLM 应用程序和工作流程。 如果您正在尝试和构建 LLM 相关的应用,那么您可能熟悉 LangChain。它提供了一个健壮的框架,简化了 LLM 驱动的应用程序的开发和部署。与 LangChain 类似,LlamaIndex 也提供了多种工具,包括数据连接器、数据索引、引擎和数据代理,以及应用程序集成。LlamaIndex 专注于消除数据与 LLM 之间的隔阂,通过对用户友好的功能简化数据任务。LlamaIndex 是专门为构建搜索和检索应用程序而设计以及优化的,例如基于 RAG 的应用程序,因为它提供了一个简单的接口来查询大语言模型并检索相关文档。 ### **解决方案概述** 本文将演示**如何使用 LlamaIndex 和 LLM 创建基于 RAG 的应用程序**。下图为该解决方案的分步架构,每一步将在接下来的章节中叙述。 ![image.png](https://dev-media.amazoncloud.cn/fcfc0e78fc984e0cb4660acd97fac27c_image.png "image.png") RAG 结合了信息检索和自然语言生成,以产生更有洞察力的回答。当接收到提示时,RAG 首先搜索文本语料库,检索与输入最相关的示例。在生成响应期间,模型会考虑这些示例来增强其功能。通过结合相关的检索段落,RAG 响应往往比基础生成模型更加实事求是、连贯一致且与上下文相关。这种检索–生成框架利用了检索和生成的优势,有助于解决单纯的自回归对话模型可能出现的重复和缺乏上下文等问题。RAG 为构建具有上下文、高质量响应的对话代理和生成式 AI 助手引入了一种有效的方法。 实施该解决方案包括以下步骤: 1. 设置 [Amazon SageMaker Studio](https://aws.amazon.com/cn/sagemaker/studio/?trk=cndc-detail) 作为开发环境,并安装所需的依赖项。 2. 从 [Amazon SageMaker JumpStart](https://aws.amazon.com/cn/sagemaker/jumpstart/?trk=cndc-detail) 中心部署 embedding 模型。 3. 下载新闻稿作为我们的外部知识库。 4. 基于新闻稿构建索引,以便查询并将其作为上下文添加到提示中。 5. 查询知识库。 6. 使用 LlamaIndex 和 LangChain 代理构建问答应用程序。 本文中的所有代码都可在 [GitHub 仓库](https://github.com/aws-samples/llms-amazon-bedrock-sagemaker/tree/main/rag_llamaindex_sagemaker?trk=cndc-detail)中找到。 ### **先决条件** 对于实施本示例,您需要一个亚马逊云科技账号,同时该账号应包含一个 Amazon SageMaker domain 和对应的 [IAM](https://aws.amazon.com/cn/iam/?trk=cndc-detail) 权限。有关亚马逊云科技账号创建的说明,请参阅[创建亚马逊云科技账户](https://docs.aws.amazon.com/sagemaker/latest/dg/gs-set-up.html#gs-account?trk=cndc-detail)。如果您还没有 Amazon SageMaker domain,请参阅 [Amazon SageMaker domain](https://docs.aws.amazon.com/sagemaker/latest/dg/gs-studio-onboard.html?trk=cndc-detail) 进行创建。在本文中,出于实验目的,我们将使用 [AmazonSageMakerFullAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonSageMakerFullAccess.html?trk=cndc-detail) 角色,但是不建议您在生产环境中使用该角色。相反,您应该创建和使用具有最小权限的角色。您还可以探索如何使用 [Amazon SageMaker Role Manager](https://docs.aws.amazon.com/sagemaker/latest/dg/role-manager.html?trk=cndc-detail) 直接通过 Amazon SageMaker 控制台为常见的[机器学习](https://aws.amazon.com/cn/machine-learning/?trk=cndc-detail)需求构建和管理 IAM 角色。 此外,您的账号需要具备以下实例类型的配额: * ml.g5.2xlarge 用于部署 [Hugging Face GPT-J](https://huggingface.co/docs/transformers/model_doc/gptj?trk=cndc-detail) 嵌入模型 * ml.g5.48xlarge 用于部署 Llama 2-Chat 模型 若要增加配额,请参阅[文档](https://docs.aws.amazon.com/servicequotas/latest/userguide/request-quota-increase.html?trk=cndc-detail)。 ### **利用 Amazon SageMaker JumpStart 部署 GPT-J 嵌入模型** 本节为您提供了两种部署 Amazon SageMaker JumpStart 模型的选项。您可以使用我们提供的代码进行基于代码的部署,或者使用 Amazon SageMaker JumpStart 用户界面  (UI) 进行部署。 #### **使用 Amazon SageMaker Python SDK 部署** 您可以使用 Amazon SageMaker Python SDK 来部署 LLM,如该代码所示。步骤如下: 1. 设置将用于部署嵌入模型的实例大小,使用 `instance_type = "ml.g5.2xlarge"` 2. 找到需要的嵌入模型的 ID。在 Amazon SageMaker JumpStart 中,它被标识为 `model_id = "huggingface-textembedding-gpt-j-6b-fp16"` 3. 获取预训练模型的容器并将其部署用于推理 当嵌入模型部署成功后,Amazon SageMaker 将返回模型端点的名称。更多请参考[代码相关文档](https://github.com/aws-samples/llms-amazon-bedrock-sagemaker/blob/main/rag_llamaindex_sagemaker/3-llm-llamaindex-langchain.ipynb?trk=cndc-detail)。 #### **使用 Amazon SageMaker Studio 部署** 在 Amazon SageMaker Studio 中使用 Amazon SageMaker JumpStart 部署模型,可根据以下步骤: 1、在 Amazon SageMaker Studio 控制台中,从导航栏选择 JumpStart。如下图所示。 ![image.png](https://dev-media.amazoncloud.cn/1f3f961d634a48c890ceac108afeeb0b_image.png "image.png") 2、搜索并选择 GPT-J 6B Embedding FP16 模型。 3、选择部署并自定义配置。如下图所示。 ![image.png](https://dev-media.amazoncloud.cn/437a891e11654ca48b80186d68b421ff_image.png "image.png") 4、对于本示例,我们直接选择默认的实例大小 `ml.g5.2xlarge` 即可。 5、点击部署(此次部署需要大概 5–10 分钟)。 ![image.png](https://dev-media.amazoncloud.cn/bd12d472339d4ba39467b3a0bbbe6d2e_image.png "image.png") 在部署了嵌入模型之后,为了使用 LangChain 与 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) API 的集成,您需要创建一个函数来处理原始文本的输入并使用该模型将它们转换为嵌入。您可以通过创建一个名为 `ContentHandler` 的类来实现这一点,它接收 JSON 类型的输入数据,并返回 JSON 格式的文本嵌入: `class ContentHandler(EmbeddingsContentHandler)`。 将模型端点的名称传给函数 ContentHandler 用以转换文本和返回嵌入: ```js embeddings = SagemakerEndpointEmbeddings(endpoint_name='huggingface-textembedding-gpt-j-6b-fp16', region_name= aws_region, content_handler=emb_content_handler). ``` 您可以在代码执行的结果中或 Amazon SageMaker JumpStart 的部署界面中找到该端点名称。 您可以通过输入一些原始文本并运行 `embeddings.embed_query(text)` 函数来测试 `ContentHandler` 函数和端点是否按照预期工作。您可以使用提供的示例 `text = "Hi! It's time for the beach"` 或尝试您自己的文本。 ### **使用 Amazon SageMaker JumpStart 部署和测试 Llama 2-Chat 模型** 现在您可以部署能够与用户进行互动对话的模型。在本示例中,我们选择了 Llama 2-chat 模型系列中的一个,如下代码所示。 ```js my_model = JumpStartModel(model_id = "meta-textgeneration-llama-2-70b-f") ``` 该模型需要使用 `predictor = my_model.deploy()` 部署到实时端点。Amazon SageMaker 将返回模型的端点名称,您可以使用该端点名称作为 `endpoint_name` 变量的值以备后用。 这里定义了一个 `print_dialogue` 函数来向聊天模型发送输入并接收其输出响应。发送的数据除了模型的超参数外,还包括以下内容: * max_new_tokens – 指模型在输出中可以生成的最大词元数。 * top_p – 指模型在生成输出时可以保留的词元的累积概率。 * temperature – 指模型生成输出的随机性。该值大于 0 或等于 1 会增加随机性水平,而等于 0 将生成最可能的词元。 您应该根据您的用例选择超参数,并对其进行适当测试。像 Llama 这个系列的模型需要您在调用时传递一个额外的参数,表示您已阅读并接受最终用户许可协议 (EULA)。如下所示。 ```js response = predictor.predict(payload, custom_attributes='accept_eula=true') ``` 要测试所部署的模型,需要替换请求体中 `content` 部分的内容:`"content": "what is the recipe of mayonnaise?"`。您也可以使用自己的文本并更新超参数以更好地理解它们。 与部署嵌入模型类似,您也可以使用 Amazon SageMaker JumpStart UI 部署 Llama-70B-Chat: 1. 在 Amazon SageMaker Studio 控制台上,选择导航窗格中的 JumpStart 2. 搜索并选择 Llama-2-70b-Chat model 3. 接受 EULA 并选择 Deploy,直接使用默认实例即可 与嵌入模型类似,您也可以通过为您的聊天模型的输入和输出创建内容模板来使用 LangChain 集成。在这种情况下,需要将输入定义为来自用户的输入,并指出它们受 `system prompt` 的约束。`system prompt` 的作用是告知模型它在特定场景下所需要扮演的特定角色。然后,在调用模型时传递这些提示词,并添加上述超参数和自定义属性( EULA 接受)。以下代码展示了调用方法。 ```js llm = SagemakerEndpoint( endpoint_name=endpoint_name, region_name="us-east-1", model_kwargs={"max_new_tokens":500, "top_p": 0.1, "temperature": 0.4, "return_full_text": False}, content_handler=content_handler, endpoint_kwargs = {"CustomAttributes": "accept_eula=true"} ) ``` 当端点可用时,我们就可以测试它是否按预期工作。您可以用自己的文本更新 `llm("what is amazon sagemaker?")`。同时还需要定义特定的 `ContentHandler` 来使用 LangChain 调用大语言模型,如该代码以及以下代码片段所示: ```js class ContentHandler(LLMContentHandler): content_type = "application/json" accepts = "application/json" def transform_input(self, prompt: str, model_kwargs: dict) -> bytes: payload = { "inputs": [ [ { "role": "system", "content": system_prompt, }, {"role": "user", "content": prompt}, ], ], "parameters": model_kwargs, } input_str = json.dumps( payload, ) return input_str.encode("utf-8") def transform_output(self, output: bytes) -> str: response_json = json.loads(output.read().decode("utf-8")) content = response_json[0]["generation"]["content"] return content content_handler = ContentHandler() ``` ### **使用 LlamaIndex 构建 RAG** 接下来我们将使用 LlamaIndex 来构建 RAG 应用程序。您可以使用 pip 安装 LlamaIndex:`pip install llama_index` 首先,我们需要将数据(知识库)加载到 LlamaIndex 中进行索引。这涉及以下几个步骤: 1、选择数据加载器 LlamaIndex 在 LlamaHub 上提供了许多用于常见数据类型 (如 JSON、CSV 和文本文件)以及其他数据源的数据连接器,允许我们摄取各种数据集。在本文中,我们使用 `SimpleDirectoryReader` 来摄取几个 PDF 文件。我们的数据样本是代码库中稿件资料文件夹中的两个 PDF 版本的 Amazon 新闻稿。加载 PDF 后,您可以看到它们已被转换为 11 个元素的列表。 除了直接加载文档,您还可以在为其创建索引之前,将 `Document` 对象转换为 `Node` 对象。是为整个 `Document` 对象创建索引,还是在索引之前先将 `Document` 转换为 `Node` 对象,这取决于您的特定用例和数据结构。对于长文档,检索文档的特定部分而不是整个文档,节点方法通常是一个不错的选择。更多相关信息,请参阅 [Documents / Nodes](https://docs.llamaindex.ai/en/stable/module_guides/loading/documents_and_nodes/root.html?trk=cndc-detail)。 2、实例化加载器并加载文档 此步骤初始化加载器类及任何所需的配置,例如是否忽略隐藏文件等。更多详细信息,请参阅 [SimpleDirectoryReader](https://docs.llamaindex.ai/en/stable/module_guides/loading/simpledirectoryreader.html?trk=cndc-detail)。 3、调用加载器的 `load_data` 方法来解析源文件和数据,并将它们转换为 LlamaIndex 的 `Document` 对象,以便进行索引和查询。您可以使用以下代码完成数据摄取和准备,以使用 LlamaIndex 的索引和检索功能进行[全文](https://github.com/aws-samples/llms-amazon-bedrock-sagemaker/tree/main/rag_llamaindex_sagemaker/pressrelease?trk=cndc-detail)搜索。 ```js docs = SimpleDirectoryReader(input_dir="pressrelease").load_data() ``` 4、构建索引 LlamaIndex 的一个关键特性是能够在数据上构建结构化的索引,表示为文档类型或节点类型。创建索引有助于高效查询数据。我们使用默认的内存向量存储和自定义的配置创建索引。LlamaIndex Settings 是一个配置对象,为 LlamaIndex 应用程序中的索引和查询操作提供常用资源和设置。它充当一个单例对象,因此允许您设置全局配置,同时还允许您通过直接传递该对象给相关接口(如大语言模型、嵌入模型)来覆盖特定组件的默认配置。当没有显式提供特定组件时,LlamaIndex 框架将会采用 `Settings` 对象中的配置作为全局默认设置。为了使用 LangChain 调用嵌入模型和 LLM 以及配置 `Settings`,我们需要安装 `llama_index.embeddings.langchain` 和 `llama_index.llms.langchain`。我们可以按如下代码配置 `Settings` 对象: ```js Settings.embed_model = LangchainEmbedding(embeddings) Settings.llm = LangChainLLM(llm) ``` 默认情况下,VectorStoreIndex 会使用内存存储 SimpleVectorStore。但在真实场景中,通常需要使用外部向量存储,如 [Amazon OpenSearch Service](https://aws.amazon.com/cn/opensearch-service/features/serverless/?trk=cndc-detail)。有关更多详细信息,请参阅 “[Vector Engine for Amazon OpenSearch Serverless](https://aws.amazon.com/cn/opensearch-service/serverless-vector-engine/?trk=cndc-detail)”。 ```js index = VectorStoreIndex.from_documents(docs, service_context=service_context) ``` 现在可以使用 LlamaIndex 的 [query_engine](https://docs.llamaindex.ai/en/stable/module_guides/deploying/query_engine/root.html?trk=cndc-detail) 对文档运行问答。为此,请传递此前创建的索引用作查询以及开始提问。查询引擎是一个通用接口,用于查询数据。它将自然语言查询作为输入,并返回内容丰富的响应。查询引擎通常借助于[检索器](https://docs.llamaindex.ai/en/stable/module_guides/querying/retriever/root.html?trk=cndc-detail)建立在一个或多个[索引](https://docs.llamaindex.ai/en/stable/module_guides/indexing/indexing.html?trk=cndc-detail)之上。 ```js query_engine = index.as_query_engine() print(query_engine.query("Since migrating to AWS in May, how much in operational cost Yellow.ai has reduced?")) ``` 可以看到,RAG 解决方案能够从所提供的文档中检索到正确的答案: ```js According to the provided information, Yellow.ai has reduced its operational costs by 20% since migrating to AWS in May ``` ### **使用 LangChain tool 和 agent** `Loader` 类被设计用于将数据加载到 LlamaIndex 中,或者作为 [LangChain agent](https://python.langchain.com/v0.1/docs/modules/agents/?trk=cndc-detail) 中的一个 `tool`。这让您在应用程序中使用它时拥有更多的可能性和灵活性。首先,从 LangChain agent 类中定义 [`tool`](https://python.langchain.com/v0.1/docs/modules/tools/?trk=cndc-detail)。其中的 `func` 就是去查询此前使用 LlamaIndex 创建的索引,如下代码所示。 ```js tools = [ Tool( name="Pressrelease", func=lambda q: str(index.as_query_engine().query(q)), description="useful pressreleases for answering relevnat questions", return_direct=True, ), ] ``` 然后,选择合适的 agent 类型。在本例子中,可以使用 `chat-zero-shot-react-descriptionagent`。使用这个 agent,大语言模型将会利用可用的 `tool`(此处为知识库的 RAG)来生成响应。这时可以通过传递 `tool`、llm 和 agent 类型来初始化 agent: ```js agent= initialize_agent(tools, llm, agent="chat-zero-shot-react-description", verbose=True) ``` 可以看到,agent 经历了 `thoughts`、`actions` 和 `observation`,同时运用了 `tool` (此处为此前所生成的索引文档),返回了一个结果: ```js 'According to the provided press release, Yellow.ai has reduced its operational costs by 20%, driven performance improvements by 15%, and cut infrastructure costs by 10% since migrating to AWS. However, the specific cost savings from the migration are not mentioned in the provided information. It only states that the company has been able to reinvest the savings into innovation and AI research and development.' ``` 在该 [GitHub repo](https://github.com/aws-samples/llms-amazon-bedrock-sagemaker/tree/main/rag_llamaindex_sagemaker?trk=cndc-detail) 中找到相关的实现代码。 ### **清理资源** 为避免不必要的成本,您可以通过 Boto3 SDK 或 Amazon JumpStart UI 来清理资源。 要使用 Boto3 SDK,请使用以下代码删除嵌入模型以及 LLM 的端点,同时还有端点配置: ```js client = boto3.client('sagemaker', region_name=aws_region) client.delete_endpoint(EndpointName=endpoint_name) client.delete_endpoint_config(EndpointConfigName=endpoint_configuration) ``` 要使用 Amazon SageMaker 控制台,请执行以下步骤: 1. 在 Amazon SageMaker 控制台的导航窗格中,选择 Inference 下的 Endpoints。 2. 搜索此前创建的 embedding 模型和 LLM 端点。 3. 在端点详情页面,选择 Delete。 4. 再次选择 Delete 以确认删除。 ### **结论** 对于以搜索和检索为重点的使用场景,LlamaIndex 提供了各种灵活的功能。它擅长为 LLM 对外部文档进行索引和检索,使其成为深入探索数据的强大工具。**LlamaIndex 能够让您创建结构化的数据索引,调用不同的 LLM,通过提升数据检索能力来提高 LLM 的性能,并使用自然语言查询数据**。 本文展示了一些 LlamaIndex 关键的概念和功能。我们**使用 GPT-J 进行嵌入,使用 Llama 2-Chat 作为 LLM 来构建 RAG 应用程序**。与此同时,您也可以使用任何合适的模型,您可以探索 Amazon SageMaker JumpStart 上提供所有的模型。 本文还展示了 LlamaIndex 如何提供强大、灵活的工具,将数据与其他框架(如 LangChain)连接、索引、检索和集成。**通过 LlamaIndex 与 LangChain 的集成,您可以构建更强大、更通用、更具洞察力的 LLM 应用程序**。 ![image.png](https://dev-media.amazoncloud.cn/7ecba57226b64f2c9e32e613fa3abafd_image.png "image.png") ![开发者尾巴.gif](https://dev-media.amazoncloud.cn/e85e54146fe9422d80b4e77dd5ff0f1e_%E5%BC%80%E5%8F%91%E8%80%85%E5%B0%BE%E5%B7%B4.gif "开发者尾巴.gif")
目录
亚马逊云科技解决方案 基于行业客户应用场景及技术领域的解决方案
联系亚马逊云科技专家
亚马逊云科技解决方案
基于行业客户应用场景及技术领域的解决方案
联系专家
0
目录
关闭