掘金 人工智能 21小时前
RAG 每日一技(四):让AI读懂你的话,初探RAG的“灵魂”——Embedding
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文深入浅出地介绍了RAG系统中核心技术Embedding,它将文本转化为数字向量,从而实现语义相似度的计算。文章通过实例演示了如何使用sentence-transformers库和m3e-base模型将文本转换为向量,并计算余弦相似度,最终实现语义搜索。文章还预告了后续将探讨向量数据库,以解决海量向量的快速搜索问题。

💡 Embedding是一种将文本转换为数字向量的技术,这些向量捕捉了原始文本的语义信息,使得计算机能够理解文本的含义。

🍎 通过将文本转换为向量,可以计算它们之间的相似度。余弦相似度是常用方法,它衡量了两个向量在方向上的接近程度,结果范围在-1到1之间,数值越高表示语义越接近。

💻 使用sentence-transformers库和m3e-base模型,可以轻松地将文本转换为向量。代码示例展示了如何加载模型、转换句子和计算相似度。

🔍 语义搜索利用Embedding技术,能够根据语义相似度找到相关的文本块,而不仅仅是基于关键词匹配。这使得RAG系统能够更准确地回答用户的问题。

前情回顾

经过前三天的努力,我们已经成功掌握了如何将各种类型的文档(纯文本、代码、Markdown)“优雅地”切分成高质量的文本块(Chunks)。可以说,我们为RAG系统准备好了最优质的“原材料”。

但是,新的问题紧接着就来了:

当用户提出一个问题(比如:“RAG的核心组件是什么?”)时,我们如何在成千上万,甚至数百万个Chunks中,快速、准确地找到与这个问题最相关的那几个呢?

你可能会想到传统的关键词搜索。但关键词搜索有巨大的局限性。比如用户问“苹果公司的创始人”,包含“乔布斯”的文本块可能就匹配不到;用户问“AI的未来”,包含“人工智能的前景”的文本块也可能被错过。

我们需要一种能理解语义相似度,而不仅仅是字面匹配的方法。而实现这一切的核心技术,就是我们今天要探索的RAG系统的“灵魂”——Embedding

什么是Embedding?

简单来说,Embedding(嵌入)就是一种将文本(或其他任何东西,如图片、声音)转换成一串数字(即“向量”)的技术。

这串数字(向量)并不是随机的,它会尽可能地捕捉原始文本的语义信息

我们可以打一个比方:

想象一张世界地图。我们可以用经纬度(一个二维向量)来表示任何一个城市的位置。在地图上,“巴黎”、“罗马”、“马德里”这些欧洲城市会聚集在一起,而“北京”、“东京”则在另一个区域,它们之间的距离反映了地理上的关系。

Embedding做的事情类似,但它是在一个更高维度的“语义空间”里,为每个词、每个句子、每个文本块分配一个“语义坐标”(一个高维向量)。在这个空间里:

    “国王”和“女王”的“坐标”会非常接近。“我喜欢夏天”和“炎热的天气真棒”的“坐标”也会很接近。而“科技新闻”和“美食菜谱”的“坐标”则会相距甚远。

通过这种方式,“文本相似度”这个模糊的概念,就被转化成了可以精确计算的“向量空间距离”。计算机不擅长理解语言,但极其擅长数学运算。这就是Embedding的魔力所在。

上手实践:将文本转化为向量

理论说完了,我们马上动手实践。我们将使用一个非常流行的开源Embedding模型库 sentence-transformers 和一个在中文领域表现优异的开源模型 m3e-base

首先,确保你已经安装了必要的库:

pip install sentence-transformers

然后,我们用代码来感受一下文本是如何变成向量的。

from sentence_transformers import SentenceTransformer# 加载一个预训练好的中文Embedding模型# 第一次运行时,它会自动从HuggingFace下载模型文件model = SentenceTransformer('m3e-base')# 准备几个待转换的句子sentences = [    "我喜欢吃苹果",    "我喜欢吃香蕉",    "今天天气真好",    "我讨厌上班"]# 使用模型将句子编码为向量embeddings = model.encode(sentences)# 我们来看看结果for sentence, embedding in zip(sentences, embeddings):    print("句子:", sentence)    # 打印向量的前5个维度和向量的总维度    print(f"向量 (前5维): {embedding[:5]}")    print(f"向量维度: {len(embedding)}")    print("-" * 20)

输出结果(你运行的结果中,向量的具体数值可能略有不同,但维度是固定的):

句子: 我喜欢吃苹果向量 (前5维): [ 0.01391807 -0.01953284  0.01596547 -0.01229419 -0.00160986]向量维度: 768--------------------句子: 我喜欢吃香蕉向量 (前5维): [ 0.01850123 -0.01908993  0.00392336 -0.01168233 -0.00832363]向量维度: 768--------------------句子: 今天天气真好向量 (前5维): [ 0.00445524 -0.03813957  0.01150338 -0.0321528  -0.03158003]向量维度: 768--------------------句子: 我讨厌上班向量 (前5维): [-0.00890695 -0.03367128  0.03842103  0.0210134  -0.01174621]向量维度: 768--------------------

看,每一个句子都被成功转换成了一个包含768个数字的向量!这就是它们的“语义坐标”。

魔法时刻:计算语义相似度

有了向量坐标,我们就可以计算它们之间的相似度了。最常用的方法是余弦相似度 (Cosine Similarity),它测量两个向量在方向上的接近程度。结果范围在-1到1之间,1表示完全相同,0表示完全无关,-1表示完全相反。

sentence-transformers 库也为我们提供了便捷的工具。

from sentence_transformers import util# 计算"我喜欢吃苹果"和其它所有句子之间的余弦相似度query_embedding = embeddings[0]other_embeddings = embeddings[1:]# util.cos_sim会返回一个张量(tensor),包含查询向量和其它所有向量的相似度cosine_scores = util.cos_sim(query_embedding, other_embeddings)print(f"查询句子: '{sentences[0]}'")for i in range(len(other_embeddings)):    print(f"与 '{sentences[i+1]}' 的相似度: {cosine_scores[0][i]:.4f}")

输出结果:

查询句子: '我喜欢吃苹果''我喜欢吃香蕉' 的相似度: 0.9038'今天天气真好' 的相似度: 0.5847'我讨厌上班' 的相似度: 0.6120

结果一目了然!

这就是Embedding和语义搜索的威力!

总结与预告

今日小结:

    Embedding 是将文本转换为数字向量(语义坐标)的过程,是RAG系统实现语义检索的基石。通过计算向量间的余弦相似度,我们可以准确地判断文本间的语义关联程度。我们可以使用 sentence-transformers 这样的开源库和 m3e-base 这样的模型,轻松地实现文本的Embedding。

现在,我们已经能将所有的文本块(Chunks)都转换成向量了。但一个新的、非常工程化的问题又摆在了面前:

当我们的知识库有数百万个Chunks,也就意味着有数百万个向量。当用户提出一个问题时,难道我们要把用户问题的向量,和这数百万个向量逐一计算余弦相似度,然后排序找分最高的吗?

这太慢了!在实际应用中是绝对无法接受的。我们需要一种能从海量向量中进行高效相似度搜索的专门技术。

明天预告:RAG 每日一技(五):大海捞针第一步,亲手构建你的向量索引!

明天,我们将正式踏入向量数据库的世界,并亲手用一个流行的库(如FAISS)来构建我们的第一个向量索引,体验什么叫“瞬间”从百万向量中找到你的目标!

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Embedding RAG系统 语义搜索 sentence-transformers m3e-base
相关文章