Skip to content

Embedding 与向量数据库

AI 技术 ⭐⭐ 中级 🔥🔥 中频

💡 核心要点

Embedding(嵌入)是将文本、图像等非结构化数据映射到稠密向量空间的技术,使得语义相近的内容在向量空间中距离更近。向量数据库则是专门用于高效存储和检索这些高维向量的基础设施。二者共同构成了 RAG、语义搜索、推荐系统等现代 AI 应用的底层支撑。

什么是 Embedding

从离散到连续

传统文本表示(如 One-Hot 编码)将每个词映射为一个高维稀疏向量,无法捕获词与词之间的语义关系。Embedding 则将文本映射到低维稠密向量空间,使得:

  • 语义相近的文本在向量空间中距离更近
  • 语义无关的文本在向量空间中距离更远
传统表示 (One-Hot):
  "猫" = [1, 0, 0, 0, 0, ...]     维度 = 词表大小(数万)
  "狗" = [0, 1, 0, 0, 0, ...]     无法反映"猫"和"狗"的语义相近

Embedding 表示:
  "猫" = [0.21, -0.35, 0.68, ...]  维度 = 768~3072
  "狗" = [0.23, -0.31, 0.65, ...]  向量相近 → 语义相近
  "汽车" = [-0.45, 0.82, -0.12, ...]  向量远离 → 语义不同

发展历程

阶段方法特点
2013Word2Vec(CBOW / Skip-gram)首次将词映射到稠密向量,发现向量算术(king - man + woman ≈ queen)
2014GloVe基于全局词共现统计训练词向量
2018ELMo / BERT上下文相关的动态 Embedding,同一个词在不同语境中有不同向量
2022+专用 Embedding 模型针对检索优化的 Embedding(对比学习训练),如 text-embedding-3、BGE

在 Word2Vec 时代,每个词有一个固定的向量。现代 Embedding 模型基于 Transformer 编码器,生成的是上下文相关的句子/段落级 Embedding。


Embedding 模型原理

编码器架构

现代 Embedding 模型通常基于 BERT 类编码器架构,通过双向注意力机制理解完整上下文:

Text --> Tokenizer --> Transformer Encoder --> Pooling --> Embedding Vector
                                                          [0.12, -0.34, ...]

训练方法:对比学习

现代 Embedding 模型主要通过**对比学习(Contrastive Learning)**训练:

其中 是查询, 是正样本(相关文档), 是负样本(不相关文档), 是温度参数。

核心思想:拉近查询与相关文档的距离,推远查询与不相关文档的距离。

负样本挖掘策略

对比学习的效果高度依赖负样本的质量:

策略说明效果
随机负样本从语料库随机采样简单但效果有限
批内负样本同一批次中其他样本的正样本作为负样本高效,广泛使用
困难负样本用 BM25 或初步模型检索出的"似是而非"的文档显著提升模型区分能力

相似度度量

将文本转为 Embedding 后,需要定义"距离"来衡量两个向量的相似程度。

余弦相似度(Cosine Similarity)

  • 范围:,值越大越相似
  • 忽略向量的长度,只关注方向
  • 最常用的相似度度量

欧氏距离(Euclidean Distance)

  • 范围:,值越小越相似
  • 受向量长度影响
  • 适合已归一化的向量

点积(Dot Product / Inner Product)

  • 范围:,值越大越相似
  • 同时考虑方向和长度
  • 当向量已归一化时,等价于余弦相似度

如何选择

场景推荐度量原因
通用语义搜索余弦相似度对向量长度不敏感,跨文档稳定
已归一化的向量点积计算更快,结果等价余弦
需要考虑"重要性"差异点积向量模长可编码重要性信息

主流 Embedding 模型

模型开发者维度最大长度特点
text-embedding-3-largeOpenAI30728191 Token英文综合性能优异
text-embedding-3-smallOpenAI15368191 Token性价比高
BGE-M3BAAI(智源)10248192 Token多语言、多粒度、多功能
GTE-Qwen2阿里云153632K Token长文本、中文表现优异
Jina-embeddings-v3Jina AI10248192 Token多语言、任务适配
Cohere embed-v3Cohere1024512 Token支持压缩和搜索类型

选择要点

  • 中文场景:优先 BGE 系列或 GTE 系列,中文语义捕获更精准
  • 多语言场景:BGE-M3 或 Jina 系列
  • 成本敏感:text-embedding-3-small 性价比最高
  • 长文本:GTE-Qwen2 支持 32K Token 上下文
  • 私有部署:BGE 和 GTE 均为开源模型,可本地部署

向量数据库

为什么需要向量数据库

传统数据库(MySQL、PostgreSQL)擅长精确匹配查询(WHERE id = 123),但无法高效处理"找到与这个向量最相似的 K 个向量"的查询。

向量数据库解决的核心问题:

  • 高维向量的高效相似度搜索——在数百万到数十亿向量中,毫秒级返回 Top-K 结果
  • 索引优化——使用 ANN(近似最近邻)算法,用微小精度损失换取数量级的速度提升
  • 混合查询——结合向量相似度搜索和元数据过滤(如 category = 'AI' AND similarity > 0.8

主流向量数据库

数据库类型特点适用场景
Chroma嵌入式轻量、Python 原生、零配置原型开发、小规模应用
Pinecone云托管全托管、自动扩缩容、无需运维生产环境、无运维团队
Milvus分布式高性能、支持十亿级向量、开源大规模生产、私有化部署
pgvectorPostgreSQL 扩展复用现有 PG 基础设施、支持 SQL 混合查询已有 PG 技术栈的团队
Qdrant独立部署Rust 实现、性能优异、过滤灵活高性能需求的生产环境
FAISS库(非数据库)Meta 开发、纯向量检索、不含持久化研究实验、自建存储层

ANN 索引算法

精确最近邻搜索(暴力遍历所有向量)的时间复杂度为 ,在大规模数据集上不可接受。ANN 算法通过构建索引结构,将搜索从线性扫描加速到对数级或亚线性级

HNSW(Hierarchical Navigable Small World)

HNSW 是目前最流行的 ANN 索引算法,构建多层图结构:

查询过程:从最高层入口节点开始,在当前层贪心搜索最近邻,逐层下降,最终在底层返回 Top-K 结果。

  • 时间复杂度
  • 优点:查询精度高(recall > 95%)、不需要训练
  • 缺点:内存占用大(需存储图结构),构建索引较慢
  • 适用场景:数据量 < 1 亿、对精度要求高

IVF(Inverted File Index)

IVF 先将向量空间聚类 个区域,查询时只搜索最相关的 个区域:

IVF 将向量空间划分为多个聚类(Voronoi cells),查询时只搜索最近的几个聚类,将搜索范围从全量缩小到

  • 时间复杂度
  • 优点:内存效率高、适合大规模数据
  • 缺点:需要训练聚类中心、精度受 影响
  • 适用场景:数据量 > 1 亿、需要平衡速度和内存

PQ(Product Quantization)

PQ 将高维向量切分为多个子段,每个子段独立量化压缩:

PQ 将高维向量切分为多个子空间,每个子空间独立量化为码本索引,大幅压缩存储空间(如 128 维 float32 → 16 字节)。

  • 优点:极大减少内存占用(可压缩 32~64 倍)
  • 缺点:精度损失相对较大
  • 适用场景:十亿级以上数据、内存受限环境
  • 通常与 IVF 结合使用(IVF-PQ)

索引选择对比

算法查询速度内存占用精度构建速度推荐规模
暴力搜索100%无需构建< 10 万
HNSW最快最高< 1 亿
IVF1 亿+
PQ最低10 亿+
IVF-PQ中高10 亿+

实践:构建语义搜索

以下示例演示使用 OpenAI Embedding 和 FAISS 构建一个简单的语义搜索系统:

python
import numpy as np
import faiss
from openai import OpenAI

client = OpenAI()

def get_embeddings(texts: list[str], model: str = "text-embedding-3-small") -> np.ndarray:
    """批量获取文本的 Embedding 向量"""
    response = client.embeddings.create(input=texts, model=model)
    return np.array([item.embedding for item in response.data], dtype="float32")

# 1. 准备文档
documents = [
    "Transformer 是一种基于自注意力机制的深度学习架构",
    "RAG 通过检索外部知识来增强语言模型的生成能力",
    "向量数据库使用 ANN 算法实现高效的相似度搜索",
    "LoRA 是一种参数高效的模型微调方法",
    "Docker 是一个开源的容器化平台",
    "Redis 是一个高性能的内存键值数据库",
]

# 2. 生成 Embedding 并构建索引
doc_embeddings = get_embeddings(documents)
dimension = doc_embeddings.shape[1]

index = faiss.IndexFlatIP(dimension)              # 内积索引(向量已归一化时等价余弦)
faiss.normalize_L2(doc_embeddings)                # L2 归一化
index.add(doc_embeddings)

# 3. 查询
query = "如何优化大模型的训练效率"
query_embedding = get_embeddings([query])
faiss.normalize_L2(query_embedding)

scores, indices = index.search(query_embedding, k=3)

print("查询:", query)
for i, (score, idx) in enumerate(zip(scores[0], indices[0])):
    print(f"  Top-{i+1} (相似度: {score:.4f}): {documents[idx]}")

生产环境最佳实践

索引调优

参数影响建议
HNSW: M(每节点连接数)M 越大精度越高,但构建越慢、内存越多通常 16~64
HNSW: ef_construction构建时搜索范围,越大索引质量越高100~500
HNSW: ef_search查询时搜索范围,越大精度越高50~200
IVF: nlist(聚类数)聚类越多查询越快但精度可能下降
IVF: nprobe搜索聚类数,越多精度越高但越慢nlist 的 1%~10%

元数据过滤

生产中通常需要结合结构化过滤和向量搜索:

python
# Qdrant 示例:结合元数据过滤
from qdrant_client import QdrantClient
from qdrant_client.models import Filter, FieldCondition, MatchValue

results = client.search(
    collection_name="articles",
    query_vector=query_embedding,
    query_filter=Filter(
        must=[
            FieldCondition(key="category", match=MatchValue(value="AI")),
            FieldCondition(key="language", match=MatchValue(value="zh")),
        ]
    ),
    limit=10,
)

关键决策

决策点选项建议
Embedding 模型开源 vs API 调用小规模用 API(如 OpenAI),大规模或隐私敏感用开源(BGE)
向量数据库嵌入式 vs 独立部署 vs 云托管原型用 Chroma,生产用 Milvus/Qdrant/Pinecone
索引类型HNSW vs IVF vs PQ数据量小选 HNSW,数据量大选 IVF-PQ
维度选择高维 vs 低维效果:高维 > 低维,速度:低维 > 高维。平衡点在 768~1536

⚠️ 常见误区

  1. 认为向量数据库可以替代传统数据库:向量数据库专注于相似度搜索,不擅长精确匹配、事务处理、复杂 SQL 查询。两者是互补关系。

  2. 忽视 Embedding 模型的选择:不同 Embedding 模型对不同语言和领域的效果差异很大。中文场景使用英文模型可能导致检索质量大幅下降。

  3. 混淆精确搜索和近似搜索:ANN 算法返回的是近似最近邻,可能遗漏真正的最近邻。recall 参数的调优直接影响搜索质量。

  4. 盲目追求高维 Embedding:更高维度不一定带来更好效果,但一定会增加存储和计算成本。实际应用中 768~1536 维通常足够。


📝 面试真题3 道高频
1. 解释 HNSW 索引算法的工作原理及其优缺点中等
2. 对比余弦相似度和点积,什么场景下结果一致?简单
3. 如何为千万级文档的语义搜索系统选择向量数据库和索引方案?困难

面试真题详解

Q1:解释 HNSW 索引算法的工作原理及其优缺点

要点

HNSW(Hierarchical Navigable Small World)是一种基于多层图结构的近似最近邻搜索算法:

构建过程

  1. 为每个向量随机分配一个层级(概率指数递减,高层节点少)
  2. 在每层中,将新向量与最近的 M 个节点建立双向连接
  3. 形成一个从稀疏(高层)到稠密(底层)的多层导航图

查询过程

  1. 从最高层的入口节点出发
  2. 在当前层进行贪心搜索,找到局部最近邻
  3. 下降到下一层,以上一层的结果为起点继续搜索
  4. 在底层(Layer 0)找到最终的 Top-K 结果

优点:查询速度快()、召回率高(> 95%)、无需训练、支持动态插入。 缺点:内存占用大(需存储图连接关系)、构建索引慢。


Q2:对比余弦相似度和点积,什么场景下结果一致?

要点

  • 余弦相似度只衡量向量的方向,忽略模长
  • 点积同时考虑向量的方向和模长

当向量已经过 L2 归一化(即 )时,两者结果完全一致:

大多数 Embedding 模型输出的向量默认已归一化,因此实际应用中两者通常等价。使用点积计算更快(少一步归一化),所以生产环境中常用点积代替余弦相似度。


Q3:如何为千万级文档的语义搜索系统选择向量数据库和索引方案?

要点

规模分析:千万级(~10M)文档,假设 1536 维 Embedding。

向量数据库选择

  • 有 PostgreSQL 基础设施 → pgvector(简单,但性能到千万级可能瓶颈)
  • 需要高性能 → QdrantMilvus
  • 不想自运维 → Pinecone

索引方案

  • 千万级在 HNSW 的最佳适用范围内(< 1 亿)
  • 推荐 HNSW:M=32, ef_construction=200, ef_search=100
  • 内存估算:10M × 1536 × 4 bytes ≈ 60GB(原始向量)+ ~30GB(HNSW 图结构)≈ 90GB
  • 如果内存受限,可选择 IVF-PQ:nlist=10000, 128 子段,内存可降至 ~10GB

其他考虑

  • 元数据过滤需求 → 选择支持 pre-filtering 的数据库(Qdrant、Milvus)
  • 实时更新需求 → HNSW 支持动态插入,IVF 需要定期重建聚类
  • 多副本高可用 → Milvus 或 Pinecone

延伸阅读