Knowhere
In diesem Abschnitt wird Knowhere vorgestellt, die zentrale Vektorausführungsmaschine von Milvus.
Überblick
Knowhere ist die zentrale Vektorausführungsmaschine von Milvus, die mehrere Bibliotheken für die Suche nach Vektorähnlichkeit enthält, darunter Faiss, Hnswlib und Annoy. Knowhere ist auch für die Unterstützung von heterogenem Computing ausgelegt. Sie steuert, auf welcher Hardware (CPU oder GPU) die Indexerstellung und Suchanfragen ausgeführt werden sollen. Daher hat Knowhere auch seinen Namen - es weiß, wo die Operationen ausgeführt werden sollen. Weitere Hardwaretypen, einschließlich DPU und TPU, werden in zukünftigen Versionen unterstützt.
Knowhere in der Milvus-Architektur
Die folgende Abbildung zeigt die Position von Knowhere in der Milvus-Architektur.
Knowhere
Die unterste Schicht ist die Systemhardware. Darüber befinden sich die Indexbibliotheken von Drittanbietern. Auf der obersten Schicht interagiert Knowhere mit dem Indexknoten und dem Abfrageknoten über CGO, das es Go-Paketen ermöglicht, C-Code aufzurufen.
Knowhere Vorteile
Im Folgenden sind die Vorteile von Knowhere gegenüber Faiss aufgeführt.
Unterstützung für BitsetView
Milvus führt einen Bitset-Mechanismus ein, um "soft deletion" zu realisieren. Ein sanft gelöschter Vektor existiert noch in der Datenbank, wird aber bei einer Vektorähnlichkeitssuche oder -abfrage nicht berechnet.
Jedes Bit in einem Bitset entspricht einem indizierten Vektor. Wenn ein Vektor im Bitset mit "1" markiert ist, bedeutet dies, dass dieser Vektor "soft-deleted" ist und bei einer Vektorsuche nicht berücksichtigt wird. Der Bitset-Parameter wird auf alle exponierten Faiss-Indexabfrage-APIs in Knowhere angewendet, einschließlich CPU- und GPU-Indizes.
Weitere Informationen über den Bitset-Mechanismus finden Sie unter Bitset.
Unterstützung für mehrere Ähnlichkeitsmetriken zur Indizierung binärer Vektoren
Knowhere unterstützt Hamming, Jaccard, Tanimoto, Superstructure, und Substructure. Jaccard und Tanimoto können verwendet werden, um die Ähnlichkeit zwischen zwei Mustersätzen zu messen, während Superstructure und Substructure verwendet werden können, um die Ähnlichkeit von chemischen Strukturen zu messen.
Unterstützung für AVX512-Befehlssatz
Neben AArch64, SSE4.2 und AVX2, den bereits von Faiss unterstützten Befehlssätzen, unterstützt Knowhere auch AVX512, was die Leistung der Indexerstellung und -abfrage um 20 bis 30 % im Vergleich zu AVX2 verbessern kann.
Automatische SIMD-Befehlsauswahl
Knowhere unterstützt den automatischen Aufruf der geeigneten SIMD-Befehle (z. B. SIMD SSE, AVX, AVX2 und AVX512) auf jedem CPU-Prozessor (sowohl vor Ort als auch auf Cloud-Plattformen), so dass die Benutzer das SIMD-Flag (z. B. "-msse4") während der Kompilierung nicht manuell angeben müssen.
Knowhere wird durch Refactoring der Codebasis von Faiss erstellt. Gängige Funktionen (z. B. Ähnlichkeitsberechnungen), die auf SIMD-Beschleunigung angewiesen sind, werden ausgegliedert. Dann werden für jede Funktion vier Versionen (d.h. SSE, AVX, AVX2, AVX512) implementiert und jeweils in eine separate Quelldatei geschrieben. Anschließend werden die Quelldateien einzeln mit dem entsprechenden SIMD-Flag weiter kompiliert. Daher kann Knowhere zur Laufzeit automatisch die am besten geeigneten SIMD-Anweisungen auf der Grundlage der aktuellen CPU-Flags auswählen und dann die richtigen Funktionszeiger mit Hooking verknüpfen.
Andere Leistungsoptimierungen
Lesen Sie Milvus: A Purpose-Built Vector Data Management System für weitere Informationen über die Leistungsoptimierung von Knowhere.
Knowhere-Code-Struktur
Die Berechnungen in Milvus beinhalten hauptsächlich Vektor- und Skalaroperationen. Knowhere verarbeitet nur die Operationen zur Vektorindizierung.
Ein Index ist eine Datenstruktur, die unabhängig von den ursprünglichen Vektordaten ist. Im Allgemeinen sind für die Indexierung vier Schritte erforderlich: Erstellen eines Indexes, Trainieren von Daten, Einfügen von Daten und Aufbau eines Indexes. In einigen KI-Anwendungen wird das Training von Datensätzen von der Vektorsuche getrennt. Daten aus Datensätzen werden zunächst trainiert und dann in eine Vektordatenbank wie Milvus für die Ähnlichkeitssuche eingefügt. Bei den offenen Datensätzen sift1M und sift1B wird beispielsweise zwischen Daten zum Trainieren und Daten zum Testen unterschieden.
In Knowhere sind die Daten für das Training und für die Suche jedoch identisch. Knowhere trainiert alle Daten in einem Segment und fügt dann alle trainierten Daten ein und baut einen Index für sie auf.
DataObj
Basis: Basisklasse
DataObj
ist die Basisklasse für alle Datenstrukturen in Knowhere. Size()
ist die einzige virtuelle Methode in DataObj
. Die Klasse Index erbt von DataObj
mit einem Feld namens "size_". Die Index-Klasse hat auch zwei virtuelle Methoden - Serialize()
und Load()
. Die Klasse VecIndex
, die von Index
abgeleitet ist, ist die virtuelle Basisklasse für alle Vektorindizes. VecIndex
bietet Methoden wie Train()
, Query()
, GetStatistics()
und ClearStatistics()
.
Basisklasse
Einige andere Indextypen sind in der obigen Abbildung rechts aufgeführt.
Der Faiss-Index hat zwei Basisklassen:
FaissBaseIndex
für alle Indizes auf Fließkomma-Vektoren undFaissBaseBinaryIndex
für alle Indizes auf binären Vektoren.GPUIndex
ist die Basisklasse für alle Faiss-GPU-Indizes.OffsetBaseIndex
ist die Basisklasse für alle selbstentwickelten Indizes. Da in einer Indexdatei nur die Vektor-IDs gespeichert werden, kann die Dateigröße für 128-dimensionale Vektoren um zwei Größenordnungen reduziert werden.
IDMAP
: Brute-Force-Suche
IDMAP
Technisch gesehen handelt es sich bei IDMAP
nicht um einen Index, sondern um eine Brute-Force-Suche. Wenn Vektoren in die Datenbank eingefügt werden, ist weder ein Datentraining noch ein Indexaufbau erforderlich. Die Suche wird direkt auf den eingefügten Vektordaten durchgeführt.
Aus Gründen der Code-Konsistenz erbt IDMAP
jedoch auch von der Klasse VecIndex
mit all ihren virtuellen Schnittstellen. Die Verwendung von IDMAP
ist die gleiche wie bei den anderen Indizes.
IVF-Indizes
IVF
Die IVF-Indizes (inverted file) sind die am häufigsten verwendeten Indizes. Die Klasse IVF
wird von VecIndex
und FaissBaseIndex
abgeleitet und erweitert sich zu IVFSQ
und IVFPQ
. GPUIVF
wird von GPUIndex
und IVF
abgeleitet. Dann erweitert sich GPUIVF
weiter zu GPUIVFSQ
und GPUIVFPQ
.
IVFSQHybrid
ist ein selbst entwickelter hybrider Index. Ein grober Quantisierer wird auf der GPU ausgeführt, während die Suche im Bucket auf der CPU stattfindet. Diese Art von Index kann das Auftreten von Speicherkopien zwischen CPU und GPU reduzieren, indem die Rechenleistung der GPU genutzt wird. IVFSQHybrid
hat die gleiche Auffindungsrate wie GPUIVFSQ
, bietet aber eine bessere Leistung.
Die Basisklassenstruktur für binäre Indizes ist relativ einfach. BinaryIDMAP
und BinaryIVF
sind von FaissBaseBinaryIndex
und VecIndex
abgeleitet.
Indizes von Drittanbietern
Drittanbieter-Indizes
Derzeit werden neben Faiss nur zwei Arten von Indizes von Drittanbietern unterstützt: der baumbasierte Index Annoy
und der graphbasierte Index HNSW
. Diese beiden gebräuchlichen und häufig verwendeten Indizes von Drittanbietern sind beide von VecIndex
abgeleitet.
Hinzufügen von Indizes zu Knowhere
Wenn Sie neue Indizes zu Knowhere hinzufügen möchten, können Sie zunächst auf bestehende Indizes verweisen:
Um quantisierungsbasierte Indizes hinzuzufügen, lesen Sie
IVF_FLAT
.Um graph-basierte Indizes hinzuzufügen, lesen Sie
HNSW
.Um baumbasierte Indizes hinzuzufügen, lesen Sie bitte
Annoy
.
Nachdem Sie auf einen bestehenden Index verwiesen haben, können Sie die folgenden Schritte ausführen, um einen neuen Index zu Knowhere hinzuzufügen.
Fügen Sie den Namen des neuen Indexes in
IndexEnum
ein. Der Datentyp ist String.Fügen Sie eine Datenvalidierungsprüfung für den neuen Index in der Datei
ConfAdapter.cpp
hinzu. Die Validierungsprüfung dient hauptsächlich dazu, die Parameter für das Datentraining und die Abfrage zu validieren.Erstellen Sie eine neue Datei für den neuen Index. Die Basisklasse des neuen Index sollte
VecIndex
und die notwendige virtuelle Schnittstelle vonVecIndex
enthalten.Fügen Sie die Indexerstellungslogik für den neuen Index in
VecIndexFactory::CreateVecIndex()
hinzu.Fügen Sie den Unit-Test unter dem Verzeichnis
unittest
hinzu.
Was kommt als nächstes?
Nachdem Sie gelernt haben, wie Knowhere in Milvus funktioniert, möchten Sie vielleicht auch:
Lernen Sie die verschiedenen Arten von Indizes kennen, die Milvus unterstützt.
Lernen Sie den Bitset-Mechanismus kennen.
Verstehen, wie Daten in Milvus verarbeitet werden.