跳到主要内容

向量数据库核心概念

深入理解向量数据库的工作原理,掌握向量化、相似度计算和索引算法的核心知识。

向量化(Vectorization)

向量化是将非结构化数据转换为数值向量的过程,这是使用向量数据库的第一步。

什么是 Embedding

Embedding(嵌入)是机器学习中的一种技术,将高维稀疏的数据映射到低维稠密的向量空间。在这个向量空间中,语义相似的数据点距离较近。

关键特性

  • 语义保持:语义相似的文本,其向量距离也近
  • 维度固定:无论输入长度如何,输出维度固定
  • 可计算:向量间可以进行数学运算

文本向量化示例

from sentence_transformers import SentenceTransformer

# 加载预训练模型
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')

# 文本向量化
texts = [
"猫在沙发上睡觉",
"小狗在院子里玩耍",
"猫咪正在打盹"
]

embeddings = model.encode(texts)

print(f"向量维度: {embeddings.shape}")
# 输出: 向量维度: (3, 384)

# 查看第一个文本的向量(前5个值)
print(f"第一个文本的向量: {embeddings[0][:5]}")
# 输出: [ 0.0234 -0.1567 0.7891 ... ]

嵌入模型选择

模型维度语言特点适用场景
text-embedding-3-small1536多语言OpenAI,性价比高通用场景
text-embedding-3-large3072多语言OpenAI,高性能高精度需求
all-MiniLM-L6-v2384英文轻量快速资源受限
paraphrase-multilingual-MiniLM-L12-v2384多语言支持中文中文场景
BGE-large-zh1024中文中文最优中文专业场景
M3E-base768中文开源中文模型中文开源方案

多模态向量化

除了文本,图像、音频也可以向量化:

# 图像向量化示例(使用 CLIP)
from transformers import CLIPProcessor, CLIPModel
from PIL import Image

model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")

image = Image.open("cat.jpg")
inputs = processor(images=image, return_tensors="pt")
image_features = model.get_image_features(**inputs)

print(f"图像向量维度: {image_features.shape}")
# 输出: torch.Size([1, 512])

相似度度量

相似度度量是向量数据库的核心,决定了如何比较两个向量的相似程度。

余弦相似度(Cosine Similarity)

最常用且效果最好的相似度度量方法。

公式

cos(θ) = (A · B) / (||A|| × ||B||)

其中:

  • A · B 表示向量点积
  • ||A|| 表示向量 A 的欧几里得范数(模长)

特点

  • 范围 [-1, 1],通常归一化后范围 [0, 1]
  • 只考虑方向,不考虑长度
  • 对文本语义相似度衡量效果最佳
import numpy as np

def cosine_similarity(a, b):
"""计算余弦相似度"""
dot_product = np.dot(a, b)
norm_a = np.linalg.norm(a)
norm_b = np.linalg.norm(b)
return dot_product / (norm_a * norm_b)

# 示例
vec1 = np.array([1, 2, 3])
vec2 = np.array([1, 2, 3])
vec3 = np.array([-1, -2, -3])

print(cosine_similarity(vec1, vec2)) # 1.0(完全相同)
print(cosine_similarity(vec1, vec3)) # -1.0(完全相反)

欧几里得距离(Euclidean Distance)

衡量向量空间中的直线距离。

公式

d(A, B) = √Σ(Ai - Bi)²

特点

  • 范围 [0, +∞)
  • 考虑向量的绝对位置
  • 适合物理空间或几何数据的相似度计算
def euclidean_distance(a, b):
"""计算欧几里得距离"""
return np.sqrt(np.sum((a - b) ** 2))

# 距离越小越相似
dist = euclidean_distance(vec1, vec2)
similarity = 1 / (1 + dist) # 转换为相似度

点积(Dot Product)

最简单的相似度计算方法。

公式

A · B = Σ(Ai × Bi)

特点

  • 无固定范围
  • 同时考虑方向和长度
  • 归一化后等价于余弦相似度
def dot_product(a, b):
"""计算点积"""
return np.dot(a, b)

相似度度量对比

度量方法是否考虑长度范围最佳场景
余弦相似度[-1, 1]文本语义搜索
欧几里得距离[0, +∞)几何/物理数据
点积无限制已归一化向量

实践建议

  • 文本搜索优先使用余弦相似度
  • 如果向量已经归一化,点积和余弦相似度等价
  • 欧几里得距离在特定场景(如图像特征)可能效果更好

近似最近邻(ANN)算法

当向量数量达到百万、亿级别时,精确搜索的 O(n) 时间复杂度无法接受。ANN 算法通过牺牲少量精度换取显著的搜索速度提升。

算法对比

算法时间复杂度空间复杂度精度特点
FlatO(n)O(n)100%暴力搜索,仅适合小规模
IVFO(√n)O(n)90-99%倒排索引,平衡选择
HNSWO(log n)O(n)95-99%图索引,速度最快
PQO(1)O(n/k)70-90%量化压缩,内存友好

HNSW(Hierarchical Navigable Small World)

目前最流行的 ANN 算法,基于图索引结构。

核心思想

构建一个多层图结构:

  • 上层:稀疏的长连接,类似"高速公路"
  • 下层:密集的短连接,类似"街道"

搜索时从顶层开始快速定位大致区域,然后在下层精确搜索。

构建过程

1. 每个新节点随机决定插入到哪几层
- 第0层概率: 1
- 第1层概率: 1/2
- 第2层概率: 1/4
- ...(概率逐层减半)

2. 在每一层中:
- 找到与新节点最接近的 M 个邻居
- 建立双向连接

3. 层数越高,节点越稀疏

搜索过程

1. 从顶层随机节点开始
2. 在当前层贪婪搜索:
- 找到距离查询点最近的节点
3. 下降到下一层:
- 以上一层的结果为起点
4. 在最底层返回 K 个最近邻

HNSW 参数调优

参数说明建议值
M每层最大连接数16-64,越大精度越高
efConstruction构建时的搜索范围100-500,越大构建越慢但精度越高
ef查询时的搜索范围大于 top_k,越大精度越高
# HNSW 索引配置示例(Milvus)
index_params = {
"metric_type": "COSINE",
"index_type": "HNSW",
"params": {
"M": 16, # 最大连接数
"efConstruction": 200 # 构建搜索范围
}
}

# 查询参数
search_params = {
"metric_type": "COSINE",
"params": {"ef": 64} # 查询搜索范围
}

IVF(Inverted File Index)

基于聚类的索引方法。

核心思想

  1. 使用 K-means 将向量空间划分为 nlist 个簇
  2. 每个向量归属到最近的簇中心
  3. 查询时只搜索最近的 nprobe 个簇

构建过程

1. 随机选择 nlist 个中心点
2. 迭代优化中心点位置(K-means)
3. 将每个向量分配到最近的中心点
4. 建立倒排列表:中心点 → 向量列表

搜索过程

1. 计算查询向量与所有中心点的距离
2. 选择距离最近的 nprobe 个中心点
3. 只在这些中心点对应的向量中搜索
4. 返回 top_k 个最近邻

IVF 参数调优

参数说明建议值
nlist聚类中心数4×√n,n 为向量总数
nprobe查询时搜索的簇数10-100,越大精度越高
# IVF 索引配置示例
index_params = {
"metric_type": "L2",
"index_type": "IVF_FLAT",
"params": {"nlist": 128} # 聚类中心数
}

search_params = {
"metric_type": "L2",
"params": {"nprobe": 10} # 搜索簇数
}

PQ(Product Quantization)

乘积量化,用于压缩向量存储。

核心思想

将高维向量分割成多个子向量,对每个子向量单独量化,大幅降低存储空间。

量化过程

原始向量: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]  (8维)
↓ 分割为 4 个子向量
子向量1: [0.1, 0.2]
子向量2: [0.3, 0.4]
子向量3: [0.5, 0.6]
子向量4: [0.7, 0.8]
↓ 每个子向量量化到最近的码本中心
量化结果: [code1, code2, code3, code4] (每个code 1字节)

PQ 参数

参数说明建议值
m分割段数向量维度/4
nbits每段量化位数8

压缩比:原始 1024 维 float32 向量需要 4KB,PQ 压缩后仅需 256 字节(m=32, nbits=8)。

索引选择建议

数据规模推荐索引理由
< 10万FLAT精确搜索,无需索引
10万-100万IVF_FLAT平衡速度和精度
100万-1000万HNSW快速搜索,高精度
> 1000万IVF_PQ 或 HNSW考虑内存使用
内存受限PQ 系列压缩存储

向量数据库架构

核心组件

┌─────────────────────────────────────────────────────────┐
│ 向量数据库系统 │
├─────────────┬─────────────┬─────────────┬───────────────┤
│ 接入层 │ 存储层 │ 索引层 │ 查询层 │
├─────────────┼─────────────┼─────────────┼───────────────┤
│ • REST API │ • 原始数据 │ • HNSW │ • 相似度计算 │
│ • SDK │ • 向量数据 │ • IVF │ • 结果排序 │
│ • 协议适配 │ • 元数据 │ • PQ │ • 过滤聚合 │
└─────────────┴─────────────┴─────────────┴───────────────┘

数据组织

Collection(集合):逻辑上的数据表,包含:

  • 向量字段(固定维度)
  • 标量字段(元数据,用于过滤)
  • 索引配置

Partition(分区):集合的物理分片,用于:

  • 数据隔离(多租户)
  • 查询优化(分区裁剪)
  • 数据管理(按时间归档)

写入流程

1. 数据验证
- 检查向量维度
- 验证标量字段类型

2. 向量编码(如果使用 PQ)
- 分割向量
- 量化到码本

3. 索引更新
- 插入到图结构(HNSW)
- 或分配到聚类中心(IVF)

4. 数据持久化
- 写入日志(WAL)
- 刷盘到存储

查询流程

1. 请求解析
- 解析查询向量
- 解析过滤条件
- 解析 top_k

2. 索引检索(ANN)
- 在索引中搜索候选集
- 返回多于 top_k 的候选结果

3. 精确计算
- 对候选集计算精确相似度
- 应用过滤条件

4. 结果排序与返回
- 按相似度排序
- 截取 top_k
- 返回结果

性能优化

索引优化

  1. 选择合适的索引类型

    • 小规模数据:无需索引或 FLAT
    • 大规模数据:HNSW(速度优先)或 IVF(内存优先)
  2. 参数调优

    • HNSW:增大 M 和 efConstruction 提升精度
    • IVF:增大 nprobe 提升精度

查询优化

  1. 使用过滤条件

    • 先过滤标量字段,减少向量搜索范围
    • 利用分区裁剪
  2. 批量查询

    • 合并多个查询请求,摊平网络开销
  3. 结果缓存

    • 缓存热门查询结果

硬件优化

  1. 内存配置

    • 确保热数据可放入内存
    • 使用内存映射文件处理超大数据
  2. GPU 加速

    • 部分数据库支持 GPU 加速(如 Faiss)
    • 适合批量查询场景

常见问题

Q: 向量维度越高越好吗?

不是。维度越高:

  • 优点:表达能力更强,语义更精确
  • 缺点:存储成本增加,计算量增大,可能出现过拟合

建议

  • 一般文本:384-768 维
  • 高精度需求:1024-1536 维
  • 资源受限:256-384 维

Q: 如何处理动态数据(增删改)?

不同数据库策略不同:

  • Pinecone:自动处理,无需关心
  • Milvus:支持增量更新,删除为软删除
  • HNSW:增量插入友好,但删除需要重建

Q: 向量数据库和传统数据库的向量扩展有什么区别?

特性专用向量数据库传统数据库扩展
性能专为向量优化通用设计
扩展性分布式架构单机或主从
功能丰富的 ANN 算法通常只支持基础算法
适用规模亿级以上百万级以下

下一步