FAISS
FAISS Index 类型是 Milvus 3.0.0 及更高版本提供的专家级透传接口。你可以通过该类型提供 Faiss index-factory string,而无需选择固定的 Milvus Index 类型。
如果你已经有经过测试的 Faiss 方案,并且需要直接控制其组成,请使用 FAISS。对于 Milvus 已提供专用 Index 类型的常用方案,建议优先使用专用类型,因为这类类型具有稳定且有明确文档说明的参数约定。
上游 Faiss 接受的 factory string 并不一定受 Milvus 支持。兼容性取决于向量字段类型、metric、维度、Milvus 镜像中编译的 Faiss 模块,以及生成的 Index 是否支持 Milvus 所需的操作。
Limits
-
FAISS支持FLOAT_VECTOR和BINARY_VECTOR字段,但不支持FLOAT16_VECTOR、BFLOAT16_VECTOR、INT8_VECTOR或SPARSE_FLOAT_VECTOR字段。 -
通用
FAISS适配器在 CPU 上运行,并非 Faiss GPU Index 类型。 -
必须指定构建参数
faiss_index_name。Milvus 会将其值直接传递给 Faiss,而不会将该索引配置转换为 Milvus 的专用 Index 类型。 -
构建参数和检索参数因 factory 而异。某个 factory 支持的参数可能会被另一个 factory 拒绝。
-
标量 Filter 要求底层 Faiss Index 支持 ID selector。Milvus 3.0.0 已测试对浮点 factory
Flat、IVF64,Flat和HNSW16,Flat执行带 Filter 的检索。不要假定所有 factory 都支持 Filter,也不要假定二进制FAISSIndex 支持标量 Filter。 -
不支持 Search Iterator。
-
该适配器不支持检索原始向量。
-
Range Search 支持情况取决于 factory。浮点
Flat已通过发布测试。不要对二进制FAISSIndex 使用 Range Search。 -
factory 可能成功完成构建,但仍会拒绝某些 Milvus 检索操作。例如,独立的
PQ8x4会拒绝标量 Filter 检索使用的 selector。请单独验证不带 Filter 的使用场景。 -
在 Milvus 3.0.0 中,Index 重新 Load 后,请验证
COSINE分数和 Range Search 阈值。Knowhere v3.0.6 在反序列化期间不会恢复FAISS适配器的余弦归一化状态。
How it works

构建 Index 时,Milvus 会将 faiss_index_name、向量字段类型、metric 以及其他构建参数转发给 Knowhere FAISS adapter。对于 FLOAT_VECTOR 字段,adapter 调用 faiss::index_factory();对于 BINARY_VECTOR 字段,则调用 faiss::index_binary_factory()。生成的对象是原生 Faiss Index,由 Milvus 的常规 Index 生命周期管理。
搜索时,adapter 会将提供的 factory 特定参数转换为对应的 Faiss SearchParameters 对象。对于支持的浮点向量 factory,adapter 还会将 Milvus 的 Filter bitset 作为 Faiss selector 传入。selector 支持因 factory 而异,已发布的测试也未证实二进制 FAISS Index 支持标量过滤。因此,在独立 Faiss 中有效的配置方案,可能会拒绝 Milvus 搜索路径所需的操作。
Prerequisites
- Milvus 3.0.0 或更高版本
- PyMilvus 3.0.0 或更高版本
- 熟悉 Faiss index-factory 语法以及所选 factory 的训练要求
有关安装说明,请参阅 安装 PyMilvus。
选择 factory string
factory string 使用一系列组件描述 Faiss Index。以下示例已通过 Milvus 3.0.0 发布测试,但并未涵盖所有可用配置。
| Factory string | 字段类型 | 发布测试涵盖的距离度量 | 搜索参数 | 说明 |
|---|---|---|---|---|
Flat | FLOAT_VECTOR | L2、IP、COSINE | None | 精确搜索。 |
IVF64,Flat | FLOAT_VECTOR | L2、IP、COSINE | nprobe | 使用 64 个倒排列表和未压缩向量的 IVF。 |
HNSW16,Flat | FLOAT_VECTOR | L2、IP、COSINE | efSearch | 使用 Flat 向量存储的 HNSW 图。 |
OPQ16,IVF64,PQ16x4 | FLOAT_VECTOR | L2 | Factory-specific | 组合使用 OPQ、IVF 和 PQ。请使用你的数据验证训练数据量和召回率。 |
IVF64,PQ8x4,RFlat | FLOAT_VECTOR | L2 | nprobe、k_factor | 召回 PQ 候选项后,使用 Flat refiner。 |
PQ8x4 | FLOAT_VECTOR | L2 | None | 可在发布测试中成功构建。由于该 Index 不接受 selector,使用标量 Filter 的搜索会失败;请单独验证不使用 Filter 的场景。 |
BFlat | BINARY_VECTOR | HAMMING | None | 对二进制向量执行精确搜索。 |
COSINE 条目表示构建和搜索已通过冒烟测试。对于 Milvus 3.0.0,这些测试无法证明重载 Index 后得分或 Range Search 的正确性。请参阅 限制。
构建并检索浮点向量 Index
以下示例创建 3,000 个 128 维向量,为示例中使用的 IVF64,Flat 配置提供充足的训练数据。展开准备步骤,并在构建和检索 Index 前运行其中的代码。
准备浮点向量 Collection
import random
from pymilvus import DataType, MilvusClient
client = MilvusClient(uri="http://localhost:19530")
collection_name = "faiss_float_example"
if client.has_collection(collection_name):
client.drop_collection(collection_name)
rng = random.Random(42)
vectors = [[rng.random() for _ in range(128)] for _ in range(3000)]
schema = client.create_schema(auto_id=False, enable_dynamic_field=False)
schema.add_field("id", DataType.INT64, is_primary=True)
schema.add_field("category", DataType.VARCHAR, max_length=32)
schema.add_field("vector", DataType.FLOAT_VECTOR, dim=128)
client.create_collection(collection_name=collection_name, schema=schema)
rows = [
{
"id": i,
"category": "reference" if i % 2 == 0 else "query",
"vector": vector,
}
for i, vector in enumerate(vectors)
]
client.insert(collection_name=collection_name, data=rows)
client.flush(collection_name=collection_name)
构建 Index
将 index_type 设置为 FAISS,并使用 faiss_index_name 选择原生 Faiss factory recipe。
index_params = client.prepare_index_params()
index_params.add_index(
field_name="vector",
index_name="faiss_ivf_flat",
index_type="FAISS",
metric_type="L2",
params={"faiss_index_name": "IVF64,Flat"},
)
client.create_index(collection_name=collection_name, index_params=index_params)
client.load_collection(collection_name=collection_name)
factory 字符串 IVF64,Flat 会创建一个包含 64 个倒排列表的 IVF Index,并在每个列表中存储未压缩的向量。
Search the index
在 search_params.params 中设置特定于 factory 的搜索参数。对于 IVF factory,nprobe 控制 Faiss 搜索的倒排列表数量。
search_params = {
"params": {"nprobe": 8},
}
results = client.search(
collection_name=collection_name,
data=[vectors[0]],
anns_field="vector",
filter='category == "reference"',
search_params=search_params,
limit=5,
output_fields=["category"],
)
for hits in results:
for hit in hits:
print(hit)
该查询使用 nprobe=8,因此 Faiss 会搜索 64 个倒排列表中的 8 个。Filter 将结果限制为 category 值为 reference 的 Entity。
构建和检索二进制 Index
对于 BINARY_VECTOR 字段,请使用 BFlat 等二进制工厂字符串以及兼容的二进制度量类型。展开以下准备代码块,并在构建和检索 Index 前运行其中的代码。
准备二进制向量 Collection
import random
from pymilvus import DataType, MilvusClient
client = MilvusClient(uri="http://localhost:19530")
collection_name = "faiss_binary_example"
if client.has_collection(collection_name):
client.drop_collection(collection_name)
rng = random.Random(7)
vectors = [bytes(rng.getrandbits(8) for _ in range(16)) for _ in range(300)]
schema = client.create_schema(auto_id=False, enable_dynamic_field=False)
schema.add_field("id", DataType.INT64, is_primary=True)
schema.add_field("binary_vector", DataType.BINARY_VECTOR, dim=128)
client.create_collection(collection_name=collection_name, schema=schema)
client.insert(
collection_name=collection_name,
data=[{"id": i, "binary_vector": vector} for i, vector in enumerate(vectors)],
)
client.flush(collection_name=collection_name)
构建 Index
在此二进制向量示例中,使用 BFlat 作为 factory string,并使用 HAMMING 作为 metric。
index_params = client.prepare_index_params()
index_params.add_index(
field_name="binary_vector",
index_name="faiss_binary_flat",
index_type="FAISS",
metric_type="HAMMING",
params={"faiss_index_name": "BFlat"},
)
client.create_index(collection_name=collection_name, index_params=index_params)
client.load_collection(collection_name=collection_name)
Search the index
BFlat 没有该索引家族特有的搜索参数。构造搜索请求时,请传入空的 params 映射。
search_params = {"params": {}}
results = client.search(
collection_name=collection_name,
data=[vectors[0]],
anns_field="binary_vector",
search_params=search_params,
limit=5,
)
for hits in results:
for hit in hits:
print(hit)
每个 128 维二进制向量使用 16 字节表示。更多信息,请参阅 Binary Vector。
配置构建和检索参数
FAISS Index 类型有一个必需的透传构建参数。
| 参数 | 位置 | 说明 |
|---|---|---|
faiss_index_name | add_index() 中的 params | Faiss index-factory 字符串,例如 IVF64,Flat。 |
在 search_params.params 中设置特定于 factory 的检索参数。下表列出了一些常见示例,但并未涵盖所有参数。
| 参数 | factory 示例 | 说明 |
|---|---|---|
nprobe | IVF64,Flat | 要检索的倒排列表数量。 |
efSearch | HNSW16,Flat | HNSW 检索候选列表的大小。 |
k_factor | IVF64,PQ8x4,RFlat | 相对于所请求 top-K,提供给 refiner 的候选项数量。 |
Milvus 仅转发 adapter 能够识别的附加参数。未知的构建参数键以及具体 factory 系列不支持的检索参数键将被拒绝。Milvus 不为所有可能的 factory 维护统一的参数 Schema。请查阅所选 factory 的 Faiss 文档,然后针对你计划部署的具体 Milvus 版本和镜像,验证完整的构建和检索流程。
处理错误和不支持的操作
-
如果 factory 字符串无效,或当前 Milvus 构建版本不支持该字符串,Index 构建将失败。加载 Collection 前,请检查 Index 状态和失败原因。
-
如果参数类型错误,Search 将失败。例如,
nprobe="invalid"会被拒绝,因为nprobe必须是数值。 -
如果参数不适用于已构建的 factory,适配器会以不支持该参数为由拒绝请求。
-
如果某个 factory 不支持 Milvus selector,即使同一个 factory 可以在独立运行的 Faiss 中执行 Search,带 Filter 的 Search 仍可能失败。
-
不要对
FAISSIndex 使用search_iterator()。
What's next
- 阅读 Index Explained,了解 Milvus 中 Index 的组织方式。
- 对比专用的 IVF_FLAT 和 HNSW Index 类型。
- 在为 factory 选择距离度量之前,先阅读 Metric Types。