FAISSCompatible with Milvus 3.0.0+
FAISS 索引类型是Milvus 3.0.0及更高版本中提供的一种专家级直通功能。它允许您提供一个Faiss索引生成器字符串,而非选择固定的Milvus索引类型。
当您已有经过测试的 Faiss 配方,且需要直接控制其构成时,请使用FAISS 。对于具有专用 Milvus 索引类型的常见配方,建议优先使用专用类型,因为它具有稳定且有文档记录的参数契约。
上游 Faiss 接受的工厂字符串并不一定自动被 Milvus 支持。兼容性取决于向量字段类型、度量、维度、编译到 Milvus 镜像中的 Faiss 模块,以及生成的索引是否支持 Milvus 所需的操作。
限制
FAISS支持FLOAT_VECTOR和BINARY_VECTOR字段。不支持FLOAT16_VECTOR、BFLOAT16_VECTOR、INT8_VECTOR或SPARSE_FLOAT_VECTOR字段。通用
FAISS适配器在 CPU 上运行。它不是 Faiss GPU 索引类型。必须指定
faiss_index_name构建参数。Milvus会将该参数的值传递给Faiss,而不会将配方转换为专用的Milvus索引类型。构建和搜索参数因工厂而异。某个工厂支持的参数可能被另一个工厂拒绝。
标量过滤要求底层 Faiss 索引支持 ID 选择器。Milvus 3.0.0 的测试涵盖了使用浮点工厂
Flat、IVF64,Flat和HNSW16,Flat进行的过滤搜索。请勿假设每个工厂都支持过滤器,也不要假设二进制FAISS索引支持标量过滤。不支持搜索迭代器。
该适配器不提供原始向量检索功能。
范围搜索的支持取决于工厂。浮点型
Flat已通过发布版测试。请勿在二进制FAISS索引上使用范围搜索。工厂可能构建成功,但仍会拒绝某些 Milvus 搜索操作。例如,Milvus Standalone
PQ8x4会拒绝标量过滤搜索所使用的选择器。请单独验证未过滤的使用情况。在 Milvus 3.0.0 中,索引重新加载后需验证
COSINE的得分和范围搜索阈值。Knowhere v3.0.6 在反序列化过程中无法恢复FAISS适配器的余弦归一化状态。
工作原理
FAISS 索引直通工作流
在构建索引时,Milvus 将 `faiss_index_name`、向量字段类型、度量以及其他构建参数转发给 Knowhere FAISS 适配器。该适配器会针对 `FLOAT_VECTOR ` 字段调用 `faiss::index_factory() `,针对 `BINARY_VECTOR ` 字段调用 `faiss::index_binary_factory() `。生成的对象是一个原生 Faiss 索引,通过常规的 Milvus 索引生命周期进行管理。
在搜索时,适配器会将提供的工厂特定参数转换为对应的 FaissSearchParameters 对象。对于受支持的浮点工厂,它还会将 Milvus 过滤器位集作为 Faiss 选择器传递。 选择器的支持因工厂而异,且已发布的测试并未针对二进制FAISS 索引建立标量过滤功能。这就是为什么某个配方在独立的 Faiss 中有效,却可能被 Milvus 搜索路径所需的操作所拒绝。
先决条件
- Milvus 3.0.0 或更高版本
- PyMilvus 3.0.0 或更高版本
- 熟悉 Faiss 索引生成器的语法以及所选生成器的训练要求
有关安装说明,请参阅《安装 PyMilvus》。
选择工厂字符串
工厂字符串将 Faiss 索引描述为一组组件的序列。以下示例已通过 Milvus 3.0.0 发布测试的覆盖验证。此列表并非详尽无遗。
| 生成器字符串 | 字段类型 | 在发布测试中验证的指标 | 搜索参数 | 备注 |
|---|---|---|---|---|
Flat | FLOAT_VECTOR | L2,IP,COSINE | 无 | 精确搜索。 |
IVF64,Flat | FLOAT_VECTOR | L2,IP,COSINE | nprobe | 使用64个反转列表和未压缩向量的IVF。 |
HNSW16,Flat | FLOAT_VECTOR | L2,IP,COSINE | efSearch | 采用扁平向量存储的HNSW图。 |
OPQ16,IVF64,PQ16x4 | FLOAT_VECTOR | L2 | 针对特定工厂 | 结合了OPQ、IVF和PQ。请使用您的数据验证训练规模和召回率。 |
IVF64,PQ8x4,RFlat | FLOAT_VECTOR | L2 | nprobe,k_factor | 在 PQ 候选项检索后使用扁平化精炼器。 |
PQ8x4 | FLOAT_VECTOR | L2 | 无 | 内置发布测试。标量过滤搜索会失败,因为索引拒绝了选择器;请单独验证未过滤的使用情况。 |
BFlat | BINARY_VECTOR | HAMMING | 无 | 二进制向量的精确搜索。 |
COSINE 条目表示构建和搜索的烟雾测试覆盖率。对于Milvus 3.0.0,这些条目无法在索引重新加载后验证得分或范围搜索的正确性。参见“限制”。
构建并搜索浮点索引
以下示例创建了 3,000 个 128 维向量。这为示例中使用的IVF64,Flat 配方提供了足够的训练数据。在构建和搜索索引之前,请展开“设置”代码块并运行它。
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_type 设置为FAISS ,并使用faiss_index_name 选择原生Faiss工厂配方。
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)
工厂字符串IVF64,Flat 会创建一个包含 64 个倒排列表的 IVF 索引,并在每个列表中存储未压缩的向量。
搜索索引
在search_params.params 中设置工厂特定的搜索参数。对于 IVF 工厂,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个。该过滤器将结果限制为category 值为reference 的实体。
构建和搜索二进制索引
对于BINARY_VECTOR 字段,请使用类似BFlat 的二进制生成字符串以及兼容的二进制度量。在构建和搜索索引之前,请展开设置代码块并运行它。
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)
构建索引
在此二进制向量示例中,请使用BFlat 作为生成字符串,并使用HAMMING 作为度量。
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)
搜索索引
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 字节表示。有关更多信息,请参阅《二进制向量》。
配置构建和搜索参数
FAISS 索引类型有一个必需的直通构建参数。
| 参数 | 位置 | 描述 |
|---|---|---|
faiss_index_name | params inadd_index() | Faiss 索引生成器字符串。例如:IVF64,Flat 。 |
请在search_params.params 中设置工厂特定的搜索参数。下表列出了常见的示例,但并非详尽无遗。
| 参数 | 工厂示例 | 描述 |
|---|---|---|
nprobe | IVF64,Flat | 要搜索的倒排列表数量。 |
efSearch | HNSW16,Flat | HNSW 搜索候选项列表的大小。 |
k_factor | IVF64,PQ8x4,RFlat | 相对于请求的“前 K 个”结果,提供给优化器的候选项数量。 |
Milvus 仅转发适配器识别的附加参数。未知构建键以及具体工厂家族不支持的搜索键将被拒绝。Milvus 不会为所有可能的工厂维护通用 Schema。 请查阅所选工厂的 Faiss 文档,然后根据您计划部署的确切 Milvus 版本和镜像,验证完整的构建和搜索流程。
处理错误和不受支持的操作
如果工厂字符串无效或在 Milvus 构建中不可用,索引构建将失败。在加载 Collection 之前,请检查索引状态和失败原因。
如果参数类型错误,搜索将失败。例如,
nprobe="invalid"会被拒绝,因为nprobe必须是数值型。如果某个参数不适用于已构建的工厂,适配器会将其视为不受支持而拒绝。
如果工厂不支持 Milvus 选择器,即使同一工厂在独立的 Faiss 中可以进行搜索,过滤搜索仍可能失败。
请勿在
FAISS索引中使用search_iterator()。