当前位置: 首页 > article >正文

使用langchain ollama gradio搭建一个本地基于deepseek r1的RAG问答系统

目录

简介

环境配置

具体实现

安装依赖

定义模型和prompt

加载检索文档

切割

向量存储

创建检索器

实例化

前端搭建

实现效果

小tips


简介

首先介绍一下使用的几个工具,模型和rag的步骤,注:这里只是简单描述一下,不展开讲解。

langchain是一个开源的大语言模型开发框架,其可以帮助开发人员轻松构建基于语言模型的应用。

ollama也是一个开源框架,其是专为在本地机器上方便部署和运行大语言模型而设计。

gradio是一个用于创建模型交互的python库,其可以快速地为模型构建一个可视化的、易于使用的Web界面。

deepseek r1是一个具体的模型,其以超低的训练成本,高超的推理能力,在近期瞬间火爆各大平台以及海内外。(这里不详细介绍模型以及训练方法)

RAG(检索增强生成):

RAG是一个参数附加微调技术,其应用在大语言模型完成训练后,在prompt中增加文本内容以使得大预言模型可以根据增加的文本做出合适的回答(就好比上考场做英语阅读理解)。

RAG可以有效的增加模型的性能,降低模型的幻觉,同时其也可以避免大模型信息过时,数据隐私等问题。

RAG技术主要有四个步骤:

切片,embedding后存储到向量数据库,检索,召回。

切片是将一整个大的文档切分成几个小的片段,其称为chunk。

embedding是词嵌入的意思,文本片段不能直接存储在计算机中,所以会将其向量化,其就是用一组向量数字来表示这一个片段,相似的片段在向量化后会更相近。经过embedding化后,我们就可以将所有的向量数字存储到向量数据库中。

检索是将用户提问的问题也经过embedding,然后和向量数据库中的其他数字向量计算距离,距离越近就证明这个片段和我们提问的问题越相近,大模型可以在这些片段中找到答案。

召回是在向量数据库中找到与问题最相近的片段后,将片段取出,和问题拼接成一个prompt喂给大模型。

环境配置

首先需要下载ollama,ollama的安装直接到其官网download即可。

Ollama

安装完ollama后,打开cmd,可以输入ollama list查看模型。

 我这里已经安装了我们项目需要的两个模型,安装也非常简单,我们进到ollama的官网,然后将下载命令复制到cmd中点击运行即可。

nomic这个模型也这样下载即可,其中deepseek-r1为聊天模型,而nomic为embedding模型。

红框左侧也可以选择模型的尺寸,我这里选择使用的是7B的模型。若内存不够,可以选择小一点的模型。

具体实现

安装依赖

首先就是pip所需要的依赖包。

from langchain.embeddings import OllamaEmbeddings
from langchain.vectorstores import FAISS
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.llms import Ollama
from langchain.prompts import PromptTemplate
from langchain.chains import RetrievalQA
from langchain.docstore.document import Document
import gradio as gr

定义模型和prompt

# 定义embedding模型,对话模型和提示词
embedder = OllamaEmbeddings(model="nomic-embed-text:latest")
llm = Ollama(model="deepseek-r1:7b")
prompt_template = PromptTemplate(
    input_variables=["context", "question"],
    template="""
    请根据上下文内容回答问题,若根据上下文内容无法得到问题答案,请输出此问题在上下文中无法获得,不要思考其他知识给出回答:
    上下文:{context}
    问题:{question}
    回答:
    """
)

这里就是用langchain框架加载我们使用ollama下载的两个模型,以及定义一个提示词模板后期供我们使用。

加载检索文档

# 加载检索文档
with open('content.txt', 'r', encoding='utf-8') as file:
    content = file.read()
document = Document(page_content=content)

这里是加载具体的供检索文档,具体以txt格式,也可以加载pdf,doc格式的文档,这里不做展开讲解,我加载的具体文档内容为斗罗大陆里面最开始的一个片段,后续会看到。

切割

# 将文档分割成chunk
splitter = RecursiveCharacterTextSplitter(chunk_size=100, chunk_overlap=20)
split_docs = splitter.split_documents([document])

由于一整个文本不一定所有的内容都与我们的问题相关,所以这里需要将文本切割成片段。

chunk_size这个参数指定了每个文本块的大小。

chunk_overlap这个参数定义了相邻文本块之间的重叠程度。

向量存储

# 创建向量存储
vector_store = FAISS.from_documents(split_docs, embedder)

这一行代码就是将我们上面切割后的每个文本片段通过embedding向量化后存储到向量数据库。

创建检索器

# 创建检索器
retriever = vector_store.as_retriever(search_type="similarity", search_kwargs={"k": 3})

这里我们创建了一个检索器,用于根据我们所问的问题去向量数据库中寻找与问题最相近的文本片段。

实例化

# 创建QA实例
qa_chain = RetrievalQA.from_llm(
    llm=llm,
    retriever=retriever,
    prompt=prompt_template
)

最后一步就是将我们上述的模型,检索器和提示词工程用来创建一个基于检索的问答系统(QA System)实例。

前端搭建

def chat(message, history):
    result = qa_chain.run(message)
    print(result)
    result = result.split("</think>")[-1]
    return result


gr.ChatInterface(fn=chat, title="deepseek-r1").launch()

最后就是用gradio这个包起一个简单的Web交互界面。

实现效果

将上述所有的代码片段合并到一起就可以运行完整的RAG程序了,让我们一起来看看运行效果如何:

这里根据文档内容,问大模型唐门暗器和圣魂村,可以看到,它都按照文档的内容回答出来了。

我们在试几个文档中没有的内容:

 

 这里,我们询问大模型中国最高的山是什么山,可以看到,大模型根据我们给的文本并不能回答这个问题,由于我们的prompt中严格明确了,若通过文本找不到问题的答案,则输出无法获得问题答案,可见效果还是不错的。

小tips

1,本项目中将检索的文档写到python代码里面了,其是可以使用gradio从前端读入文档的。

2,最后的chat函数中,有一个print,我这里没有贴命令行的运行截图,大家可以看一下,在命令行中可以看到deepseek的思考过程,其会被两个</think>包住。

3,最后的输出那里,我加了个字符串的split操作,这是因为我发现如果直接return result的话,在前端界面中将没有输出,推测可能是</think>这个特殊字符搞的鬼,于是进行切分后就发现可以在前端正常显示了,由于本人并不是专门学Web的,路过的大佬看到也可以在评论区解释下,小编先提前感谢啦。


http://www.kler.cn/a/525767.html

相关文章:

  • 005 单点登录
  • Ubuntu-手动安装 SBT
  • mysql_init和mysql_real_connect的形象化认识
  • python:斐索实验(Fizeau experiment)
  • 基于Cipher的Java加密工具类
  • 【Matlab高端绘图SCI绘图模板】第006期 对比绘柱状图 (只需替换数据)
  • C28.【C++ Cont】顺序表的实现
  • 详细解释java当中的所有知识点(前言及数据类型及变量)(第一部分)
  • 《攻克语言密码:教AI理解隐喻与象征》
  • Airflow:深入理解Apache Airflow 调度器
  • Github 2025-01-30 Go开源项目日报 Top10
  • Linux下多线程编程
  • MySQL 事务的隔离级别
  • 一文讲解Java中的BIO、NIO、AIO之间的区别
  • 力扣动态规划-15【算法学习day.109】
  • JavaScript 进阶(上)
  • openRv1126 AI算法部署实战之——TensorFlow TFLite Pytorch ONNX等模型转换实战
  • 开源 OA 办公系统
  • AI大模型开发原理篇-9:GPT模型的概念和基本结构
  • 亚博microros小车-原生ubuntu支持系列:17 gmapping
  • 指针(C语言)从0到1掌握指针,为后续学习c++打下基础
  • 小程序-基础加强-自定义组件
  • Java Stream API中的状态性操作与陷阱
  • JSR303校验教学
  • 某盾Blackbox参数参数逆向
  • 网络安全技术简介