前言
今天学习了《用LangChain快速构建基于“易速鲜花”本地知识库的智能问答系统》,正好利用这个机会写一篇笔记记录一下知识点,顺便完成一下课后的思考题。
用LangChain快速构建基于“易速鲜花”本地知识库的智能问答系统
在这一节的课程中,主要是介绍了怎么基于LangChain搭建一个基本本地知识库的问答系统。之所以要搭建这样一个系统,是因为一般的大模型是在复杂多样的文本数据上进行训练的,如各种书籍文本,从互联网爬取的文本等。但是如果是针对某个企业,想打造企业内部的大模型的话,通用的大模型就无法胜任了。
打造专属大模型也有两条路线。分别是 对大模型进行微调 和 使用检索信息增强(RAG) 这两种方法。基于微调的方法流程更加复杂,要准备微调数据集和硬件资源,并且微调的结果也并不是一定能达到预期。而基于RAG的方法更加方便快捷,只需要准备 本地知识库 ,然后使用LangChain和大模型搭建检索链就可以实现。
在这篇笔记中,和课程类似的知识就不再赘述了,主要是回答一下思考题。
1. 请你用自己的话简述一下这个基于文档的QA(问答)系统的实现流程?
做一个简单的RAG(检索增强生成)问答系统,需要以下几个步骤:
1. 加载相关文档: 可以是各种格式的文本,如txt、pdf、doc、csv、xlsx等。然后把它们用langchain_community.document_loaders的几个依赖加载到一个列表中。
2. 分割文档: 将文档列表按照需要进行分割,固定分割后的片段大小和重叠字符数。
3. 文档向量化并存储向量: 分割后的文档因为格式不是结构化的,所以需要用向量数据库进行存储。使用嵌入器将文本嵌入为向量,嵌入器可以选择openai的,也可以用其他模型的。在本次课程中的代码就是自己定义的doubao的嵌入器。数据库可以选择开源的向量数据库,如Qdrant、Chroma、Milvus等。使用向量数据库的原因是因为向量数据库可以存储和检索向量,而向量是由模型生成的,模型可以理解和生成文本。检索时可以使用余弦相似度和欧氏距离,但由于文本长度不一,并且余弦相似度更容易找到与问题方向更近的向量,所以一般使用余弦相似度进行检索。
4. 创建检索链: 实例化大模型,这个大模型可以是各种大模型的接口,实例方式和前面课程的一致;实例化多查询检索器MultiQueryRetriever,这可以将问题转换出多个相似问题,从而在检索过程中更容易检索到相关内容;构建检索链,把大模型和检索器作为参数传入RetrievalQA.from_chain_type函数。
5. 问答检索: 用户给出一个问题,问题首先进行文本嵌入,然后使用向量数据库检索最相关的文档。然后把问题和检索到的文档作为上下文,输入给大模型,再使用大模型的能力生成答案。
2. LangChain支持很多种向量数据库,你能否用另一种常用的向量数据库Chroma来实现这个任务?
这一部分就是替换向量数据库,但是要注意,Chroma的参数和Qdrant不尽相同,所以不能直接复制,需要根据实际要求传入参数。下面的代码段中,注释掉的是原来的Qdrant代码,Chroma的参数没有location,这个要注意。
from typing import Dict, List
from langchain_community.vectorstores import Chroma
# 需要修改一下DouBaoEmbeddings
class DoubaoEmbeddings(BaseModel, Embeddings):
client: Ark = None
api_key: str = ""
model: str
def __init__(self, **data: Dict) -> None: # 主要是这行Any改成Dict
# # 定义向量数据库Qdrant
# vectorstore = Qdrant.from_documents(
# documents=chunked_documents, # 传入分割后的文档列表
# embedding=DoubaoEmbeddings(model=os.environ["EMBEDDING_MODELEND"]), # 传入自定义的Embeddings类
# location=":memory:", # 向量数据库存储在内存中
# collection_name="my_documents" # 向量数据库的名称
# )
# 使用chroma向量数据库
vectorstore = Chroma.from_documents(
documents=chunked_documents, # 传入分割后的文档列表
embedding=DoubaoEmbeddings(model=os.environ["EMBEDDING_MODELEND"]), # 传入自定义的Embeddings类
collection_name="my_documents" # 向量数据库的名称
)
如果直接替换代码,在AI练中学直接运行的话,可能会出现一些库版本不兼容的情况,处理起来还是有些麻烦的。直接运行上述代码会出现sqlite3版本不匹配的错误,要求大于3.50,因但是AI练中学只能更新到3.47,所以需要先安装一个库pip install pysqlite3-binary,然后修改一下chromadb库中的一些代码,打开下面这个文件,/home/cloudide/.local/lib/python3.12/site-packages/chromadb/__init__.py,在开头添加下面的代码即可。具体的修改方法参考这个链接。
__import__('pysqlite3')
import sys
sys.modules['sqlite3'] = sys.modules.pop('pysqlite3')
然后就可以运行了!
3. LangChain支持很多种大语言模型,你能否用HuggingFace网站提供的开源模型 google/flan-t5-xl 代替GPT-3.5完成这个任务?
这里就是替换大模型,并且需要一个hugging face账号,注册之后,要在设置里面生成一个token,让代码可以访问huggingface中的模型,但是AI练中学有可能访问不了hf,所以可以通过环境变量设置镜像export HF_ENDPOINT=https://hf-mirror.com。而且我还想吐个槽,模型名是flan-t5-xl,但是题目打成了flan-t5-x1,帮助别的同学避个坑,别抄错了。
代码如下:
import os
from langchain_community.llms import HuggingFaceHub
os.environ["HUGGINGFACEHUB_API_TOKEN"] = "your_token"
# 实例化大模型,,调用豆包的API
# llm = ChatOpenAI(
# model=os.environ["LLM_MODELEND"],
# temperature=0
# )
# 设置 Hugging Face Hub token,确保有 Hugging Face 帐号
llm = HuggingFaceHub(
repo_id="google/flan-t5-xl",
model_kwargs={"temperature": 0, "max_length": 200}
)