HNSW_SQ

HNSW_SQ kombiniert Hierarchical Navigable Small World (HNSW)-Graphen mit Scalar Quantization (SQ) und schafft damit eine fortschrittliche Vektorindizierungsmethode, die einen kontrollierbaren Kompromiss zwischen Größe und Genauigkeit bietet. Im Vergleich zu Standard-HNSW behält dieser Indextyp eine hohe Abfrageverarbeitungsgeschwindigkeit bei, während die Indexerstellungszeit leicht ansteigt.

Überblick

HNSW_SQ kombiniert zwei Indizierungstechniken: HNSW für schnelle graphbasierte Navigation und SQ für effiziente Vektorkompression.

HNSW

HNSW konstruiert einen mehrschichtigen Graphen, bei dem jeder Knoten einem Vektor im Datensatz entspricht. In diesem Graphen sind die Knoten auf der Grundlage ihrer Ähnlichkeit miteinander verbunden, was eine schnelle Durchquerung des Datenraums ermöglicht. Die hierarchische Struktur ermöglicht es dem Suchalgorithmus, die in Frage kommenden Nachbarn einzugrenzen, wodurch der Suchprozess in hochdimensionalen Räumen erheblich beschleunigt wird.

Weitere Informationen finden Sie unter HNSW.

SQ

SQ ist eine Methode zur Komprimierung von Vektoren, indem sie mit weniger Bits dargestellt werden. Zum Beispiel:

  • SQ8 verwendet 8 Bits, die Werte in 256 Stufen abbilden. Weitere Informationen finden Sie unter IVF_SQ8.

  • SQ6 verwendet 6 Bits zur Darstellung jedes Gleitkommawertes, was zu 64 diskreten Stufen führt.

Hnsw Sq Hnsw Sq

Durch diese Präzisionsreduzierung wird der Speicherplatzbedarf drastisch verringert und die Berechnung beschleunigt, während die wesentliche Struktur der Daten erhalten bleibt.

SQ4UCompatible with Milvus 2.6.8+

Für Szenarien, die extreme Abfragegeschwindigkeit und minimalen Speicherbedarf erfordern, führt Milvus SQ4U ein, eine 4-Bit Uniform Scalar Quantization. Dabei handelt es sich um eine aggressive Form der Skalarquantisierung, bei der der Gleitkommawert jeder Dimension in eine vorzeichenlose 4-Bit-Ganzzahl komprimiert wird.

Das "U" in SQ4U steht für Uniform. Im Gegensatz zur uneinheitlichen Skalarquantisierung, bei der die Minimal- und Maximalwerte in der Regel unabhängig voneinander für jede Dimension berechnet werden (Quantisierung pro Dimension), erzwingt SQ4U eine globale, einheitliche Quantisierungsstrategie:

  1. Globale Statistik: Das System berechnet einen einzigen Mindestwert vmin und einen einzigen Wertebereich vdiff, der für alle Dimensionen des Vektors (oder das gesamte Vektorsegment) gilt.

  2. Einheitliches Mapping: Der globale Wertebereich wird in 16 gleiche Intervalle unterteilt. Jeder Fließkommawert im Vektor, unabhängig davon, zu welcher Dimension er gehört, wird mithilfe dieser gemeinsamen Parameter auf eine 4-Bit-Ganzzahl (0-15) abgebildet.

Leistungsvorteile:

  • 8x Komprimierungsverhältnis: Verringert die Größe um das 8-fache im Vergleich zu FP32 und um das 2-fache im Vergleich zu SQ8, wodurch der Druck auf die Speicherbandbreite - oft der Engpass bei der Vektorsuche - erheblich verringert wird.

  • SIMD-Optimierung: Die kompakte Struktur ermöglicht es modernen CPUs (AVX2/AVX-512), mehr Dimensionen pro Zyklus zu verarbeiten. Entscheidend ist, dass durch die Verwendung globaler Parameter das Laden variierender Skalen-/Offset-Werte während der Abstandsberechnung entfällt und die Befehlspipeline vollständig gesättigt bleibt.

  • Cache-Effizienz: Kleinere Vektorgrößen bedeuten, dass mehr Daten in den CPU-Cache passen, was die durch den Speicherzugriff verursachte Latenz verringert.

Aufgrund der gemeinsamen Nutzung globaler Parameter erbringt SQ4U die beste Leistung bei normalisierten Daten oder Datensätzen mit konsistenter Werteverteilung über alle Dimensionen.

HNSW + SQ

HNSW_SQ kombiniert die Stärken von HNSW und SQ, um eine effiziente approximative Suche nach dem nächsten Nachbarn zu ermöglichen. So funktioniert der Prozess:

  1. Datenkomprimierung: SQ komprimiert die Vektoren unter Verwendung von sq_type (z. B. SQ6 oder SQ8), was die Speichernutzung reduziert. Diese Komprimierung kann zu einer geringeren Genauigkeit führen, ermöglicht es dem System jedoch, größere Datensätze zu verarbeiten.

  2. Konstruktion von Graphen: Die komprimierten Vektoren werden verwendet, um einen HNSW-Graphen zu erstellen. Da die Daten komprimiert sind, ist der resultierende Graph kleiner und schneller zu durchsuchen.

  3. Abfrage von Kandidaten: Wenn ein Abfragevektor bereitgestellt wird, verwendet der Algorithmus die komprimierten Daten, um schnell einen Pool von Nachbarschaftskandidaten aus dem HNSW-Graphen zu ermitteln.

  4. (Optional) Verfeinerung der Ergebnisse: Die anfänglichen Kandidatenergebnisse können zur Verbesserung der Genauigkeit anhand der folgenden Parameter verfeinert werden:

    • refine: Steuert, ob dieser Verfeinerungsschritt aktiviert ist. Wenn er auf true gesetzt ist, berechnet das System die Abstände unter Verwendung höherer Genauigkeit oder unkomprimierter Darstellungen neu.

    • refine_type: Gibt den Präzisionsgrad der Daten an, die während der Verfeinerung verwendet werden (z. B. SQ6, SQ8, BF16). Eine höhere Genauigkeit wie FP32 kann genauere Ergebnisse liefern, erfordert aber mehr Speicherplatz. Diese muss die Genauigkeit des ursprünglichen komprimierten Datensatzes um sq_type übersteigen.

    • refine_k: Wirkt wie ein Vergrößerungsfaktor. Wenn z. B. Ihr Top k 100 und refine_k 2 ist, ordnet das System die 200 besten Kandidaten neu und gibt die besten 100 zurück, was die Gesamtgenauigkeit erhöht.

Eine vollständige Liste der Parameter und der gültigen Werte finden Sie unter Indexparametern.

Index erstellen

Um einen HNSW_SQ -Index für ein Vektorfeld in Milvus zu erstellen, verwenden Sie die Methode add_index() und geben Sie die Parameter index_type, metric_type und zusätzliche Parameter für den Index an.

from pymilvus import MilvusClient

# Prepare index building params
index_params = MilvusClient.prepare_index_params()

index_params.add_index(
    field_name="your_vector_field_name", # Name of the vector field to be indexed
    index_type="HNSW_SQ", # Type of the index to create
    index_name="vector_index", # Name of the index to create
    metric_type="L2", # Metric type used to measure similarity
    params={
        "M": 64, # Maximum number of neighbors each node can connect to in the graph
        "efConstruction": 100, # Number of candidate neighbors considered for connection during index construction
        "sq_type": "SQ6", # Scalar quantizer type
        "refine": true, # Whether to enable the refinement step
        "refine_type": "SQ8" # Precision level of data used for refinement
    } # Index building params
)

In dieser Konfiguration:

  • index_type: Der Typ des zu erstellenden Index. In diesem Beispiel setzen Sie den Wert auf HNSW_SQ.

  • metric_type: Die Methode zur Berechnung des Abstands zwischen Vektoren. Unterstützte Werte sind COSINE, L2 und IP. Einzelheiten finden Sie unter Metrische Typen.

  • params: Zusätzliche Konfigurationsoptionen für den Aufbau des Index. Weitere Informationen finden Sie unter Indexerstellungsparameter.

Sobald die Indexparameter konfiguriert sind, können Sie den Index erstellen, indem Sie die Methode create_index() direkt verwenden oder die Indexparameter in der Methode create_collection übergeben. Weitere Informationen finden Sie unter Sammlung erstellen.

Suche im Index

Sobald der Index erstellt und die Entitäten eingefügt sind, können Sie Ähnlichkeitssuchen im Index durchführen.

search_params = {
    "params": {
        "ef": 10, # Parameter controlling query time/accuracy trade-off
        "refine_k": 1 # The magnification factor
    }
}

res = MilvusClient.search(
    collection_name="your_collection_name", # Collection name
    anns_field="vector_field",  # Vector field name
    data=[[0.1, 0.2, 0.3, 0.4, 0.5]],  # Query vector
    limit=3,  # TopK results to return
    search_params=search_params
)

In dieser Konfiguration:

Index-Parameter

Dieser Abschnitt gibt einen Überblick über die Parameter, die für den Aufbau eines Index und die Durchführung von Suchen im Index verwendet werden.

Indexaufbau-Parameter

In der folgenden Tabelle sind die Parameter aufgeführt, die in params beim Aufbau eines Index konfiguriert werden können.

Parameter

Beschreibung

Wertebereich

Tuning-Vorschlag

HNSW

M

Maximale Anzahl von Verbindungen (oder Kanten), die jeder Knoten im Graphen haben kann, einschließlich ausgehender und eingehender Kanten.

Dieser Parameter wirkt sich direkt auf den Indexaufbau und die Suche aus.

Typ: Integer

Bereich: [2, 2048]

Standardwert: 30 (bis zu 30 ausgehende und 30 eingehende Kanten pro Knoten)

Eine größere M führt im Allgemeinen zu einer höheren Genauigkeit, erhöht jedoch den Speicher-Overhead und verlangsamt sowohl den Indexaufbau als auch die Suche.

Erwägen Sie eine Erhöhung von M für Datensätze mit hoher Dimensionalität oder wenn eine hohe Wiederauffindbarkeit entscheidend ist.

Ziehen Sie eine Verringerung von M in Betracht, wenn die Speichernutzung und die Suchgeschwindigkeit im Vordergrund stehen.

In den meisten Fällen wird empfohlen, einen Wert innerhalb dieses Bereichs festzulegen: [5, 100].

efConstruction

Anzahl der Nachbarschaftskandidaten, die bei der Indexerstellung für die Verbindung berücksichtigt werden.

Für jedes neue Element wird ein größerer Pool von Kandidaten ausgewertet, aber die maximale Anzahl der tatsächlich hergestellten Verbindungen ist immer noch durch M begrenzt.

Typ: Integer

Bereich: [1, int_max]

Standardwert: 360

Ein höherer efConstruction führt normalerweise zu einem genaueren Index, da mehr potenzielle Verbindungen untersucht werden. Dies führt jedoch auch zu einer längeren Indizierungszeit und einem erhöhten Speicherverbrauch während der Erstellung.

Erwägen Sie, efConstruction zu erhöhen, um die Genauigkeit zu verbessern, insbesondere in Szenarien, in denen die Indizierungszeit weniger kritisch ist.

Ziehen Sie eine Verringerung von efConstruction in Betracht, um den Indexaufbau zu beschleunigen, wenn Ressourcenbeschränkungen ein Problem darstellen.

In den meisten Fällen wird empfohlen, einen Wert innerhalb dieses Bereichs festzulegen: [50, 500].

SQ

sq_type

Legt die skalare Quantisierungsmethode für die Komprimierung von Vektoren fest. Jede Option bietet ein anderes Gleichgewicht zwischen Komprimierung und Genauigkeit:

  • SQ4U: Kodiert Vektoren mit einheitlicher 4-Bit-Quantisierung. Dieser Modus bietet die höchste Geschwindigkeit und Kompression.

  • SQ6: Kodiert Vektoren unter Verwendung von 6-Bit-Ganzzahlen.

  • SQ8: Kodiert Vektoren unter Verwendung von 8-Bit-Ganzzahlen.

  • BF16: Verwendet das Format Bfloat16.

  • FP16: Verwendet das standardmäßige 16-Bit-Gleitkommaformat.

Typ: Zeichenkette

Bereich: [ SQ4U, SQ6, SQ8, BF16, FP16 ]

Standardwert: SQ8

Die Wahl von sq_type hängt von den spezifischen Anforderungen der Anwendung ab. SQ4U wird für maximale Geschwindigkeit und Speichereffizienz gewählt. SQ6 oder SQ8 könnten für eine ausgewogene Leistung geeignet sein. Wenn andererseits die Genauigkeit im Vordergrund steht, könnten BF16 oder FP16 bevorzugt werden.

refine

Ein boolesches Flag, das steuert, ob während der Suche ein Verfeinerungsschritt durchgeführt wird. Bei der Verfeinerung werden die ursprünglichen Ergebnisse neu geordnet, indem die genauen Abstände zwischen dem Abfragevektor und den Kandidaten berechnet werden.

Typ: Boolean

Bereich: [true, false]

Standardwert: false

Setzen Sie true, wenn hohe Genauigkeit wichtig ist und Sie etwas langsamere Suchzeiten tolerieren können. Verwenden Sie false, wenn Geschwindigkeit eine Priorität ist und ein kleiner Kompromiss bei der Genauigkeit akzeptabel ist.

refine_type

Bestimmt die Genauigkeit der für die Verfeinerung verwendeten Daten.

Diese Genauigkeit muss höher sein als die der komprimierten Vektoren (wie durch sq_type festgelegt), was sich sowohl auf die Genauigkeit der neu eingestuften Vektoren als auch auf deren Speicherbedarf auswirkt.

Typ: Zeichenkette

Bereich:[ SQ6, SQ8, BF16, FP16, FP32 ]

Standardwert: Keine

Verwenden Sie FP32 für maximale Präzision bei höheren Speicherkosten oder SQ6/SQ8 für bessere Komprimierung. BF16 und FP16 bieten eine ausgewogene Alternative.

Indexspezifische Suchparameter

In der folgenden Tabelle sind die Parameter aufgeführt, die in search_params.params für die Suche im Index konfiguriert werden können.

Parameter

Beschreibung

Wertebereich

Tuning-Vorschlag

HNSW

ef

Steuert die Breite der Suche während der Suche nach den nächsten Nachbarn. Er bestimmt, wie viele Knoten besucht und als potenzielle nächste Nachbarn bewertet werden.

Dieser Parameter wirkt sich nur auf den Suchprozess aus und gilt ausschließlich für die unterste Schicht des Graphen.

Typ: Integer

Bereich: [1, int_max]

Standardwert: limit (TopK nearest neighbors to return)

Eine größere ef führt im Allgemeinen zu einer höheren Suchgenauigkeit, da mehr potenzielle Nachbarn berücksichtigt werden. Dies erhöht jedoch auch die Suchzeit.

Erwägen Sie, ef zu erhöhen, wenn eine hohe Wiederfindungsrate entscheidend ist und die Suchgeschwindigkeit weniger wichtig ist.

Ziehen Sie in Erwägung, ef zu verringern, um schnelleren Suchen den Vorzug zu geben, insbesondere in Szenarien, in denen eine leichte Verringerung der Genauigkeit akzeptabel ist.

In den meisten Fällen wird empfohlen, einen Wert innerhalb dieses Bereichs zu wählen: [K, 10K].

SQ

refine_k

Der Vergrößerungsfaktor, der steuert, wie viele zusätzliche Kandidaten während der Verfeinerungsphase im Verhältnis zu den angeforderten Top-K-Ergebnissen untersucht werden.

Typ: Float

Bereich: [1, float_max)

Standardwert: 1

Höhere Werte von refine_k können die Auffindbarkeit und Genauigkeit verbessern, erhöhen aber auch die Suchzeit und den Ressourcenverbrauch. Ein Wert von 1 bedeutet, dass der Verfeinerungsprozess nur die anfänglichen Top-K-Ergebnisse berücksichtigt.

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
Feedback

War diese Seite hilfreich?