LLM之RAG实战(二十五)| 使用LlamaIndex和BM25重排序实践

       本文,我们将研究高级RAG方法的中的重排序优化方法以及其与普通RAG相比的关键差异。

一、什么是RAG?

       检索增强生成(RAG)是一种复杂的自然语言处理方法,它包括两个不同的步骤:信息检索生成语言建模。这种方法旨在为语言模型提供访问外部数据源,来提高其在生成响应时的准确性和相关性,从而增强语言模型的能力。

1.1 检索组件:

目的:检索组件的主要功能是响应查询或提示,从大型数据库或语料库中提取相关文档或信息片段。

过程:当收到查询时,检索系统会搜索其数据库(如维基百科文章、书籍或其他文本数据的集合),以找到与查询相关的内容。

输出:此阶段的输出是一组与输入查询相关的文档或文本段落。

1.2 生成语言模型:

与检索到的数据集成:将检索到的文档输入到生成语言模型中,该模型使用这些文档中的信息来通知其响应生成。

响应生成:语言模型处理原始查询和检索到的文档中的信息,以生成不仅与上下文相关而且由外部数据提供信息的响应。

      这种方法(RAG)允许语言模型产生比仅依靠其预先训练的知识更准确、更详细、更适合上下文的反应。

二、什么是高级RAG?

       高级检索增强生成(Advanced RAG)通过结合复杂的检索前和检索后过程来增强传统的RAG。Advanced RAG中检索后过程的一个关键方面是“ReRank”,它涉及对检索到的文档进行重新排序,来优先考虑最相关的信息。ReRank通过采用各种算法或框架来实现的,比如基于文档多样性与查询的相关性之类的标准来调整排序。重新排序的目的是向大型语言模型提供最相关的信息,从而提高生成的响应的质量和相关性。

三、RAG和高级RAG之间的主要区别是什么?

四、高级RAG重排序代码实施:

       有了对Advanced RAG概念的理解,现在让我们将使用LlamaIndex作为实施的框架,BM25作为我们的排序函数。BM25算法是信息检索系统中广泛使用的排序函数,特别是在文档检索中。它是概率信息检索家族的一部分,是对经典TF-IDF(术语频率逆文档频率)方法的改进。因此,我们将使用它作为我们的重新排序函数。

       在这篇文章中,我们将研究两种不同的实现高级RAG的方法,一种是使用OpenAI LLM,另一种是在完全局部LLM(Mistral)

       首先在项目文件夹的根目录中创建一个项目文件夹和包括如下内容的.env文件。

OPENAI_API_KEY="<YOUR_OPENAI_API_KEY>"LLM_URI="http://localhost:11434"

        导入相关库

import nest_asyncioimport osimport sysimport loggingfrom dotenv import load_dotenv, find_dotenvfrom llama_index import (    SimpleDirectoryReader,    ServiceContext,    StorageContext,    VectorStoreIndex,)from llama_index.query_engine import RetrieverQueryEnginefrom llama_index.retrievers import BM25Retrieverfrom llama_index.llms import OpenAI, Ollamafrom llama_index.embeddings import OllamaEmbeddingfrom llama_index.postprocessor import SentenceTransformerRerankfrom llama_index import QueryBundle

        配置asynciologger

logging.basicConfig(stream=sys.stdout, level=logging.INFO)logging.getLogger().handlers = []logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))nest_asyncio.apply()

        让我们设计一个名为AdvancedRAG的类,该类具有以下3个函数:

class AdvancedRAG:    def __init__(self):        _ = load_dotenv(find_dotenv())        # load documents        self.documents = SimpleDirectoryReader("./data/", required_exts=['.pdf']).load_data()        # global variables used later in code after initialization        self.retriever = None        self.reranker = None        self.query_engine = None        self.bootstrap()    def bootstrap(self):        # initialize LLMs        llm = OpenAI(model="gpt-4",                    api_key=os.getenv("OPENAI_API_KEY"),                    temperature=0,                    system_prompt="You are an expert on the Inflamatory Bowel Diseases and your job is to answer questions. Assume that all questions are related to the Inflammatory Bowel Diseases (IBD). Keep your answers technical and based on facts – do not hallucinate features.")        # initialize service context (set chunk size)        service_context = ServiceContext.from_defaults(chunk_size=1024, llm=llm)        nodes = service_context.node_parser.get_nodes_from_documents(self.documents)        # initialize storage context (by default it's in-memory)        storage_context = StorageContext.from_defaults()        storage_context.docstore.add_documents(nodes)        index = VectorStoreIndex(            nodes=nodes,            storage_context=storage_context,            service_context=service_context,        )        # We can pass in the index, doctore, or list of nodes to create the retriever        self.retriever = BM25Retriever.from_defaults(similarity_top_k=2, index=index)        # reranker setup & initialization        self.reranker = SentenceTransformerRerank(top_n=1, model="BAAI/bge-reranker-base")        self.query_engine = RetrieverQueryEngine.from_args(            retriever=self.retriever,            node_postprocessors=[self.reranker],            service_context=service_context,        )    def query(self, query):        # will retrieve context from specific companies        nodes = self.retriever.retrieve(query)        reranked_nodes = self.reranker.postprocess_nodes(            nodes,            query_bundle=QueryBundle(query_str=query)        )        print("Initial retrieval: ", len(nodes), " nodes")        print("Re-ranked retrieval: ", len(reranked_nodes), " nodes")        for node in nodes:            print(node)        for node in reranked_nodes:            print(node)        response = self.query_engine.query(str_or_query_bundle=query)        return response

Initialization方法(__init__):

环境设置:使用load_dotenv(find_dotenv())加载环境变量。这可能用于配置设置,如API密钥或URL。

文档加载:使用SimpleDirectoryReader从指定目录加载文档。这些文档可能被用作检索任务的语料库。

全局变量:为检索器重排序器query_engine设置占位符,它们可能是检索和排序过程中的关键组件。

Bootstrap方法调用:调用Bootstrap方法来初始化各种组件。

Bootstrap方法:

初始化大型语言模型(llm):使用Ollama或OpenAI GPT-4设置语言模型实例(llm)。

初始化嵌入模型:使用OllamaEmbedding设置嵌入模型(embed_mode),该模型用于创建文本的矢量表示。

服务上下文:使用块大小和模型(llm和embed_mode)配置服务上下文。

节点解析和存储:将文档解析为节点,并将其存储在内存数据库中,以便快速访问。

索引创建:使用VectorStoreIndex创建索引,以高效检索文档。

Retriever初始化:初始化BM25Retriever,这是一个基于BM25算法的检索模型。

重新排序初始化:使用SentenceTransformerRerank设置重新排序,重新排序检索到的结果的相关性。

查询引擎初始化:初始化一个查询引擎,该引擎将检索器重排序器组合在一起以处理查询。

Query方式:

检索:检索与给定查询相关的节点(文档)。

重排序:对检索到的节点应用重新排序。

响应生成:使用查询引擎根据查询生成响应。

if __name__ == "__main__":    adv_rag = AdvancedRAG()    resp = adv_rag.query("What is the impact of IBD in women ?")    print(resp)

         当您使用OpenAI GPT-4配置运行上述代码时,以下应该是输出。

       使用本地LLM和本地嵌入模型(Mistral)修改代码,在上面的代码中,只需注释现有的OpenAI GPT-4 LLM并使用下面的代码。

# initialize LLMsllm = Ollama(base_url=os.getenv("LLM_URI"), model="mistral")

        初始化Mistral嵌入,如下所示

# initialize mistral embed modelembed_model = OllamaEmbedding(base_url=os.getenv("LLM_URI"), model_name="mistral")

        现在,通过传递embed_mode来修改现有的服务上下文,如下所示:

# initialize service context (set chunk size)service_context = ServiceContext.from_defaults(chunk_size=1024, llm=llm, embed_model=embed_model)

      现在,如果将代码指向下面的本地LLM和本地嵌入来编写代码,那么输出如下:

      您可以清楚地看到,GPT-4和Mistral等2种方法生成的响应发生了一些显著变化,但具有置信度|重新排序分数的检索节点保持不变。

六、结论

       总之,高级检索增强生成(Advanced Retrieval Augmented Generation,简称RAG)是信息检索和自然语言处理领域的一次重大飞跃。通过将BM25等最先进的排名算法与先进的重新排序技术和GPT-4或Mistral等尖端语言模型相集成,advanced RAG为处理复杂的查询任务提供了一个强大而灵活的解决方案。正如我们在讨论中举例说明的那样,这种实际实现不仅展示了Advanced RAG的理论潜力,还展示了其在现实世界中的适用性。无论是在提高搜索引擎的准确性、提高聊天机器人中响应的相关性,还是在推进知识系统的前沿领域,高级RAG证明了人工智能驱动的语言理解和信息处理的不断发展和成熟。Advanced RAG中检索准确性和上下文生成的融合为各种应用中更智能、更灵敏、更知识渊博的系统铺平了道路,预示着人工智能能力的新时代。

参考文献:

[1] https://blog.stackademic.com/advanced-retrieval-augmented-generation-how-reranking-can-change-the-game-d06e12b77074

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

爬虫2—用爬虫爬取壁纸(想爬多少张爬多少张)

先看效果图&#xff1a; 我这个是爬了三页的壁纸60张。 上代码了。 import requests import re import os from bs4 import BeautifulSoupcount0 img_path "./壁纸图片/"#指定保存地址 if not os.path.exists(img_path):os.mkdir(img_path) headers{ "User-Ag…

【九章斩题录】Leetcode:判定是否互为字符重排(C/C++)

面试题 01.02. 判定是否互为字符重排 ✅ 模板&#xff1a;C class Solution { public:bool CheckPermutation(string s1, string s2) {} }; 「 法一 」排序 &#x1f4a1; 思路&#xff1a;看到题目中说 "重新排列后能否变成另一个字符串"&#xff0c;等等……重新…

如何升级 gpt4?快速升级至ChatGPT Plus指南,爆火的“ChatGPT”到底是什么?

提到 ChatGPT。想必大家都有所耳闻。自从 2022 年上线以来&#xff0c;就受到国内外狂热的追捧和青睐&#xff0c;上线2个月&#xff0c;月活突破1个亿&#xff01;&#xff01;&#xff01; 而且还在持续上涨中。因为有很多人都在使用 ChatGPT 。无论是各大头条、抖音等 App、…

UUID算法:独一无二的标识符解决方案

引言 在分布式系统和大数据环境下&#xff0c;唯一标识符的生成和管理是一项关键任务。UUID&#xff08;Universally Unique Identifier&#xff09;算法应运而生&#xff0c;成为了解决重复数据和标识符冲突的有效工具。本文将探讨UUID算法的优势和劣势&#xff0c;分析其在分…

【Spring】

目录 前言 1.Spring框架中的单例bean是线程安全的吗? 2.什么是AOP? 3.你们项目中有没有使用到AOP&#xff1f; 4.Spring中的事务是如何实现的&#xff1f; 5.Spring中事务失效的场景有哪些&#xff1f; 6.Spring的bean的生命周期。 7.Spring中的循环引用 8.构造方法…

休斯顿NASA太空机器人进入最后测试阶段,或可模拟人类执行外星任务!

美国宇航局开发研制的太空智能机器人目前正在德州休斯顿的约翰逊航天中心接受最后的运行测试&#xff0c;距离太空智能化时代又要更进一步了&#xff01; NASA表示&#xff0c;日前在德州休斯顿附近的约翰逊航天中心进行测试的机器人名为Valkyrie&#xff0c;是以北欧神话中的一…

Postgresql 的编译安装与包管理安装, 全发行版 Linux 通用

博客原文 文章目录 实验环境信息编译安装获取安装包环境依赖编译安装安装 contrib 下工具代码 创建用户创建数据目录设置开机自启动启动数据库常用运维操作 apt 安装更新源安装 postgresql开机自启修改配置修改密码 实验环境信息 Ubuntu 20.04Postgre 16.1 编译安装 获取安装…

.NET命令行(CLI)常用命令

本文用于记录了.NET软件开发全生命周期各阶段常用的一些CLI命令&#xff0c;用于开发速查。 .NET命令行&#xff08;CLI&#xff09;常用命令 项目创建&#xff08;1&#xff09;查看本机SDK&#xff08;2&#xff09;查看本机可以使用的.NET版本&#xff08;3&#xff09;生成…

159基于matlab的基于密度的噪声应用空间聚类(DBSCAN)算法对点进行聚类

基于matlab的基于密度的噪声应用空间聚类(DBSCAN)算法对点进行聚类&#xff0c;聚类结果效果好&#xff0c;DBSCAN不要求我们指定集群的数量&#xff0c;避免了异常值&#xff0c;并且在任意形状和大小的集群中工作得非常好。它没有质心&#xff0c;聚类簇是通过将相邻的点连接…

Android:内存泄漏检查内存优化

3.17Android优化 手机移动设备的内存是有限的,需要避免内存泄漏,优化内存使用。 1.java中四种引用类型 强引用、软引用、弱引用、虚引用。 强引用:使用类构造方法,创建对象,当内存超出了,也不会释放对象所占内存空间; String str = new String(‘1223’); 切断引用str=…

代码随想录算法训练营第44天 | 完全背包理论基础 518.零钱兑换II 377.组合总和 Ⅳ

完全背包理论基础 完全背包与01背包只相差在物品是无限取用的。因此和01背包相比第二层对背包容量的遍历应该是正序的&#xff0c;而且正因为这个正序&#xff0c;使得在纯完全背包问题中&#xff0c;背包容量和物品的遍历是可以倒过来的。 #include <bits/stdc.h> usi…

网络的基本概念和socket编程

网络的基本概念 1.协议1.1 协议的基本概念1.2 常见的协议 2.分层模型2.1网络七层OSI 7层模型&#xff1a;物数网传会表应(口诀)2.2TCP/IP模型2.3数据通信的过程2.4网络的设计模式2.5以太网帧的格式 3.SOCKET编程3.1网络字节序3.2 相关结构体和函数3.3 代码实现 1.协议 1.1 协议…

前端JavaScript篇之对象继承的方式有哪些?

目录 对象继承的方式有哪些&#xff1f;1. 原型链继承2. 借用构造函数3. 组合继承4. 原型式继承5. 寄生式组合继承 对象继承的方式有哪些&#xff1f; 1. 原型链继承 当使用原型链继承时&#xff0c;子类型的原型对象被设置为父类型的一个实例。这意味着子类型通过其原型可以…

VUE学习——数组变化侦测

官方文档 变更方法&#xff1a; 使用之后&#xff0c;ui可以直接发生改变。改变原数组 替换数组&#xff1a; 使用之后需要接受重新赋值&#xff0c;不然ui不发生改变。不改变原数组

第70讲axios后端请求工具类封装

axios工具类封装&#xff1a; // 引入axios import axios from axios;// 创建axios实例 const httpService axios.create({// url前缀-http:xxx.xxx// baseURL: process.env.BASE_API, // 需自定义baseURL:http://localhost:80/,// 请求超时时间timeout: 3000 // 需自定义 })…

嵌入式系统:挑战与机遇并存的领域

嵌入式系统&#xff1a;挑战与机遇并存的领域嵌入式系统是一个既具有挑战性又充满前景的领域。要成为一名合格的嵌入式系统工程师&#xff0c;需要经过大量的学习和实践。然而&#xff0c;进入这个领域时&#xff0c;刚入行可能会面临许多困境。让我们一起探讨一下嵌入式系统工…

Python爬虫实战 | 京东平台电商API接口采集京东商品京东工业商品详情数据

item_get-获得JD商品详情API测试 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[item_search,item_get,item_search_shop等]cac…

【Maven】依赖、构建管理 继承与聚合 快速学习(3.6.3 )

文章目录 Maven是什么&#xff1f;一、Maven安装和配置本地配置文件设置idea配置本地maven 二、基于IDEA的Maven工程创建2.1 Maven工程GAVP属性2.2 Idea构建Maven JavaEE工程 三、Maven工程项目结构说明四、Maven核心功能依赖和构建管理4.1 依赖管理和配置4.2 依赖传递和冲突4.…

【数学建模】【2024年】【第40届】【MCM/ICM】【E题 财产保险的可持续性】【解题思路】

一、题目 &#xff08;一&#xff09; 赛题原文 2024 ICM Problem E: Sustainability of Property Insurance Extreme-weather events are becoming a crisis for property owners and insurers. The world has endured “more than $1 trillion in damages from more than …

vue+springboot前后端视频文件等的上传与展示(基于七牛云)

前言&#xff1a;在初步说明完成功能之前&#xff0c;我会把重要的部分说明下。后续我会细化。 vue视频文件上传 其实这里和图片这些文件就是一样的。因为上传只是把我们想在云端展示的文件按等传输到云端的bucket。然后方便网站去请求引用。 有人问我我就说明下。这种东西无…