PDF 聊天机器人的一步一步指南:使用 Langchain 和 Ollama

《PDF 聊天机器人的一步一步指南:利用 Langchain 和 Ollama》

介绍

在科技不断改变我们与信息互动方式的时代,PDF聊天机器人的概念为我们带来了全新的便利和效率。本文深入探讨了使用Langchain和Ollama创建PDF聊天机器人的有趣领域,通过极简配置即可访问开源模型。告别框架选择的复杂性和模型参数调整的困扰,让我们踏上解锁PDF聊天机器人潜力的旅程。发现如何无缝安装Ollama,下载模型并制作一款能够对您的问题提供智能回答的PDF聊天机器人。让我们一起探索这令人兴奋的技术与文件处理的融合,使信息检索变得更加轻松便捷。

学习目标

  • 了解如何在计算机上安装Ollama。
  • 学习如何使用Ollama下载和运行开源模型。
  • 探索使用Langchain和Ollama创建PDF聊天机器人的过程。

本文是数据科学博文马拉松的一部分。

前提条件

为了正确理解本文,您需要:

  • 精通Python;
  • 对Langchain有基本的了解,如链条、向量库等。

Langchain提供了用于创建LLM应用程序的各种功能。对此进行详细介绍需要单独一篇文章。如果您不知道Langchain是什么,请阅读一些关于Langchain的文章或教程。您还可以观看此视频

什么是Ollama?

Ollama使您能够下载开源模型并在本地使用。它会从最佳源自动下载模型。如果您的计算机上有专用的GPU,它将使用GPU加速来运行模型。您无需手动设置。您甚至可以通过更改提示来自定义模型(是的,您不需要Langchain)。Ollama也可以作为docker镜像提供,使您能够将自己的模型部署为docker容器。是不是令人兴奋?现在让我们看看如何在您的计算机上安装Ollama。

如何安装Ollama?

不幸的是,Ollama目前仅支持MacOS和Linux。但是不要担心,Windows用户也有使用Ollama的方法-WSL2。如果您的计算机上没有安装WSL2,请阅读此文章。我在这篇文章中解释了关于WSL2的一切以及如何在VS Code中使用它。如果您已经安装了WSL2,请打开Ubuntu并在终端中运行以下命令。

curl https://ollama.ai/install.sh | sh

这将在WSL2中安装Ollama。如果您使用的是MacOS,请访问这里。现在您已经准备好使用Ollama下载模型了。保持终端打开,我们还没完成。

下载模型

Ollama提供各种模型-llama2、llama2-uncensored、codellama、orca-mini等。如果您想了解所有可用模型的信息,您可以访问此网站。您将下载orca-mini 3b模型。它是一种使用在Orca论文中定义的方法创建的orca-style数据集上进行训练的Llama模型。尽管此模型较小(1.9GB),但仍能提供良好的响应。要下载此模型,请运行以下命令:

ollama run orca-mini

这个命令将在终端上下载并运行orca-mini模型。在运行此模型之前,请确保您的计算机上至少有8GB的RAM。

如果您正在运行该模型,请向它提问并查看它的响应。这里是一个例子:

从上面的例子中可以看出,有时候会提供一些不相关的信息。我们可以通过改变提示来解决这个问题。我们创建聊天机器人时会改变提示。

现在模型可以正常工作,让我们开始使用它创建PDF聊天机器人。

创建聊天机器人

设置项目目录

如果你不知道如何在WSL2中创建项目,请参考这篇文章的最后部分。那里我解释了一切。我们在这里使用VS Code作为开发工具。

安装必要的库

在开始之前,让我们安装所需的库。创建一个名为requirements.txt的文件,并写入以下依赖项。

langchainpymupdfhuggingface-hubfaiss-cpusentence-transformers

完成后,只需在VS Code中打开终端并运行以下命令。

>>> pip install -r requirements.txt

现在需要一些时间。由于这是一个应用程序,你不需要任何Ollama包。现在我们可以开始编写我们的聊天机器人。

创建必要的函数

在Langchain中创建聊天机器人需要遵循以下步骤:

  • 使用Langchain中的任何PDF加载程序读取PDF文件。
  • 如果文件非常大,将其分成较小的部分,也称为块。这样,我们可以确保模型得到了关于你的问题的正确信息,同时又不使用太多资源。这就像给模型只提供它需要的那些部分,而不是一次性地给它提供所有信息。每个模型都有一个令牌限制,不是吗?
  • 之后,我们必须将这些块转换为向量嵌入,以便模型更好地理解数据。然后我们必须创建向量存储,以便在需要时高效地存储和检索这些嵌入。在这里,我们将使用FAISS向量存储。
  • 现在我们准备好查询PDF文件了。为此,我们将使用Langchain的RetrievalQA。它将以检索器和我们将使用的模型作为参数。根据我们的需求,还使用了一些其他参数。

导入所需的包

这是一个基本的PDF聊天机器人的步骤。如果你想创建一个复杂的聊天机器人,还需要一些额外的步骤。例如,添加记忆、包含路由等。现在让我们为每个步骤创建一些函数,这样我们就不必重复多次测试的代码。首先,我们导入所需的包:

# 导入所需的包from langchain.embeddings import HuggingFaceEmbeddingsfrom langchain.document_loaders import PyMuPDFLoaderfrom langchain.text_splitter import RecursiveCharacterTextSplitterfrom langchain.vectorstores import FAISSfrom langchain.chains import RetrievalQAimport textwrap

之后,我们创建我们的第一个函数,它将加载PDF文件。在这里,你将使用Langchain的PyMuPDFLoader读取PDF文件。

# 加载PDF文件def load_pdf_data(file_path):    # 使用文件路径创建一个PyMuPDFLoader对象    loader = PyMuPDFLoader(file_path=file_path)        # 加载PDF文件    docs = loader.load()        # 返回加载的文档    return docs

然后,我们必须将文档分割为几个块。在这里,我们将使用Langchain的RecursiveCharacterTextSplitter进行文本拆分,这是最流行的文本拆分方法。

# 负责将文档分割为几个块def split_docs(documents, chunk_size=1000, chunk_overlap=20):        # 使用chunk_size和chunk_overlap初始化RecursiveCharacterTextSplitter    text_splitter = RecursiveCharacterTextSplitter(        chunk_size=chunk_size,        chunk_overlap=chunk_overlap    )        # 将文档分割为块    chunks = text_splitter.split_documents(documents=documents)        # 返回文档块    return chunks

现在是嵌入的时候了。为此,我们首先要使用Langchain中的HuggingFaceEmbedding加载嵌入模型,然后使用FAISS创建向量存储。用于嵌入的模型是all-MiniLM-L6-v2,稍后您将看到。

# 加载嵌入模型的函数def load_embedding_model(model_path, normalize_embedding=True):    return HuggingFaceEmbeddings(        model_name=model_path,        model_kwargs={'device':'cpu'}, # 在这里,我们只使用CPU运行模型        encode_kwargs = {            'normalize_embeddings': normalize_embedding # 保持为True以计算余弦相似度        }    )# 使用FAISS创建嵌入的函数def create_embeddings(chunks, embedding_model, storing_path="vectorstore"):    # 使用FAISS创建嵌入    vectorstore = FAISS.from_documents(chunks, embedding_model)        # 将模型保存在当前目录中    vectorstore.save_local(storing_path)        # 返回向量存储    return vectorstore

让我们创建一个自定义的提示模板,以使聊天机器人按预期工作。orca-mini模型的默认提示如下所示。

prompt = """### System:你是一个非常善于遵循指令的AI助手,尽可能帮助。### User:{prompt}### Response:"""

因此,保持提示的格式可以得到更好的回答。下面是修改后的提示模板:

template = """### System:您是一个尊重和诚实的助手。您必须根据提供给您的上下文回答用户的问题。如果您不知道答案,请坦率地说您不知道。不要试图编造答案。### Context:{context}### User:{question}### Response:"""

现在我们必须创建问答链。这里我们使用Langchain的RetrievalQA。RetrievalQA没有聊天机器人的记忆,即它只回答你的问题,但不记住以前的对话。

# 创建用于问答的链def load_qa_chain(retriever, llm, prompt):    return RetrievalQA.from_chain_type(        llm=llm,        retriever=retriever, # 这里我们使用向量存储作为检索器        chain_type="stuff",        return_source_documents=True, # 包含源文档在输出中        chain_type_kwargs={'prompt': prompt} # 自定义提示    )

我们还将创建一个函数来美化响应。以下是代码:

# 美化响应def get_response(query, chain):    # 从链中获取响应    response = chain({'query': query})        # 为在Jupyter Notebook中更好的输出而包装文本    wrapped_text = textwrap.fill(response['result'], width=100)    print(wrapped_text)

现在,我们创建了所有必要的函数,是时候创建聊天机器人了。

创建Jupyter Notebook

首先,在您的目录中创建一个Jupyter Notebook。为此,创建一个扩展名为.ipynb的新文件。还不要忘记从pip中安装jupyter。否则,笔记本将无法运行。只需运行以下命令安装jupyter。

>>> pip install jupyter

如果VS Code未检测到Jupyter Notebook的内核,则会在右上角看到一个“选择内核”的选项。下面会出现一些选项。

选择Python Environments。它会再次给您一些选项。

选择Starred环境。之后,您就可以使用Jupyter Notebook了。

导入必要的库

现在,我们将导入必要的库。这里我们将导入三个库:

  • 我们编写功能的Python脚本。我给了文件名为lang_funcs.py
  • 从langchain.llms导入Ollama
  • 从langchain导入PromptTemplate

让我们导入这些库:

from lang_funcs import *
 from langchain.llms import Ollama
 from langchain import PromptTemplate

加载模型

现在我们要加载orca-mini模型和名为all-MiniLM-L6-v2的嵌入模型。这个嵌入模型小而有效。

# 从Ollama加载orca-mini模型llm = Ollama(model="orca-mini", temperature=0)# 加载嵌入模型embed = load_embedding_model(model_path="all-MiniLM-L6-v2")

Ollama模型位于本地端口11434。我们不需要指定,因为在langchain的Ollama()类中已经指定了。如果嵌入模型未下载到您的计算机上,它将自动从Huggingface进行下载。稍等片刻,你就可以开始了。

加载数据并创建向量存储

现在是加载数据和创建嵌入的时候了。这里我们将使用一本关于机器学习的PDF书。

# 加载和拆分文档docs = load_pdf_data(file_path="data/ml_book.pdf")documents = split_docs(documents=docs)# 创建向量存储vectorstore = create_embeddings(documents, embed)# 将向量存储转换为检索器retriever = vectorstore.as_retriever()

创建嵌入需要一些时间。所以,请耐心等待。编程都是需要耐心的,不是吗?

你离成功就差一步了!

我知道你已经走了很长的路。现在我们需要创建链式结构并开始测试我们的聊天机器人。所以,让我们做到这一点。

# 从之前创建的模板创建提示prompt = PromptTemplate.from_template(template)# 创建链式结构chain = load_qa_chain(retriever, llm, prompt)

现在我们准备测试我们的聊天机器人了。

测试聊天机器人

现在让我们向聊天机器人提问。下面是一些示例:

>>>get_response("什么是随机森林?", chain)>>> 随机森林是一种集成学习技术,它使用决策树作为基分类器来创建一个新的分类器。它是一种集成学习方法,将多个决策树组合起来以提高最终模型的准确性并减少过拟合。随机森林算法在生长树时引入了额外的随机性,而不是在分割节点时搜索最佳特征(就像常规决策树那样)。这导致了更高的树的多样性,以低偏差换取更低的方差。与Bagging和Boosting等其他集成学习方法相比,它的计算效率更高。>>>get_response("什么是投票分类器?", chain)>>> 投票分类器是一种机器学习算法,它基于多个分类器的多数投票来预测给定输入数据点的类别。换句话说,它采用了几个不同分类器的预测,然后预测得到最多投票的类别。这种方法可以通过使用不同分类器的预测的多样性来提高机器学习模型的准确性。硬投票分类器是这一方法的一种简单实现。另一方面,随机森林是一种集成学习方法,它使用决策树作为基分类器。它通过随机选择训练数据子集来训练,它的训练方法是装袋方法。随机森林分类器对于决策树比投票分类器更方便和优化,并且通常会产生更好的模型。

它的回应非常好。你可以问一些更多的问题来看它的回应。

结论

我希望现在你对如何使用Langchain和Ollama创建一个PDF聊天机器人有了清楚的理解。Ollama在这个领域是一个新秀,它能让我们的生活变得更加简单。你已经看到了如何在一行代码中初始化orca-mini模型,否则你就需要使用Langchain的HuggingfacePipeline。

主要收获

  • Ollama简化模型部署:Ollama通过提供一种简单的方式在本地计算机上下载和运行开源模型,简化了模型部署的过程。
  • PDF聊天机器人开发:了解创建PDF聊天机器人的步骤,包括加载PDF文档、将其分成片段和创建聊天机器人链。
  • 为更好的回应进行定制:了解如何定制提示和模板以改善聊天机器人的回应。

你可以在这里找到本文中使用的所有代码。

常见问题

本文中显示的媒体不归Analytics Vidhya所有,只是作者自行决定使用。