LLM RAG 多种方式装载LLM的实践

一、大模型系统中检索增强生成(RAG)的意义

当前大模型在处理特定领域或者高度专业化的查询时表现出知识缺失,当所需信息超出模型训练数据范围或需要最新数据时,大模型可能无法提供准确答案。基于行业SOP、行业标准、互联网实时信息等领域外部知识构建私域知识向量模型,设计RAG系统用于多文档、多源数据、多维数据的检索器,设计优化双编码、联合编码等方法的信息生成器,使得生成组件能够更深入地理解问题背后的上下文,并产生更加信息丰富的回答。

二、LLM-RAG的框架设计

整体框架包括 大部分:私域知识的嵌入;文档知识的分割;私域知识的向量化;大模型的装载;问答链的组装;
在这里插入图片描述
1、私域知识的嵌入
借助langchain及llama-index开发框架可满足目前大部分知识形式的嵌入,包括数据库、PDF、word、excel、csv、txt、markdown、知识图谱(neo4j)、图片等。
在这里插入图片描述
Llama-index提供的知识嵌入工具
在这里插入图片描述
Langchain 知识嵌入工具
2、文档知识的分割
我们知道目前的大模型对处理信息的多少有限制,输入到大模型系统内的信息量及其组合将直接影响大模型给出答案的相关性、准确性和及时性。因此对文档知识的合理分割是提升大模型检索增强及生成问答的关键。
文本分割主要考虑两个因素:1)embedding模型的Tokens限制情况;2)语义完整性对整体的检索效果的影响。一些常见的文本分割方式如下:
句分割:以”句”的粒度进行切分,保留一个句子的完整语义。常见切分符包括:句号、感叹号、问号、换行符等。
固定长度分割:根据embedding模型的token长度限制,将文本分割为固定长度(例如256/512个tokens),这种切分方式会损失很多语义信息,一般通过在头尾增加一定冗余量来缓解。

text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=150)
split_docs = text_splitter.split_documents(docs)

3、私域知识的向量化
向量化是一个将文本数据转化为向量矩阵的过程,该过程会直接影响到后续检索的效果。目前常见的embedding模型如表中所示,这些embedding模型基本能满足大部分需求,但对于特殊场景(例如涉及一些罕见专有词或字等)或者想进一步优化效果,则可以选择开源Embedding模型微调或直接训练适合自己场景的Embedding模型。
在这里插入图片描述
知识向量化的几种方式:

#modelscope下载:国内推荐
from langchain.embeddings import ModelScopeEmbeddings
model_id = "damo/nlp_corom_sentence-embedding_chinese-base"
#damo/nlp_corom_sentence-embedding_chinese-base
#damo/nlp_corom_sentence-embedding_english-base
embeddings = ModelScopeEmbeddings(model_id=model_id)
#hunggingface下载:国外推荐
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")
#from langchain.embeddings import SentenceTransformerEmbeddings
#embeddings = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
# 构建向量数据库
# 加载数据库
vectordb = Chroma.from_documents(documents=split_docs,embedding=embeddings,)

4、大模型的装载
目前基于大模型的应用开发有多种框架,如何根据硬件、场景需求等高效、便捷装载大模型是开发LLM-RAG系统的关键。以下汇总了多种装载方式:
1)基于llama.cpp的cpu低成本装载:主要模型文件来自于hunggingface;
2)基于chatglm.cpp的CPU低成本装载:包括langchian[api]、openai[api]等形式。
3)基于langchain及Hugging Face Local Pipelines装载:支持的模型参考langchian文档中心。
5、问答链的组装
同样的,langchain为我们准备了一些构造好的问答链(langchain chains),包括sql数据库查询链、CSV查询链、html查询链、问答链等。

三、LLM-RAG的实践

1、多种方式低成本装载LLM
① langchain local_model形式

from langchain.llms.base import LLM
from typing import Any, List, Optional
from langchain.callbacks.manager import CallbackManagerForLLMRun
from transformers import AutoTokenizer, AutoModelForCausalLM,pipeline
import torch
from langchain.llms.huggingface_pipeline import HuggingFacePipeline
model_path = "Qwen/Qwen-1_8B-Chat"
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(model_path, trust_remote_code=True).to(torch.bfloat16).cuda(0)
pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=200000)
llm = HuggingFacePipeline(pipeline=pipe)

② langchain chatglm.cpp形式
参考chatglm.cpp GitHub网站:https://github.com/li-plus/chatglm.cpp

#安装chatglm.cpp库
!pip install --upgrade pip
!pip install chatglm.cpp[api]
#下载chatglm3-6b cpu量化文件
!git clone https://www.modelscope.cn/tiansz/chatglm3-6b-ggml.git
#启动 chatglm3-6b langchain-api服务
MODEL=./chatglm3-6b-ggml/chatglm3-ggml.bin uvicorn chatglm_cpp.langchain_api:app --host 127.0.0.1 --port 8000

获得chatglm3-6b langchain-api服务地址:http://127.0.0.1:8000
将chatglm3-6b接入langchain框架

endpoint_url = "http://127.0.0.1:8000"
llm = ChatGLM(endpoint_url=endpoint_url,max_token=1024,history=[["我是数据分析师,可以向我查询任何关于数据分析的问题。"]],top_p=0.9,model_kwargs={"sample_model_args": False},
)

③ langchian llama.cpp形式
llama.cpp是使用原始C ++的项目来重写LLaMa(长格式语言模型)等开源大模型推理代码。这使得可以在各种硬件上本地运行大模型。

#安装llama-cpp
!pip install llama-cpp-python
#从modelscope或者hunggingface下载量化模型:gguf
from modelscope.hub.file_download import model_file_download
model_dir = model_file_download(model_id='mikeee/TheBloke-openbuddy-zephyr-7B-v14.1-GGUF',file_path='openbuddy-zephyr-7b-v14.1.Q4_K_S.gguf',cache_dir='./Qwen')
#载入大模型
from langchain.llms import LlamaCpp
from langchain.prompts import PromptTemplate
from langchain.callbacks.manager import CallbackManager
callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])n_gpu_layers =0  # Change this value based on your model and your GPU VRAM pool.
n_batch = 5120  # Should be between 1 and n_ctx, consider the amount of VRAM in your GPU.
callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])
# Make sure the model path is correct for your system!
llm = LlamaCpp(model_path="./Qwen/mikeee/TheBloke-openbuddy-zephyr-7B-v14.1-GGUF/openbuddy-zephyr-7b-v14.1.Q4_K_S.gguf",n_gpu_layers=n_gpu_layers,n_batch=n_batch,max_tokens=200000,n_ctx=8912,callback_manager=callback_manager,verbose=True,  # Verbose is required to pass to the callback manager
)

2、私有知识的装载及向量化
① 多文档处理

#装载文件
def get_doc(dir_path):file_lst = os.listdir(dir_path)docs = []i = 1for file in file_lst:file_type = file.split('.')[-1]#print(file_type)if  file_type == 'docx':loader = UnstructuredWordDocumentLoader(dir_path+'/'+file)elif file_type == 'csv':loader = UnstructuredCSVLoader(dir_path+'/'+file)elif file_type == 'pdf':loader = UnstructuredPDFLoader(dir_path+'/'+file)else:# 如果是不符合条件的文件,直接跳过continuedocs.extend(loader.load())print(str(i)+'-----'+file+'------完成装载')i = +1return docs

文档分割及向量化

#载入开源向量化模型
from langchain.embeddings import ModelScopeEmbeddings
model_id = "damo/nlp_corom_sentence-embedding_chinese-base"
#damo/nlp_corom_sentence-embedding_chinese-base
#damo/nlp_corom_sentence-embedding_english-base
embeddings = ModelScopeEmbeddings(model_id=model_id)
#文档分割
docs = get_doc('./Qwen')
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=150)
#文档向量化
split_docs = text_splitter.split_documents(docs)
vectordb = Chroma.from_documents(documents=split_docs,embedding=embeddings)

② 单文档处理

#pdf
loader = UnstructuredPDFLoader('./Qwen/2304.08485.pdf')
docs=loader.load()
#docx
loader = UnstructuredWordDocumentLoader('./Qwen/《主数据质量检查报告》LL.docx')
docs=loader.load()
#csv
from langchain.document_loaders.csv_loader import CSVLoader
loader = CSVLoader(file_path="./Qwen/正则式.csv")
docs = loader.load()
#web文件
from langchain.document_loaders import AsyncHtmlLoader
urls = ["https://price.21food.cn/yurou/", "https://price.21food.cn/fushipin/"]
loader = AsyncHtmlLoader(urls)
docs = loader.load()

3、文档:RAG Q&A
使用 RetrievalQA 作为问答链

from langchain.prompts import PromptTemplate# 我们所构造的 Prompt 模板
template = """你是一个数据治理工程师同时也是一个知识搜索查询工程师,请根据可参考的上下文回答用户的问题,如果用户的问题不清晰且不是给定的上下文覆盖的,请不要乱回答,请回答 抱歉!我尚未学习该知识。
问题: {question}
可参考的上下文:
···
{context}
···
基于用户给定的信息,重新汇总上下文生成精准的回答。
如果给定的上下文无法让你做出回答,请回答你不知道。
有用的回答:"""
# 调用 LangChain 的方法来实例化一个 Template 对象,该对象包含了 context 和 question 两个变量,在实际调用时,这两个变量会被检索到的文档片段和用户提问填充
QA_CHAIN_PROMPT = PromptTemplate(input_variables=["context","question"],template=template)from langchain.chains import RetrievalQA
qa_chain = RetrievalQA.from_chain_type(llm,retriever=vectordb.as_retriever(),return_source_documents=True,chain_type_kwargs={"prompt":QA_CHAIN_PROMPT})
#Q&A
question = "千信金属产业园主要业务数据以及业务术语有哪些?"
result = qa_chain({"query": question})
print("检索问答链回答 question 的结果:")
print(result["result"])

使用 ConversationalRetrievalChain 问答链检索增强生成

from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
bot = ConversationalRetrievalChain.from_llm(llm, retriever=vectordb.as_retriever(),memory=memory,verbose=True,return_source_documents=False)query = "根基提供的上下文,千信产业园主要业务术语及主数据,并给出数据治理的建议"
result = bot.invoke({"question": query})
result["answer"]

4、问答结果探讨
将某企业的数据治理方向的一些文档做成私有知识库,基于私有知识库回答数据治理方面的问题。
在这里插入图片描述
私有知识库文档
问题一:

query = "根基提供的上下文,千信产业园主数据质量分析情况"
result = bot.invoke({"question": query})
result["answer"]

结果分析:对于私有知识库内确定的知识,整个RAG系统能比较精准的定位检索到用户问题所需的文档及文档块,并给出精准的答案。
在这里插入图片描述
问题二:

query = "根基提供的上下文,千信产业园仓储管理系统主数据质量评分都是多少"
result = bot.invoke({"question": query})
result["answer"]

结果分析:对于文档内存在的表格,目前简单的检索链和问答链无法给出精准的回答,分析原因应该是表格数据的检索还是需要使用CSV文件的嵌入以及CSV-chain才能获取精准的答案。
在这里插入图片描述

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

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

相关文章

【Android 10】 BatteryController

学习了一下电池的相关模式,也就是它的观察者模式,先附上图 图应该挺清晰的,BatteryControllerImpl就是被观察者,BatteryControllerImpl重写了CallbackController的两个方法用于添加或移除观察者。 void addCallback(T listener);…

vivado 预设文件、IP设置(_P)、用户参数、以太网时钟处理、GT位置限制、当前可识别板的IP列表

了解预设文件 预设文件有助于在特定配置中自定义IP核心。PS7、axi_emc和当linear_flash或DDR3_SDRAM 界面是在Vivado IP集成商的Board选项卡中选择的。预设文件使用XML格式。preset_file是为特定的Board文件定义的&#xff0c;可以是用于将预设应用于多个IP。 <ip_presets…

UG制图-视图与投影

当我们进入图纸页后&#xff0c;我们需要对产品进行投影然后进行标注 注意&#xff1a;如果是从零件3D中直接进入制图&#xff0c;默认情况下图框所在的图层是不显示的&#xff0c;我们可以通过菜单或者快捷键ctrl L进入图层设置模块&#xff0c;将图层170和173勾选为显示 我…

解开缺省参数与函数重载的衣裳

解开缺省参数与函数重载的衣裳 代码是如何由编译器变为可执行文件&#xff1f;预处理 ->编译->汇编->链接预处理编译汇编链接 语法了解缺省参数语法实践语法探究函数重载语法实践语法探究结语 本期和大家一起探究C中的缺省函数与重载函数的语法说明与汇编过程代码是如…

[java基础揉碎]位运算符

java中有7个位运算&#xff08;&、|、^、~、>>、<<和>>>&#xff09; 第一组 分别是按位与&、按位或|、按位异或^&#xff0c;按位取反~&#xff0c;它们的运算规则是&#xff1a; 按位与& : 两位全为1&#xff0c;结果为1&#xff0c;否则…

蓝桥杯官网填空题(奇怪的分式)

题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 上小学的时候&#xff0c;小明经常自己发明新算法。一次&#xff0c;老师出的题目是&#xff1a;1/4乘以8/5 小明居然把分子拼接在一起&#xff0c;分母拼接在一起&…

基于SpringBoot的高校学科竞赛平台管理系统

基于SpringBoot的高校学科竞赛平台管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 前台界面 管理员界面 教师界面 学生界面 摘要 本文详细介绍了一款基于…

革新区块链:代理合约与智能合约升级的未来

作者 张群&#xff08;赛联区块链教育首席讲师&#xff0c;工信部赛迪特聘资深专家&#xff0c;CSDN认证业界专家&#xff0c;微软认证专家&#xff0c;多家企业区块链产品顾问&#xff09;关注张群&#xff0c;为您提供一站式区块链技术和方案咨询。 代理合约&#xff08;Prox…

开源项目_大模型应用_Chat2DB

1 基本信息 项目地址&#xff1a;https://github.com/chat2db/Chat2DBStar&#xff1a;10.7K 2 功能 Chat2DB 是一个智能且多功能的 SQL 客户端和报表工具&#xff0c;适用于各种数据库。 对于那些平时会用到数据库&#xff0c;但又不是数据库专家的程序员来说&#xff0c;…

盘点几种有线扩展Wifi覆盖范围方式的优缺点

前言 前几天小白到一个朋友的家里&#xff0c;发现她家的主路由是放在玄关的。 这个方式就导致了她家三个卧室的Wifi信号都很弱。 她叫我过去帮忙弄一下网络的问题&#xff0c;这个对于有一点电脑知识的小伙伴来说&#xff0c;基本上不是什么难事&#xff0c;因为每个房间基本…

AVL树底层实现

目录 AVL树简介 AVL树节点定义​编辑 AVL树特性 AVL树的建立 AVL树的插入 AVL树的旋转 验证AVL树 AVL树的实现&#xff08;代码部分&#xff09; AVL树简介 AVL树是对二叉搜索树的改进&#xff0c;二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序…

PDsehell16连接pgsql出现“Could not initialize JavaVM“时的解决步骤

问题原因:PowerDesigned16是32位的&#xff0c;只能使用32位的JDK来运行JDBC驱动 解决方案&#xff1a; 一、弄一个32为jdk的免安装包 二、 接下来就是配置系统环境变量了&#xff08;注意是系统不是用户环境变量&#xff09; JAVA_HOME配置刚刚32位的存放地址&#xff0c; …

(二十四)Kubernetes系列之Helm3

Helm为kubernetes的包管理工具&#xff0c;就像Linux下的包管理器&#xff08;yum/apt等&#xff09;&#xff0c;可以很方便的将之前打包好的yaml文件部署到kubernetes上。 1.安装访问地址&#xff1a;https://github.com/helm/helm/releases 点击查看最新的版本&#xff0c…

文件操作与IO(3)

文件内容的读写--数据流 这里我们将要讲到文件操作中的重要概念--流. 之前也在C语言讲解中提到了文件流的概念---读写文件内容 分为这几步:(1)打开文件;(2)读/写文件;(3)关闭文件. 数据流主要分为字节流和字符流. 字节流:以字节为单位进行读写(代表:InputStream,OutputStrea…

【Java网络编程01】网络原理初识

【Java网络编程01】网络原理初识 1. 网络通信基础概念 网络通信&#xff1a;网络互连的目的就是网络通信&#xff0c;即网络数据传输&#xff0c;再直白点而言就是不同主机的不同进程之间基于网络进行数据的传输交互。 那么&#xff0c;在组建的网络上有各种各样的主机&#…

Python量化交易- mplfinance库 -画K线图

mplfinance库 1. mplfinance 模块说明2. mplfinance安装3. mplfinance 模块 plot 基本用法参数typestylemake_addplot设置图表颜色 make_marketcolors添加图表样式 make_mpf_style 4. mplfinance 的基本K线图实现自定义风格和颜色图表尺寸调整、相关信息的显示添加完整移动平均…

Vue 实例创建流程

✨ 专栏介绍 在当今Web开发领域中&#xff0c;构建交互性强、可复用且易于维护的用户界面是至关重要的。而Vue.js作为一款现代化且流行的JavaScript框架&#xff0c;正是为了满足这些需求而诞生。它采用了MVVM架构模式&#xff0c;并通过数据驱动和组件化的方式&#xff0c;使…

CentOs7 安装Mysql(5.7和8.0版本)密码修改跳过 超详细教程

CSDN 成就一亿技术人&#xff01; 今天出一期Centos下安装Mysql&#xff08;详细教程&#xff09;包括数据库密码跳过修改 CSDN 成就一亿技术人&#xff01; 目录 1.获取安装包 2.安装程序 安装下载的rpm包 查看安装包 修改5.7版本&#xff08;重要&#xff09; 安装M…

设置代码模板创建sql映射文件、Mybatis主配置文件

目录 1、Sql映射&#xff08;Sql Mapper&#xff09;文件的介绍 2、Mybatis的主配置文件的介绍 3、通过代码模板创建Sql映射文件 4、通过代码模板创建Mybatis主配置文件 1、Sql映射&#xff08;Sql Mapper&#xff09;文件的介绍 <?xml version"1.0" encod…

太太二字的由来?

“太太”这个称谓的由来可以追溯到周朝时期的“周室三母”。这三位贤妃分别是太姜、太任和太姒。她们以母仪天下的德范&#xff0c;养育和辅佐了开创太平盛世的数位君王&#xff0c;成为了夫君的良佐、胎教的典范。因此&#xff0c;后世尊称别人的妻子为“太太”&#xff0c;以…