基于网页知识库的检索增强生成RAG
0.项目信息
- 日期: 2023-12-2
- 作者:小知
- 课题: RAG(Retrieval-Augmented Generation,检索增强生成)是一种利用知识库检索的方法,提供与用户查询相关的内容,从而增强模型答案的准确性和特异性。RAG包括本地知识库、基于网络的知识库、记忆知识库和数据库知识库。
- PyLMKit设计了四种RAG功能:
- 基于本地文档的知识库DocRAG
- 基于网页的知识库WebRAG
- 基于数据库的知识库DBRAG
- 基于记忆的知识库MemoryRAG
- GitHub:https://github.com/52phm/pylmkit
- PyLMKit官网教程
- PyLMKit应用(online application)
- English document
- 中文文档
PyLMKit RAG架构图
1.下载安装
# 下载安装
pip install pylmkit -U --user
pip install sentence-transformers --user
pip install faiss-cpu --user
2.设置API KEY
应用哪个大模型,就提前设置好该大模型对应的 API KEY
import os
# openai chatgpt
os.environ['openai_api_key'] = ""
# 百度
os.environ['qianfan_ak'] = ""
os.environ['qianfan_sk'] = ""
# 阿里
os.environ["DASHSCOPE_API_KEY"] = ""
# 科大讯飞-星火
os.environ["spark_appid"] = ""
os.environ["spark_apikey"] = ""
os.environ["spark_apisecret"] = ""
os.environ["spark_domain"] = "generalv3"
# 智谱AI
os.environ['zhipu_apikey'] = ""
或者在.env
文件中批量加载设置好的API KEY
,加载方法如下:
from dotenv import load_dotenv
# load .env
# load_dotenv()
3.加载大语言模型
导入大语言模型,在本案例中使用百度千帆
大模型作为例子进行介绍。
from pylmkit.llms import ChatQianfan # 百度-千帆
from pylmkit.llms import ChatSpark # 讯飞-星火
from pylmkit.llms import ChatZhipu # 清华-智谱
from pylmkit.llms import ChatHunyuan # 腾讯-混元
from pylmkit.llms import ChatBaichuan # 百川
from pylmkit.llms import ChatTongyi # 阿里-通义
from pylmkit.llms import ChatOpenAI # OpenAI
llm_model = ChatQianfan()
4.选择记忆功能
PyLMKit 设计了四种记忆功能,分别如下:
- MemoryHistoryLength:记忆历史长度,强调使用近期多长的记忆内容;
- MemoryConversationsNumber:记忆对数数,强调使用近期N组对话作为记忆的内容;
- MemorySummary:记忆摘要,强调精简提取记忆;
- 暂未公布
本案例使用MemoryHistoryLength
记忆功能,使得大语言模型能到根据该历史记忆记住上下文内容,以便连贯回答用户的问题。(更多关于记忆的用法,可以在后续memory专题中查阅)
from pylmkit.memory import MemoryHistoryLength
memory = MemoryHistoryLength(memory_length=500, streamlit_web=False) # 在python中运行
# memory2 = MemoryHistoryLength(memory_length=500, streamlit_web=True) # 在streamlit web中运行
5.设计角色模板
大语言模型是一种一对多
关系的模型架构,其中一
表示大语言模型,而多
表示下游任务,比如写作、客服、分析数据等这些都属于下游任务。
因此需要我们通过设计提示词模板去引导大语言模型高效且有质量地完成指定下游任务
。
在设计角色模板之前,我们先来了解PyLMKit
中一些必须固定的关键词:
- {query}:表示这是用户输入的提问内容;
- {search}:表示线上实时搜索引擎搜索返回的内容;
- {memory}:表示记忆的内容;
- {ra}:表示知识库搜索返回的内容。
下面我们来看一个角色模板的例子:
# 它们所在的位置,表示它们内容所嵌入的位置
role_template = "{memory}\n {search}\n 用户提问:{query}"
# 当然,你还可以进一步设计模板
role_template = "历史对话内容:{memory}\n 搜索的相似内容:{search} {ra}\n 请结合上述内容回答问题:{query}"
model.invoke(query="如何学习python?")
角色模板决定大语言模型回答的质量,因此角色模板需要反复打磨,以设计一个高质量的角色模板,对问题的解决效果可以达到事半功倍。
另外,值得注意的是,如果你设计的角色模板的关键词,不在[query, search, ra, memory]
中,那么你需要额外添加新的变量和变量值,例如:
role_template = "{memory}\n 请为我推荐{query}的{topic}"
# 额外的关键字,可以像 topic="美食" 一样添加,多个也是一样的步骤进行添加
model.invoke(query='北京', topic="美食")
role_template = "{memory}\n 请为我推荐{query}的{topic}"
6.加载知识库
PyLMKit设计了四种RAG功能:
- 基于本地文档的知识库DocRAG
- 基于网页的知识库WebRAG
- 基于数据库的知识库DBRAG
- 基于记忆的知识库MemoryRAG
本案例介绍DocRAG
和WebRAG
,下面先介绍如何快速加载本地文档和网页知识库。
- 加载本地知识库
DocumentLoader
from pylmkit.perception.text import DocumentLoader
# 加载器:可以加载一个文档,也可以批量加载指定文件夹中的文档
# loader = DocumentLoader(path='./document_test/aaa.txt')
loader = DocumentLoader(path='./document_test', show_progress=True)
# 分割器
docs1 = loader.split(chunk_size=200, chunk_overlap=50)
print(len(docs1))
print(docs1[0])
0%| | 0/5 [00:00<?, ?it/s]2023-12-02 12:20:29 - pylmkit.perception.directory - WARNING - Error loading file document_test\loader.yaml: Invalid file document_test\loader.yaml. The FileType.UNK file type is not supported in partition.
20%|████████████████▊ | 1/5 [00:01<00:07, 1.90s/it]2023-12-02 12:20:29 - pylmkit.perception.directory - WARNING - Error loading file document_test\qqqqq.yaml: Invalid file document_test\qqqqq.yaml. The FileType.UNK file type is not supported in partition.
100%|████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:03<00:00, 1.45it/s]
144
page_content='电机(俗称“马达”)是指依据电磁感应定律实现电能转换或传递的一种电磁装置。分为电动机(符号为M)和发电机(符号为G)。\n\n中文名电机\n\n外文名Electric machinery\n\n依据原理电磁感应定律\n\n电路中表示电动机为M,发电机为G\n\n定 义电能转换或传递的一种电磁装置\n\n目录\n\n1划分\n\n2直流式\n\n3电磁式\n\n4直流电机\n\n▪他励\n\n▪并励\n\n▪串励\n\n▪复励\n\n5永磁式' metadata={'source': 'document_test\\aaa.txt'}
- 加载网页知识库
WebLoader
from pylmkit.perception.text import WebLoader
# 加载器:可以加载一个网页,也可以批量加载网页
loader = WebLoader(path='https://zhuanlan.zhihu.com/p/339971541')
# loader = WebLoader(
# path=[
# 'https://zhuanlan.zhihu.com/p/339971541',
# 'https://zhuanlan.zhihu.com/p/339971541',
# ]
# )
# 分割器
docs2 = loader.split(chunk_size=200, chunk_overlap=50)
print(len(docs2))
print(docs2[-1])
2023-12-02 12:20:31 - langchain.document_loaders.web_base - INFO - fake_useragent not found, using default user agent.To get a realistic header for requests, `pip install fake_useragent`.
44
page_content=',因此相比竞品而言 上 汽魔方电池在各个容量电池包的体积效率转换和重量效率转换都更为出色。上汽魔方电池躺式布局https://www.zhihu.com/video/1549353400738979841编辑于 2022-09-03 11:19动力电池锂电池\u200b赞同 183\u200b\u200b7 条评论\u200b分享\u200b喜欢\u200b收藏\u200b申请转载\u200b' metadata={'source': 'https://zhuanlan.zhihu.com/p/339971541', 'title': '一文读懂汽车动力电池 - 知乎', 'description': '动力电池作为电动汽车的三大件(电池、电机、电控)之一,是整个车辆系统的动力来源,一直以来被视为电动汽车发展的标志性技术,其性能好坏直接关系到车辆续航里程的长短,重要性不言而喻。今天小七带大家拨开迷雾…', 'language': 'zh'}
可以将本地知识库和网页知识库融合应用。
docs = []
docs.extend(docs1)
docs.extend(docs2)
print(len(docs))
188
7.加载词向量模型
文本是一种非结构化的数据类型,因此需要使用词嵌入技术将文本向量化,PyLMKit提供两大类型的词向量模型调用:
- 使用付费的词向量模型:通过API调用词向量模型,如OpenAI的
EmbeddingsOpenAI
,百度千帆的EmbeddingsQianfan
- 下载开源模型到本地免费使用:在
huggingface
中下载模型,如EmbeddingsHuggingFace
,EmbeddingsHuggingFaceBge
和EmbeddingsHuggingFaceInstruct
除了通过PyLMKit
调用,还支持langchain
导入。
另外,值得注意的是,不同词向量模型的准确性不一,因此也要选择合适的词向量模型才能发挥更大的作用。
# 付费调用
from pylmkit.llms import EmbeddingsQianfan # 百度-千帆-词向量模型
from pylmkit.llms import EmbeddingsOpenAI # OpenAI-词向量模型
# 本地调用
from pylmkit.llms import EmbeddingsHuggingFace # 使用 HuggingFace 中开源模型
from pylmkit.llms import EmbeddingsHuggingFaceBge
from pylmkit.llms import EmbeddingsHuggingFaceInstruct
# 本案例使用本地模型,为了方便使用一个小模型(下载模型一般会下载超时,需合理上网)
embed_model = EmbeddingsHuggingFace(model_name="all-MiniLM-L6-v2")
G:\anzhuangqu\anaconda2023\envs\gradio_env\Lib\site-packages\tqdm\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
from .autonotebook import tqdm as notebook_tqdm
2023-12-02 12:20:37 - sentence_transformers.SentenceTransformer - INFO - Load pretrained SentenceTransformer: all-MiniLM-L6-v2
2023-12-02 12:20:38 - sentence_transformers.SentenceTransformer - INFO - Use pytorch device: cpu
8.加载向量数据库
向量数据库无疑是今年的大热点,因为RAG或者说基于本地知识库的垂直领域知识问答,这种低成本且可行的技术方案在今年特别爆火,而向量数据库作为一种能存储向量和检索相似文档中起着重要作用。
下面使用FAISS
向量数据库进行演示。
from langchain.vectorstores import FAISS
vdb_model = FAISS
9.加载RAG应用
PyLMKit设计了四种RAG功能:
- 基于本地文档的知识库DocRAG
- 基于网页的知识库WebRAG
- 基于数据库的知识库DBRAG
- 基于记忆的知识库MemoryRAG
RAG是基于知识库检索 + RolePlay角色扮演两部分组成,因此RAG具备RolePlay应用的参数和功能。
from pylmkit.app import DocRAG
from pylmkit.app import WebRAG
# 角色模板可以根据自己情况进行设计,这是一个简单例子
role_template = "{ra}\n user question: {query}"
rag = DocRAG(
embed_model=embed_model,
vdb_model=vdb_model,
llm_model=llm_model,
corpus=docs,
role_template=role_template,
return_language="中文",
online_search_kwargs={},
# online_search_kwargs={'topk': 2, 'timeout': 20}, # 搜索引擎配置,不开启则可以设置为 online_search_kwargs={}
)
Batches: 100%|███████████████████████████████████████████████████████████████████████████| 6/6 [00:06<00:00, 1.02s/it]
2023-12-02 12:20:44 - faiss.loader - INFO - Loading faiss with AVX2 support.
2023-12-02 12:20:44 - faiss.loader - INFO - Could not load library with AVX2 support due to:
ModuleNotFoundError("No module named 'faiss.swigfaiss_avx2'")
2023-12-02 12:20:44 - faiss.loader - INFO - Loading faiss.
2023-12-02 12:20:44 - faiss.loader - INFO - Successfully loaded faiss.
10.在python中运行
while True:
query = input("User query:")
response, refer = rag.invoke(query, topk=10) # 使用检索最相似的topk=10个
print("\nAI:\n", response)
print("\nRefer:\n", refer)
User query:电机有哪些类型?
Batches: 100%|███████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 33.42it/s]
>>><<< 10
AI:
电机主要有以下几种类型:
1. 直流电机:它是一种将直流电能转换为机械能的旋转电机。
2. 交流电机:它是一种将交流电能转换为机械能的旋转电机,最常见的类型是异步电机和同步电机。
3. 无刷电机:它是一种无需机械式转动部件的电机,通常使用直流电源或交流电源驱动。
4. 永磁电机:它使用永久磁铁产生磁场,通常用于高速旋转设备,如吹风机或电动工具。
此外,软启动器通常使用交流电机,因为它没有碳刷和整流子,所以它具有免维护、坚固、应用广的特点。在控制方面,它使用复杂控制技术来达到相当于直流电机的性能。在微处理机和功率组件发展迅速的今天,通过适当控制交流电机的电流分量,可以实现对交流电机的控制并达到类似于直流电机的性能。在某些特定的场合下,软启动器还会提供软停车功能,以避免自由停车引起的转矩冲击。在推广无刷电机的使用和维护时,我们也需要加强宣传和培训工作。
至于你提到的“为什么动力电池偏偏用的是锂电池呢?”这个问题,能量密度是一个重要的考虑因素。锂电池具有较高的能量密度,可以提供更长的行驶距离或工作时间,因此被广泛应用于电动汽车等动力系统中。同时,锂电池的充电和放电性能也较好,适合于大功率和快速充电的应用场景。当然,在选择动力电池时还需要考虑其他因素,如安全性、寿命、成本等。
Refer:
[1] **document_test\aaa.txt** 固定磁场无刷电机
[2] **document_test\aaa.txt** 弱磁控制:当电机转速超过一定数值后,励磁电流已经相当小,基本不能再调节,此时进入弱磁控制阶段。
[3] **document_test\aaa.txt** 于环境极为恶劣的场合,如潮湿、高温、多尘、腐蚀等场合。所有这些,造成了电机更容易损坏,尤其是过载、短路、缺相、扫膛等故障出现频率最高。
[4] **document_test\aaa.txt** 机床上传统的“旋转电机 +
[5] **document_test\aaa.txt** 三、磁阻同步电动机
[6] **https://zhuanlan.zhihu.com/p/339971541** 电池,就不得不拉回正题,谈谈动力电池,目前市面上电动汽车基本上都采用的是锂离子电池(以下简称锂电池),可能会有很多朋友会问,为什么动力电池偏偏用的是锂电池呢?回答这个问题前,我们先来看看一个概念——能量密度。能量密度(Energy
[7] **document_test\aaa.txt** 定电压,以降低晶闸管的热损耗,延长软启动器的使用寿命,提高其工作效率,又使电网避免了谐波污染。软启动器同时还提供软停车功能,软停车与软启动过程相反,电压逐渐降低,转数逐渐下降到零,避免自由停车引起的转矩冲击。
[8] **document_test\aaa.txt** 控制原理
[9] **document_test\aaa.txt** 到限制。交流电机没有碳刷及整流子,免维护、坚固、应用广,但特性上若要达到相当于直流电机的性能须用复杂控制技术才能达到。现今半导体发展迅速功率组件切换频率加快许多,提升驱动电机的性能。微处理机速度亦越来越快,可实现将交流电机控制置于一旋转的两轴直交坐标系统中,适当控制交流电机在两轴电流分量,达到类似直流电机控制并有与直流电机相当的性能。
[10] **document_test\aaa.txt** 五、加强宣传培训
User query:动力电池有哪些分类?
Batches: 100%|███████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 83.53it/s]
>>><<< 10
AI:
您好!动力电池根据不同标准有不同分类方式,常见分类如下:
1. 按照工作性质可分为:动力电池、牵引电池(含蓄电池)、起动电池;
2. 按照正极材料种类可分为:钴酸锂电池、锰酸锂电池、三元材料(NCM)电池、磷酸铁锂(LFP)电池;
3. 按照电池的形状可分为:圆柱形电池、方壳电池、软包电池。
以上是动力电池常见的分类方式,具体到上汽魔方电池,其采用的是躺式布局的锂离子电池,具有能量密度高、体积小、重量轻等优势。同时,上汽魔方电池还具有高低温性能优异、安全性好、寿命长等优势。
以上信息仅供参考,如果您还有疑问,建议咨询专业人士意见。
Refer:
[1] **https://zhuanlan.zhihu.com/p/339971541** 一文读懂汽车动力电池 -
[2] **https://zhuanlan.zhihu.com/p/339971541** 电池,就不得不拉回正题,谈谈动力电池,目前市面上电动汽车基本上都采用的是锂离子电池(以下简称锂电池),可能会有很多朋友会问,为什么动力电池偏偏用的是锂电池呢?回答这个问题前,我们先来看看一个概念——能量密度。能量密度(Energy
[3] **document_test\aaa.txt** 固定磁场无刷电机
[4] **document_test\aaa.txt** 弱磁控制:当电机转速超过一定数值后,励磁电流已经相当小,基本不能再调节,此时进入弱磁控制阶段。
[5] **document_test\aaa.txt** 直流电动机工作原理
导体受力的方向用左手定则确定。这一对电磁力形成了作用于电枢一个力矩,这个力矩在旋转电机里称为电磁转矩,转矩的方向是逆时针方向,企图使电枢逆时针方向转动。如果此电磁转矩能够克服电枢上的阻转矩(例如由摩擦引起的阻转矩以及其它负载转矩),电枢就能按逆时针方向旋转起来。
[6] **https://zhuanlan.zhihu.com/p/339971541** ,因此相比竞品而言 上 汽魔方电池在各个容量电池包的体积效率转换和重量效率转换都更为出色。上汽魔方电池躺式布局https://www.zhihu.com/video/1549353400738979841编辑于 2022-09-03 11:19动力电池锂电池赞同 1837 条评论分享喜欢收藏申请转载
[7] **document_test\aaa.txt** 二、认真组织电机生产企业执行强制性能效标准
[8] **document_test\aaa.txt** 机床上传统的“旋转电机 +
[9] **document_test\aaa.txt** 到限制。交流电机没有碳刷及整流子,免维护、坚固、应用广,但特性上若要达到相当于直流电机的性能须用复杂控制技术才能达到。现今半导体发展迅速功率组件切换频率加快许多,提升驱动电机的性能。微处理机速度亦越来越快,可实现将交流电机控制置于一旋转的两轴直交坐标系统中,适当控制交流电机在两轴电流分量,达到类似直流电机控制并有与直流电机相当的性能。
[10] **document_test\aaa.txt** 控制原理
11.在streamlit web中运行
要在终端中运行:假设你的.py
文件名为main.py
,那么在终端运行:
streamlit run main.py
# main.py
from pylmkit.core.base import BaseWebUI
from pylmkit.memory import MemoryHistoryLength
web = BaseWebUI(language='zh') # 使用中文网站
memory = MemoryHistoryLength(memory_length=web.param(label="记忆长度", type='int', value=500), # 添加页面交互参数
streamlit_web=True
)
web.run(
obj=rag.invoke,
input_param=[{"name": "query", "label": "用户输入内容", "type": "chat"},
{"name": "topk", "label": "最相似topk", "type": "int"},
],
output_param=[{'label': '结果', 'name': 'response', 'type': 'chat'},
{'label': '参考', 'name': 'refer', 'type': 'refer'}
]
)