FAISSCompatible with Milvus 3.0.0+
Der Index-Typ „ FAISS “ ist eine Pass-Through-Funktion für Experten, die ab Milvus 3.0.0 verfügbar ist. Damit können Sie eine Faiss-Index-Factory-Zeichenkette angeben, anstatt einen festen Milvus-Index-Typ auszuwählen.
Verwenden Sie „ FAISS “, wenn Sie bereits über ein getestetes Faiss-Rezept verfügen und direkte Kontrolle über dessen Zusammensetzung benötigen. Bei gängigen Rezepten mit einem dedizierten Milvus-Indextyp sollten Sie den dedizierten Typ bevorzugen, da dieser über eine stabile, dokumentierte Parameterkonvention verfügt.
Ein von Upstream-Faiss akzeptierter Factory-String wird von Milvus nicht automatisch unterstützt. Die Kompatibilität hängt vom Vektorfeldtyp, der Metrik, der Dimension, den in das Milvus-Image kompilierten Faiss-Modulen sowie davon ab, ob der resultierende Index die von Milvus benötigten Operationen unterstützt.
Einschränkungen
FAISSunterstützt die Felder „FLOAT_VECTOR“ und „BINARY_VECTOR“. Die Felder „FLOAT16_VECTOR“, „BFLOAT16_VECTOR“, „INT8_VECTOR“ und „SPARSE_FLOAT_VECTOR“ werden nicht unterstützt.Der generische „
FAISS“-Adapter läuft auf der CPU. Es handelt sich nicht um einen Faiss-GPU-Indextyp.Der Build-Parameter „
faiss_index_name“ ist erforderlich. Milvus übergibt dessen Wert an Faiss, ohne das Rezept in einen dedizierten Milvus-Indextyp zu konvertieren.Build- und Suchparameter sind fabrikspezifisch. Ein von einer Fabrik unterstützter Parameter kann von einer anderen abgelehnt werden.
Für die skalare Filterung muss der zugrunde liegende Faiss-Index einen ID-Selektor unterstützen. Die Tests von Milvus 3.0.0 decken die gefilterte Suche mit den Float-Fabriken „
Flat“, „IVF64,Flat“ und „HNSW16,Flat“ ab. Gehen Sie nicht davon aus, dass jede Fabrik Filter unterstützt oder dass binäre „FAISS“-Indizes die skalare Filterung unterstützen.Such-Iteratoren werden nicht unterstützt.
Der Adapter bietet keine Raw-Vektor-Abfrage.
Die Unterstützung der Bereichssuche hängt von der Factory ab. „Float
Flat“ ist in der aktuellen Version enthalten. Verwenden Sie die Bereichssuche nicht mit binären „FAISS“-Indizes.Eine Factory kann erfolgreich erstellt werden, aber dennoch einige Milvus-Suchoperationen ablehnen. Beispielsweise lehnt der eigenständige „
PQ8x4“ den von der skalargefilterten Suche verwendeten Selektor ab. Überprüfen Sie die ungefilterte Verwendung separat.In Milvus 3.0.0 sollten Sie nach einem Neuladen des Index die „
COSINE“-Scores und die Schwellenwerte für die Bereichssuche überprüfen. Knowhere v3.0.6 stellt den Zustand der Kosinus-Normalisierung des „FAISS“-Adapters während der Deserialisierung nicht wieder her.
So funktioniert es
FAISS-Index-Passthrough-Workflow
Zum Erstellen des Indexes leitet Milvus „ faiss_index_name “, den Vektorfeldtyp, die Metrik und weitere Erstellungsparameter an den Knowhere-FAISS-Adapter weiter. Der Adapter ruft „ faiss::index_factory() “ für „ FLOAT_VECTOR “-Felder oder „ faiss::index_binary_factory() “ für „ BINARY_VECTOR “-Felder auf. Das resultierende Objekt ist ein nativer FAISS-Index, der über den normalen Milvus-Index-Lebenszyklus verwaltet wird.
Für die Suche wandelt der Adapter die übergebenen herstellerspezifischen Parameter in das entsprechende Faiss- SearchParameters -Objekt um. Bei unterstützten Float-Herstellern übergibt er zudem das Milvus-Filter-Bitset als Faiss-Selektor. Die Selektorunterstützung ist fabrikspezifisch, und die veröffentlichten Tests stellen keine skalare Filterung für „binary FAISS “-Indizes her. Aus diesem Grund kann ein Rezept in der eigenständigen Faiss-Version gültig sein, aber eine vom Milvus-Suchpfad geforderte Operation ablehnen.
Voraussetzungen
- Milvus 3.0.0 oder höher
- PyMilvus 3.0.0 oder höher
- Vertrautheit mit der Syntax der Faiss-Index-Factory und den Trainingsanforderungen der ausgewählten Factory
Anweisungen zur Installation finden Sie unter „PyMilvus installieren“.
Wählen Sie einen Factory-String
Ein Factory-String beschreibt einen Faiss-Index als Folge von Komponenten. Die folgenden Beispiele wurden mit der Release-Test-Version von Milvus 3.0.0 getestet. Diese Liste erhebt keinen Anspruch auf Vollständigkeit.
| Factory-String | Feldtyp | In den Release-Tests getestete Metriken | Suchparameter | Anmerkungen |
|---|---|---|---|---|
Flat | FLOAT_VECTOR | L2, IP, COSINE | Keine | Exakte Suche. |
IVF64,Flat | FLOAT_VECTOR | L2, IP, COSINE | nprobe | IVF mit 64 invertierten Listen und unkomprimierten Vektoren. |
HNSW16,Flat | FLOAT_VECTOR | L2, IP, COSINE | efSearch | HNSW-Graph mit flacher Vektorspeicherung. |
OPQ16,IVF64,PQ16x4 | FLOAT_VECTOR | L2 | Fabrikspezifisch | Kombiniert OPQ, IVF und PQ. Überprüfen Sie Trainingsgröße und Recall anhand Ihrer Daten. |
IVF64,PQ8x4,RFlat | FLOAT_VECTOR | L2 | nprobe, k_factor | Verwendet nach der PQ-Kandidatenauswahl einen „Flat Refiner“. |
PQ8x4 | FLOAT_VECTOR | L2 | Keine | Integriert Release-Tests. Die skalargefilterte Suche schlägt fehl, da der Index den Selektor ablehnt; überprüfen Sie die ungefilterte Verwendung separat. |
BFlat | BINARY_VECTOR | HAMMING | Keine | Exakte Suche nach binären Vektoren. |
Die Einträge unter „ COSINE “ geben die Abdeckung der Build- und Such-Smoke-Tests an. Bei Milvus 3.0.0 wird nach einem Neuladen des Indexes weder die Korrektheit der Bewertung noch der Bereichssuche gewährleistet. Siehe „Einschränkungen“.
Erstellen und Durchsuchen eines Float-Index
Das folgende Beispiel erstellt 3.000 128-dimensionale Vektoren. Dies liefert genügend Trainingsdaten für das im Beispiel verwendete „ IVF64,Flat “-Rezept. Erweitern Sie den Setup-Block und führen Sie ihn aus, bevor Sie den Index erstellen und durchsuchen.
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)
Erstellen Sie den Index
Stellen Sie „ index_type “ auf „ FAISS “ ein und wählen Sie mit „ faiss_index_name “ das native Faiss-Factory-Rezept aus.
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)
Die Factory-Zeichenkette „ IVF64,Flat “ erstellt einen IVF-Index mit 64 invertierten Listen und speichert in jeder Liste unkomprimierte Vektoren.
Durchsuchen Sie den Index
Legen Sie fabrikspezifische Suchparameter innerhalb von ` search_params.params` fest. Bei einer IVF-Fabrik steuert ` nprobe `, wie viele invertierte Listen Faiss durchsucht.
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)
Die Abfrage verwendet ` nprobe=8`, sodass Faiss 8 der 64 invertierten Listen durchsucht. Der Filter beschränkt die Ergebnisse auf Entitäten, deren ` category `-Wert ` reference` ist.
Erstellen und Durchsuchen eines Binärindexes
Verwenden Sie für „ BINARY_VECTOR “-Felder eine binäre Factory-Zeichenkette wie „ BFlat “ und eine kompatible binäre Metrik. Erweitern Sie den Setup-Block und führen Sie ihn aus, bevor Sie den Index erstellen und durchsuchen.
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)
Erstellen Sie den Index
Verwenden Sie für dieses Beispiel mit Binärvektoren „ BFlat “ als Factory-String und „ HAMMING “ als Metrik.
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)
Durchsuchen Sie den Index
BFlat verfügt über keinen familienspezifischen Suchparameter. Übergeben Sie beim Erstellen der Suchanfrage ein leeres „ params “-Mapping.
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)
Jeder 128-dimensionale Binärvektor wird durch 16 Byte dargestellt. Weitere Informationen finden Sie unter „Binärvektor“.
Konfigurieren Sie Build- und Suchparameter
Der Indextyp „ FAISS “ verfügt über einen erforderlichen Passthrough-Erstellungsparameter.
| Parameter | Speicherort | Beschreibung |
|---|---|---|
faiss_index_name | params in add_index() | Die Zeichenfolge der Faiss-Index-Factory. Zum Beispiel: „ IVF64,Flat “. |
Legen Sie fabrikspezifische Suchparameter innerhalb von „ search_params.params “ fest. Die folgende Tabelle enthält gängige Beispiele und erhebt keinen Anspruch auf Vollständigkeit.
| Parameter | Beispiel-Fabrik | Beschreibung |
|---|---|---|
nprobe | IVF64,Flat | Anzahl der zu durchsuchenden invertierten Listen. |
efSearch | HNSW16,Flat | Größe der HNSW-Suchkandidatenliste. |
k_factor | IVF64,PQ8x4,RFlat | Anzahl der an den Refiner übergebenen Kandidaten im Verhältnis zum angeforderten Top-K. |
Milvus leitet nur vom Adapter erkannte zusätzliche Parameter weiter. Unbekannte Build-Schlüssel und Suchschlüssel, die von der jeweiligen Factory-Familie nicht unterstützt werden, werden abgelehnt. Milvus unterhält kein universelles Parameterschema für jede mögliche Factory. Lesen Sie die Faiss-Dokumentation für die ausgewählte Factory und überprüfen Sie anschließend den gesamten Build- und Suchablauf anhand der genauen Milvus-Version und des Images, die Sie bereitstellen möchten.
Behandlung von Fehlern und nicht unterstützten Operationen
Wenn die Factory-Zeichenkette ungültig oder im Milvus-Build nicht verfügbar ist, schlägt der Indexaufbau fehl. Überprüfen Sie den Indexstatus und den Fehlergrund, bevor Sie die Sammlung laden.
Wenn ein Parameter den falschen Typ hat, schlägt die Suche fehl. Beispielsweise wird „
nprobe="invalid"“ abgelehnt, da „nprobe“ numerisch sein muss.Wenn ein Parameter nicht auf die erstellte Factory zutrifft, lehnt der Adapter ihn als nicht unterstützt ab.
Wenn eine Factory den Milvus-Selektor nicht unterstützt, kann die gefilterte Suche fehlschlagen, selbst wenn dieselbe Factory in einem eigenständigen Faiss-System suchen kann.
Verwenden Sie „
search_iterator()“ nicht mit einem „FAISS“-Index.
Was kommt als Nächstes
- Erfahren Sie in „Index Explained“, wie Milvus-Indizes aufgebaut sind.
- Vergleichen Sie die speziellen Index-Typen „IVF_FLAT “ und „HNSW “.
- Lesen Sie den Abschnitt „Metriktypen“, bevor Sie eine Metrik für die Factory auswählen.