AIGC:【LLM(四)】——LangChain+ChatGLM:本地知识库问答方案

文章目录

    • 一.文件加载与分割
    • 二.文本向量化与存储
      • 1.文本向量化(embedding)
      • 2.存储到向量数据库
    • 三.问句向量化
    • 四.相似文档检索
    • 五.prompt构建
    • 六.答案生成

LangChain+ChatGLM项目(https://github.com/chatchat-space/langchain-ChatGLM)实现原理如下图所示 (与基于文档的问答 大同小异,过程包括:1 加载文档 -> 2 读取文档 -> 3/4文档分割 -> 5/6 文本向量化 -> 8/9 问句向量化 -> 10 在文档向量中匹配出与问句向量最相似的top k个 -> 11/12/13 匹配出的文本作为上下文和问题一起添加到prompt中 -> 14/15提交给LLM生成回答 )
在这里插入图片描述

一.文件加载与分割

加载文件:这是读取存储在本地的知识库文件的步骤
读取文件:读取加载的文件内容,通常是将其转化为文本格式
文本分割(Text splitter):按照一定的规则(例如段落、句子、词语等)将文本分割

def _load_file(self, filename):# 判断文件类型if filename.lower().endswith(".pdf"):  # 如果文件是 PDF 格式loader = UnstructuredFileLoader(filename)   # 使用 UnstructuredFileLoader 加载器来加载 PDF 文件text_splitor = CharacterTextSplitter()      # 使用 CharacterTextSplitter 来分割文件中的文本docs = loader.load_and_split(text_splitor)  # 加载文件并进行文本分割else:          # 如果文件不是 PDF 格式loader = UnstructuredFileLoader(filename, mode="elements")  # 使用 UnstructuredFileLoader 加载器以元素模式加载文件text_splitor = CharacterTextSplitter()      # 使用 CharacterTextSplitter 来分割文件中的文本docs = loader.load_and_split(text_splitor)  # 加载文件并进行文本分割return docs    # 返回处理后的文件数据

二.文本向量化与存储

1.文本向量化(embedding)

这通常涉及到NLP的特征抽取,可以通过诸如TF-IDF、word2vec、BERT等方法将分割好的文本转化为数值向量。

# 初始化方法,接受一个可选的模型名称参数,默认值为 Nonedef __init__(self, model_name=None) -> None:  if not model_name:  # 如果没有提供模型名称# 使用默认的嵌入模型# 创建一个 HuggingFaceEmbeddings 对象,模型名称为类的 model_name 属性self.embeddings = HuggingFaceEmbeddings(model_name=self.model_name)

2.存储到向量数据库

文本向量化之后存储到数据库vectorstore。

def init_vector_store(self):persist_dir = os.path.join(VECTORE_PATH, ".vectordb")  # 持久化向量数据库的地址print("向量数据库持久化地址: ", persist_dir)              # 打印持久化地址# 如果持久化地址存在if os.path.exists(persist_dir):  # 从本地持久化文件中加载print("从本地向量加载数据...")# 使用 Chroma 加载持久化的向量数据vector_store = Chroma(persist_directory=persist_dir, embedding_function=self.embeddings)  # 如果持久化地址不存在else:      # 加载知识库documents = self.load_knownlege()  # 使用 Chroma 从文档中创建向量存储vector_store = Chroma.from_documents(documents=documents, embedding=self.embeddings,persist_directory=persist_dir)  vector_store.persist()      # 持久化向量存储return vector_store             # 返回向量存储def load_knownlege(self):docments = []         # 初始化一个空列表来存储文档# 遍历 DATASETS_DIR 目录下的所有文件for root, _, files in os.walk(DATASETS_DIR, topdown=False):for file in files:filename = os.path.join(root, file)      # 获取文件的完整路径docs = self._load_file(filename)         # 加载文件中的文档# 更新 metadata 数据new_docs = []             # 初始化一个空列表来存储新文档for doc in docs:# 更新文档的 metadata,将 "source" 字段的值替换为不包含 DATASETS_DIR 的相对路径doc.metadata = {"source": doc.metadata["source"].replace(DATASETS_DIR, "")} print("文档2向量初始化中, 请稍等...", doc.metadata)  # 打印正在初始化的文档的 metadatanew_docs.append(doc)  # 将文档添加到新文档列表docments += new_docs      # 将新文档列表添加到总文档列表return docments      # 返回所有文档的列表

三.问句向量化

这是将用户的查询或问题转化为向量,应使用与文本向量化相同的方法,以便在相同的空间中进行比较 。

四.相似文档检索

在文本向量中匹配出与问句向量最相似的top k个,这一步是信息检索的核心,通过计算余弦相似度、欧氏距离等方式,找出与问句向量最接近的文本向量。

def query(self, q):"""在向量数据库中查找与问句向量相似的文本向量"""vector_store = self.init_vector_store()docs = vector_store.similarity_search_with_score(q, k=self.top_k)for doc in docs:dc, s = docyield s, dc

五.prompt构建

匹配出的文本作为上下文和问题一起添加到prompt中,这是利用匹配出的文本来形成与问题相关的上下文,用于输入给语言模型。

六.答案生成

最后,将这个问题和上下文一起构成的prompt提交给在线(例如GPT-4/ChatGPT)或本地化部署大语言模型,让它生成回答。

class KnownLedgeBaseQA:# 初始化def __init__(self) -> None:k2v = KnownLedge2Vector()      # 创建一个知识到向量的转换器self.vector_store = k2v.init_vector_store()     # 初始化向量存储self.llm = VicunaLLM()         # 创建一个 VicunaLLM 对象# 获得与查询相似的答案def get_similar_answer(self, query):# 创建一个提示模板prompt = PromptTemplate(template=conv_qa_prompt_template, input_variables=["context", "question"]  # 输入变量包括 "context"(上下文) 和 "question"(问题))# 使用向量存储来检索文档retriever = self.vector_store.as_retriever(search_kwargs={"k": VECTOR_SEARCH_TOP_K}) docs = retriever.get_relevant_documents(query=query)  # 获取与查询相关的文本context = [d.page_content for d in docs]     # 从文本中提取出内容result = prompt.format(context="\n".join(context), question=query) # 格式化模板,并用从文本中提取出的内容和问题填充return result                 # 返回结果

这种通过组合langchain+LLM的方式,特别适合一些垂直领域或大型集团企业搭建通过LLM的智能对话能力搭建企业内部的私有问答系统,也适合个人专门针对一些英文paper进行问答,比如比较火的一个开源项目:ChatPDF,其从文档处理角度来看,实现流程如下(图源):
在这里插入图片描述

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

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

相关文章

Python连接Hive实例教程

一 Python连接hive环境实例 经在网络查询相关的教程,发现有好多的例子,发现连接底层用的的驱动基本都是pyhive和pyhs2两种第三方库的来连接的 hive,下面将简介windows 10 python 3.10 连接hive的驱动程序方式,开发工具:pycharm …

架构实践方法

一、识别复杂度 将主要的复杂度问题列出来,然后根据业务、技术、团队等综合情况进行排序,优先解决当前面临的最主要的复杂度问题。对于按照复杂度优先级解决的方式,存在一个普遍的担忧:如果按照优先级来解决复杂度,可…

List list=new ArrayList()抛出的ArrayIndexOutOfBoundsException异常

1.应用场景,今天生产日志监控到一组new ArrayList() 进行add 异常,具体日志如下: eptionHandler.handler(178): TXXYBUSSINESS|执行异常 java.util.concurrent.CompletionException: java.lang.ArrayIndexOutOfBoundsException: Index 1 out…

银河麒麟QT连接DM8数据库

1. 安装达梦8 官网下载, 按照官方文档进行安装即可. 2. 安装unixodbc 1> 下载odbc安装包 unixODBC-2.3.7pre.tar.gz 2> 解压 tar -xvf unixODBC-2.3.7pre.tar.gz3> 编译 ./configure -prefix /usr/local make && make install4> 查找配置 odbcinst -j5…

【从零学习python 】04. Python编程基础:变量、数据类型与标识符

文章目录 变量以及数据类型一、变量的定义二、变量的类型三、查看数据类型 标识符和关键字标识符命名规则命名规范 关键字进阶案例 变量以及数据类型 一、变量的定义 对于重复使用,并且经常需要修改的数据,可以定义为变量,来提高编程效率。…

代码随想录算法训练营第51天|动态规划part09|198.打家劫舍、213.打家劫舍II、337.打家劫舍III

代码随想录算法训练营第51天|动态规划part09|198.打家劫舍、213.打家劫舍II、337.打家劫舍III 198.打家劫舍 198.打家劫舍 思路: 仔细一想,当前房屋偷与不偷取决于 前一个房屋和前两个房屋是否被偷了。 所以这里就更感觉到&a…

鉴源论坛·观模丨形式化方法的工业应用:轨交领域

作者 | 王依玲 上海控安可信软件创新研究院系统建模组 版块 | 鉴源论坛 观模 社群 | 添加微信号“TICPShanghai”加入“上海控安51fusa安全社区” 引言:前面几期文章介绍了形式化方法的发展历史和具体技术,并从整体的角度介绍了形式化方法的工程化。本…

SpringBoot 的事务及使用

一、事务的常识 1、事务四特性(ACID) A 原子性:事务是最小单元,不可再分隔的一个整体。C 一致性:事务中的方法要么同时成功,要么都不成功,要不都失败。I 隔离性:多个事务操作数据库中同一个记录或多个记录时,对事务进…

TikTok推出PrivacyGo,品牌可与平台共享部分用户数据

1.TikTok宣布允许用户关闭内容自动显示功能 TikTok近日宣布修改运营方式,即允许用户关闭内容自动显示功能,以遵守将于8月底生效的欧盟新规定(欧盟数字服务法案DSA),该法案对平台提出了新的要求,以更好地保…

.NET 应用程序 部署

**硬件支持型号 点击 查看 硬件支持 详情** DTU701 产品详情 DTU702 产品详情 DTU801 产品详情 DTU802 产品详情 DTU902 产品详情 G5501 产品详情 本文内容 在设备上部署 dotnet应用,与任何其他平台的部署相同,可以2种方式: 依赖于框…

适配器模式来啦

网上的大多数的资料中适配器模式和代理模式都是紧挨着进行介绍的,为什么呢??? 是因为适配器模式和代理模式有太多的相似之处,可以进行联动记忆但是也要做好区分。 在菜鸟教程中,适配器模式的定义是作为两…

数学类问题(Leetcode)

1.质数数量 nullhttps://leetcode.cn/problems/count-primes/description/解题思路&#xff1a; 遍历大于1 且小于n的每个数的倍数&#xff0c;设置为非质数&#xff0c;剩下的就都是质数了。 代码&#xff1a; class Solution { public:int countPrimes(int n) {if(n<2)…

【机器学习2】什么是Jupyter notebook 新手使用Jupter notebook

什么是Jupyter notebook? Jupyter Notebook&#xff08;此前被称为 IPython notebook&#xff09;是一个交互式笔记本&#xff0c;支持运行 40 多种编程语言。 Jupyter Notebook 的本质是一个 Web 应用程序&#xff0c;便于创建和共享程序文档&#xff0c;支持实时代码&#x…

机器学习实战13-超导体材料的临界温度预测与分析(决策树回归,梯度提升回归,随机森林回归和Bagging回归)

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下机器学习实战13-超导体材料的临界温度预测与分析(决策树回归,梯度提升回归,随机森林回归和Bagging回归)&#xff0c;这几天引爆网络的科技大新闻就是韩国科研团队宣称发现了室温超导材料-LK-99&#xff0c;这种材料…

Redisson 3.23.1 正式发布,官方推荐的 Redis 客户端

导读Redisson 3.23.1 现已发布&#xff0c;这是一个 Java 编写的 Redis 客户端&#xff0c;具备驻内存数据网格&#xff08;In-Memory Data Grid&#xff09;功能&#xff0c;并获得了 Redis 的官方推荐。 此版本更新内容如下&#xff1a; Improvement 减少了 RLiveObjectSer…

决策树和随机森林对比

1.用accuracy来对比 # -*-coding:utf-8-*-""" accuracy来对比决策树和随机森林 """ from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import RandomForestClassifier from sklearn.datasets import load_wine#(178, 13…

K8S系列文章之 自动化运维利器 Ansible

Ansible-安装 第一步&#xff1a;安装我们的epel扩展源 yum -y install epel-release 我这里会报/var/run/yum.pid 已被锁定&#xff0c;如果没有直接进行下一步 [rootmaster home]# yum -y install epel-release 已加载插件&#xff1a;fastestmirror, langpacks /var/run/…

C语言 用数组名作函数参数

当用数组名作函数参数时&#xff0c;如果形参数组中各元素的值发生变化&#xff0c;实参数组元素的值随之变化。 1.数组元素做实参的情况&#xff1a; 如果已经定义一个函数&#xff0c;其原型为 void swap(int x,int y);假设函数的作用是将两个形参&#xff08;x,y&#xf…

【css】组合器

组合器是解释选择器之间关系的某种机制。在简单选择器器之间&#xff0c;可以包含一个组合器&#xff0c;从而实现简单选择器难以达到的效果。 CSS 中有四种组合器&#xff1a; 后代选择器 (空格)&#xff1a;匹配属于指定元素后代的所有元素&#xff0c;示例&#xff1a;div …

GWJDN-400型2MHZ自动平衡高温介电温谱仪

GWJDN-400型2MHZ自动平衡高温介电温谱仪 关键词&#xff1a;介电常数&#xff0c;高温介电&#xff0c;自动平衡 主要功能&#xff1a; 材料介电常数测试仪 半导体材料的介电常数、导电率和C-V特性液晶材料:液晶单元的介电常数、弹性常数等C-V特性 性能特点: 温度&#xf…