首页 » 软件优化 » [机器翻译_转载]使用大模型构建本地 PDF 聊天应用程序(聊天应用程序模型初始化文档)

[机器翻译_转载]使用大模型构建本地 PDF 聊天应用程序(聊天应用程序模型初始化文档)

落叶飘零 2024-07-24 09:23:21 0

扫一扫用手机浏览

文章目录 [+]

PDF 聊天机器人是可以回答有关 PDF 文件的问题的聊天机器人。
它可以通过使用大型语言模型 (LLM) 来理解用户的查询,然后在 PDF 文件中搜索相关信息来实现此目的。
然后,聊天机器人可以用简单的语言生成对用户查询的响应。

PDF 聊天机器人可用于多种目的,例如:

回答有关 PDF 文件内容的问题提供 PDF 文件的摘要在 PDF 文件中搜索特定关键字或短语将 PDF 文件翻译成另一种语言

在本文中,我将向您展示如何使用 Mistral 7b LLM、Langchain、Ollama 和 Streamlit 制作 PDF 聊天机器人。

[机器翻译_转载]使用大模型构建本地 PDF 聊天应用程序(聊天应用程序模型初始化文档) 软件优化
(图片来自网络侵删)
Mistral 7b

Mistral 7b 是 Mistral AI 开发的 70 亿参数大语言模型 (LLM)。
它经过大量文本和代码数据集的训练,可以执行各种任务。
Mistral 7b 仍在开发中,但它已经在各种基准测试中取得了最先进的结果。
例如,它优于所有其他类似规模的预训练 LLM,甚至比 Llama 2 13B 等较大的 LLM 更好。
它旨在部署在 GPU 和 CPU 等商用硬件上,无需昂贵的 TPU 集群。
这使得更广泛的用户和企业更容易使用它。

先决条件:使用 Ollama 在本地运行 Mistral7b

Ollama允许您在本地运行开源大型语言模型,例如 Llama 2。
Ollama 将模型权重、配置和数据捆绑到一个包中,由模型文件定义。
它优化了设置和配置细节,包括 GPU 使用情况。

对于 Mac 和 Linux 用户:Ollama 可以轻松地与 Mac 和 Linux 系统集成,提供用户友好的安装过程。
Mac 和 Linux 用户可以快速设置 Ollama 以访问其丰富的功能以使用本地语言模型。
详细说明可在此处找到:Ollama GitHub Repository for Mac and Linux。

对于 Windows 用户,该过程涉及一些额外的步骤,以确保流畅的 Ollama 体验:

1. 安装 WSL 2:要启用 WSL 2,请参阅 Microsoft 官方文档以获取完整的安装说明:安装 WSL 2。

2. 安装Docker:Docker for Windows是一个重要的组件。
Docker 官方文档中提供了安装指南:Install Docker for Windows。

3. 使用 Docker 镜像:Windows 用户可以使用此处提供的 Docker 镜像来访问 Ollama:Ollama Docker Image。

现在我们可以使用以下命令轻松地在 CMD 中使用 Mistral:

docker exec -it ollama ollama 运行 MistraLangChain

LangChain是一个用于开发由语言模型支持的应用程序的框架。
它使开发人工智能应用程序变得非常容易,并且拥有 Python 和 Javascript 库。
我已经使用 langchain 将 Ollama 与我的应用程序集成。

我使用RAG(检索增强生成)的概念在特定文档的上下文中生成响应。
检索增强生成 (RAG) 应用程序是一种大型语言模型 (LLM) 应用程序,它通过从外部知识库检索相关信息来增强其生成能力。
这使得 RAG 应用程序能够针对更广泛的提示和问题生成信息更丰富、更全面的响应。

在本文中,我将展示如何使用 Mistral 7B 模型和 Chroma Vector 数据库构建 RAG 应用程序。
架构如下

使用 Mistal 7B、Ollama 和 Streamlit 的 RAG 应用程序的代码可以在我的 GitHub 存储库中找到。

让我们编码吧‍

让我们首先导入必要的库:

#从langchain import hub from langchain.chains import RetrievalQA from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler from langchain.callbacks.manager import CallbackManager from langchain.llms import Ollama from langchain.embeddings.ollama import OllamaEmbeddings from langchain.vectorstores import Chroma从langchain.text_splitter导入RecursiveCharacterTextSplitter从langchain.document_loaders导入PyPDFLoader从langchain.prompts导入PromptTemplate从langchain.memory导入ConversationBufferMemory导入Streamlit as st导入os导入时间

加载文档并将文档分割成块,然后将它们嵌入到矢量数据库中。
我选择的块大小为 1500 个令牌。
您可以更改此设置以适合您的特定用例。

loader = PyPDFLoader( "example.pdf" ) data = loader.load() text_splitter = RecursiveCharacterTextSplitter( chunk_size= 1500 , chunk_overlap= 100 ) all_splits = text_splitter.split_documents(data)

使用 vectorstore.persist() 将数据库保留到光盘上以保存它,这样您就不必每次都预处理文档。

persist_directory = 'jj' vectorstore = Chroma.from_documents( 文档=all_splits, embedding=OllamaEmbeddings(model= "mistral" ),persist_directory=persist_directory) vectorstore.persist()

保存后可以选择持久化目录并从磁盘加载。
现在我们可以从磁盘加载持久数据库,并正常使用它。
请记住选择与之前相同的嵌入模型。

矢量存储 = Chroma(persist_directory=persist_directory, embedding_function=OllamaEmbeddings(model= "mistral" ) )

现在初始化 llm 并创建一个检索器

llm = Ollama(base_url= "http://localhost:11434", model= "mistral:instruct", verbose= True, callback_manager=CallbackManager( [StreamingStdOutCallbackHandler()]) )检索器 = vectorstore.as_retriever()

对话缓冲区内存用于维护聊天历史记录,以便 LLM 也可以在提示中参考以前的聊天。

正在初始化对话缓冲区内存和提示模板。

template = """ 您是一个知识渊博的聊天机器人,在这里帮助解决用户的问题。
您的语气应该专业且信息丰富。
上下文:{context} 历史记录:{history} 用户:{question} 聊天机器人:"" """提示 = PromptTemplate( input_variables=[ "历史" , "上下文" , "问题" ], template=template, )内存 = ConversationBufferMemory( memory_key= "历史" , return_messages= True , input_key= "问题" )

创建问答链:

qa_chain = RetrievalQA.from_chain_type( llm=st.session_state.llm, chain_type= 'stuff' , 检索器=st.session_state.retriever, verbose= True , chain_type_kwargs={ "verbose" : True , "prompt" : 提示, "内存": 记忆, } )

现在你可以直接查询llm:

while True : query = input ( "问一个问题:" ) response = qa_chain(query)使用 Streamlit 制作 UI

Streamlit是一个面向机器学习和数据科学团队的开源应用程序框架。
在几分钟内创建漂亮的网络应用程序。

首先,我们将使用文件上传器组件上传 pdf 文件并对其进行预处理。

import Streamlit as st uploaded_file = st.file_uploader( "上传您的 PDF" , type = 'pdf' )

我们将使用 chat_history 变量来维护 Streamlit 会话中的聊天历史记录。

# 初始化聊天记录if 'chat_history' not in st.session_state: st.session_state.chat_history = []

注意:我们不能直接使用简单变量来存储值,因为 Streamlit 在每次运行时都会重新初始化每个变量,因此我们必须将其存储为会话变量。
(我花了4个小时才意识到这一点)

所以我们必须为内存、提示符、llm 和向量存储创建会话变量,如下所示:

if 'prompt' not in st.session_state: st.session_state.prompt = PromptTemplate( input_variables=[ "history" , "context" , "question" ], template=template, ) # 初始化对话历史记录的内存if 'memory' not in st.session_state: st.session_state.memory = ConversationBufferMemory( memory_key= "history" , return_messages= True , input_key= "question" ) #如果'vectorstore'不在st.session_state中,则初始化文档嵌入的向量存储: st. session_state.vectorstore = Chroma(persist_directory= 'jj' , embedding_function=OllamaEmbeddings( model= "mistral:instruct" ) ) #如果'llm'不在st.session_state中,则初始化 Ollama 大语言模型 (LLM) : st.session_state.llm = Ollama(base_url= "http://localhost:11434", model= "mistral:instruct", verbose= True, callback_manager=CallbackManager( [StreamingStdOutCallbackHandler()])

Streamlit 文件上传不会给我们路径,所以我们必须先获取它的字节,然后将其保存到文件目录中。

bytes_data = uploaded_file.read() f = open ( "files/" +uploaded_file.name+ ".pdf" , "wb" ) f.write(bytes_data) f.close() loader = PyPDFLoader( "files/" +uploaded_file.名称 + ".pdf" )数据 = loader.load()

现在我们将重复相同的步骤来处理数据并使用 ChromaDb 对其进行矢量存储。

# 初始化文本分割器text_splitter = RecursiveCharacterTextSplitter( chunk_size=1500, chunk_overlap=200, length_function=len ) all_splits = text_splitter.split_documents(data) # 创建并保存向量存储st.session_state.vectorstore = Chroma.from_documents( Documents=all_splits, embedding =OllamaEmbeddings(model= "mistral" ) ) st.session_state.vectorstore.persist()

初始化 QA 链

如果 'qa_chain' 不在 st.session_state中: st.session_state.qa_chain = RetrievalQA.from_chain_type( llm=st.session_state.llm, chain_type= 'stuff' , retriever=st.session_state.retriever, verbose= True , chain_type_kwargs={ "详细”:True, “提示”:st.session_state.prompt, “内存”:st.session_state.memory, } )

现在我们必须处理用户查询和 llm 的响应。
我们通过为提示中的“用户”、“助理”等消息分配角色来做到这一点。
此外,我们会将每条消息附加到聊天历史记录中,以维护会话中的聊天。

if user_input := st.chat_input( "You:" , key= "user_input" ): user_message = { "role" : "user" , "message" : user_input} st.session_state.chat_history.append(user_message) 与st. chat_message( "user" ): st.markdown(user_input) with st.chat_message( "assistant" ): with st.spinner( "Assistant istying..." ): response = st.session_state.qa_chain(user_input) message_placeholder = st.empty() full_response = "" for chunk in response[ 'result' ].split(): full_response += chunk + " " time.sleep( 0.05 ) # 添加闪烁的光标来模拟打字 message_placeholder.markdown(full_response + "▌" ) message_placeholder.markdown(full_response) chatbot_message = { "角色" : "助理" , "消息" : 响应[ '结果' ]} st.session_state.chat_history.append(chatbot_message)

您可以在我的 github 存储库中找到完整的代码。

https://github.com/SonicWarrior1/pdfchat

结论

在本指南中,我们释放了人工智能的潜力,彻底改变了我们处理 PDF 文档的方式。
我们的 PDF 聊天机器人由 Mistral 7B、Langchain 和 Ollama 提供支持,弥合了静态内容和动态对话之间的差距。

通过了解检索增强生成 (RAG) 的功能并利用开源工具,您现在已经具备了创建智能文档交互解决方案的基础。
可能性是无限的。

获取这些知识,根据您的特定需求进行定制,并探索人工智能在文档交互中的无限应用。
我们很高兴看到您将如何塑造 PDF 交互的未来。

感谢您与我一起踏上这段人工智能之旅。

标签:

相关文章