向量化是将非结构化数据(如文本、图像等)转化为数字表示的一种过程。在RAG 中,通常会使用预训练的Transformer模型(如BERT、RoBERTa等)将文本表示为 高维的向量。这些向量能够捕捉到数据的语义信息,从而在向量空间中表示相似性。 两段相似的文本在向量空间中将非常接近。
快速检索:向量化将文本转换为向量后,可以通过向量相似度算法(如余弦相似 度)快速检索与查询相关的信息。
语义理解:通过向量化,检索系统不仅能基于字面
相似度检索信息,还能捕捉到 深层的语义相似性,提升检索的效果。
高效计算:与传统的基于关键词的检索相比,向量化检索可以在高维空间中更高 效地处理大规模数据。
1. 预处理数据:对数据进行清洗和标准化处理,如去除停用词、标点符号,或者进 行分词等预处理操作。
2. 使用预训练模型生成向量:通过预训练的深度学习模型,如BERT,获取文本的向 量表示。
3. 存储与索引:将生成的向量存储到向量数据库中,如FAISS(Facebook AI Similarity Search)或其他专门用于高效向量检索的数据库。
4. 相似度计算:在检索阶段,通过计算查询向量与数据库中向量的相似度(通常使 用余弦相似度或欧几里得距离)来找到最相关的向量。
安装依赖
pip install sentence-transformers==3.3.0 scikit-learn==1.5.2 faiss-cpu==1.9.0
下载 embedding 模型
它的主要作用是将中文文本(如句子、段落或文档)转化为一个高维度的数字向量,也就是嵌入向量(Embedding)。这些向量捕捉了文本的语义信息,使得计算机可以通过计算向量间的距离来理解文本的含义。
简单来说,它的工作原理是:
输入:一段中文文本。
输出:一个 1024 维的向量。
from modelscope.hub.snapshot_download import snapshot_download
emb_model_dir = snapshot_download('AI-ModelScope/bge-large-zh-v1.5',cache_dir='models')
应用场景
这个模型通常不直接用于生成回答,而是作为更大型 AI 系统(特别是 RAG)的底层组件:
语义搜索(Semantic Search):通过将用户的查询和文档库中的文本都转换为向量,然后找到向量距离最近的文档,从而实现基于语义而非关键词的搜索。
问答系统:在 RAG(检索增强生成)架构中,它负责从外部知识库中检索出与用户问题最相关的文档片段。
文本聚类与分类:将语义相近的文本分组或分类。
推荐系统:根据用户过去浏览或喜欢的文本,推荐语义相关的其他内容。
与大语言模型的区别
与 Qwen2.5-7B-Instruct
这类大语言模型(LLM)不同:
大语言模型(如 Qwen):负责理解、推理和生成人类可读的文本,它们是聊天、创作等任务的主力。
嵌入模型(如 BGE):不直接生成文本,只负责将文本编码成数字表示,是幕后负责“理解”和“记忆”的工具。
from sentence_transformers import SentenceTransformer
model=SentenceTransformer('/home/AI_big_model/models/AI-ModelScope/bge-large-zh-v1___5')
texts = ["院子里有一只可爱的小猫", "厨房里有一只黑色的猫", "大模型真简单"]
embedding=model.encode(texts)
print(embedding)
print(embedding.shape)
print(type(embedding))
'''
[[ 0.00539989 -0.04684957 -0.00222198 ... 0.02075759 0.01118603
0.0027347 ]
[-0.00607152 -0.01552003 0.02354841 ... 0.09244978 -0.00619848
0.02541843]
[ 0.01297168 0.02126065 0.00450938 ... -0.03023773 -0.00547749
0.01475393]]
(3, 1024)
'''
我们使用sklearn库中的cosine_similarity函数来计算句子之间的相似度。在这里,我 们分别计算了第一句与第二句、第一句与第三句的相似度得分。可以看到和我们 直观感受一样第一句话和第二句话的相似度更高一些。
from sklearn.metrics.pairwise import cosine_similarity
similary1=cosine_similarity([embedding[0]],[embedding[1]])
similary2=cosine_similarity([embedding[0]],[embedding[2]])
similary3=cosine_similarity([embedding[1]],[embedding[2]])
print(similary1)
print(similary2)
print(similary3)
FAISS是一个高效的相似性搜索库,可以用于处理大规模的嵌入向量。
import faiss
import numpy as np
index=faiss.IndexFlatIP(1024)
index.add(embedding)
query_embedding=model.encode(["黑色的猫在哪?"])
D,I=index.search(query_embedding,k=3)
print(I)
print(D)
'''
[[1 0 2]]
[[0.67033833 0.45103025 0.08964221]]
'''
# LangChain 的集成方式更加高级和方便,它将编码和搜索步骤封装在一起。
# 实例化 LangChain 的 HuggingFaceEmbeddings,它会加载相同的模型。
embedding=HuggingFaceEmbeddings(model_name='/home/AI_big_model/models/AI-ModelScope/bge-large-zh-v1___5')
# vs=FAISS.from_texts(texts, embedding) 是一个非常方便的函数。
# 它会自动完成以下步骤:
# 1. 将 texts 列表中的每个文本转换为嵌入向量。
# 2. 使用 FAISS 构建一个向量数据库。
# 3. 返回一个可用于搜索的 LangChain 向量存储对象。
vs=FAISS.from_texts(texts,embedding)
# 使用 LangChain 的 vs.similarity_search() 方法进行搜索。
# 它会自动将查询文本转换为向量,并在内部完成相似性搜索,最后返回一个封装好的 Document 对象列表。
# 这比手动使用 faiss.search() 更直观,结果也包含了原始文本内容。
print(vs.similarity_search('黑色的猫在哪?'))
'''
[
Document(id='5b0bcd7b-71a4-4757-b429-ce3f723a6cc6', metadata={}, page_content='厨房里有一只黑色的猫'),
Document(id='15de0980-84c5-49f0-944b-5d22534e5fd1', metadata={}, page_content='院子里有一只可爱的小猫'),
Document(id='ad4b88f5-f7d6-4e3c-baec-9dd10f5d4c64', metadata={}, page_content='大模型真简单')
]
'''