一个基于 Streamlit 和 LlamaIndex 的资料问答系统。它使用了预训练的模型和本地知识库来回答用户的问题。这个博客包含部分核心部分代码只作为分享使用。这个博客演示RAG项目怎么解决大模型的幻觉和精度问题,取得了很好的结果。
项目成果:
-
高效问答系统:成功开发了一个高效的 RAG 问答系统,能够从本地知识库中检索相关信息并生成高质量的回答。
-
性能优化:通过 GPU 加速和存储优化,显著提升了模型推理速度和数据读写速度。
-
用户体验:通过 Streamlit 构建的交互式 Web 界面,提升了用户体验,支持用户与系统进行实时对话。
技术栈:
-
后端:Python、LlamaIndex、HuggingFace、PyTorch
-
前端:Streamlit
-
模型:
paraphrase-multilingual-MiniLM-L12-v2
、Qwen-5B-Instruct
-
硬件:i5 10400f、RX 580 8GB、1TB USB 3.0 硬盘
核心代码概述
-
初始化模型:加载预训练的文本嵌入模型和语言模型。
-
加载知识库:将本地文档加载为数据,并为这些数据构建向量索引。
-
用户界面:基于 Streamlit 构建一个简单的问答网页界面。
-
问答逻辑:通过用户输入的问题,从知识库中检索相关信息并生成答案。
1. 导入必要的库
import streamlit as st
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.llms.huggingface import HuggingFaceLLM
-
streamlit
:用于构建网页界面。 -
llama_index.core
:LlamaIndex 的核心模块,包含向量索引和数据加载器。 -
HuggingFaceEmbedding
和HuggingFaceLLM
:分别用于加载嵌入模型和语言模型。
2. 设置页面配置
st.set_page_config(page_title="RAG资料问答系统", page_icon="灰灰")
st.title("LlamaIndex RAG")
-
st.set_page_config
:设置网页标题和图标 -
st.title
:设置网页的标题。
3. 初始化模型和知识库
@st.cache_resource
def init_models():
# 检查是否有可用的 GPU
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Using device: {device}")
# 加载嵌入模型并指定设备
embed_model = HuggingFaceEmbedding(
model_name="D:\\AIProject\\modelscope\\Ceceliachenen\\paraphrase-multilingual-MiniLM-L12-v2",
device=device
)
Settings.embed_model = embed_model
# 加载语言模型并指定设备
llm = HuggingFaceLLM(
model_name="D:\\AIProject\\modelscope\\Qwen\\Qwen2___5-0___5B-Instruct",
tokenizer_name="D:\\AIProject\\modelscope\\Qwen\\Qwen2___5-0___5B-Instruct",
model_kwargs={"trust_remote_code": True, "device": device,"torch_dtype": torch.float16},
tokenizer_kwargs={"trust_remote_code": True}
)
Settings.llm = llm
# 加载文档并构建索引
documents = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()
return query_engine
-
@st.cache_resource
:标记为静态资源,避免重复加载。 -
embed_model
:加载paraphrase-multilingual-MiniLM-L12-v2
嵌入模型,用于将文本转换为向量。 -
llm
:加载语言模型Qwen-5B-Instruct
,用于生成回答。 -
documents
:从本地目录./data
加载文档数据。 -
index
:为文档构建向量索引,便于后续检索。 -
query_engine
:创建查询引擎,用于处理用户查询。 -
device
:检查当前环境中是否有可用的 GPU -
device=device
:指定模型运行的设备(CPU 或 GPU)。
4. 检查是否初始化模型
if 'query_engine' not in st.session_state:
st.session_state['query_engine'] = init_models()
-
st.session_state
:Streamlit 的状态管理,保存初始化的模型和引擎。
5. 定义问答函数
def greet2(question):
response = st.session_state['query_engine'].query(question)
return response
-
query_engine.query(question)
:从知识库中检索相关信息并生成回答。
6. 初始化消息记录
if "messages" not in st.session_state.keys():
st.session_state.messages = [{"role": "assistant", "content": "你好,我是你的助手,有什么我可以帮助你的吗?"}]
-
如果消息列表为空,初始化一条欢迎信息。
7. 显示和清理聊天记录
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.write(message["content"])
def clear_chat_history():
st.session_state.messages = [{"role": "assistant", "content": "你好,我是你的助手,有什么我可以帮助你的吗?"}]
st.sidebar.button('Clear Chat History', on_click=clear_chat_history)
-
遍历消息列表并显示。
-
clear_chat_history
:清空聊天记录。 -
st.sidebar.button
:侧边栏的按钮,点击时触发清空聊天记录。
8. 处理用户输入和生成回答
def generate_llama_index_response(prompt_input):
return greet2(prompt_input)
if prompt := st.chat_input():
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.write(prompt)
if st.session_state.messages[-1]["role"] != "assistant":
with st.chat_message("assistant"):
with st.spinner("Thinking..."):
response = generate_llama_index_response(prompt)
placeholder = st.empty()
placeholder.markdown(response)
message = {"role": "assistant", "content": response}
st.session_state.messages.append(message)
-
st.chat_input()
:获取用户的输入。 -
generate_llama_index_response
:调用问答函数生成回答。 -
st.chat_message
:分别显示用户和助手的消息。 -
st.spinner
:显示加载动画,表示正在思考生成回答。
总结
这个代码实现了一个简单的RAG问答系统,主要流程如下:
-
加载预训练模型和本地知识库。
-
构建向量索引,以便快速检索相关信息。
-
用户输入问题后,通过查询引擎从知识库中检索答案。
-
使用语言模型生成最终的回答。
-
通过 Streamlit 提供交互式界面,支持聊天和清空消息。
本地部署资源需求总结
-
存储:至少 315MB 用于存储模型文件,加上其他依赖库的存储空间。
-
内存:几百 MB 到 1GB,具体取决于使用场景。
-
CPU:可以在普通 CPU 上运行,但性能有限。
-
GPU:建议使用 4GB 显存的 GPU 以提高性能。
-
依赖库:需要安装
sentence-transformers
、transformers
、torch
等库
内容无力,其它可自行探索,有其它问题发评论区