使用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 resultgr.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.rhkb.cn/news/10149.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android获取EditText内容,TextWatcher按条件触发

android获取EditText内容&#xff0c;TextWatcher按条件触发 背景&#xff1a;解决方案&#xff1a;效果&#xff1a; 背景&#xff1a; 最近在尝试用原生安卓实现仿element-ui表单校验功能&#xff0c;其中涉及到EditText组件内容的动态校验&#xff0c;初步实现功能后&#…

hive:基本数据类型,关于表和列语法

基本数据类型 Hive 的数据类型分为基本数据类型和复杂数据类型 加粗的是常用数据类型 BOOLEAN出现ture和false外的其他值会变成NULL值 没有number,decimal类似number 如果输入的数据不符合数据类型, 映射时会变成NULL, 但是数据本身并没有被修改 创建表 创建表的本质其实就是在…

《LLM大语言模型+RAG实战+Langchain+ChatGLM-4+Transformer》

文章目录 Langchain的定义Langchain的组成三个核心组件实现整个核心组成部分 为什么要使用LangchainLangchain的底层原理Langchain实战操作LangSmithLangChain调用LLM安装openAI库-国内镜像源代码运行结果小结 使用Langchain的提示模板部署Langchain程序安装langserve代码请求格…

【四川乡镇界面】图层shp格式arcgis数据乡镇名称和编码2020年wgs84无偏移内容测评

本文将详细解析标题和描述中提到的IT知识点&#xff0c;主要涉及GIS&#xff08;Geographic Information System&#xff0c;地理信息系统&#xff09;技术&#xff0c;以及与之相关的文件格式和坐标系统。 我们要了解的是"shp"格式&#xff0c;这是一种广泛用于存储…

数据分析系列--⑤RapidMiner进行关联分析(中文数据案例)

一、数据集 二、数据预处理 1.读取数据、拆分、重命名 2.数据预处理 三、关联分析 四、结论 一、数据集 点击下载数据集shopping_basket.xlsx ,这个数据集专门使用中文数据来进行分析. 二、数据预处理 1.读取数据、拆分、重命名 2.数据预处理 三、关联分析 四、结论 Ok,E…

拦截器快速入门及详解

拦截器Interceptor 快速入门 什么是拦截器&#xff1f; 是一种动态拦截方法调用的机制&#xff0c;类似于过滤器。 拦截器是Spring框架中提供的&#xff0c;用来动态拦截控制器方法的执行。 拦截器的作用&#xff1a;拦截请求&#xff0c;在指定方法调用前后&#xff0c;根…

PythonFlask框架

文章目录 处理 Get 请求处理 POST 请求应用 app.route(/tpost, methods[POST]) def testp():json_data request.get_json()if json_data:username json_data.get(username)age json_data.get(age)return jsonify({username: username测试,age: age})从 flask 中导入了 Flask…

134.力扣刷题--加油站--滑动窗口

你知道的&#xff0c;失败总是贯穿人生的始终。 加油站 在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发&#x…

大数据学习之Kafka消息队列、Spark分布式计算框架一

Kafka消息队列 章节一.kafka入门 4.kafka入门_消息队列两种模式 5.kafka入门_架构相关名词 Kafka 入门 _ 架构相关名词 事件 记录了世界或您的业务中 “ 发生了某事 ” 的事实。在文档中 也称为记录或消息。当您向 Kafka 读取或写入数据时&#xff0c;您以事件的 形式执行…

书生大模型实战营5

文章目录 L1——基础岛书生大模型全链路开源开放体系概览书生大模型全链路的数据书生大模型全链路的开源数据处理工具箱预训练 InterEvo微调 XTunerOpenCompass 评测体系部署 LMDeploy智能体 Lagent智能体 MindSearchHuixiangDou L1——基础岛 书生大模型全链路开源开放体系 …

Deepseek技术浅析(二):大语言模型

DeepSeek 作为一家致力于人工智能技术研发的公司&#xff0c;其大语言模型&#xff08;LLM&#xff09;在架构创新、参数规模扩展以及训练方法优化等方面都达到了行业领先水平。 一、基于 Transformer 架构的创新 1.1 基础架构&#xff1a;Transformer 的回顾 Transformer 架…

leetcode——对称二叉树(java)

给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false 解题方法&#xff1a;&#xff08…

Spring Boot 日志:项目的“行车记录仪”

一、什么是Spring Boot日志 &#xff08;一&#xff09;日志引入 在正式介绍日志之前&#xff0c;我们先来看看上篇文章中&#xff08;Spring Boot 配置文件&#xff09;中的验证码功能的一个代码片段&#xff1a; 这是一段校验用户输入的验证码是否正确的后端代码&#xff0c…

android 圆形弹窗摄像头开发踩坑——源码————未来之窗跨平台操作

一、飘窗刷脸&#xff0c;拍照采用飘窗 刷脸认证安卓接口采用飘窗具有在不干扰用户主要操作的前提下以醒目方式引导用户完成认证&#xff0c;且能灵活定制样式以提升用户体验和认证效率的优点 二、踩坑只有一个扇形 <?xml version"1.0" encoding"utf-8&quo…

DeepSeek的崛起与全球科技市场的震荡

引言 近年来&#xff0c;人工智能&#xff08;AI&#xff09;技术的快速发展不断重塑全球科技格局。 近日&#xff0c;中国初创企业DeepSeek推出了一款据称成本极低且性能强大的AI模型&#xff0c;引发全球市场的剧烈反应。NVIDIA、台积电等半导体和AI科技巨头股价大幅下跌&am…

单机伪分布Hadoop详细配置

目录 1. 引言2. 配置单机Hadoop2.1 下载并解压JDK1.8、Hadoop3.3.62.2 配置环境变量2.3 验证JDK、Hadoop配置 3. 伪分布Hadoop3.1 配置ssh免密码登录3.2 配置伪分布Hadoop3.2.1 修改hadoop-env.sh3.2.2 修改core-site.xml3.2.3 修改hdfs-site.xml3.2.4 修改yarn-site.xml3.2.5 …

大数据相关职位 职业进阶路径

大数据相关职位 & 职业进阶路径 &#x1f4cc; 大数据相关职位 & 职业进阶路径 大数据领域涵盖多个方向&#xff0c;包括数据工程、数据分析、数据治理、数据科学等&#xff0c;每个方向的进阶路径有所不同。以下是大数据相关职位的详细解析及其职业进阶关系。 &#…

《大语言模型》综述学习笔记

《A Survey of Large Language Models》英文版综述最近出了中文版书——《大语言模型》&#xff0c;本博客作为阅读笔记记录一下&#xff0c;综述主页&#xff1a;https://github.com/RUCAIBox/LLMSurvey 关于LLM的一些概述和理解 记录一些有启发性的说法&#xff1a; 1、当前…

供应链系统设计-供应链中台系统设计(十二)- 清结算中心设计篇(一)

概述 在之前的文章中&#xff0c;我们通过之前的两篇文章中&#xff0c;如下所示&#xff1a; 供应链系统设计-供应链中台系统设计&#xff08;十&#xff09;- 清结算中心概念片篇 供应链系统设计-供应链中台系统设计&#xff08;十一&#xff09;- 清结算中心概念片篇 说…

MySQL查询优化(三):深度解读 MySQL客户端和服务端协议

如果需要从 MySQL 服务端获得很高的性能&#xff0c;最佳的方式就是花时间研究 MySQL 优化和执行查询的机制。一旦理解了这些&#xff0c;大部分的查询优化是有据可循的&#xff0c;从而使得整个查询优化的过程更有逻辑性。下图展示了 MySQL 执行查询的过程&#xff1a; 客户端…