一、从文本到向量:Embedding 的核心思想
我们日常使用的自然语言,对于计算机来说只是一串离散的、没有内在数学意义的符号。要让机器真正“理解”语言,就需要一种方法将这些符号转化为计算机擅长处理的、连续的数值形式。Embedding(嵌入)正是实现这一目标的核心技术。它的本质是将一个离散对象(如单词、句子、文档,甚至是用户或商品)映射到一个高维连续向量空间中的一个点。
这个过程并非随意的数字编码。一个好的 Embedding 模型会确保,在这个高维空间中,语义相似的对象,它们的向量表示在空间距离上也更接近。例如,“国王”和“女王”的向量距离,会比“国王”和“苹果”的向量距离近得多。这种映射关系使得抽象的“语义”有了具体的、可计算的数学形式,成为了现代搜索、推荐、聚类等众多AI应用的基石。
二、语义检索:超越关键词的“读懂”你
传统的搜索引擎或检索系统(如 LIKE 查询)主要依赖关键词匹配。它的缺点显而易见:用户搜索“笔记本维修”时,可能错过标题包含“笔记本电脑故障排除”的完美结果。因为系统无法理解“维修”和“故障排除”在语义上的高度相关性。
语义检索正是为了解决这个问题。它的核心思想是:将用户的查询(Query)和文档库中的每一份文档(Document)都通过同一个 Embedding 模型转换成向量。然后,计算查询向量与所有文档向量之间的相似度(通常使用余弦相似度),最后返回相似度最高的文档作为结果。这个过程完全基于“意思”而非“字面”,因此能够实现更加智能和灵活的匹配。
提示:语义检索并非要完全取代关键词检索。在实际生产中,常将二者结合(混合检索),用关键词保证精确性(如搜索特定编号),用语义保证召回率(如搜索概念),从而达到最佳效果。
三、模型生成:如何获得文本的“灵魂”
如何将文本变成高质量的向量?这依赖于预训练的深度学习模型。现代主流的 Embedding 模型大多基于 Transformer 架构(如 BERT、RoBERTa 及其变种)。模型通过在海量文本语料上进行“掩码语言建模”等自监督任务预训练,学习到了丰富的语言知识。
针对语义检索任务,通常还会用对比学习(Contrastive Learning)的思路对模型进行微调。简单来说,就是让模型学习:将意思相近的句子对(如 <查询, 相关文档>)的向量拉得更近,将意思无关的句子对的向量推得更远。这样训练出的模型,其输出的向量天然具有优秀的语义区分度。
四、关键组件:相似度计算与向量索引
有了向量,检索的过程就变成了在数百万甚至数十亿向量中,快速找到与查询向量最相似的几个。这涉及两个关键点:
- 相似度度量:最常用的是余弦相似度,它计算两个向量夹角的余弦值,衡量它们的方向一致性,对向量长度不敏感,非常适合文本语义。
- 近似最近邻搜索:对于海量向量,精确计算每对向量的相似度是不可行的(时间复杂度 O(N))。因此需要使用 ANN(Approximate Nearest Neighbor)算法。常见库如 FAISS、Annoy 和 ScaNN,它们通过构建特定的索引结构(如树、图、哈希)来实现快速、近似的相似向量检索,将复杂度降至接近 O(log N)。
五、实践入门:用 Sentence Transformers 尝试语义检索
下面是一个简单的 Python 代码示例,使用流行的 sentence-transformers 库来演示从句子生成向量并进行相似度计算的全过程。
from sentence_transformers import SentenceTransformer, util
import torch
# 1. 加载一个预训练的语义相似度模型
model = SentenceTransformer('all-MiniLM-L6-v2') # 一个轻量级、效果不错的模型
# 2. 准备一些句子
sentences = [
"如何给猫咪洗澡?",
"洗猫的正确步骤是什么?",
"今天股票市场大涨。",
"猫咪清洁护理指南"
]
# 3. 将所有句子编码为向量(嵌入)
embeddings = model.encode(sentences, convert_to_tensor=True)
# 4. 定义查询句
query = "怎么给猫洗澡"
query_embedding = model.encode(query, convert_to_tensor=True)
# 5. 计算查询句与所有句子的余弦相似度
cosine_scores = util.cos_sim(query_embedding, embeddings)
# 6. 输出最相似的结果
print(f"查询:'{query}'")
print("语义相似度排名:")
for i, (sentence, score) in enumerate(zip(sentences, cosine_scores[0])):
print(f"{i+1}. '{sentence}' (相似度: {score:.4f})")
运行上述代码,你会看到“如何给猫咪洗澡?”和“洗猫的正确步骤是什么?”这两个句子与查询的相似度得分非常高,而与股票相关的句子得分则很低,这完美体现了语义理解的能力。
六、应用场景与价值
Embedding 和语义检索技术的价值在于它能理解“意图”,因此应用场景极其广泛:
- 智能问答系统:直接匹配问题与知识库中的标准答案。
- 电商搜索:用户搜“适合夏天的轻薄连衣裙”,可以返回商品标题中带有“透气”、“凉爽”、“A字裙”等相关属性的产品。
- 内容推荐:根据用户阅读的一篇文章的向量,去内容库中寻找语义相近的其他文章进行推荐。
- 企业知识库:员工用自然语言提问,系统能从海量内部文档(PDF、Confluence页面)中精准定位答案段落。
七、从原理到实践的关键提示
在将 Embedding 和语义检索技术落地时,有几个要点需要牢记:
- 模型选择:没有“最好”的模型,只有“最合适”的。需要在模型大小、推理速度、向量维度和最终任务效果之间做权衡。
all-MiniLM-L6-v2是一个不错的通用起点。 - 维度与性能:向量维度(如 384, 768)越高,表达能力通常越强,但也意味着存储和计算成本更高。需要通过实验找到平衡点。
- 数据质量:“垃圾进,垃圾出”。用于微调或评估 Embedding 模型的数据质量直接决定了最终检索效果。
- 评估指标:常用的离线评估指标包括命中率、平均倒数排名(MRR)和归一化折损累计增益(NDCG)。务必在真实业务数据上测试。
提示:处理中文语义检索时,务必选择在中文语料上预训练或微调过的模型(如 shibing624/text2vec-base-chinese),直接用英文模型处理中文效果会大打折扣。