赞
踩
实现一个依据 wiki.deepin.org 网站内容回答问题的机器人。
https://wiki.deepin.org 上有900多条deepin系统相关的中文教程和词条,请编写能根据这些内容回答问题的中文聊天机器人。
使用者通过命令行界面输入问题,机器人输出回答和参考的wiki文档的链接。
题目需要实现一个能够基于Deepin系统文档问答的聊天机器人,基于文档的问答系统(Document-Based Question Answering System)是一种自然语言处理技术(NLP),用于回答用户提出的问题。它的原理是通过分析文档中的内容,提取出与用户问题相关的信息,并将其转换成可回答问题的格式。基于深度神经网络的机器阅读理解 ( Machine Reading Comprehension,MRC )的发展,MRC模型以问题和文档为输入,通过阅读文档内容预测问题的答案。根据需要预测的答案形式不同,阅读理解任务可以分为填空式 ( Cloze-style )、多项选择式 ( Multi-choice )、片段提取式 ( Span-extraction ) 和自由文本 ( Free-form )。最具影响力的片段提取式MRC公开数据集有SQuAD和MSMARCO等,这些数据集的出现促进了MRC模型的发展。
近年来预训练语言模型如BERT,RoBERTa和XLNet等在众多NLP任务上取得突破性进展,尤其是在阅读理解任务上。这些工作在编码阶段采用Transformer结构获得问题和文档向量表示,在输出层同样采用边界预测方式预测答案在文档中的位置。
这里实际做的是将用户请求的query和document做匹配,也就是所谓的q-d匹配。q-d匹配的问题在于query和document在表达方式存在较大差异,通常query是以疑问句为主,而document则以称述说明为主,这种差异可能会影响最终匹配的效果。一种改进的方法是,不直接做q-d匹配,而是先通过document生成一批候选的question,当用户发来请求的时候,首先是把query和候选的question做匹配,进而找到相关的document片段,这种方法就是’q-q匹配’,具体思路如下:
SimBERT是一个融生成和检索于一体的模型,可以用来作为句向量的一个比较高的baseline,也可以用来实现相似问句的自动生成,可以作为辅助数据扩增工具使用,它以Google开源的BERT模型为基础,基于微软的UniLM思想设计了融检索与生成于一体的任务,来进一步微调后得到的模型,所以它同时具备相似问生成和相似句检索能力。SimBERTv2是SimBERT的升级版,它们主要的区别在于训练的细节上,可以用两个公式进行对比:
S
i
m
B
E
R
T
=
B
E
R
T
+
U
n
i
L
M
+
对比学习
S
i
m
B
E
R
T
v
2
=
R
o
f
o
r
m
e
r
+
U
n
i
L
M
+
对比学习
+
B
A
R
T
+
蒸馏
SimBERT=BERT+UniLM+对比学习 \\ SimBERTv2=Roformer+UniLM+对比学习+BART+蒸馏
SimBERT=BERT+UniLM+对比学习SimBERTv2=Roformer+UniLM+对比学习+BART+蒸馏SimBERT属于有监督训练,训练语料是自行收集到的相似句对,通过一句来预测另一句的相似句生成任务来构建Seq2Seq部分,
ChatGLM-6B 是一个开源的、支持中英双语的对话语言模型,基于 General Language Model (GLM) 架构,具有 62 亿参数。ChatGLM-6B 使用了和 ChatGPT 相似的技术,针对中文问答和对话进行了优化。经过约 1T 标识符的中英双语训练,辅以监督微调、反馈自助、人类反馈强化学习等技术的加持,62 亿参数的 ChatGLM-6B 已经能生成相当符合人类偏好的回答。
ChatGLM2-6B 是开源中英双语对话模型 ChatGLM-6B 的第二代版本,在保留了初代模型对话流畅、部署门槛较低等众多优秀特性的基础之上,ChatGLM2-6B 引入了新特性。该模型具有以下特点:
ChatGPT是一种大规模预训练语言模型,可以生成自然语言响应。它的原理是在大量的文本数据上进行训练,从而学习到自然语言的结构、规则和语义。使用ChatGPT模型可以解决询问文档中不相关问题是,模型能够依托其大语言模型给出相似答案。
时下主流的预训练框架有三种:autoregressive自回归模型(如GPT)、autoencoding自编码模型(如BERT)、encoder-decoder编码-解码模型(如T5、BigBird)。GLM模型基于autoregressive blank infilling方法,结合了上述三种预训练模型的思想。从简易化出发,我们选择了技术面更广更新的GLM模型,而并未选择BERT模型。
在确定了Langchain 与 ChatGLM 等大语言模型为框架的基础下,需选取Embedding 模型和 LLM 作为本地模型接入。我们对目前已有的模型进行学习和研究,并最终确定了 THUDM/chatglm2-6b 作为 LLM,moka-ai/m3e-base、GanymedeNil/text2vec-large-chinese 作为 Embedding 模型。
最终,我们采用了基于 Langchain 与 ChatGLM 等大语言模型的本地知识库问答应用实现该功能。下为原理图:
首先将本地文档(LocalDocuments)输入到Langchain中,并加载文档(UnstructuredLoader),随后对得到的文本(Text)进行文本分割(TextSplitter),之后构建向量库(Embedding),并将其存储到本地(VectorStore)。当用户进行询问时,Langchain将用户询问内容进行同样向量化处理,并与池化后的向量库进行相似度匹配,选取与用户询问相似度最高的内容作为结果通过大语言模型(LargeLanguageModel)输出给用户最终答案。
为设计基于文档问答机器人,首先需获取全部文档作为训练集,题目已给出与Deepin操作系统相关的全部markdown文档,通过下面指令添加到本地仓库。
git clone https://github.com/linuxdeepin/wiki.deepin.org.git
文档中存在很多不便于展示的图片,在对文档进行处理后,保留有效的文件作为dataset。并在每个文档中添加如下信息:
参考链接:<url>
将得到的训练集分别以.md(markdown)和.txt格式存储。
硬件配置:
CPU AMD Ryzen 9 3950X 16-Core Processor
GPU NVIDIA GeForce RTX 2070
操作系统:
Ubuntu 18.04LTS、Windows 10 1909H
项目环境:Python 3.8.1、CUDA 11.8
首先需要将模型下载至本地,由于模型文件过大需要用LFS服务进行大文件下载,需安装 Git LFS,随后从huggingface上找到需要的模型文件进行clone。
git LFS install
git clone https://huggingface.co/THUDM/chatglm2-6b
git clone https://huggingface.co/moka-ai/m3e-base
git clone https://huggingface.co/GanymedeNil/text2vec-large-chinese
在模型下载完后,需要对项目进行配置,复制文件 configs/model_config.py.example
存储至项目路径下 ./configs
路径下,并重命名为 model_config.py
。在 model_config.py
中,需要指定使用本地模型及模型路径,并在llm_model_dict
与embedding_model_dict
中进行修改。
llm_model_dict={
"chatglm2-6b": {
"local_model_path": "/Users/chatglm2-6b",
"api_base_url": "http://localhost:8888/v1",
"api_key": "EMPTY"
},
}
embedding_model_dict = {
"m3e-base": "/Users/xxx/Downloads/m3e-base",
}
当前项目的知识库信息存储在数据库中,在正式运行项目之前需初始化数据库。第一次运行项目,知识库尚未建立,或者配置文件中的知识库类型、嵌入模型发生变化,需要以下命令初始化或重建知识库:
python3 init_database.py --recreate-vs
首先在终端中启动LLM服务,使用基于多进程脚本 llm_api.py 启动 LLM 服务:
python server/llm_api.py
再执行 server/api.py 脚本启动 API 服务;在线调用API服务的情况下,直接执执行 server/api.py 脚本启动 API 服务,启动 API 服务后,可访问 localhost:7861
FastAPI 自动生成的 docs 进行接口查看与测试。
python server/api.py
最后,执行 webui.py 启动 Web UI 服务(默认使用端口 8501):
streamlit run webui.py
在webui中,可以通过UI操作,点击知识库管理,随后向知识库中上传待训练的文件,在文件上传完后,点击添加知识库即可。
为使回答和问题要有80%以上概率的相关性,下面定义query句子,并获得它的向量表示:
query = '在此输入问题' # A query sentence uses for searching semantic similarity score.
queries = [query]
query_embeddings = model.encode(queries)
对得到的结果进行相似度检测,可以利用text2vec包,通过以下函数sim_model.get_score(s1[i], s2[j])
可计算得到余弦相似度值,score
范围是[-1, 1],值越大越相似。
import sys
sys.path.append('..')
from text2vec import Similarity
# Two lists of sentences
sentences1 = ['']
sentences2 = ['']
sim_model = Similarity()
for i in range(len(sentences1)):
for j in range(len(sentences2)):
score = sim_model.get_score(sentences1[i], sentences2[j])
print("{} \t\t {} \t\t Score: {:.4f}".format(sentences1[i], sentences2[j], score))```
我们对得到的结果进行多次相似度检测,计算均值得到结果为:
因此可确定该问答机器人回答准确率在90%以上。
[E050] Can't find model 'zh_core_web_sm'. It doesn't seem to be a Python package or a valid path to a data directory.
查阅资料后发现缺少 ‘zh_core_web_sm’ 模型,参考官网指导进行安装:
pip3 install en_core_web_sm-3.0.0.tar.gz
pip3 install zh_core_web_sm-3.0.0.tar.gz
-i https://pypi.tuna.tsinghua.edu.cn/simple/
Resource punkt not found. Please use the NLTK Downloader to obtain the resource
解决方案:运行下面代码:
import nltk
nltk.download()
在打开的界面中下载punkt模型:
通过本次开发Deepin系统文档问答机器人,我们有很多收获。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。