Embedding 向量嵌入:语义空间、相似度与模型选择

一句话怎样变成一串数字

计算机很容易比较数字,却不能直接理解"如何启动服务"和"服务的启动步骤"表达了相近含义。Embedding 模型解决的正是这个问题:它把文本、图片或音频映射成一组稠密向量,让语义关系能够通过数学距离来比较。

text 复制代码
"如何启动服务"
        ↓ Embedding 模型
[0.12, -0.31, 0.08, 0.44, ...]

语义相近的内容在向量空间中通常更靠近,语义无关的内容则更远。RAG 因此可以把用户问题与所有知识片段放到同一个空间中,寻找最近的若干片段。

图中的两个维度只用于直观说明。真实 Embedding 往往有数百或数千维,单个维度通常不能被直接解释成"动物程度"或"技术程度"。模型学习的是大量维度共同构成的关系。

稠密向量与独热编码有什么不同

传统独热编码会为词表中的每个词分配一个位置:

text 复制代码
猫 = [1, 0, 0, 0]
狗 = [0, 1, 0, 0]
车 = [0, 0, 1, 0]

在这种表示下,猫与狗和猫与车的距离没有体现语义差别。Embedding 则把信息分散在多个连续数值中,使猫和狗更可能接近,汽车落在另一个区域。这种表示称为稠密向量。

早期的 Word2Vec 主要学习词级关系,现代 Embedding 模型可以直接编码句子、段落甚至文档。有些多模态模型还会把文字与图片对齐到同一个空间,但这必须是模型训练时明确具备的能力,不能假设任意文本模型都能处理图片。

三种常见的相似度计算

余弦相似度

余弦相似度比较两个向量方向是否接近:

text 复制代码
cos(a, b) = (a · b) / (||a|| × ||b||)

它对向量长度不敏感,在文本语义检索中非常常见。值越大,通常表示方向越接近。

欧氏距离

欧氏距离计算空间中的直线距离。值越小,两个向量越接近。它同时受到方向和向量长度影响。

点积

点积同时反映方向和模长。若向量已做 L2 归一化,点积与余弦相似度会得到相同的排序;未归一化时,两者不能混为一谈。

下面用 NumPy 直观看三种结果:

python 复制代码
import numpy as np

a = np.array([0.2, 0.8, 0.1])
b = np.array([0.3, 0.7, 0.2])

cosine = np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
euclidean = np.linalg.norm(a - b)
dot_product = np.dot(a, b)

print("cosine:", cosine)       # 越大越相似
print("euclidean:", euclidean) # 越小越相似
print("dot:", dot_product)     # 解释取决于模型与归一化方式

选择哪种距离不能只凭习惯。Embedding 模型通常会在文档中说明推荐的相似度与是否需要归一化,向量数据库的索引配置必须与之保持一致。

查询与文档必须使用同一套表示

建立知识库时,文档片段由一个 Embedding 模型生成向量;查询时也必须使用兼容的模型和相同预处理方式。

python 复制代码
# 建库
doc_vectors = embed_model.encode(chunks, normalize=True)
vector_db.upsert(chunks, doc_vectors)

# 查询
query_vector = embed_model.encode([question], normalize=True)[0]
hits = vector_db.search(query_vector, top_k=5)

如果建库后更换模型,新旧向量并不处在同一个语义空间,必须重新生成全部文档向量。即使模型名称相同,若升级版本改变了维度或表示方式,也要先验证兼容性。

有些模型区分"查询"和"文档"的输入前缀,例如要求加上 query:、passage:,或使用不同的编码方法。这不是多余格式,而是训练方式的一部分,遗漏后可能明显降低召回效果。

如何选择 Embedding 模型

排行榜可以作为参考,却不能代替业务测试。选型时至少要看以下方面。

语言和领域

中文、跨语言、代码和专业术语对模型的要求不同。一个通用英文模型即使在综合榜单上成绩很好,也未必适合中文企业文档。

输入长度

模型能接收多长文本,会限制 Chunk 上限。超过限制时,有的 SDK 报错,有的会截断;静默截断最危险,因为向量可能根本没有编码后半段答案。

向量维度与成本

更高维度会增加存储、网络传输和索引内存,但不自动意味着检索更准。云端模型还要评估调用价格与数据合规,本地模型则要考虑显存、吞吐和部署维护。

真实检索表现

准备一组"问题---正确片段"对,然后计算 Recall@K、MRR 或 nDCG。至少要与关键词检索基线比较,因为产品编号、错误码和人名等精确词,往往是关键词方法更擅长。

本地调用示例

许多本地模型服务会提供 OpenAI 兼容的 Embedding 接口。假设服务运行在 localhost:1234,可以这样请求:

bash 复制代码
curl http://localhost:1234/v1/embeddings \
  -H "Content-Type: application/json" \
  -d '{
    "model": "your-embedding-model",
    "input": ["技术课程", "怎样构建本地知识库"]
  }'

返回结果通常包含每条输入对应的向量:

json 复制代码
{
  "data": [
    {"index": 0, "embedding": [0.012, -0.083, 0.041]},
    {"index": 1, "embedding": [-0.022, 0.017, 0.096]}
  ]
}

示例省略了大部分维度。生产环境还要设置批量大小、超时、重试与缓存,并记录模型名称和版本,保证索引可以重建。

可视化能告诉我们什么

TensorFlow Embedding Projector 可以用 PCA、t-SNE 或 UMAP 等方法把高维向量投影到二维或三维,用于观察聚类和异常点。

但投影会损失信息。二维图上看似靠近的点,在原始高维空间中不一定同样接近。因此,可视化适合发现线索,不适合代替检索指标。

常见误区

第一个误区是把相似度当成事实正确性。向量只能告诉我们两段文字"像不像",不能证明内容真实或最新。

第二个误区是只使用向量检索。对错误码、订单号、专有名词等查询,关键词检索往往更可靠。把稠密向量与 BM25 等关键词方法结合,再做重排,通常更稳健。

第三个误区是只看模型,不检查数据。若原文解析顺序错误或 Chunk 缺少标题,再强的 Embedding 也无法恢复已经丢失的语义。

小结

Embedding 是 RAG 中连接自然语言与数学检索的桥梁。它把查询和知识片段映射到同一向量空间,再通过余弦、欧氏距离或点积寻找相近内容。

相关推荐
lie..1 天前
30天从零开始学AI应用开发(Day 16):Embedding 是什么?用人话讲明白“向量检索”
人工智能·算法·embedding
大连好光景2 天前
RAG中为什么要做Embedding?嵌入模型如何选?
embedding·ai-native
Light Gao2 天前
Encoder 与 Decoder 详解:从 Embedding 到 Seq2Seq 的完整数据流
java·开发语言·embedding
Light Gao3 天前
RNN 原理、架构与一次完整手算
人工智能·rnn·深度学习·神经网络·embedding
91刘仁德6 天前
RAG实战-Embedding模型(BGE)
笔记·embedding·rag
田园诗人之园6 天前
一文搞懂 Token化、Embedding 与位置编码
embedding·位置编码·深度学习token
XLYcmy14 天前
大语言模型(LLM)核心技术梳理:从词元化到 RAG 的工程实践
自然语言处理·prompt·embedding·token·cot·tokenization·上下文工程
geminigoth15 天前
从零开始学习RAG——02 项目架构
embedding·rag架构·rag学习·faiss 索引·rag清洗提取·rag切片·向量化与索引
书源丶16 天前
Qwen3-Embedding-0.6B 纯 CPU
网络·语言模型·embedding·llama