向量算法的选型
完成了文本导入后,可以尝试测试一下效果了。
Chroma向量库中原生的embeddings效果不理想,使用的是 all-MiniLM-L6-v2 算法来进行向量嵌入。这个算法来自于 Sentence Transformers 库。Sentence Transformers 的还有其他算法:
Model |
Performance Semantic Search (6 Datasets) |
Queries (GPU / CPU) per sec. |
multi-qa-MiniLM-L6-dot-v1 |
49.19 |
18,000 / 750 |
multi-qa-distilbert-dot-v1 |
52.51 |
7,000 / 350 |
multi-qa-mpnet-base-dot-v1 |
57.60 |
4,000 / 170 |
拿西游记的全文向量化导入后,查询 东胜神洲(孙悟空的老家花果山) 相关的信息,发现基本无法命中结果。
于是重新修改向量的算法,看了一下,如果要自定义向量算法,只需要按照以下的数据导入到库里就行。
collection.add( 文章内容:documents=["doc1", "doc2", "doc3", ...], 向量内容:embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...], 原始数据:metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...], ID:ids=["id1", "id2", "id3", ...] )
我们在魔搭ModelScope社区。
在https://modelscope.cn/models/damo/nlp_corom_sentence-embedding_chinese-base/summary上查看有关该模型的详细信息 。 在不同的领域还可以选择不同的的CoROM模型。
我们对文本分割器和向量库进行了修改后,重新导入了文本,并进行了查询,这次终于成功地获得了有关东胜神洲的相关信息。
最终效果
把模型+Prompt+向量算法+向量数据库组合起来后,选用的技术和框架如下图所示:
总结
用手工编写的方式实现了完整基于个人知识库的QA Bot,采用手工编写的方式。相比于langchain,这种方法具有以下优点:
- 可以通过SaaS服务对每个部分进行加速,
- 每个部分都可以轻松地进行自定义修改。通过简单修改modelid可以使用modelscope的社区的模型,更加适合中文场景。
- 在满足硬件条件的情况下,可以轻松地将其改为分布式架构,以处理高频访问。
然而,我们可以看到回答的效果仍然不是很好, 文本分割和向量化的过程会直接影响结果,但是对比直接使用langchain,灵活性和中文的相关性好了很多(不过langchain也可以改向量算法)。
在专业领域来说,如果有已经构建好知识图谱的数据,使用这种方式可能会取得非常好的效果。
30分钟快速体验
以下代码已经在modelscope社区的notebook的环境中测试通过。从编写代码到回复,大概需要30分钟左右即可完成,非常适合测试和验证。
1、 安装依赖 ,为了方便使用,我已经把上述的代码整合成一个微型框架 vectorGPTBot 中。
pip install protobuf==3.20.0 transformers==4.27.1 icetk cpm_kernels chromadb pip install "modelscope[nlp]" -f https://modelscope.oss-cn-beijing.aliyuncs.com/releases/repo.html pip install vectorGPTBot=="0.1.6" -i https://pypi.Python.org/simple/
2、 在modelscope的环境中,由于pyhton是3.7的版本。请按照以下步骤修改文件
/opt/conda/lib/python3.7/site-packages/chromadb/api/types.py
将第一行修改为以下两行:
from typing import Optional, Union, Dict, Sequence, TypeVar, List from typing_extensions import Literal, TypedDict, Protocol
保存文件并退出。
3、 启动
有三个参数可以自由定义 , 后面两个可以去modelscope社区根据自己的需求进行更换。
v= mainClass( '/mnt/workspace/test2', #向量数据库保存的路径 "damo/nlp_corom_sentence-embedding_chinese-base", #文本向量算法 "ZhipuAI/ChatGLM-6B", #llm模型 )
核心是两个命令
- v.put_data 把数据导入向量库
- v.query_data 查询数据
from vectorGPTBot.vectorGPTBot import mainClass v= mainClass( '/mnt/workspace/test2', #向量数据库保存的路径 "damo/nlp_corom_sentence-embedding_chinese-base", #文本向量算法 "ZhipuAI/ChatGLM-6B", #llm模型 ) v.put_data([ '你是谁?我是向量知识库问答机器人。', '你可以做什么?回答问题。', '吃了海鲜后是不能再喝牛奶的,因为牛奶中含得有维生素C,如果海鲜喝牛奶一起服用会对人体造成一定的伤害', '吃海鲜是不能同时喝牛奶吃水果,这个至少间隔6小时以上才可以。', '吃海鲜是不可以吃柠檬的因为其中的维生素C会和海鲜中的矿物质形成砷。', ]) v.query_data('你是谁?')