跳到主要内容
基于 Word2Vec 与 RAG 的个人知识库构建指南 | 极客日志
Python AI 算法
基于 Word2Vec 与 RAG 的个人知识库构建指南 基于 Word2Vec 和 RAG 技术构建个人知识库的完整流程。涵盖环境搭建、数据预处理(中文分词、简繁转换)、模型训练、向量生成与相似度计算、向量数据库(Qdrant)部署以及 ChatGLM 大模型集成。通过本地化部署实现私有知识检索问答。
t ag 发布于 2025/2/7 更新于 2026/6/14 28 浏览方案选择
目前的方案基本上可以分为:
LLM + Fine-tune:对已有的大模型进行微调,这种方式成本高,效果不一定很好。
LLM + 外挂知识库:就是本文章着重介绍的。
环境搭建
Python
安装 conda
brew install miniconda
创建自定义虚拟环境
conda create -n [[name]]
激活虚拟环境
conda activate [[name]]
NLP 相关依赖安装
自然语言处理,简称 NLP,是人工智能的一个分支,它允许机器理解、处理和操纵人类语言。
Pytorch
conda install pytorch
Numpy
conda install numpy
Scipy
conda install scipy
Gensim
⚠️ gensim 依赖于 scipy 和 numpy,一定要先安装前两者再安装。Gensim 是一个著名的开源 Python 库,用于从原始的非结构化的文本中,无监督地学习到文本隐层的主题向量表达。Gensim 支持包括 TF-IDF,LDA 和 word2vec 在内的多种主题模型算法,因此很多算法工程师会将其作为主题建模的首选库。
conda install -c conda-forge gensim
NLP 基础概念
标记 (Token):是具有已知含义的字符串,标记可以是单词、数字或只是像标点符号的字符。'你好'、'123'和'-'是标记的一些示例。
句子 (Sentence):是一组意义完整的记号。'天气看起来不错'是一个句子的例子,句子的标记是【'天气', '看起来', '不错'】。
段落 (Paragraph):是句子或短语的集合,也可以将句子视为段落的标记。
文档 (Documents):可能是一个句子、一个段落或一组段落。发送给个人的文本消息是文档的一个示例。
语料 (Corpus):通常是作为词袋的原始文档集合。语料库包括每个记录中每个单词的 id 和频率计数。语料库的一个例子是发送给特定人的电子邮件或文本消息的集合。
稀疏向量 (SparseVector):通常,我们可以略去向量中多余的 0 元素。此时,向量中的每一个元素是一个 (index, value) 的元组。
模型 (Model):是一个抽象的术语。定义了两个向量空间的变换(即从文本的一种向量表达变换为另一种向量表达)。
模型介绍
Word2vec
Word2Vec 是一种用于处理自然语言处理的模型,它是在 2013 年由 Google 的研究员 Mikolov 等人首次提出的。Word2Vec 通过训练海量的文本数据,能够将每个单词转换为一个具有一定维度的向量。这个向量就可以代表这个单词的语义。因为这个向量是在大量语境中学到的,所以这个向量能很好的表达这个单词的语义。Word2Vec 包括 Skip-Gram 和 CBOW 两种模型,主要是通过优化模型计算词与词之间的关系,从而获得词的向量表示。Skip-Gram 模型是通过一个词预测其上下文。举个例子,给定词汇'苹果',Skip-Gram 模型的目标是生成它的上下文'吃了一个大'和'感觉真满足'。CBOW 模型是给定一个词的上下文词汇,预测这个词。比如,给定上下文'吃了一个大'和'感觉真满足',CBOW 模型会预测中间的词汇,也就是'苹果'。这两种模型都是通过学习词汇与其上下文之间的关系,获得词的向量表示。这两个向量的距离可以用来衡量两个词语义上的相似度,距离越近意味着两个词语义上越相似。
同类型模型
word2vec 模型已经很老了,本教程主要用于教学,让读者对大模型相关知识有一些实践的了解,故不强追求质量效率等。若读者感兴趣,可尝试其他词向量模型。
GloVe(Global Vectors for Word Representation) :这是 Stanford 大学开发的一个词向量模型。不同于 Word2Vec,GloVe 会在全局的词频统计上进行建模从而生成词向量。因此会比 Word2Vec 更注重词与词之间的共现信息。
FastText :这是 Facebook AI 研究团队开发的一种模型,它在 Word2Vec 的基础上进行了扩展。FastText 不仅考虑整体词的信息,还考虑词中的子词信息。这使得 FastText 可以更好地处理词形变化以及拼写错误等问题。
ELMo(Embeddings from Language Models) :ELMo 模型把词的语境信息也考虑在内,它认为每一个词的表示应依赖于整个输入的句子。通过这种动态的词向量,ELMo 模型在很多 NLP 任务中达到了很好的效果。
BERT(Bidirectional Encoder Representations from Transformers) :这是 Google 在 2018 年提出的模型。BERT 通过使用 Transformer 模型,对上下文进行双向编码,从而对每个词生成更加丰富的向量表示。BERT 在一系列的 NLP 任务中都取得了非常好的效果。
数据处理
中文 Wiki
数据提取
数据处理
OpenCC Open Chinese Convert(OpenCC)是一个开源的中文简繁转换项目,致力于制作高质量的基于统计语料的简繁转换词库。还提供函数库 (libopencc)、命令行简繁转换工具、人工校对工具、词典生成程序、在线转换服务及图形用户界面。
pip3 install opencc-python-reimplemented
清华大学自然语言处理实验室数据集 [thuctc.thunlp.org/#%E6%A0%B7%…]
数据提取 我们下载的是.zip 文件,先原地解压 THUCNews.zip。
数据处理
数据合并 需要把所有数据集合并为一个数据集,作为最终训练模型用的数据集。
模型训练 数据集并不大,直接在本地硬造就行。训练 10 轮,大约一个半小时可以完成。
model = Word2Vec(sentences, vector_size=300 , window=5 , epochs=10 , compute_loss=True , callbacks=[epoch_logger])
模型使用
词向量生成 print (model.vector_size)
print (model.total_train_time)
print (model.wv.most_similar('猫' ))
print (model.wv.most_similar('吉林大学' ))
300
4965.289603250014
[('狗', 0.7110657691955566), ('猫咪', 0.671169638633728), ('小猫', 0.6650978326797485), ('兔子', 0.6501124501228333), ('小狗', 0.6325607691955566), ('小猫咪', 0.6306896805763245), ('犬', 0.620497543429565), ('宠物猫', 0.6035280227661133), ('吉娃娃', 0.5858094096183777), ('宠物狗', 0.5799086393902588)]
[('东北师范大学', 0.7164520621299744), ('大连理工大学', 0.6689789295196533), ('哈尔滨工程大学', 0.6448072791099548), ('哈尔滨工业大学', 0.6403888888888888), ('西北农林科技大学', 0.6375338888888888), ('东北财经大学', 0.6347338888888888), ('中国医科大学', 0.630100429058075), ('杭州大学', 0.6278635353535353), ('华东政法学院', 0.6263535353535353), ('白求恩医科大学', 0.626026346741)]
句向量生成 word2vec 模型本身只能对词语进行 embedding 操作,如果想对句子进行 embedding,有以下几种方法:
平均值:最简单的做法是将句子中所有词的向量进行平均。这会给你一个固定长度的向量,可以用作句子的 embedding,但是这种方法不包含句子的语序信息。
TF-IDF 加权平均:与简单的平均法类似,但是每个词的权重与其在句子中的 TF-IDF 值成比例。这可以强调句子中更重要的词,但仍然不包含语序信息。
Doc2Vec:这是一种在 word2vec 模型上进行了扩展,可以包含更大的上下文信息,即全文信息。Doc2Vec 可以生成一个整体的句子向量,且保留了语序信息。
神经网络:可以使用深度学习模型,如 RNN,GRU,LSTM 或 Transformer,这些模型可以利用 word2vec 词向量生成句子的嵌入向量,并且能捕捉到句子中的词序。
from typing import List , Dict
import numpy as np
from tqdm import tqdm
def encode (self, sentences: List [str ], show_progress_bar: bool = False , input_is_string: bool = False ) -> np.ndarray:
all_embeddings = []
for sentence in tqdm(sentences, desc='Word2Vec Embeddings' , disable=not show_progress_bar):
emb = []
count = 0
for word in sentence:
if word in self .stopwords:
continue
if word in self .w2v.key_to_index:
emb.append(self .w2v.get_vector(word, norm=True ))
count += 1
else :
if len (word) == 1 :
continue
ws = self .jieba.lcut(word, cut_all=True , HMM=True )
for w in ws:
if w in self .w2v.key_to_index:
emb.append(self .w2v.get_vector(w, norm=True ))
count += 1
tensor_x = np.array(emb).sum (axis=0 )
if count > 0 :
avg_tensor_x = np.divide(tensor_x, count)
else :
avg_tensor_x = np.zeros(self .w2v.vector_size, dtype=float )
all_embeddings.append(avg_tensor_x)
all_embeddings = np.array(all_embeddings, dtype=float )
if input_is_string:
all_embeddings = all_embeddings[0 ]
return all_embeddings
文档分块 def split_sentences (text ):
sent_delimiters = ['。' , '?' , '!' , '?' , '!' , '.' ]
for delimiter in sent_delimiters:
text = text.replace(delimiter, '\n' )
sentences = text.split('\n' )
sentences = [sent for sent in sentences if sent.strip()]
return sentences
除此之外,还可以考虑使用以下库:pyltp(语言技术平台)、pkuseg、spaCy、NLTK。
向量相似度计算 向量相似度的计算通常基于一种叫做余弦相似度(Cosine Similarity)的度量方法。余弦相似度直观地表示了两个向量间的夹角,其值越接近于 1,表示两个向量越相似。
def cosine_similarity (vec1, vec2 ):
norm_vec1 = np.linalg.norm(vec1)
norm_vec2 = np.linalg.norm(vec2)
if norm_vec1 == 0 or norm_vec2 == 0 :
return 0
else :
dot_product = np.dot(vec1, vec2)
return dot_product / (norm_vec1 * norm_vec2)
知识库检索
知识库端
将各类文档统一转为纯文本格式
文档分块
对各文档块进行向量化
将所有文本向量存储起来(持久化或非持久化均可)
查询端
将用户的查询语句向量化
将查询向量放入知识库进行相似性检索
获取检索到的向量,加入大模型的上下文中
获取大模型问答结果
使用以下背景段落来回答问题,如果段落内容不相关就返回未查到相关信息:
背景:{{knowledge}}
问题:{{userInput}}
向量数据库
定义 向量数据库是一种特殊类型的数据库,用于存储和检索向量嵌入以进行快速的相似性搜索。它们具有存储、查询和管理向量数据的能力,适用于各种应用,如语义搜索、图像识别、推荐系统等。向量数据库使用特殊的搜索技术,如近似最近邻搜索(ANN),以便在高维空间中查找最相似的向量。这些数据库还提供了数据管理、容错性、安全性和查询引擎等附加功能。
主流向量数据库 Pinecone 是一个专门为工程师与开发者设计的向量数据库。作为一个全托管的服务,它减轻了工程师以及运维人员的负担,使得客户可以聚焦于数据内在价值的抽取。
Weaviate 是一个开源的向量数据库,可以存储对象、向量,支持将矢量搜索与结构化过滤与云原生数据库容错和可拓展性等能力相结合。支持 GraphQL、REST 和各种语言的客户端访问。
Redis 通过 RedisSearch 模块,也原生支持向量检索。RedisSearch 是一个 Redis 模块,提供了查询、二级索引,全文检索以及向量检索等能力。如果要使用 RedisSearch,需要首先在 Redis 数据上声明索引。
面向下一代的生成式 AI 向量数据库,同时也具备云原生的特性。
一个开源的向量数据库。可以快速基于 Python 和 JavaScript 构建内存级 LLM 应用。
知识库持久化 如果我们想把知识库作为大模型的外接知识库,就需要借助向量数据库来存储之前被向量化的文档。我们选用 Qdrant 来部署。
Qdrant 部署 docker pull qdrant/qdrant
docker run -p 6333:6333 -p 6334:6334 \
-v $(pwd )/qdrant_storage:/qdrant/storage:z \
qdrant/qdrant
在 python 里调用 Qdrant 需要安装官方依赖
pip3 install qdrant-client
from qdrant_client import QdrantClient
client = QdrantClient("localhost" , port=6333 )
ChatGLM 大模型部署
本机配置
环境安装
创建虚拟 & 激活虚拟环境 conda create -n chatglm python=3.10
conda activate chatglm
下载源码 cd /tmp
git clone https://github.com/THUDM/ChatGLM2-6B
安装依赖 pip3 install -r requirements.txt
pip3 install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cpu
下载模型文件 GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/THUDM/chatglm2-6b
下载模型参数 将下载的文件替换到本地的 chatglm2-6b 目录下。
部署模型 将模型下载到本地之后,将以上代码中的 THUDM/chatglm2-6b 替换为你本地的 chatglm2-6b 文件夹的路径,即可从本地加载模型。
对于 mac,需要使用 mps 后端。同时需要修改模型的路径,修改为本地路径。
python web_demo.py
streamlit run web_demo2.py
参考
组合起来! 相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
Mermaid 预览与可视化编辑 基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
随机西班牙地址生成器 随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online
Gemini 图片去水印 基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online