Type something to search...
在本地运行 DeepSeek-R1:使用 Ollama 和 FAISS 构建自定义矢量数据库和人工智能聊天机器人

在本地运行 DeepSeek-R1:使用 Ollama 和 FAISS 构建自定义矢量数据库和人工智能聊天机器人

介绍

大型语言模型 (LLMs) 的演变显著改变了人工智能的格局。然而,许多强大的模型需要基于云的 API,这引发了对 数据隐私、成本和延迟 的担忧。

幸运的是,DeepSeek-R1,一个 80亿参数的语言模型,现在可以通过 Ollama 完全离线部署——这是一个简化本地运行 LLM 的框架。

在本综合指南中,我们将逐步介绍:✅ 设置 Ollama 以在本地运行 DeepSeek-R1。✅ 高效下载和配置 DeepSeek-R1 模型。✅ 理解 Ollama 如何通过量化优化 LLM。✅ 构建自定义 FAISS 向量数据库 以实现智能文档检索。✅ 将 DeepSeek 与 LangChain 和 Chainlit 集成 以创建一个互动 AI 聊天机器人。

通过本教程的学习,您将拥有一个功能齐全的 基于 LLM 的检索聊天机器人,能够根据 自定义 PDF 文档 回答问题,所有操作均在 100% 本地机器上 运行。

步骤 1:安装和设置 Ollama

在运行 DeepSeek-R1 之前,我们首先需要安装 Ollama,它提供了一种简化的方式来本地运行和与 LLMs 互动。

从官方网站下载 Ollama Desktop:访问官方网站:🔗 https://ollama.com点击 “下载”按钮以获取 Windows 版本。下载完成后,您将在 下载文件夹中找到 Ollama 安装程序文件OllamaSetup.exe)。

运行安装程序:

  • 双击 OllamaSetup.exe 文件。
  • 按照屏幕上的说明进行操作 — 点击“下一步”和“安装”以完成安装。

验证安装:

  • 打开 命令提示符(CMD)。
  • 输入以下命令并按 Enter:

  • 输入 ‘ollama serve’

此错误表示 Ollama 尝试在端口 127.0.0.1:11434 上运行,但该端口已被占用

  • 验证输入 ‘netstat -ano | findstr :11434’

  • 现在在任何浏览器中打开一个新标签页,输入 ‘http://localhost:11434/’,您将看到消息 ‘Ollama is running’

在使用 DeepSeek-R1自定义数据集 之前,我们首先需要 在本地下载(拉取)模型。这确保我们在机器上存储模型以进行 离线推理,而不是每次都实时运行它。

打开您的网页浏览器,访问 Ollama 模型库:🔗 https://ollama.com/library/deepseek-r1

在这里,您将看到不同版本的 DeepSeek-R1 模型,具有各种参数大小。

选择 8B 参数版本,以在性能和资源使用之间获得最佳平衡。

在网站上,您会注意到命令

ollama run deepseek-r1:8b

然而,我们 在这个阶段不打算使用 run

❌ ollama run deepseek-r1:8b

  • 会立即启动模型进行本地推理
  • 如果您只是想与模型进行互动聊天,这很有用。
  • 但在我们的情况下,我们需要使用自定义数据集,因此我们必须先下载(拉取)模型

✅ ollama pull deepseek-r1:8b

  • 下载模型而不运行它。
  • 这使我们能够将其用作API或与FAISS & LangChain集成,以便用于我们的向量数据库。
  • 这是必要的,因为我们想处理自定义数据集,而不是直接在交互模式中使用模型。

输入‘ollama run deepseek-r1:8b’后,您将看到:

  • Ollama将从其仓库获取DeepSeek-R1模型(约4.9GB)。
  • 模型将被本地存储,因此不需要再次下载。
  • 这确保了快速推理离线可用性

成功拉取DeepSeek-R1:8B模型后,确认模型已下载并可供使用非常重要。

要检查模型是否存储在本地,请打开您的终端或命令提示符并运行以下命令:

ollama list

您将看到此类输出,

Step 2: Python Setup for DeepSeek-R1 Chatbot

要将 DeepSeek-R1自定义向量数据库 集成,我们需要设置 Python 环境 并安装必要的库。请按照以下步骤操作,以确保一切顺利运行。下载 Python 3.12.x 以适应您的操作系统。

为了保持项目依赖的隔离,请在安装所需库之前创建一个 虚拟环境

在您的项目文件夹中运行以下命令:

python -m venv deepseek_env  # Create a virtual environment
source deepseek_env/bin/activate  # For macOS/Linux
source deepseek_env/Scripts/activate  # For Windows

为了确保功能顺畅,我们将通过 requirements.txt 文件安装 所有必要的依赖

创建 requirements.txt 文件

在您的项目目录中创建一个名为 requirements.txt 的文件,并 添加以下依赖项:

langchain
ctransformers
pypdf
tiktoken
langchain-community
transformers
sentence-transformers
tqdm
accelerate
chainlit
unidecode
huggingface_hub
langchain-huggingface
pypdfium2
pydantic==2.9.2
langchain_ollama

创建文件后,在终端中运行以下命令以一次性安装所有所需的包:

pip install -r requirements.txt

创建一个名为 ‘data’ 的文件夹,并 将所有 PDF 文件 放置在此 data/ 文件夹中。这些文档将用于创建 FAISS 向量数据库,使聊天机器人能够 根据内容检索和回答查询

第 3 步:Python 编码

现在我们可以开始构建 FAISS 向量数据库并将其与DeepSeek-R1集成,以便处理自定义数据集!

创建一个 Python 文件 (admin.py) 用于 FAISS 向量数据库的创建。此 Python 脚本用于将 PDF 文档转换为向量数据库,使用FAISS (Facebook AI Similarity Search)Hugging Face sentence-transformer embeddings

admin.py 代码解析与说明

1. 导入所需库

#from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_huggingface import HuggingFaceEmbeddings
#from langchain.vectorstores import FAISS
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import PyPDFLoader, DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
import os

🔹 这里发生了什么?

  • HuggingFaceEmbeddings: 用于将文本转换为数值向量(嵌入)。
  • FAISS: 一个快速高效的向量搜索库,用于存储和检索嵌入。
  • PyPDFLoader & DirectoryLoader: 从目录加载PDF并提取其文本。
  • RecursiveCharacterTextSplitter: 将大型文档拆分为较小的块,以便更好地生成嵌入。
  • os: 处理目录创建。

2. 定义文件路径

DATA_PATH = 'data/'
DB_FAISS_PATH = 'vectorstore/db_faiss'

🔹 这里发生了什么?

  • DATA_PATH:存储PDF文档的目录。
  • DB_FAISS_PATH:保存FAISS向量数据库的目录。

3. 创建向量数据库的函数

def create_vector_db():
    loader = DirectoryLoader(DATA_PATH,
                             glob='*.pdf',
                             loader_cls=PyPDFLoader)

🔹 这里发生了什么?

  • DirectoryLoader(DATA_PATH, glob='*.pdf', loader_cls=PyPDFLoader):
  • 这将加载 data/ 目录下的所有 .pdf 文件。
  • 使用 PyPDFLoader 从每个 PDF 中提取文本。

4. 将文档拆分为块

documents = loader.load()
    text_splitter = RecursiveCharacterTextSplitter(chunk_size=500,
                                                   chunk_overlap=50)
    texts = text_splitter.split_documents(documents)

🔹 这里发生了什么?

  • loader.load(): 从PDF中读取提取的文本。
  • RecursiveCharacterTextSplitter: 将长文本拆分为较小的块,以便每个块可以单独处理。

5. 创建文本嵌入

embeddings = HuggingFaceEmbeddings(model_name='sentence-transformers/all-MiniLM-L6-v2',
                                       model_kwargs={'device': 'cpu'})

🔹 这里发生了什么?

  • 嵌入是文本的数值表示,用于高效的相似性搜索。
  • sentence-transformers/all-MiniLM-L6-v2:一个 预训练模型,将文本转换为嵌入。
  • model_kwargs={'device': 'cpu'}:在 CPU 上运行模型(可以更改为 'cuda' 以使用 GPU)。

6. 在 FAISS 中存储文本嵌入

db = FAISS.from_documents(texts, embeddings)
    db.save_local(DB_FAISS_PATH)

🔹 这里发生了什么?

  • FAISS.from_documents(texts, embeddings):
  • 将文本块转换为 嵌入
  • 将它们存储在 FAISS 索引 中(一个快速的向量搜索数据库)。
  • db.save_local(DB_FAISS_PATH):
  • 将 FAISS 索引本地保存,以便后续使用。

7. 运行脚本

if __name__ == "__main__":
    # 确保 vectorstore 目录存在
    os.makedirs(DB_FAISS_PATH, exist_ok=True)
    create_vector_db()

🔹 这里发生了什么?

  • os.makedirs(DB_FAISS_PATH, exist_ok=True): 如果 vectorstore/db_faiss 目录不存在,则创建该目录。
  • create_vector_db(): 调用该函数以生成 FAISS 向量数据库。

现在创建另一个 python 文件 (app.py),用于关于 自定义 PDF 文档 的问题,聊天机器人将 从 FAISS 中检索相关信息 并使用 DeepSeek-R1 生成响应

app.py 代码分解与解释

1. 导入所需库

import requests
from langchain_community.document_loaders import PyPDFLoader, DirectoryLoader
from langchain.prompts import PromptTemplate
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.chains import RetrievalQA
from langchain_ollama import OllamaLLM
import chainlit as cl

🔹 这里发生了什么?

  • requests: 用于发送 HTTP 请求(在脚本中未积极使用)。
  • PyPDFLoader, DirectoryLoader: 加载 PDF 并提取文本。
  • PromptTemplate: 定义聊天机器人的 问答格式
  • HuggingFaceEmbeddings: 将文本转换为 嵌入(数值表示)。
  • FAISS: 加载和搜索向量化文档。
  • RetrievalQA: 创建一个 问答链,获取相关信息。
  • OllamaLLM: 通过 Ollama API 使用 DeepSeek-R1 LLM 进行文本生成。
  • chainlit: 提供一个 聊天用户界面 以便用户互动。

2. 数据库路径定义和自定义提示模板

DB_FAISS_PATH = 'vectorstore/db_faiss'

custom_prompt_template = """Use the following pieces of information to answer the user's question.
If you don't know the answer, just say that you don't know, don't try to make up an answer.Context: {context}
Question: {question}
Only return the helpful answer below and nothing else.
Helpful answer:
"""
  • 这定义了 预构建的 FAISS 向量数据库 的位置(在 admin.py 中创建)。
  • 该数据库包含用于检索的 PDF 文本嵌入
  • 提供从检索文档中获得的上下文。
  • 确保模型不会生成虚假信息
  • 以清晰的格式结构化响应。

3. 设置提示模板的函数

def set_custom_prompt():
    prompt = PromptTemplate(template=custom_prompt_template, input_variables=['context', 'question'])
    return prompt

🔹 这个函数的作用

  • 使用自定义模板创建一个PromptTemplate对象。
  • 定义输入变量(来自FAISS的context和用户的question)。
  • 返回将在LLM链中使用的提示。

4. 通过 Ollama 加载 DeepSeek-R1

def load_llm():
    llm = OllamaLLM(
        model="deepseek-r1:8b",
        base_url="http://localhost:11434",  # Ollama 的默认基础 URL
        temperature=0.3,  # 较低的创造性以获得简洁的响应
        top_p=0.85,       # 稍微调整多样性
        max_tokens=150    # 限制响应的长度
    )
    return llm

🔹 这个函数的作用

  • 通过 Ollama 加载 DeepSeek-R1 8B 模型(本地运行)。
  • 设置关键参数:
  • temperature=0.3:保持响应 简洁和事实性(较低的值减少随机性)。
  • top_p=0.85控制响应的多样性(接近 1 的值允许更多样化的响应)。
  • max_tokens=150限制响应长度(防止答案过长)。

5. 设置检索问答链

def retrieval_qa_chain(llm, prompt, db):
    qa_chain = RetrievalQA.from_chain_type(
        llm=llm,
        chain_type="stuff",
        retriever=db.as_retriever(search_kwargs={'k': 1}),  # Retrieve the most relevant document
        return_source_documents=True,
        chain_type_kwargs={'prompt': prompt}
    )
    return qa_chain

🔹 此功能的作用

  • 使用 RetrievalQA 创建基于检索的聊天机器人
  • 使用 db.as_retriever(search_kwargs={'k': 1}) 从 FAISS 数据库中检索信息
  • k=1:仅为每个查询获取 最相关 的文档。
  • 使用 DeepSeek-R1 LLM 生成响应
  • 返回检索到的源文档 (return_source_documents=True)。

6. 设置 QA 机器人

def qa_bot():
    embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
    db = FAISS.load_local(DB_FAISS_PATH, embeddings, allow_dangerous_deserialization=True)
    llm = load_llm()
    qa_prompt = set_custom_prompt()
    qa = retrieval_qa_chain(llm, qa_prompt, db)
    return qa

🔹 此功能的作用

  1. 加载 FAISS 向量数据库 (FAISS.load_local(DB_FAISS_PATH, embeddings)).
  2. 加载 DeepSeek-R1 LLM (load_llm()).
  3. 设置自定义提示模板 (set_custom_prompt()).
  4. 创建一个结合 FAISS 检索和 DeepSeek 生成的 QA 链 (retrieval_qa_chain(...)).
  5. 返回用于推理的 QA 模型.

7. Chainlit 聊天机器人 UI:机器人初始化

@cl.on_chat_start
async def start():
    chain = qa_bot()
    msg = cl.Message(content="Starting the bot...")
    await msg.send()
    msg.content = "Hi, Welcome to the DeepSeek ChatBot. How can I assist you today?"
    await msg.update()
    cl.user_session.set("chain", chain)

🔹 聊天机器人启动时会发生什么?

  1. 加载 QA bot (qa_bot())
  2. 向用户发送“正在启动机器人…”消息
  3. 将消息更新为“嗨,欢迎来到 DeepSeek 聊天机器人!”
  4. 将 QA 链存储在 Chainlit 的会话中 (cl.user_session.set("chain", chain))

8. 处理用户消息

@cl.on_message
async def main(message: cl.Message):
    chain = cl.user_session.get("chain")
    if chain is None:
        await cl.Message(content="错误:链未初始化。").send()
        return

    cb = cl.AsyncLangchainCallbackHandler(
        stream_final_answer=True,
        answer_prefix_tokens=["最终", "答案"]
    )

    response = await chain.acall({'query': message.content}, callbacks=[cb])
    answer = response["result"]
    sources = response.get("source_documents", [])

    if sources:
        answer += "\n来源:" + "\n".join([str(doc.metadata['source']) for doc in sources])
    else:
        answer += "\n未找到来源"

    await cl.Message(content=answer).send()

🔹 用户发送消息时会发生什么?

  1. 检索存储的 QA 模型 (chain = cl.user_session.get("chain"))
  2. 如果聊天机器人未初始化,则返回错误消息
  3. 创建异步回调处理程序以流式传输响应 (cb = cl.AsyncLangchainCallbackHandler(...))。
  4. 调用 RetrievalQA 链 (chain.acall({'query': message.content}, callbacks=[cb]))
  • 这将从 FAISS 检索相关文本。
  • 使用 DeepSeek-R1 LLM 生成答案。

现在聊天机器人已准备就绪,您可以:✅ 使用 Chainlit 进行测试

chainlit run app.py

现在 PDF,

如果我们问“工业政策是什么时候引入的?”

第4步:结论

在本指南中,我们成功构建了一个 retrieval-augmented chatbot,能够处理 custom PDF documents 并提供 context-aware responses,使用 DeepSeek-R1, FAISS, 和 LangChain。与传统聊天机器人不同,该系统 在生成答案之前从上传的文档中检索相关信息,确保更高的准确性和可靠性。

Related Posts

结合chatgpt-o3-mini与perplexity Deep Research的3步提示:提升论文写作质量的终极指南

结合chatgpt-o3-mini与perplexity Deep Research的3步提示:提升论文写作质量的终极指南

AI 研究报告和论文写作 合并两个系统指令以获得两个模型的最佳效果 Perplexity AI 的 Deep Research 工具提供专家级的研究报告,而 OpenAI 的 ChatGPT-o3-mini-high 擅长推理。我发现你可以将它们结合起来生成令人难以置信的论文,这些论文比任何一个模型单独撰写的都要好。你只需要将这个一次性提示复制到 **

阅读更多
让 Excel 过时的 10 种 Ai 工具:实现数据分析自动化,节省手工作业时间

让 Excel 过时的 10 种 Ai 工具:实现数据分析自动化,节省手工作业时间

Non members click here作为一名软件开发人员,多年来的一个发现总是让我感到惊讶,那就是人们还在 Excel

阅读更多
使用 ChatGPT 搜索网络功能的 10 种创意方法

使用 ChatGPT 搜索网络功能的 10 种创意方法

例如,提示和输出 你知道可以使用 ChatGPT 的“搜索网络”功能来完成许多任务,而不仅仅是基本的网络搜索吗? 对于那些不知道的人,ChatGPT 新的“搜索网络”功能提供实时信息。 截至撰写此帖时,该功能仅对使用 ChatGPT 4o 和 4o-mini 的付费会员开放。 ![](https://images.weserv.nl/?url=https://cdn-im

阅读更多
掌握Ai代理:解密Google革命性白皮书的10个关键问题解答

掌握Ai代理:解密Google革命性白皮书的10个关键问题解答

10 个常见问题解答 本文是我推出的一个名为“10 个常见问题解答”的新系列的一部分。在本系列中,我旨在通过回答关于该主题的十个最常见问题来分解复杂的概念。我的目标是使用简单的语言和相关的类比,使这些想法易于理解。 图片来自 [Solen Feyissa](https://unsplash.com/@solenfeyissa?utm_source=medium&utm_medi

阅读更多
在人工智能和技术领域保持领先地位的 10 项必学技能 📚

在人工智能和技术领域保持领先地位的 10 项必学技能 📚

在人工智能和科技这样一个动态的行业中,保持领先意味着不断提升你的技能。无论你是希望深入了解人工智能模型性能、掌握数据分析,还是希望通过人工智能转变传统领域如法律,这些课程都是你成功的捷径。以下是一个精心策划的高价值课程列表,可以助力你的职业发展,并让你始终处于创新的前沿。 1. 生成性人工智能简介课程: [生成性人工智能简介](https://genai.works

阅读更多
揭开真相!深度探悉DeepSeek AI的十大误区,您被误导了吗?

揭开真相!深度探悉DeepSeek AI的十大误区,您被误导了吗?

在AI军备竞赛中分辨事实与虚构 DeepSeek AI真的是它所宣传的游戏规则改变者,还是仅仅聪明的营销和战略炒作?👀 虽然一些人将其视为AI效率的革命性飞跃,但另一些人则认为它的成功建立在借用(甚至窃取的)创新和可疑的做法之上。传言称,DeepSeek的首席执行官在疫情期间像囤积卫生纸一样囤积Nvidia芯片——这只是冰山一角。 从其声称的550万美元培训预算到使用Open

阅读更多
Type something to search...