检索增强生成RAG系列1--RAG的实现

大模型出现涌现能力之后,针对大模型的应用也如雨后春笋般。但是,在大模型真正落地之前,其实还需要做好最后一公里,而这个最后一公里,其中不同应用有着不同的方法。其中prompt、微调和RAG都是其中方法之一。本系列就是针对RAG从入门到落地应用的流程。

目录

  • 1 概念
  • 2 架构
  • 3 代码实现

1 概念

RAG的全称是Retrieval-Augment Generation,即称为检索增强生成。通过特定prompt方式为 LLM 提供了从某些数据源检索到的信息,并基于此修正生成的答案。其中有几个关键的点需要知道:

  • 一个是从某些数据源检索到的信息
  • 提供特定的prompt
  • 修正生成答案

简单用一句话来说就是:利用向量数据库将格外的知识以向量存储,然后在回答用户问题时,先将用户问题在向量数据库中进行相似度查询,将查询结果以prompt的方式扔给大模型,获得最终答案。
那么RAG与prompt、微调(fine-tuning)有何应用场景的不同,以下是整理了RAG与其对比表格:

promptfine-tuningRAG
定义在不改变模型参数的前提条件下,利用提示工程来提升大语言模型处理复杂任务场景的能力通过一个微训练的过程来修改大模型它本身的参数,使模型能更加专业化在不改变大模型参数下,通过大语言模型理解用户的查询需求,并将相关的片段从数据库中检索出来,将提示工程与数据库查询相结合以获得上下文丰富的答案
解决问题提高回答的精准度更擅长回答特定场景下的相关问题提升生成内容的精准度且保留数据安全
场景通用且简单的场景,比如普通聊天问答等开放专业领域,比如医疗、法律等场景封闭专业领域,比如企业内部数据场景
优点无需改变模型;推理耗时低;成本低;准确度高;推理耗时低;无需改变模型;准确度高;安全性强;及时内容;
缺点准确度低;稳定性低;无及时内容;成本高;灵活度低;稳定性低 ;流程复杂;成本较高;

三者都有不同的优缺点,在实践中,可以参考以下图表对你的应用场景进行适配:

在这里插入图片描述
1) 横轴表示LLM本身优化,也就是优化LLM本身按照你想要的表达方式来表达
2) 纵轴表示上下文优化,也就是增加LLM的专业知识

  • Prompt engineering:相当于告诉你要考试,但是考试内容没有告诉你
  • RAG:相当于给你一本书,在考试的时候你可以查
  • Fine-tuning:相当于你学习了知识,然后闭卷考试
  • Fine-tuning+RAG:相当于你学了知识的同时开卷考试

2 架构

一个RAG架构应该是怎么样的?你或许见过比较复杂的流程,但是这里先介绍一个RAG最少需要包括哪些部分。(后续会逐步介绍各个模块以及更多优化的流程)

在这里插入图片描述

1)专业知识:需要一个专业知识读取,这时候可能是pdf、Excel等不同类型的文档,因此需要一个文档读取工具
2)入库:需要将专业知识入库,而入库的操作就是将专业知识向量化,也就是embedding,因此你需要一个embedding工具
3)数据库:一般使用向量数据库,当然也可以使用其它(但考虑到相似度搜索,向量数据库最合适),其作用就是用于存储格外的专业知识,用于问题做相似度匹配
4)prompt:给特定的prompt,比如:根据以下知识:…(这里填入查询出来的内容),回答:…(这里是问题)。

3 代码实现

本实例是基于text2vec-large-chinese将文档向量化,采用Chroma向量数据库,大模型使用ChatGLM,基础架构使用LangChain。都是本地部署,因此需要做一些前置工作。

前置工作:
1)下载text2vec-large-chinese模型
2)下载ChatGLM3-6B的模型
3)下载ChatGLM3的github源码,运行openai_api_demo/api_server.py文件,启动api服务

from langchain.document_loaders import DirectoryLoader
from langchain.prompts import PromptTemplate
from langchain.text_splitter import CharacterTextSplitter
from langchain.embeddings.huggingface import HuggingFaceEmbeddings
from langchain.vectorstores import Chroma
from langchain.chains import RetrievalQA
from langchain.llms import ChatGLM
import os# 第一步,加载text2vec-large-chinese模型
encode_kwargs = {"normalize_embeddings": False}
model_kwargs = {"device": "cuda:0"}
embeddings = HuggingFaceEmbeddings(model_name='text2vec-large-chinese路径',  # 换成自己的embedding模型路径model_kwargs=model_kwargs,encode_kwargs=encode_kwargs
)
# 第二步,创建数据库
if os.path.exists('VectorStore'):db = Chroma(persist_directory='VectorStore', embedding_function=embeddings)
# 第三步,加载文档
loader = DirectoryLoader("documents文档路径")  # 换成自己的文档路径
documents = loader.load()
text_spliter = CharacterTextSplitter(chunk_size=256, chunk_overlap=0)
documents = text_spliter.split_documents(documents)
# 第四步,存储文档
database = Chroma.from_documents(documents, embeddings, persist_directory="VectorStore")
database.persist()
# 第五步,创建llm
print("load model api")
llm = ChatGLM(endpoint_url='http://127.0.0.1:8000',  # 换成自己的apimax_token=80000,top_p=0.9
)
# 第六步,设置prompt
QA_CHAIN_PROMPT = PromptTemplate.from_template("""根据下面的上下文(context)内容回答问题。
如果你不知道答案,就回答不知道,不要试图编造答案。
{context}
问题:{question}
""")
print("load RetrievalQA")
# 第七步,进行相似度查询数据
retriever = database.as_retriever()
# 第八步,将数据和问题组成prompt格式,扔给大模型获取回答
qa = RetrievalQA.from_chain_type(llm=llm,retriever=retriever,verbose=True,chain_type_kwargs={"prompt": QA_CHAIN_PROMPT}
)
print("running... ...")
print(qa.run("ChatGLM是什么"))

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

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

相关文章

简单的同步压缩变换脊线检测(PythonMATLAB)

由于 Heisenberg 测不准原理,线性时频变换方法无法同时在时间和频率方向达到最佳的时频分布,窗函数和小波函数的选择也降低了各方法的自适应性。同样,二次型变换方法难以在去除交叉干扰项的同时保证较高的能量集中度。为了解决该问题&#xf…

MySQL的安装与配置

MySQL提供安装包和压缩包两种安装方式,安装包是以.msi作为后缀名的二进制分发文件,压缩包是以.zip为后缀的压缩文件。安装包的安装只要双击安装文件,然后按照提示一步步安装就可以了,属于“傻瓜”式安装;压缩包的安装需…

基于SpringBoot校园一卡通系统设计和实现(源码+LW+调试文档+讲解等)

💗博主介绍:✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 Java精品实战案例《600套》 2023-2025年最值得选择的Java毕业设计选题大全&#xff1…

World of Warcraft [CLASSIC] Level 70 Riding Skill

World of Warcraft http://account.battlenet.com.cn-CSDN博客 World of Warcraft [CLASSIC] Level 70 Riding Skill 魔兽世界【怀旧】70级骑术 部落如何学习70级骑术,如何区影月谷,影月村,怀旧一下 荆棘谷 暮色森林 逆风小径 悲伤沼泽 诅…

变工况下转子、轴承数据采集及测试

1.固定工况下的数据采集 1.wireshark抓包 通过使用 Wireshark 抓包和 Linux 端口重放技术,可以模拟实际机械设备的运行环境,从而减少实地验证软件和算法的复杂性和麻烦。 打开设备正常运转,当采集器通过网口将数据发送到电脑时&#xff0c…

ubuntu 编译交叉环境arm 版本的openssl库

一,下载源码 [ Old Releases ] - /source/old/index.html 二,设置交叉编译环境 我的交叉环境是RV1126开发板,/home/rpdzkj/development/cross-compile-tools/rv1126/ 对应的是我电脑里的RV1126开发板的交叉环境下的gc g等路径存放 设置环境…

5. zabbix分布式监控

zabbix分布式监控 一、zabbix分布式监控二、zabbix分布式监控部署1、环境描述2、zabbix proxy的部署2.1 安装zabbix proxy相关的软件2.2 创建proxy需要的库、导入表2.3 编辑zabbix proxy配置文件,指定数据库连接2.4 启动zabbix proxy 3、在zabbix server添加代理4、…

数据结构与算法基础(王卓)--学习笔记

1 数据结构分类 1.1 逻辑结构分类 集合结构线性结构:线性表、栈、队列、串树形结构图形结构 1.2 物理结构分类 逻辑结构在计算机中的真正表示方式(又称为映射)称为物理结构,也可叫做存储结构 顺序存储结构:数组链…

高德地图获取key值步骤

1、创建新应用 进入控制台(https://lbs.amap.com/dev/),创建一个新应用。 如果您之前已经创建过应用,可直接跳过这个步骤。 2、添加新Key 在创建的应用上分别填写key名称、选择服务平台、SHA1、以及PackageName SHA1:是在安卓…

【项目实训】解决前后端跨域问题

由于前端框架使用vue,后端使用flask,因此需要解决前后端通信问题 在vue.config.js中修改 module.exports defineConfig({transpileDependencies: true,lintOnSave:false, }) // 跨域配置 module.exports {devServer: { //记住&#x…

Omniverse 下载 isaac sim过慢的解决办法

比如在上海地区,下载isaac只有 200kb/s,这8个G下载要很长时间 对于着急的小伙伴,可以直接去日志里拿下载链接,在Omniverse里点右上角小人,点开里面SETTINGS,如图 点击,LOGS LOCATION&#xff0c…

海外仓一件代发效率提升方案:拣货区规划策略

作为海外仓的核心业务,一件代发处理的效率和准确性,可以说直接影响了海外仓的经济效益。今天我们就会针对大家都比较头疼的一件代发效率问题,给大家分享一些实用建议。 提升一件代发效率要考虑的3个关键要素 对以一件代发为主要业务的海外仓…

分布式系统:常见的陷阱和复杂性

分布式系统的复杂性是工程师和开发人员面临的重要挑战。复杂性往往会随着系统的发展而增加,因此积极主动非常重要。让我们来谈谈您可能会遇到哪些类型的复杂性以及在工作中应对它的有效策略。 分布式系统和复杂性 在开发中,分布式系统是相互连接并执行…

PyTorch入门:探索Tensor的基本操作(2)

torch.cat() a torch.zeros((2,4)) b torch.ones((2,4)) out torch.cat((a,b), dim1) print(out)运行结果如下: tensor([[0., 0., 0., 0., 1., 1., 1., 1.],[0., 0., 0., 0., 1., 1., 1., 1.]])torch.stack()&…

深度学习 --- stanford cs231学习笔记五(训练神经网络之数据的预处理)

数据的预处理(Data Preprocessing) 2 Data Preprocessing数据的预处理 数据预处理的几种方法 2,1 数据的零点中心化 数据的零点中心化的目的就是为了把数据的整体分布拉回到原点附近,也就是让数据的整体均值变为0。 ​ 2,2 数据的标准化 数据…

缓冲区溢出

本文作者:杉木涂鸦智能安全实验室 前置知识点 栈 栈(Stack)是计算机中的一种数据结构,用于存储临时数据。它的特点是后入先出(LIFO),只能在栈顶添加或删除数据。在程序中,栈被用于…

从一道算法题开始,爱上Python编程

Python是一门简单易学、高效强大的编程语言,许多人因为它的便捷性和广泛应用而爱上编程。今天,我将通过一道有趣的算法题,带领大家一步步写出Python代码,并最终解决问题。希望通过这篇文章,能激发大家对Python编程的兴…

[创业之路-131] :制造业企业的必备管理神器-ERP-ERP常见单据

目录 一、采购管理的ERP常见单据 1.1 请购单: 主要内容 作用 操作流程 1.2 采购订单(Purchase Order, PO): 1.3 采购合同(Purchase Contract): 1.4 采购发票(Purchase Invoi…

操纵系统的特征-线程的六种状态

线程的六种状态 线程是操作系统进行运算调度的最小单位,它可以分为六种状态 新建状态(NEW) 用new创建一个线程对象,这时候处于新建状态 可运行状态(RUNNABLE) 可运行状态又分为两种状态:就绪…

计算机网络模型(OSI架构、TCP/IP架构)

OSI开放式系统互联 为什么会有通用的网络通信模型(OSI、TCP/IP)一、OSI(1)OSI 是什么(2)OSI 七层第七层、应用层第六层、表示层第五层、会话层第四层、传输层第三层、网络层第二层、数据链路层第一层、物理…