【大模型】基于LlamaIndex实现大模型RAG

文章目录

  • 一、RAG基础
  • 二、使用大语言模型LLMs
    • 2.1 使用OpenAI大模型
    • 2.2 本地大模型
  • 三、构建RAG pipeline
    • 3.1 加载数据
      • 3.1.1 SimpleDirectoryReader
      • 3.1.2 DatabaseReader
      • 3.1.3 直接创建文档Document
    • 3.2 转换数据
    • 3.3 索引/嵌入 Indexing & Embedding
    • 3.4 存储
    • 3.5 查询
    • 3.6 评估
      • 3.6.1 生成结果质量评估
      • 3.6.2 检索结果评估
  • 三、RAG示例
  • 参考资料

LlamaIndex是一个LLM文本增强的框架,其中包含完整的RAG解决方案。项目在2023年1月29日发布了第一个版本,当时叫做“GPT Index v0.2.17” ,项目作者Jerry Liu。

  • Github地址:https://github.com/run-llama/llama_index
  • 官方文档:https://docs.llamaindex.ai/en/stable/

一、RAG基础

LLM是在大量数据上训练的,但它们并没有在你的私有数据上训练。检索增强生成(RAG)通过将您的数据添加到LLM已经可以访问的数据中来解决这个问题。

RAG的工作流程如下:
在这里插入图片描述

RAG(检索增强生成)包括五个关键阶段:加载(Loading)、索引(Indexing)、存储(Storing)、查询(Querying)和评估(Evaluation)。

  1. 加载(Loading):加载阶段涉及从数据源获取数据,可以是文本文件、PDF、其他网站、数据库或API。LlamaHub提供了数百个连接器可供选择,用于将数据导入到数据处理流程中。
  2. 索引(Indexing):索引阶段意味着创建一个数据结构,以便对数据进行查询。对于LLM(大型语言模型)来说,这几乎总是意味着创建向量嵌入(vector embeddings),即数据含义的数值表示,以及许多其他元数据策略,使得可以轻松准确地找到上下文相关的数据。
  3. 存储(Storing):将数据存储到向量数据库中。
  4. 查询(Querying):对于任何给定的索引策略,可以利用LLM和LlamaIndex数据结构进行查询,包括子查询、多步查询和混合策略等多种方式。
  5. 评估(Evaluation):在任何流程中,评估都是至关重要的步骤,用于检查相对于其他策略或在进行更改时流程的有效性。评估提供了关于对查询的响应有多准确、忠实和快速的客观度量标准。

在这里插入图片描述

二、使用大语言模型LLMs

在LlamaIndex中,我们可以使用大语言模型的API接口或者本地大语言模型。

首先安装环境:

pip install llama-index

如果配置ollama本地模型,需要额外安装:

pip install llama-index-llms-ollama
pip install llama-index-embeddings-ollama

2.1 使用OpenAI大模型

from llama_index.llms.openai import OpenAI
from llama_index.core import SettingsSettings.llm = OpenAI(temperature=0.2, model="gpt-4")

在上述代码中,我们实例化了一个OpenAI的LLM并将其传递给Settings。其中,Settings设置是一组配置数据,您可以将其传递到LlamaIndex的不同部分。

2.2 本地大模型

LlamaIndex还支持本地大模型,Ollama是比较常用的本地大模型部署及提供服务的工具,具体使用可以参见本人之前的博客:【大模型】Ollama的安装部署及运行大模型教程

在基于Ollama部署好大模型后,就可以用 Settings.llm = Ollama(model="llama2") 来设置本地大模型了。

from llama_index.llms.ollama import Ollama
from llama_index.core import SettingsSettings.llm = Ollama(model="llama2", request_timeout=60.0)

三、构建RAG pipeline

我们首先介绍下LlamaIndex中的几个基本概念:

  • 文档(document):文档是任何数据源的通用容器。 例如,PDF、API 输出或从数据库检索的数据。 它们可以手动构建,也可以通过数据加载器自动创建。 默认情况下,文档存储文本以及一些其他属性。
  • 节点(node):节点代表源文档的“块(chunk)”,无论是文本块、图像还是更多。 它们还包含元数据以及与其他节点和索引结构的关系信息。可以选择直接定义节点及其所有属性。 还可以选择通过 NodeParser 类将源文档“解析”为节点。
  • 元数据(metadata):每个文档/节点的元数据字典可以包含附加信息来帮助通知响应并跟踪查询响应的来源。 此信息可以是任何内容,例如文件名或类别。 此信息包含在节点中,使索引能够在查询和响应中利用它。 默认情况下,元数据会注入到嵌入和 LLM 模型调用的文本中。

3.1 加载数据

在我们选择的LLM对数据进行操作前,我们首先需要加载并处理数据。这与机器学习中的数据清理/特征工程管道或传统数据设置中的ETL管道相似。数据加载及处理由三个主要阶段组成:

  1. 加载数据 (Load the data)
  2. 转换数据 (Transform the data)
  3. 索引并存储数据 (Index and store the data)

3.1.1 SimpleDirectoryReader

LlamaIndex中最简单最常用的Reader是SimpleDirectoryReader,它内置于LlamaIndex中,可以读取各种格式,包括Markdown、PDF、Word文档、PowerPoint幻灯片、图像、音频和视频。

from llama_index.core import SimpleDirectoryReaderdocuments = SimpleDirectoryReader("./data").load_data()

3.1.2 DatabaseReader

在这个例子中,LlamaIdex下载并安装了名为DatabaseReader的连接器,该连接器对SQL数据库运行查询,并将结果的每一行作为Document返回:

from llama_index.core import download_loaderfrom llama_index.readers.database import DatabaseReaderreader = DatabaseReader(scheme=os.getenv("DB_SCHEME"),host=os.getenv("DB_HOST"),port=os.getenv("DB_PORT"),user=os.getenv("DB_USER"),password=os.getenv("DB_PASS"),dbname=os.getenv("DB_NAME"),
)query = "SELECT * FROM users"
documents = reader.load_data(query=query)

3.1.3 直接创建文档Document

我们也可以不使用loader,而是直接创建 Document,代码如下:

from llama_index.core import Documentdoc = Document(text="text")

3.2 转换数据

加载数据后,在将数据存储入库前,需要对数据进行处理和转换。这些转换包括:

  • 分块 (chunking)
  • 提取元数据 (extracting metadata)
  • 块嵌入 (embedding each chunk)

示例代码如下:

from llama_index.core import VectorStoreIndexvector_index = VectorStoreIndex.from_documents(documents)
vector_index.as_query_engine()

引擎(engine)提供了数据连接到自然语言的,LlamaIndex主要包含有两种引擎:

  • 查询引擎(Query engine):用于检索查询任务。
  • 聊天引擎(Chat engine):支持多轮对话。

3.3 索引/嵌入 Indexing & Embedding

在RAG(检索增强生成)中的索引阶段涉及以下内容:

  • 索引(Indexes):在摄取数据后,LlamaIndex将数据索引到一个易于检索的结构中。通常这包括生成向量嵌入(vector embeddings),并将其存储在称为向量存储(vector store)的专门数据库中。索引还可以存储关于数据的各种元数据。
  • 嵌入(Embeddings):LLM(大型语言模型)生成称为嵌入(embeddings)的数据的数值表示。在过滤与查询相关的数据时,LlamaIndex会将查询转换为嵌入,并且您的向量存储将找到与查询嵌入数值相似的数据。

LlamaIndex 提供了几种不同的索引类型。 在这里介绍最常见的VectorStoreIndex

  • Vector Store Index:向量数据库索引获取文档document并将它们分成节点node。 然后,它创建每个节点文本的向量嵌入,以供LLM查询。要使用向量存储索引,将在加载阶段创建的文档列表或者Node 对象列表传递给它。
from llama_index.core import VectorStoreIndexindex = VectorStoreIndex.from_documents(documents)

3.4 存储

LlamaIndex 还支持可交换存储组件,包括:

  • 文档存储:存储摄取的文档(即 Node 对象)的位置
  • 索引存储:存储索引元数据的位置
  • 向量存储:存储嵌入向量的位置
  • 图存储:存储知识图的位置(即 KnowledgeGraphIndex)
  • 聊天存储:存储和组织聊天消息的地方

3.5 查询

简单的查询只是对LLM的prompt调用:它可以是一个问题并获得答案,或者是一个总结请求。更复杂的查询可能涉及重复/链接prompt+ LLM 调用,甚至跨多个组件的推理循环。

在RAG(检索增强生成)中的查询阶段涉及以下内容:

  • 检索器(Retrievers):检索器定义了如何在给定查询时从索引中高效检索相关上下文。检索策略对于检索到的数据的相关性和效率至关重要。
  • 路由器(Routers):路由器确定将使用哪个检索器从知识库中检索相关上下文。更具体地说,RouterRetriever类负责选择一个或多个候选检索器来执行查询。它们使用选择器根据每个候选的元数据和查询选择最佳选项。
  • 节点后处理器(Node Postprocessors):节点后处理器接收一组检索到的节点,并对它们应用转换、过滤或重新排序逻辑。
  • 响应合成器(Response Synthesizers):响应合成器使用用户查询和一组检索到的文本块从LLM生成响应。

在下面的示例中,我们自定义检索器以对 top_k 使用不同的值,并添加一个后处理步骤,该步骤要求检索到的节点达到要包含的最小相似度分数。 当有相关结果时,这将提供大量数据,但如果没有任何相关结果,则可能不会提供任何数据。

from llama_index.core import VectorStoreIndex, get_response_synthesizer
from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.core.postprocessor import SimilarityPostprocessor# build index
index = VectorStoreIndex.from_documents(documents)# configure retriever
retriever = VectorIndexRetriever(index=index,similarity_top_k=10,
)# configure response synthesizer
response_synthesizer = get_response_synthesizer()# assemble query engine
query_engine = RetrieverQueryEngine(retriever=retriever,response_synthesizer=response_synthesizer,node_postprocessors=[SimilarityPostprocessor(similarity_cutoff=0.7)],
)# query
response = query_engine.query("What did the author do growing up?")
print(response)

3.6 评估

LlamaIndex 提供了衡量生成结果质量和检索质量的关键模块。

3.6.1 生成结果质量评估

LlamaIndex 提供基于LLM的评估模块来衡量结果的质量。 这使用“黄金”LLM(例如 GPT-4)以多种方式决定预测答案是否正确。当前的评估模块不需要真实标签。 可以通过查询、上下文、响应的某种组合来完成评估,并将这些与 LLM 调用结合起来。

这些评估模块有以下形式:

  • 正确性:生成的答案是否与给定查询的参考答案匹配(需要标签)。
  • 语义相似度 预测答案在语义上是否与参考答案相似(需要标签)。
  • 忠实性(Faithfulness):评估答案是否忠实于检索到的上下文(换句话说,是否存在幻觉)。
  • 上下文相关性:检索到的上下文是否与查询相关。
  • 答案相关性:生成的答案是否与查询相关。
  • 准则遵守情况:预测答案是否遵守特定准则。
from llama_index.core import VectorStoreIndex
from llama_index.llms.openai import OpenAI
from llama_index.core.evaluation import FaithfulnessEvaluator# create llm
llm = OpenAI(model="gpt-4", temperature=0.0)# build index
...
vector_index = VectorStoreIndex(...)# define evaluator
evaluator = FaithfulnessEvaluator(llm=llm)# query index
query_engine = vector_index.as_query_engine()
response = query_engine.query("What battles took place in New York City in the American Revolution?"
)
eval_result = evaluator.evaluate_response(response=response)
print(str(eval_result.passing))

3.6.2 检索结果评估

给定问题数据集和真实排名,我们可以使用平均倒数排名(MRR)、命中率、精度等排名指标来评估检索器。核心检索评估步骤围绕以下内容:

  • 数据集生成:给定非结构化文本语料库,综合生成(问题、上下文)对。
  • 检索评估:给定检索器和一组问题,使用排名指标评估检索结果。
from llama_index.core.evaluation import RetrieverEvaluator# define retriever somewhere (e.g. from index)
# retriever = index.as_retriever(similarity_top_k=2)
retriever = ...retriever_evaluator = RetrieverEvaluator.from_metric_names(["mrr", "hit_rate"], retriever=retriever
)retriever_evaluator.evaluate(query="query", expected_ids=["node_id1", "node_id2"]
)

三、RAG示例

使用本地大模型实现一个简单的RAG的代码如下:

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama_index.llms.ollama import Ollama
from llama_index.embeddings.ollama import OllamaEmbedding# 加载本地数据
documents = SimpleDirectoryReader("./data").load_data()# Embedding模型
Settings.embed_model = OllamaEmbedding(model_name="nomic-embed-text")# 引入本地大模型
Settings.llm = Ollama(model="llama3.1:8b", request_timeout=360)# 构建索引
index = VectorStoreIndex.from_documents(documents)# 查询引擎
query_engine = index.as_query_engine()# 执行查询并获取响应
response = query_engine.query("霸王茶姬香港店什么时候开业?店长薪酬多少?")
print(response)

参考资料

  • https://docs.llamaindex.ai/en/stable/
  • LlamaIndex——RAG概述
  • https://www.bilibili.com/video/BV1jE421A77u/?spm_id_from=333.1387.favlist.content.click&vd_source=87a3abdad251514e8efa36af41d3eba9

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

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

相关文章

Mac 终端命令大全

—目录操作— ꔷ mkdir 创建一个目录 mkdir dirname ꔷ rmdir 删除一个目录 rmdir dirname ꔷ mvdir 移动或重命名一个目录 mvdir dir1 dir2 ꔷ cd 改变当前目录 cd dirname ꔷ pwd 显示当前目录的路径名 pwd ꔷ ls 显示当前目录的内容 ls -la ꔷ dircmp 比较两个目录的内容 di…

你猜猜 攻防世界

你猜猜 打开附件: 504B03040A0001080000626D0A49F4B5091F1E0000001200000008000000666C61672E7478746C9F170D35D0A45826A03E161FB96870EDDFC7C89A11862F9199B4CD78E7504B01023F000A0001080000626D0A49F4B5091F1E0000001200000008002400000000000000200000000000000…

优惠券平台(一):基于责任链模式创建优惠券模板

前景概要 系统的主要实现是优惠券的相关业务,所以对于用户管理的实现我们简单用拦截器在触发接口前创建一个单一用户。 // 用户属于非核心功能,这里先通过模拟的形式代替。后续如果需要后管展示,会重构该代码 UserInfoDTO userInfoDTO new…

VsCode创建VUE项目

1. 首先安装Node.js和npm 通过网盘分享的文件:vsCode和Node(本人电脑Win11安装) 链接: https://pan.baidu.com/s/151gBWTFZh9qIDS9XWMJVUA 提取码: 1234 它们是运行和构建Vue.js应用程序所必需的。 1.1 Node安装,点击下一步即可 …

大模型产品Deepseek(五)、本地安装部署(Docker方式)

DeepSeek 本地部署指南 DeepSeek是一款高效的智能搜索与推荐引擎,除了通过云端API提供服务外,它还支持本地部署,让开发者可以完全控制数据和计算资源。通过本地部署,您可以将DeepSeek集成到内部系统中,在私有环境下运行模型,减少对外部API的依赖,同时提升数据隐私性与响…

JVM 中的四类引用:强、软、弱、虚

导言 在 Java 开发中,垃圾收集(GC)机制通过自动管理内存提升了开发效率。但你是否知道 JVM 通过四种引用类型(强、软、弱、虚)精细控制对象生命周期? 强引用(Strong Reference) 特…

数据结构--八大排序算法

1. 直接插入排序 当插入第 i(i>1) 个元素时,前面的 array[0],array[1],…,array[i-1] 已经排好序,此用 array[i] 的排序码与 array[i-1],array[i-2],… 的排序码顺序进行比较,找到插入位置即将 array[i] 插入,原来位置上的元素…

【C/C++算法】从浅到深学习---双指针算法(图文兼备 + 源码详解)

绪论:冲击蓝桥杯一起加油!! 每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry” 绪论​: 本章是新开篇章也是算法的第一篇章----双指针算法,双指针算法是算法中非常…

Python内置函数map(), list(), len(), iter(), hex(), hash()的详细解析,包括功能、语法、示例及注意事项

1. map(function, iterable, ...) 功能:对可迭代对象中的每个元素应用指定函数,返回一个迭代器。 参数: function:要执行的函数(可以是lambda表达式)。 iterable:一个或多个可迭代对象&#x…

Win本地安装Ollama+本地运行大模型+Cherrystudio使用

0. 前言 本文主要介绍 win 本地安装 Ollama ,本地部署 Ollama 的 deepseek-r1:7b 大模型,使用具有界面画操作的工具 Cherrystudio进行操作。文章内容仅供参考。 1. Ollama简介 ‌ ‌Ollama 是一个开源的框架,旨在本地运行大型语言模型…

用户点击商品埋点的实现方案

在高并发、可扩展性和高可用性的前提下,实现用户点击商品的埋点,方案应包括 数据采集、数据传输、数据存储和数据分析 四个主要环节。下面是一个完整的埋点实现方案: 1. 方案架构 整体流程: 前端埋点:用户点击商品时…

【C++】AVLTree(AVL树)简单模拟

文章目录 1.AVL树的结点2.AVL树的插入3.AVL树的旋转3.1 新节点插入较高左子树的左侧---左左:右单旋3.2 新节点插入较高右子树的右侧---右右:左单旋3.3 新节点插入较高左子树的右侧---左右:先左单旋再右单旋3.4 新节点插入较高右子树的左侧---…

零基础Vue入门6——Vue router

本节重点: 路由定义路由跳转 前面几节学习的都是单页面的功能(都在专栏里面https://blog.csdn.net/zhanggongzichu/category_12883540.html),涉及到项目研发都是有很多页面的,这里就需要用到路由(vue route…

【数据结构】(6) LinkedList 链表

一、什么是链表 1、链表与顺序表对比 不同点LinkedListArrayList物理存储上不连续连续随机访问效率O(N)O(1)插入、删除效率O(1)O(N) 3、链表的分类 链表根据结构分类,可分为单向/双向、无头结点/有头节点、非循环/循环链表,这三组每组各取…

使用Pygame制作“俄罗斯方块”游戏

1. 前言 俄罗斯方块(Tetris) 是一款由方块下落、行消除等核心规则构成的经典益智游戏: 每次从屏幕顶部出现一个随机的方块(由若干小方格组成),玩家可以左右移动或旋转该方块,让它合适地堆叠在…

(苍穹外卖)项目结构

苍穹外卖项目结构 后端工程基于 maven 进行项目构建,并且进行分模块开发。 1). 用 IDEA 打开初始工程,了解项目的整体结构: 对工程的每个模块作用说明: 序号名称说明1sky-take-outmaven父工程,统一管理依赖版本&…

【漫画机器学习】082.岭回归(或脊回归)中的α值(alpha in ridge regression)

岭回归(Ridge Regression)中的 α 值 岭回归(Ridge Regression)是一种 带有 L2​ 正则化 的线性回归方法,用于处理多重共线性(Multicollinearity)问题,提高模型的泛化能力。其中&am…

websocket自动重连封装

websocket自动重连封装 前端代码封装 import { ref, onUnmounted } from vue;interface WebSocketOptions {url: string;protocols?: string | string[];reconnectTimeout?: number; }class WebSocketService {private ws: WebSocket | null null;private callbacks: { [k…

【华为OD-E卷 - 115 数组组成的最小数字 100分(python、java、c++、js、c)】

【华为OD-E卷 - 数组组成的最小数字 100分(python、java、c、js、c)】 题目 给定一个整型数组,请从该数组中选择3个元素组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字) 输…

在Vue3 + Vite 项目中使用 Tailwind CSS 4.0

文章目录 首先是我的package.json根据官网步骤VS Code安装插件验证是否引入成功参考资料 首先是我的package.json {"name": "aplumweb","private": true,"version": "0.0.0","type": "module","s…