【Milvus】稀疏向量 和 稠密向量
【Milvus】稀疏向量 和 稠密向量
1. 基础定义
(1)稀疏向量
向量绝大多数维度都有非 0 浮点值,几乎不存在大量零元素,存储为完整定长数组。
- 存储格式:完整数组,所有维度都占用内存;
- 典型来源:LLM/BERT/Sentence-BERT 输出语义 Embedding、图像特征;
- 示例(768 维文本稠密向量简化示意):
[0.12, 0.56, 0.33, 0.89, 0.27, ...]几乎无 0。
(2)稠密向量
向量95% 以上维度都是 0,仅少量维度存在有效值,只存储「(维度下标,权重值)」,舍弃全部零值节省空间。
- 存储格式:键值对,只记录非零位置;
- 典型来源:TF-IDF、Splade、词袋、分词关键词权重;
- 示例(完整 10000 维,仅 2 个有效值):
完整展开:[0,0,0,2.1,0,...,1.6,0,0]稀疏存储简写:{(3, 2.1), (892, 1.6)}
2. 核心差异对比
(1)存储占用
- 稠密:维度越高内存线性暴涨,768 维单条向量约 3KB;
- 稀疏:总维度再大也不占空间,只看非零词数量,万维、十万维向量体积很小。
(2)相似度计算逻辑
- 稠密:余弦 / 内积 / L2 距离,遍历全部维度做运算;
- 稀疏:仅计算两个向量共同存在的非零维度,零值直接跳过,关键词匹配速度更快。
(3)向量数据库索引适配
| 向量类型 | 支持索引 | 不支持索引 |
|---|---|---|
| 稠密向量 | HNSW、IVF_FLAT、IVF_PQ | 稀疏倒排索引 |
| 稀疏向量 | SPARSE_INVERTED_INDEX(稀疏倒排) | HNSW |
注意:Milvus 中稠密、稀疏向量必须分开字段、分开建索引,不能混用一套索引。
(4)检索能力侧重
-
稠密向量:语义模糊匹配,擅长同义、转述、上下文理解;
例:“汽车” 和 “小轿车” 能匹配到; -
稀疏向量:字面关键词精准匹配,擅长专有名词、实体、专业术语不漏召回;
例:只有包含 “汽车” 这个分词才会命中,不会泛化语义。
3. 业务使用场景
(1)稠密向量适用场景
- RAG 语义检索、多模态图文匹配;
- 句子、段落、长文本语义相似度;
- 模糊语义搜索、同义内容召回。
(2)稀疏向量适用场景
- 关键词精准检索、知识库专有名词匹配;
- 短文本标题、标签、商品类目过滤;
- 解决稠密向量丢失实体关键词的问题。
(3)主流方案:混合检索(Hybrid Search)
- 稠密向量(dense_vec):召回语义相近的文档;
- 稀疏向量(sparse_vec):召回包含核心关键词、专业术语的文档;
- 两路分数加权融合排序,兼顾语义理解和关键词精准度,大幅提升召回准确率。
4. 优缺点:
(1)稠密向量
-
优点:语义表达能力强,模糊匹配效果好,HNSW 检索成熟稳定;
-
缺点:高维内存开销大,纯关键词召回容易漏实体。
(2)稀疏向量
- 优点:超大维度极低存储,关键词检索速度极快;
- 缺点:无泛化语义能力,只能字面匹配,无法使用 HNSW 索引。
5. 向量类型汇总
| 向量类型 | 精度 / 存储 | 类型 | 入门 / 进阶 | 特点 | 使用前提 |
|---|---|---|---|---|---|
FLOAT_VECTOR |
fp32,4 字节 / 维度 | 稠密向量 | 基础通用 | 精度最高、通用首选 | 无转换,Embedding 直接输出,所有 RAG 首选 |
BFLOAT16_VECTOR |
bf16 半精度,2 字节 / 维度 | 稠密向量 | 进阶压缩 | 节省空间,小数精度表现好 | 向量需转为 bf16 格式,适配大模型 GPU 推理 |
FLOAT16_VECTOR |
fp16 半精度,2 字节 / 维度 | 稠密向量 | 进阶压缩 | 数值范围大,小数精度弱 | 尾数精度更高,适合图像特征向量 |
INT8_VECTOR |
int8 整型,1 字节 / 维度 | 稠密向量 | 进阶极致压缩 | 存储 -128~127 整数向量 | 原始 fp32 向量必须做量化映射,海量数据降内存专用 |
BINARY_VECTOR |
1 比特 / 维度 | 稠密向量 | 特殊稠密 | 稀疏向量,适配超高维度场景 | 图像哈希二值特征,维度必须是 8 的倍数 |
SPARSE_FLOAT_VECTOR |
按需存储 | 稀疏向量 | 基础通用 | 二进制向量,极致压缩存储 | 稀疏向量,适配超高维度场景 |
6. 创建 稠密向量 和 稀疏向量
(1)SQL创建
-- 创建 FLOAT_VECTOR
create collection vec_demo_fp32 (
id bigint primary key autoincrement,
text varchar(2000),
vec_fp32 FLOAT VECTOR(768)
);
-- 创建 BFLOAT16_VECTOR
create collection vec_demo_bf16 (
id bigint primary key autoincrement,
text varchar(2000),
vec_bf16 BFLOAT16_VECTOR(768)
);
-- 创建 FLOAT16_VECTOR
create collection vec_demo_fp16 (
id bigint primary key autoincrement,
text varchar(2000),
vec_fp16 FLOAT16_VECTOR(768)
);
-- 创建 INT8_VECTOR
create collection vec_demo_int8 (
id bigint primary key autoincrement,
text varchar(2000),
vec_int8 INT8_VECTOR(768)
);
-- 创建 BINARY_VECTOR
create collection vec_demo_bin (
id bigint primary key autoincrement,
text varchar(2000),
vec_bin BINARY_VECTOR(512)
);
-- 创建 SPARSE_FLOAT_VECTOR
create collection vec_demo_sparse (
id bigint primary key autoincrement,
text varchar(2000),
sparse_vec SPARSE_FLOAT_VECTOR
);
(2)Python SDK Schema
from pymilvus import FieldSchema, DataType
# 创建 FLOAT_VECTOR
field_fp32 = FieldSchema(
name="vec_fp32",
dtype=DataType.FLOAT_VECTOR,
dim=768
)
# 创建 BFLOAT16_VECTOR
field_bf16 = FieldSchema(
name="vec_bf16",
dtype=DataType.BFLOAT16_VECTOR,
dim=768
)
# 创建 FLOAT16_VECTOR
field_fp16 = FieldSchema(
name="vec_fp16",
dtype=DataType.FLOAT16_VECTOR,
dim=768
)
# 创建 INT8_VECTOR
field_int8 = FieldSchema(
name="vec_int8",
dtype=DataType.INT8_VECTOR,
dim=768
)
# 创建 BINARY_VECTOR
field_bin = FieldSchema(
name="vec_bin",
dtype=DataType.BINARY_VECTOR,
dim=512
)
# 创建 SPARSE_FLOAT_VECTOR
field_sparse = FieldSchema(
name="sparse_vec",
dtype=DataType.SPARSE_FLOAT_VECTOR
)
# 组装完整通用基础字段
base_fields = [
FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),
FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=2000)
]

浙公网安备 33010602011771号