使用 LlamaIndex 实现的检索增强生成(RAG)

Retrieval Augmented Generation (RAG) using LlamaIndex — ROCm Blogs (amd.com)

2024 年 4 月 4 日 作者:Clint Greene.

先决条件

要运行本博客,您需要具备以下条件:

  • Linux: 参见受支持的 Linux 发行版

  • ROCm: 参见安装说明

  • AMD GPU: 参见兼容 GPU 列表

简介

大型语言模型(LLM),如 ChatGPT,是能够执行许多复杂写作任务的强大工具。然而,它们也有其限制,主要包括:

  • 缺乏获取最新信息的能力:LLM 的训练数据是静态的,这意味着它们无法访问最新的新闻或信息。

  • 域特定任务的适用性有限:LLM 并未使用域特定数据训练,因此在专门用途的场景中,可能会给出不相关或不准确的回答。

为了解决这些限制,可以采用两种主要方法引入最新和域特定数据:

  •  微调:为 LLM 提供最新的、域特定的提示和完成对文本对。然而,这种方法成本高,特别是当用于微调的数据经常变动时,需要频繁更新。

  • 上下文提示:将最新数据作为上下文插入提示中,LLM 可以将这些信息作为附加信息来生成回答。然而,这种方法也有局限性,因为并非所有最新的域特定文档都可以适合插入到提示的上下文中。

为了克服这些障碍,可以使用检索增强生成(RAG)。RAG 是一种通过向 LLM 提供最新、相关的信息来增强其准确性和可靠性的方法。它的工作原理是自动将外部文档分割成指定大小的块,根据查询检索最相关的块,并增强输入提示以使用这些块作为回答用户查询的上下文。这种方法允许创建域特定的应用程序,而无需进行微调或手动将信息插入上下文提示中。

AI 社区用于 RAG 的一个流行框架是 LlamaIndex。它是一个用于构建 LLM 应用程序的框架,重点在于摄取、构建和访问私有或域特定数据。其工具有助于将自定义的分布外数据集成到 LLM 中。 

入门

要开始,首先安装用于RAG的`transformers`, accelerate和`llama-index`:

!pip install llama-index llama-index-llms-huggingface llama-index-embeddings-huggingface llama-index-readers-web transformers accelerate -q

然后,导入`LlamaIndex`库:

from llama_index.core import ServiceContext
from llama_index.core import VectorStoreIndex
from llama_index.llms.huggingface import HuggingFaceLLM
from llama_index.core.prompts.base import PromptTemplate
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.readers.web import BeautifulSoupWebReader

许多开源LLM在每个提示之前需要一个前序或对提示进行特定的结构化,你可以使用`system_prompt`或`messages_to_prompt`在生成之前进行编码。另外,查询可能需要一个额外的包装器,你可以使用`query_wrapper_prompt`指定这些信息。这些信息通常可以在你使用的模型的Hugging Face模型卡上找到。在这种情况下,你将使用`zephyr-7b-alpha`进行RAG,因此你可以从 这里获取预期的提示格式。

def messages_to_prompt(messages):
  prompt = ""
  for message in messages:
    if message.role == 'system':
      prompt += f"<|system|>\n{message.content}</s>\n"
    elif message.role == 'user':
      prompt += f"<|user|>\n{message.content}</s>\n"
    elif message.role == 'assistant':
      prompt += f"<|assistant|>\n{message.content}</s>\n"

LlamaIndex支持通过将模型名称传递给`HuggingFaceLLM`类直接使用Hugging Face的LLM。你可以通过`model_kwargs`指定模型参数,例如使用的设备和量化程度。你可以在`generate_kwargs`中指定控制LLM生成策略的参数,如`top_k`、`top_p`和`temperature`。你也可以直接在类中指定控制输出长度的参数,如`max_new_tokens`。要了解更多关于这些参数及其影响生成方式的细节,请查看Hugging Face的text generation文档。

llm = HuggingFaceLLM(
    model_name="HuggingFaceH4/zephyr-7b-alpha",
    tokenizer_name="HuggingFaceH4/zephyr-7b-alpha",
    query_wrapper_prompt=PromptTemplate("<|system|>\n</s>\n<|user|>\n{query_str}</s>\n<|assistant|>\n"),
    context_window=3900,
    max_new_tokens=256,
    model_kwargs={"use_safetensors": False},
    # tokenizer_kwargs={},
    generate_kwargs={"do_sample":True, "temperature": 0.7, "top_k": 50, "top_p": 0.95},
    messages_to_prompt=messages_to_prompt,
    device_map="cuda",
)

原始提示 

为了演示前面提到的不足之处,可以提示你的LLM并询问Paul Graham如何推荐努力工作。

question = "How does Paul Graham recommend to work hard? Can you list it as steps"
response = llm.complete(question)
print(response)

Paul Graham's advice on working hard, as outlined in his essay "How to Be a Maker," can be summarized into several steps:

1. Work on something you care about. This will give you the motivation and energy to work harder and longer than you would if you were working on something that didn't matter to you.

2. Set specific goals. Instead of just working on your project, set specific milestones and deadlines for yourself. This will give you a clear sense of direction and help you to focus your efforts.

3. Eliminate distractions. Turn off your phone, close your email, and find a quiet place to work. Eliminating distractions will help you to stay focused and make progress.

4. Work in short, intense bursts. Rather than working for long periods of time, break your work into short, intense bursts. This will help you to maintain your focus and avoid burnout.

5. Take breaks. Taking breaks is important for maintaining your focus and avoiding burnout. Use your breaks to clear your mind, recharge your batteries, and come back to your work with fresh energy.

6. Work on your weaknesses.

乍看起来,生成的回应看起来准确合理。LLM知道我们在谈论Paul Graham和如何努力工作。推荐的努力工作步骤看起来也很合理。然而,这些并不是Paul Graham关于如何努力工作的建议。LLM在遇到知识空白时,可能会出现‘幻觉’,即做出虚假但似乎合理的陈述。 

提示工程

一个简单的方法来克服事实的‘幻觉’是修改提示以包括外部的上下文信息。让我们从Paul Graham的 文章 《如何努力工作》中复制文本。

以使用Python中的BeautifulSoup库自动复制这些文本:

url = "https://paulgraham.com/hwh.html"

documents = BeautifulSoupWebReader().load_data([url])

现在,修改原始问题,并在提问时包括更新的信息:

context = documents[0].text
prompt = f"""Answer the question based on the context below. If the
question cannot be answered using the information provided answer
with "I don't know".

Context: {context}

Question: {question}

Answer: """

现在,将此提示输入到你的LLM中,并注意响应:

response = llm.complete(prompt)
print(response)

1. Learn the shape of real work: Understand the difference between fake work and real work, and be able to distinguish between them.

2. Find the limit of working hard: Learn how many hours a day to spend on work, and avoid pushing yourself to work too much.

3. Work toward the center: Aim for the most ambitious problems, even if they are harder.

4. Figure out what to work on: Determine which type of work you are suited for, based on your interests and natural abilities.

5. Continuously assess and adjust: Regularly evaluate both how hard you're working and how well you're doing, and be willing to switch fields if necessary.

6. Be honest with yourself: Consistently be clear-sighted and honest in your evaluations of your abilities, progress, and interests.

7. Accept failure: Be open to the possibility of failure and learn from it.

8. Stay interested: Find work that you find interesting and enjoyable, rather than simply for financial gain or external validation.

9. Balance work and rest: Give yourself time to get going, but also recognize when it's time to take a

通过提示LLM使用文章作为上下文,你限制了LLM使用提示中的信息生成内容,从而生成准确的响应。现在,尝试使用RAG(检索增强生成)方法生成响应,并与上下文提示方法进行比较。

构建检索增强生成(Retrieval Augmented Generation,RAG)应用程序

要构建RAG应用程序,首先需要调用`ServiceContext`,这会建立要使用的语言和嵌入模型,以及确定文档解析的关键参数(例如`chunk_size` 和`chunk_overlap`)。

service_context = ServiceContext.from_defaults(llm=llm, embed_model="local:BAAI/bge-base-en-v1.5", chunk_size=256, chunk_overlap=32)

在执行RAG时,文档被分成较小的块。`chunk_size`参数指定每个块的长度(以token为单位),而`chunk_overlap`指定每个块与其相邻块重叠的token数量。

用你在前面实验中使用的`llm`变量设置`llm`参数。对于嵌入模型,使用`bge-base`(已证明在检索任务中表现优异)来嵌入文档块。

接下来,使用`VectorStoreIndex`构建向量索引,它将你的文档传递给嵌入模型以进行分块和嵌入。然后调用`query_engine`准备索引用于查询,指定`similarity_top_k`以返回与输入查询最相似的前八个文档块。

index = VectorStoreIndex.from_documents(documents, service_context=service_context)
query_engine = index.as_query_engine(similarity_top_k=8)

你的RAG应用程序现在已经可以进行查询了。让我们用原始问题进行查询:

response = query_engine.query(question)
print(response)

Paul Graham recommends the following steps to work hard:
1. Constantly aim toward the center of the problem you're working on, which is usually the most ambitious and difficult part.

2. Measure both how hard you're working and how well you're doing. Don't solely rely on pushing yourself to work, as there may be times where you need to focus on easier, peripheral work.

3. When working on a specific problem, aim as close to the center as you can without stalling.

4. When working on a larger scale, make big, lifetime-scale adjustments about which type of work to do.

5. Give yourself time to get going on a new problem, but don't give up too soon if results aren't immediate.

6. Learn to distinguish between good and bad results, and adjust accordingly.

7. Find an easy way to do something hard.

8. Be consistently honest and clear-sighted, and your network will automatically assume an optimal shape.

9. Determination, interest, and natural ability are the three ingredients in great work.

10. Go on vacation occasionally, but learn something new while there.

这个响应与上下文提示引导的示例相当类似。这并不令人惊讶,因为它使用相同的上下文信息生成响应。提示工程需要手动指定上下文,而可以将RAG视为一种高级和自动化的提示工程,它利用文档数据库检索最优的上下文来指导生成过程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/907930.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【计网】深入理解NAT机制,内网穿透与内网打洞,代理服务

我没胆量犯错 才把一切错过 --- 林夕 《我对不起我》--- 一文了解NAT机制&#xff0c;代理服务&#xff0c;内网穿透 1 再谈 NAT 机制2 内网穿透与内网打洞3 代理服务器 1 再谈 NAT 机制 NAT机制我们在解决IP地址不足的问题中提到过。为了解决IP地址不足的问题&#xff0c;采…

京东毫秒级热key探测框架JD-hotkey

前言 对任意突发性的&#xff0c;无法预先感知的热点数据&#xff0c;包括热点数据&#xff08;如突发大量请求同一个商品&#xff09;、热用户&#xff08;如恶意爬虫刷子&#xff09;、热接口&#xff08;突发海量请求同一个接口&#xff09;等&#xff0c;一瞬间打到我们的服…

2025生物发酵展(济南)为生物制造产业注入新活力共谱行业新篇章

2025第十四届国际生物发酵展将于3月3-5日济南盛大举办&#xff01;产业链逐步完整&#xff0c;展会面积再创历史新高&#xff0c;展览面积较上届增涨至60000平方米&#xff0c;专业观众40000&#xff0c;品牌展商800&#xff0c;同期活动会议增加至50场&#xff0c;展会同期将举…

设计模式08-行为型模式1(命令模式/迭代器模式/观察者模式/Java)

五、行为型模式 **行为模式的定义&#xff1a;**行为型模式是对不同的对象之间划分职责和算法的抽象化。行为型模式定义了系统中对象之间的交互与通信&#xff0c;研究系统在运行时对象之间的相互通信与协作&#xff0c;进一步明确对象的职责&#xff0c;包括对系统中较为复杂的…

边缘计算网关在机床数据采集中的应用-天拓四方

随着工业4.0和智能制造的快速发展&#xff0c;机床作为制造业的核心设备&#xff0c;其数据采集与分析对于提升生产效率、保证产品质量、优化加工过程具有重要意义。传统的数据采集方式存在数据传输速度慢、实时性差、数据处理能力有限等问题。为了解决这些问题&#xff0c;边缘…

Navicat 连接远程腾讯云服务器的MySQL数据库

首先需要开放开放腾讯云安全端口&#xff0c;可以参考这个链接腾讯云服务器入站规则端口开放使用指南(CentOS系统)。 但是注意需要开放的是IPv6&#xff0c;这个可以通过netstat命令查看确认。 然后查看当前用户信息 select user, host from mysql.user一般看到的都是 localh…

Navicat for MySQL 错误:1251

mySql&#xff1a;8.4 Navicat for MySQL&#xff1a;11.0.10 企业版 绿色版 官网中关于mysql_native_password插件的说法&#xff1a;链接 1. 问题 连接数据库报错&#xff1a;1251 要求升级Navicat for MySQL 2. 原因 mysql中的mysql_native_password插件默认是关闭的 …

mysql5安装

1.下载安装包 https://downloads.mysql.com/archives/community/ mysql-5.7.44-1.el7.x86_64.rpm-bundle.tar tar -xvf mysql-5.7.44-1.el7.x86_64.rpm-bundle.tar2.安装依赖 yum -y install perl yum -y install net-tools yum install numactl libaio libaio-devel -y也可…

【MyBatis】【基于轻量型架构的WEB开发】课程 课后习题 章节测试

mybatis关联查询、缓存、注解 一. 单选题 1. 下列关于 <collection> 元素的描述正确的是&#xff08;&#xff09;。 A. MyBatis 就是通过 <collection> 元素来处理一对多关联关系的 B. <collection> 元素的属性与 <association> 元素完全相同 C.…

C++ | Leetcode C++题解之第528题按权重随机选择

题目&#xff1a; 题解&#xff1a; class Solution { private:mt19937 gen;uniform_int_distribution<int> dis;vector<int> pre;public:Solution(vector<int>& w): gen(random_device{}()), dis(1, accumulate(w.begin(), w.end(), 0)) {partial_sum(…

opencv - py_imgproc - py_canny Canny边缘检测

文章目录 Canny 边缘检测目标理论OpenCV 中的 Canny 边缘检测其他资源 Canny 边缘检测 目标 在本章中&#xff0c;我们将学习 Canny 边缘检测的概念用于该目的的 OpenCV 函数&#xff1a;cv.Canny() 理论 Canny 边缘检测是一种流行的边缘检测算法。它由 John F. Canny 于1…

java、excel表格合并、指定单元格查找、合并文件夹

#创作灵感# 公司需求 记录工作内容 后端&#xff1a;JAVA、Solon、easyExcel、FastJson2 前端&#xff1a;vue2.js、js、HTML 模式1&#xff1a;合并文件夹 * 现有很多文件夹 想合并全部全部的文件夹的文件到一个文件夹内 * 每个部门发布的表格 合并全部的表格为方便操作 模…

数据结构作业day5

链栈&#xff0c;自己实现一遍&#xff0c;但是节点存储不是整数&#xff0c;存储学生信息&#xff08;年龄&#xff0c;分数&#xff0c;姓名&#xff09;三级引用。 1、建立学生信息结构体&#xff0c;将data改为学生信息结构体类型。 2、循环入栈和入队。 循环入栈代码 …

【学术精选】SCI期刊《Electronics》特刊“New Challenges in Remote Sensing Image Processing“

英文名称&#xff1a;New Challenges in Remote Sensing Image Processing 中文名称&#xff1a;"遥感图像处理的新挑战"特刊 期刊介绍 “New Challenges in Remote Sensing Image Processing”特刊隶属于《Electronics》期刊&#xff0c;聚焦遥感图像处理领域快速…

2024 CSS保姆级教程 - BFC详解

前言 - CSS中的文档流 在介绍BFC之前&#xff0c;需要先给大家介绍一下文档流。​ 我们常说的文档流其实分为定位流、浮动流、普通流三种。​ ​ 1. 绝对定位(Absolute positioning)​ 如果元素的属性 position 为 absolute 或 fixed&#xff0c;它就是一个绝对定位元素。​ 在…

数字化装配助力柔性制造与快速换型,驱动效率飞跃

数字化装配是利用先进的数字化技术&#xff0c;如三维建模、仿真分析、物联网、大数据、人工智能等&#xff0c;对装配过程进行精确设计、优化控制和智能管理的一种现代化生产方式。它打破传统装配依赖于人工经验和物理样机的局限&#xff0c;通过模拟环境进行预装配验证&#…

如何在服务器端对PDF和图像进行OCR处理

介绍 今天我想和大家分享一个我在研究技术资料时发现的很好玩的东西——Tesseract。这不仅仅是一个普通的库&#xff0c;而是一个用C语言编写的OCR神器&#xff0c;能够识别一大堆不同国家的语言。我一直在寻找能够处理各种文档的工具&#xff0c;而Tesseract就像是给了我一把…

QT——TCP网络调试助手

目录 一.项目展示 ​编辑 二.开发流程 三.QTcpServer、QTcpSocket、QUdpSocket类的学习 1.QTcpServer服务端 2.QTcpSocket客户端 3.Udp通信 四.网络调试助手 1.首先我们实现当用户选择不同协议类型时不同的UI组件如何切换 2.实现打开/关闭按键图片的切换 方式一&…

eclipse下载与安装(汉化教程)超详细

目录 一、下载eclipse安装包 三、配置eclipse 代码自动补全功能 安装汉化包 中英文切换 四、用eclipse写hello world 一、下载eclipse安装包 1、首先进入 eclipse官网 如下&#xff1a; 2、这里面有很多版本&#xff1b;我们小白一般选择第二个&#xff0c;向下滑动&…

[FE] React 初窥门径(四):React 组件的加载过程(render 阶段)

1. 回顾 前几篇文章中&#xff0c;我们采用了 VSCode 插件 CodeTour 来记录代码的执行过程&#xff0c; 并把相关的数据 .tour/ 放到了 github: thzt/react-tour 中。 截止到本文为之&#xff0c;我们总共记录了这些 code-tour&#xff0c; .tour/ ├── 2. 构建过程.tour ├─…