Freigeben über


Aktivieren und Verwenden der DiskANN-Erweiterung

DiskANN ist ein skalierbarer Algorithmus für angenäherte nächste Nachbarnsuche zur effizienten Vektorsuche in jeder Größenordnung. Diese Funktion bietet hohen Recall, viele Abfragen pro Sekunde und eine niedrige Abfragelatenz, auch für Datasets mit Milliarden Elementen. Diese Merkmale machen es zu einem leistungsstarken Tool für die Verarbeitung großer Datenmengen.

Weitere Informationen zu DiskANN finden Sie unter DiskANN: Vektorsuche für Webskalensuche und Empfehlung.

Die pg_diskann Erweiterung bietet Unterstützung für die Verwendung von DiskANN für effiziente Vektorindizierung und Suche.

Aktivieren von pg_diskann

Um die pg_diskann Erweiterung in Ihrer Azure-Datenbank für flexible Serverinstanz von PostgreSQL zu verwenden, müssen Sie die Erweiterung auf Instanzebene zulassen. Anschließend müssen Sie die Erweiterung für jede Datenbank erstellen, in der Sie die von der Erweiterung bereitgestellte Funktionalität verwenden möchten.

Da pg_diskann eine Abhängigkeit von der vector Erweiterung hat, können Sie entweder die Erweiterung in derselben Datenbank zulassen und vector oder den folgenden Befehl ausführen:

CREATE EXTENSION IF NOT EXISTS pg_diskann;

Alternativ können Sie das explizite Zulassen und Erstellen der vector Erweiterung überspringen und stattdessen den vorherigen Befehl ausführen, der die CASCADE Klausel anfügen soll. Diese Klausel weist PostgreSQL an, CREATE EXTENSION für die Erweiterung, von der es abhängt, implizit auszuführen. Führen Sie dazu den folgenden Befehl aus:

CREATE EXTENSION IF NOT EXISTS pg_diskann CASCADE;

Führen Sie den folgenden Befehl aus, um die Erweiterung aus der Datenbank abzulegen, mit der Sie derzeit verbunden sind:

DROP EXTENSION IF EXISTS pg_diskann;

Verwenden der Diskann-Indexzugriffsmethode

Nachdem die Erweiterung installiert wurde, können Sie einen diskann-Index für eine Tabellenspalte erstellen, die Vektordaten enthält. Wenn Sie beispielsweise einen Index für die embedding-Spalte der demo-Tabelle erstellen möchten, verwenden Sie den folgenden Befehl:

CREATE TABLE demo (
 id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
 embedding public.vector(3)
 -- other columns
);

-- insert dummy data
INSERT INTO demo (embedding) VALUES
('[1.0, 2.0, 3.0]'),
('[4.0, 5.0, 6.0]'),
('[7.0, 8.0, 9.0]');

-- create a diskann index by using Cosine distance operator
CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)

Nachdem der Index erstellt wurde, können Sie Abfragen ausführen, um die nächsten Nachbarn zu finden.

Die folgende Abfrage findet die 5 nächsten Nachbarn des Vektors [2.0, 3.0, 4.0]:

SELECT id, embedding
FROM demo
ORDER BY embedding <=> '[2.0, 3.0, 4.0]'
LIMIT 5;

Postgres entscheidet automatisch, wann der DiskANN-Index verwendet werden soll. Wenn der Index in einem Szenario nicht verwendet werden soll, in dem Sie ihn verwenden möchten, führen Sie den folgenden Befehl aus:

-- Explicit Transcation block to force use for DiskANN index.

BEGIN;
SET LOCAL enable_seqscan TO OFF;
-- Similarity search queries
COMMIT;

Wichtig

Wenn enable_seqscan deaktiviert ist, hält dies den Planer davon ab, den Abfrageplaner für sequenzielle Überprüfungen zu verwenden, wenn andere Methoden verfügbar sind. Da sie mit dem SET LOCAL Befehl deaktiviert wird, wird die Einstellung nur für die aktuelle Transaktion wirksam. Nach einem COMMIT oder ROLLBACK wird wieder die Einstellung auf Sitzungsebene wirksam. Beachten Sie, dass die Einstellung, wenn die Abfrage andere Tabellen umfasst, auch davon abhält, sequenzielle Scans in allen Tabellen zu verwenden.

Effiziente Skalierung mit Quantisierung (Vorschau)

DiskANN verwendet die Produktquantisierung (Product Quantization, PQ), um den Speicherbedarf der Vektoren erheblich zu reduzieren. Im Gegensatz zu anderen Quantisierungstechniken kann der PQ-Algorithmus Vektoren effektiver komprimieren und die Leistung erheblich verbessern.  DiskANN mit PQ kann mehr Daten im Arbeitsspeicher behalten, wodurch der Zugriff auf langsameren Speicher reduziert wird, und beim Vergleich komprimierter Vektoren weniger Rechenaufwand verwendet wird. Dies führt zu einer besseren Leistung und erheblichen Kosteneinsparungen beim Arbeiten mit größeren Datenmengen (> 1 Millionen Zeilen)

Um zugriff auf das Produkt quantization(PQ)-Feature zu erhalten, registrieren Sie sich für die Vorschau.

Beschleunigung des Indexaufbaus

Wir empfehlen einige Möglichkeiten, um die Indexbuildzeiten zu verbessern.

Verwenden von mehr Arbeitsspeicher

Um die Erstellung des Indexes zu beschleunigen, können Sie den in Ihrer Postgres-Instanz zugewiesenen Speicher für den Indexbuild erhöhen. Die Speicherauslastung kann über den maintenance_work_mem Parameter angegeben werden.

-- Set the parameters
SET maintenance_work_mem = '8GB'; -- Depending on your resources

Anschließend CREATE INDEX verwendet der Befehl den angegebenen Arbeitsspeicher, abhängig von den verfügbaren Ressourcen, um den Index zu erstellen.

CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)

Tipp

Sie können ihre Speicherressourcen während des Indexbuilds skalieren, um die Indizierungsgeschwindigkeit zu verbessern, und dann nach Abschluss der Indizierung wieder herunterskalieren.

Verwenden der Parallelisierung

Um die Erstellung des Indexes zu beschleunigen, können Sie parallele Worker verwenden. Die Anzahl der Mitarbeiter kann durch den parallel_workers Speicherparameter der CREATE TABLE Anweisung angegeben werden, wenn sie die Tabelle erstellt. Sie kann später mithilfe der SET-Klausel der ALTER TABLE-Anweisung angepasst werden.

CREATE TABLE demo (
	id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
	embedding public.vector(3)
) WITH (parallel_workers = 4);
ALTER TABLE demo SET (parallel_workers = 8);

Anschließend verwendet der Befehl CREATE INDEX die angegebene Anzahl von parallelen Arbeitsprozessen, abhängig von den verfügbaren Ressourcen, um den Index zu erstellen.

CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)

Wichtig

Der Leiterprozess kann nicht an parallelen Indexbuilds teilnehmen.

Wenn Sie den Index mithilfe von parallelen Workern erstellen möchten, müssen Sie auch die Parameter max_parallel_workers, max_worker_processes und max_parallel_maintenance_workers entsprechend festlegen. Weitere Informationen zu diesen Parametern finden Sie unter Parametern, die Ressourcenverwendungen und asynchrones Verhalten steuern.

Sie können diese Parameter auf unterschiedlichen Granularitätsebenen festlegen. Um sie beispielsweise auf Sitzungsebene festzulegen, können Sie die folgenden Anweisungen ausführen:

-- Set the parameters
SET max_parallel_workers = 8;
SET max_worker_processes = 8; -- Note: Requires server restart
SET max_parallel_maintenance_workers = 4;

Weitere Informationen zu anderen Optionen zum Konfigurieren dieser Parameter in azure Database for PostgreSQL flexible Server finden Sie unter Konfigurieren von Serverparametern.

Hinweis

Für den parameter max_worker_processes muss ein Serverneustart wirksam werden.

Wenn die Konfiguration dieser Parameter und der verfügbaren Ressourcen auf dem Server nicht das Starten der parallelen Worker erlaubt, fällt PostgreSQL automatisch zurück, um den Index im nichtparallel-Modus zu erstellen.

Konfigurationsparameter

Beim Erstellen eines diskann Indexes können Sie verschiedene Parameter angeben, um das Verhalten zu steuern.

Indexparameter

  • max_neighbors: maximale Anzahl von Kanten pro Knoten im Graph (Standardwert: 32) Ein höherer Wert kann den Rückruf bis zu einem bestimmten Punkt verbessern.
  • l_value_ib: Größe der Suchliste während der Indexerstellung (Standardwert: 100) Ein höherer Wert macht die Kompilierung langsamer, aber der Index ist von höherer Qualität.
  • pq_param_num_chunks: Anzahl der Blöcke für die Produktquantisierung (Standardwert: 0). 0 bedeutet, dass sie basierend auf den Einbettungsmaßen automatisch bestimmt wird. Es wird empfohlen, 1/3 der ursprünglichen Einbettungsabmessungen zu verwenden.
  • pq_param_training_samples: Anzahl der Vektoren zum Trainieren der PQ-Pivottable (Standardwert: 0). 0 bedeutet, dass sie basierend auf der Tabellengröße automatisch bestimmt wird.
CREATE INDEX demo_embedding_diskann_custom_idx ON demo USING diskann (embedding vector_cosine_ops)
WITH (
 max_neighbors = 48,
 l_value_ib = 100,
 pq_param_num_chunks = 0,
 pq_param_training_samples = 0
 );

Erweiterungsparameter

  • diskann.iterative_search: Steuert das Suchverhalten.

    Konfigurationen für diskann.iterative_search:

    • relaxed_order (Standard): ermöglicht diskann das iterative Durchsuchen des Graphen in Batches von diskann.l_value_is, bis die gewünschte Anzahl von Tupeln (möglicherweise durch die LIMIT-Klausel begrenzt) zurückgegeben wird Das kann dazu führen, dass die Ergebnisse nicht in der richtigen Reihenfolge sind.

    • strict_order: Ähnlich wie relaxed_order ermöglicht Diskann, den Graphen iterativ zu durchsuchen, bis die gewünschte Anzahl von Tupeln erhalten wird. Es stellt jedoch sicher, dass die Ergebnisse in strenger Reihenfolge sortiert nach Entfernung zurückgegeben werden.

    • off: Verwendet nicht iterative Suchfunktionen, was bedeutet, dass versucht wird, diskann.l_value_is Tupeln in einem Schritt abzurufen. Die nichtiterative Suche kann nur ein Maximum von diskann.l_value_is Vektoren für eine Abfrage zurückgeben, unabhängig von der LIMIT Klausel oder der Anzahl der Tupel, die der Abfrage entsprechen.

    Um das Suchverhalten zu strict_order ändern, führen Sie für alle abfragen, die in der aktuellen Sitzung ausgeführt werden, die folgende Anweisung aus:

    SET diskann.iterative_search TO 'strict_order';
    

    Führen Sie die folgende Anweisung aus, um sie so zu ändern, dass sie sich nur auf alle Abfragen auswirkt, die in der aktuellen Transaktion ausgeführt werden:

    BEGIN;
    SET LOCAL diskann.iterative_search TO 'strict_order';
    -- All your queries
    COMMIT;
    
  • diskann.l_value_is: L-Wert für die Indexüberprüfung (Standardwert: 100). Das Erhöhen des Werts verbessert den Recall, kann aber Abfragen verlangsamen.

    Um den L-Wert für die Indexüberprüfung in 20 zu ändern, führen Sie für alle Abfragen, die in der aktuellen Sitzung ausgeführt werden, die folgende Anweisung aus:

    SET diskann.l_value_is TO 20;
    

    Führen Sie die folgende Anweisung aus, um sie so zu ändern, dass sie sich nur auf alle Abfragen auswirkt, die in der aktuellen Transaktion ausgeführt werden:

    BEGIN;
    SET LOCAL diskann.l_value_is TO 20;
    -- All your queries
    COMMIT;
    
Datasetgröße (Zeilen) Parametertyp Name Empfohlener Wert
<1 Mio. Indexerstellung l_value_ib 100
<1 Mio. Indexerstellung max_neighbors 32
<1 Mio. Abfragezeit diskann.l_value_is 100
 
1M-50M Indexerstellung l_value_ib 100
1M-50M Indexerstellung max_neighbors 64
1M-50M Abfragezeit diskann.l_value_is 100
 
>50M Indexerstellung l_value_ib 100
>50M Indexerstellung max_neighbors 96
>50M Abfragezeit diskann.l_value_is 100

Hinweis

Diese Parameter können je nach spezifischem Dataset und Anwendungsfall variieren. Benutzer müssen möglicherweise mit verschiedenen Parameterwerten experimentieren, um die optimalen Einstellungen für ihr bestimmtes Szenario zu finden.

Fortschritt von CREATE INDEX und REINDEX

Mit PostgreSQL 12 und höher können Sie mit pg_stat_progress_create_index den Fortschritt der Vorgänge CREATE INDEX oder REINDEX überprüfen.

SELECT phase, round(100.0 * blocks_done / nullif(blocks_total, 0), 1) AS "%" FROM pg_stat_progress_create_index;

Weitere Informationen zu den möglichen Phasen, in denen ein CREATE INDEX- oder REINDEX-Vorgang durchlaufen wird, finden Sie unter CREATE INDEX-Phasen.

Auswählen der Indexzugriffsfunktion

Mit dem Vektortyp können Sie drei Arten von Suchen für die gespeicherten Vektoren durchführen. Sie müssen die richtige Zugriffsfunktion für Ihren Index auswählen, damit die Datenbank den Index berücksichtigen kann, wenn Sie Ihre Abfragen ausführen.

pg_diskann unterstützt die folgenden Entfernungsoperatoren:

  • vector_l2_ops: <-> Euklidischer Abstand
  • vector_cosine_ops: <=> Kosinusabstand
  • vector_ip_ops: <#> Inneres Produkt

Problembehandlung

Fehler: : assertion left == right failed left: 40 right: 0

  • DiskANN GA Version, v0.6.x, führt zu wichtigen Änderungen im Indexmetadatenformat. Mit v0.5.x erstellte Indizes sind nicht vorwärtskompatibel mit v0.6.x-Einfügevorgängen. Wenn Sie versuchen, eine Tabelle mit einem veralteten Index einzufügen, tritt ein Fehler auf, auch wenn der Index gültig ist.

  • Wenn dieser Fehler auftritt, können Sie folgendes beheben:

    • Option 1: Ausführen der Anweisung REINDEX oder REDINDEX CONCURRENTLY für den Index.

    • Option 2: Neuerstellen des Indexes

      DROP INDEX your_index_name;
      CREATE INDEX your_index_name ON your_table USING diskann(your_vector_column vector_cosine_ops);
      
      

Fehler: : diskann index needs to be upgraded to version 2...

  • Wenn dieser Fehler auftritt, können Sie folgendes beheben:
    • Option 1: Ausführen der Anweisung REINDEX oder REDINDEX CONCURRENTLY für den Index.

    • Option 2: Da REINDEX möglicherweise lange dauern kann, stellt die Erweiterung auch eine benutzerdefinierte Funktion namens upgrade_diskann_index() bereit, die Ihren Index schneller aktualisiert, wenn möglich.

      Führen Sie zum Aktualisieren des Indexes die folgende Anweisung aus:

      SELECT upgrade_diskann_index('demo_embedding_diskann_custom_idx');
      

      Führen Sie die folgende Anweisung aus, um alle Diskann-Indizes in der Datenbank auf die aktuelle Version zu aktualisieren:

      SELECT upgrade_diskann_index(pg_class.oid)
      FROM pg_class
      JOIN pg_am ON (pg_class.relam = pg_am.oid)
      WHERE pg_am.amname = 'diskann';