什么是向量嵌入(Vector Embedding)
人类理解文字,计算机理解数字。Embedding 模型的核心任务是:将任意长度的文本映射到一个固定维度的数值向量,并且语义相近的文本对应的向量在空间中彼此接近。
举一个直觉性的例子:
- "苹果" →
[0.82, -0.13, 0.45, ...](1536维) - "水果" →
[0.79, -0.11, 0.42, ...](与"苹果"非常接近) - "汽车" →
[0.12, 0.67, -0.33, ...](与"苹果"相距较远)
向量空间中的"距离"反映了语义的"相似度"。RAG 检索的本质是:把用户问题也编码成向量,然后在向量空间中找距离最近的文档向量,即找语义最相关的文档片段。
Embedding 模型的工作原理
语义相似度的计算
import numpy as np
from openai import OpenAI
client = OpenAI()
def get_embedding(text: str, model: str = "text-embedding-3-small") -> np.ndarray:
resp = client.embeddings.create(model=model, input=text)
return np.array(resp.data[0].embedding)
def cosine_similarity(a: np.ndarray, b: np.ndarray) -> float:
"""余弦相似度"""
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
def euclidean_distance(a: np.ndarray, b: np.ndarray) -> float:
"""欧几里得距离(值越小越相似)"""
return np.linalg.norm(a - b)
# 测试语义相似度
sentences = [
"如何构建 RAG 系统?", # 查询
"RAG 检索增强生成的实现步骤", # 高度相关
"向量数据库的基本概念", # 相关
"今天天气怎么样", # 不相关
]
query_vec = get_embedding(sentences[0])
for sent in sentences[1:]:
vec = get_embedding(sent)
sim = cosine_similarity(query_vec, vec)
print(f"相似度 {sim:.3f}: {sent}")
# 输出:
# 相似度 0.891: RAG 检索增强生成的实现步骤
# 相似度 0.743: 向量数据库的基本概念
# 相似度 0.312: 今天天气怎么样
主流 Embedding 模型对比(2025)
| 模型 | 维度 | 最大 Token | 语言 | 价格 | 特点 |
|---|---|---|---|---|---|
| text-embedding-3-large | 3072 | 8191 | 多语言 | $0.00013/1K | OpenAI 最强,支持维度缩减 |
| text-embedding-3-small | 1536 | 8191 | 多语言 | $0.00002/1K | 性价比极高,推荐生产使用 |
| BAAI/bge-m3 | 1024 | 8192 | 多语言 | 免费(自托管) | 支持稠密+稀疏+多向量,开源最强 |
| BAAI/bge-large-zh-v1.5 | 1024 | 512 | 中文为主 | 免费(自托管) | 中文场景表现优秀 |
| moka-ai/m3e-base | 768 | 512 | 中文 | 免费(自托管) | 专为中文优化,轻量快速 |
| jina-embeddings-v3 | 1024 | 8192 | 多语言 | 免费额度+付费 | 任务感知 Embedding,支持指令 |
| voyage-3-large | 1024 | 32000 | 多语言 | $0.00018/1K | Anthropic 推荐,超长上下文 |
使用 BGE-M3(开源本地部署)
# 安装:pip install sentence-transformers
from sentence_transformers import SentenceTransformer
import numpy as np
# BGE-M3:支持稠密、稀疏、多向量混合检索
model = SentenceTransformer("BAAI/bge-m3")
sentences = [
"RAG 检索增强生成",
"向量数据库 Qdrant",
"Embedding 模型对比",
]
# encode 支持批量,默认返回归一化向量
embeddings = model.encode(
sentences,
batch_size=32,
normalize_embeddings=True, # L2 归一化后点积=余弦相似度
show_progress_bar=True,
)
print(embeddings.shape) # (3, 1024)
# BGE 模型的特殊用法:query 前加指令前缀
query = "Represent this sentence for searching relevant passages: RAG 的核心流程"
query_vec = model.encode([query], normalize_embeddings=True)[0]
# 计算相似度矩阵
sim_matrix = embeddings @ embeddings.T
print(sim_matrix)
OpenAI Embedding 维度缩减(Matryoshka)
text-embedding-3 系列支持 Matryoshka 表示学习:可以截断向量维度,以更低存储成本换取略微下降的精度,非常适合大规模生产场景。
from openai import OpenAI
client = OpenAI()
# 请求缩减维度(3072 → 512)
response = client.embeddings.create(
model="text-embedding-3-large",
input="检索增强生成 RAG",
dimensions=512 # 缩减到 512 维,存储减少 83%
)
embedding_512d = response.data[0].embedding
print(f"向量维度:{len(embedding_512d)}") # 512
# 维度 vs 性能权衡(MTEB 基准):
# 3072d → MTEB 0.641 存储 100%
# 1536d → MTEB 0.638 存储 50%
# 512d → MTEB 0.624 存储 17%
# 256d → MTEB 0.608 存储 8%
维度选择:越大越好?
高维度的优势
- 表达能力更强,捕捉更细腻的语义差异
- 在复杂专业领域(法律/医疗)精度更高
- 长文档的语义信息损失更少
高维度的代价
- 存储成本线性增长(百万向量差异显著)
- 检索速度变慢(HNSW 索引构建时间增加)
- 维度诅咒:超高维空间中距离趋于均匀
- API 费用:按 token 计费,不受维度影响
中文场景:优先选 BGE-M3 或 bge-large-zh-v1.5(免费,中文优化),或 text-embedding-3-small(稳定好用)。英文/多语言:text-embedding-3-small 性价比最高,若需要极致精度用 text-embedding-3-large。隐私敏感:一定用本地模型(BGE 系列 / M3E),数据不出内网。
Embedding 的重要特性:任务感知
部分现代 Embedding 模型支持"指令式"(Instruction-following)调用:可以在 Embedding 前添加任务描述,引导模型针对特定任务优化向量表示。
# Jina v3:支持任务指令
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("jinaai/jina-embeddings-v3", trust_remote_code=True)
# 查询时用 retrieval.query 任务类型
query = model.encode(
["RAG 系统如何处理多跳推理?"],
task="retrieval.query",
prompt_name="retrieval.query"
)
# 文档索引时用 retrieval.passage 任务类型
docs = model.encode(
["多跳推理需要将问题分解为子问题,逐步检索..."],
task="retrieval.passage",
)
# E5 系列(微软)同样支持指令前缀
# 查询:前缀 "query: "
# 文档:前缀 "passage: "
评估 Embedding 模型:MTEB 基准
MTEB(Massive Text Embedding Benchmark)是评估 Embedding 模型最权威的标准,覆盖 56 个数据集、8 类任务。
MTEB 主要以英文数据为主。中文 Embedding 模型应参考 C-MTEB(中文版 MTEB)排行榜,地址:https://huggingface.co/spaces/mteb/leaderboard,选择 Chinese 标签页。
本章总结
- Embedding 模型将文本映射到高维向量空间,语义相近的文本向量距离也近
- 双编码器适合 RAG 检索(可预计算),交叉编码器适合精排(Reranker)
- 中文场景推荐:BGE-M3(开源免费)或 text-embedding-3-small(简单稳定)
- 维度并非越大越好,需要在精度、存储、速度之间权衡
- 关注 C-MTEB 排行榜选模型,不要仅凭直觉