基于 VLLM、LangChain 和 FAISS 构建知识库问答系统
·
环境准备
在开始之前,确保你的开发环境已经安装了以下必要的库和工具:
- Python:3.10.0
- vllm:0.4.1+cu118
- numba:0.62.1
- langchain:0.3.27
- langchain-community:0.3.27
- langchain-core:0.3.75
- langchain-openai:0.3.27
- langchain-text-splitters:0.3.11
- langsmith:0.4.34
- faiss:用于高效相似性搜索
- fitz(PyMuPDF):用于处理 PDF 文件
你可以使用以下命令来安装这些依赖项:
pip install python==3.10.0 vllm==0.4.1+cu118 numba==0.62.1 langchain==0.3.27 langchain-community==0.3.27 langchain-core==0.3.75 langchain-openai==0.3.27 langchain-text-splitters==0.3.11 langsmith==0.4.34 faiss fitz
启动 VLLM 服务器
首先,我们需要启动一个 VLLM 服务器,用于提供模型推理服务。运行以下命令来启动服务器:
python -m vllm.entrypoints.openai.api_server \
--model Qwen/Qwen2.5-1.5B-Instruct \
--port 8000 \
--dtype float16 \
--gpu-memory-utilization 0.8
这将启动一个监听 8000 端口的服务器,使用 Qwen2.5-1.5B-Instruct 模型进行推理。
构建知识库
接下来,我们需要从 PDF 文件中提取文本内容,并将其存储到 FAISS 索引中。以下是完整的代码:
import faiss
import fitz # PyMuPDF
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.schema import Document
import os
# 定义保存路径和文件夹路径
save_path = "/home/AI/yuanxianpeng/vllm/faiss_index"
folder = "/home/AI/yuanxianpeng/vllm/docs/"
texts = []
# 读取 PDF 文件并提取文本
for filename in os.listdir(folder):
if filename.endswith(".pdf"):
file_path = os.path.join(folder, filename)
doc = fitz.open(file_path)
content = ""
for page in doc:
content += page.get_text()
if content.strip():
texts.append(content)
# 分割文本
splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = []
for text in texts:
chunks.extend(splitter.split_text(text))
# 转换为 Document 对象
doc_objects = [Document(page_content=chunk) for chunk in chunks]
# 向量化并存储到 FAISS 索引
embeddings_model = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
vector_store = FAISS.from_documents(doc_objects, embeddings_model)
vector_store.save_local(save_path)
代码解释
- 读取 PDF 文件:使用
fitz库读取指定文件夹中的 PDF 文件,并提取每一页的文本内容。 - 分割文本:使用
RecursiveCharacterTextSplitter将提取的文本分割成大小为 500 字符的块,块之间有 50 字符的重叠。 - 转换为 Document 对象:将每个文本块转换为
Document对象。 - 向量化并存储到 FAISS 索引:使用 Hugging Face 的
all-MiniLM-L6-v2模型将文本块向量化,并将向量化的文档存储到 FAISS 索引中。
构建问答系统
现在我们已经构建了知识库,接下来我们将构建问答系统。以下是完整的代码:
from langchain.chains import RetrievalQA
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_openai import ChatOpenAI
from langchain_community.vectorstores import FAISS
# 初始化嵌入模型
embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
# 加载本地 FAISS 索引
vector_store = FAISS.load_local("faiss_index", embeddings, allow_dangerous_deserialization=True)
# 初始化 LLM(语言模型)
llm = ChatOpenAI(
model_name="Qwen/Qwen2.5-1.5B-Instruct", # 与 vLLM 加载名保持一致
openai_api_key="EMPTY", # vLLM 不校验可随意
openai_api_base="http://localhost:8000/v1",
temperature=0.7,
max_tokens=256,
)
# 构建问答系统
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=vector_store.as_retriever(search_kwargs={"k": 3}),
return_source_documents=True
)
# 提出问题并获取答案
query = "陆士曾是谁?"
result = qa_chain({"query": query})
print(result)
代码解释
- 加载 FAISS 索引:使用
FAISS.load_local方法加载之前保存的 FAISS 索引。 - 初始化 LLM:使用
ChatOpenAI初始化语言模型,指定模型名称、API 基地址、温度参数和最大生成的 token 数量。 - 构建问答链:使用
RetrievalQA.from_chain_type方法构建问答链,指定语言模型、链类型、检索器和是否返回源文档。 - 提出问题并获取答案:使用问答链处理用户的问题,并打印结果。
总结
通过上述步骤,我们成功构建了一个基于 VLLM、LangChain 和 FAISS 的知识库问答系统。这个系统可以从 PDF 文件中提取文本内容,将其存储到 FAISS 索引中,并使用语言模型生成答案。
更多推荐
所有评论(0)