DiskANN-extensie inschakelen en gebruiken in Azure Database for PostgreSQL flexibele server

DiskANN is een schaalbaar algoritme voor het benaderend zoeken naar dichtstbijzijnde buren, voor efficiënte vectorzoekopdrachten op elke schaal. Het biedt hoge recall, hoge queries per seconde en lage querylatentie, zelfs voor datasets met miljarden punten. Deze kenmerken maken het een krachtig hulpprogramma voor het verwerken van grote hoeveelheden gegevens.

Voor meer informatie over DiskANN, zie DiskANN: Vector Search for Web Scale Search and Recommendation.

De pg_diskann extensie voegt ondersteuning toe voor het gebruik van DiskANN voor efficiënte vectorindexering en zoeken.

pg_diskann inschakelen

Als u de pg_diskann extensie op uw Azure Database for PostgreSQL flexibele server wilt gebruiken, moet u de extensie op serverniveau toestaan. Vervolgens moet u de extensie maken voor elke database waarin u de functionaliteit van de extensie wilt gebruiken.

Omdat pg_diskann een afhankelijkheid heeft van de vector extensie, kunt u de extensie in dezelfde database toestaan en vector en dan de volgende opdracht uitvoeren:

CREATE EXTENSION IF NOT EXISTS pg_diskann;

U kunt ook het expliciet toestaan en maken van de vector extensie overslaan en in plaats daarvan de vorige opdracht uitvoeren die de CASCADE component toevoegt. Die PostgreSQL-instructie voert impliciet CREATE EXTENSION uit voor de extensie waarvan het afhankelijk is. Voer hiertoe de volgende opdrachten uit:

CREATE EXTENSION IF NOT EXISTS pg_diskann CASCADE;

Als u de extensie wilt verwijderen uit de database waarmee u momenteel verbonden bent, voert u de volgende opdracht uit:

DROP EXTENSION IF EXISTS pg_diskann;

De toegangsmethode voor de diskann-index gebruiken

Nadat u de extensie hebt geïnstalleerd, kunt u een diskann index maken op een tabelkolom die vectorgegevens bevat. Als u bijvoorbeeld een index wilt maken in de embedding kolom van de demo tabel, gebruikt u de volgende opdracht:

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)

Nadat u de index hebt gemaakt, kunt u query's uitvoeren om de dichtstbijzijnde buren te vinden.

Met de volgende query worden de vijf dichtstbijzijnde buren aan de vector [2.0, 3.0, 4.0]gevonden:

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

Postgres bepaalt automatisch wanneer de DiskANN-index moet worden gebruikt. Als de index niet wordt gebruikt in een scenario waarin u de index wilt gebruiken, voert u de volgende opdracht uit:

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

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

Belangrijk

Als enable_seqscan op off is ingesteld, ontmoedigt dit de planner om een sequentieel scanplan te gebruiken als er andere methoden beschikbaar zijn. Omdat deze is uitgeschakeld met behulp van de SET LOCAL opdracht, wordt de instelling alleen van kracht voor de huidige transactie. Na een COMMIT of ROLLBACK wordt de instelling op sessieniveau opnieuw van kracht. Als de query andere tabellen omvat, wordt het gebruik van sequentiële scans in alle tabellen door de instelling afgeraden.

Efficiënt schalen met Kwantisatie (preview)

DiskANN maakt gebruik van product kwantisatie (PQ) om de geheugenvoetafdruk van de vectoren aanzienlijk te verminderen. In tegenstelling tot andere kwantisatietechnieken kan het PQ-algoritme vectoren effectiever comprimeren, waardoor de prestaties aanzienlijk worden verbeterd.  Met behulp van PQ kan DiskANN meer gegevens in het geheugen bewaren, de noodzaak verminderen om toegang te krijgen tot tragere opslag en minder rekenkracht gebruiken bij het vergelijken van gecomprimeerde vectoren. Dit resulteert in betere prestaties en aanzienlijke kostenbesparingen bij het werken met grotere hoeveelheden gegevens (> 1 miljoen rijen).

Belangrijk

Product kwantisatieondersteuning in DiskANN is beschikbaar vanaf pg_diskann v0.6 en hoger.

Als u de grootte van uw index wilt verkleinen en meer gegevens in het geheugen wilt aanpassen, gebruikt u PQ:

CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann(embedding vector_cosine_ops) 
WITH(
    product_quantized=true
    );    

De nauwkeurigheid verbeteren bij het gebruik van PQ met vectorherordening

Rerankering met volledige vectoren is een techniek die wordt gebruikt in bij benadering dichtstbijzijnde buren (ANN) zoeksystemen zoals DiskANN met Product Quantization (PQ) om de nauwkeurigheid van resultaten te verbeteren door de top-N opgehaalde kandidaten opnieuw te ordenen met behulp van de oorspronkelijke, niet-gecomprimeerde vectoren (volledige precisie). Deze rerankingtechniek is uitsluitend gebaseerd op exacte metriek voor vectorsimilariteit (bijvoorbeeld cosinussimilariteit of Euclidische afstand). Deze techniek is niet hetzelfde als het opnieuw rangschikken met behulp van een classificatiemodel.

Om een balans te vinden tussen snelheid en precisie bij het zoeken naar vectorovereenkomsten, implementeert u een herordeningsstrategie in twee stappen wanneer u query's uitvoert met DiskANN en productkwantisatie om de nauwkeurigheid te verbeteren.

  1. Initiële benaderende zoekopdracht: De interne query gebruikt DiskANN om de 50 benaderende dichtstbijzijnde buren op te halen op basis van de cosinusafstand tussen de opgeslagen embeddings en de queryvector. Deze stap is snel en efficiënt, waarbij gebruik wordt gemaakt van de indexeringsmogelijkheden van DiskANN.

  2. Nauwkeurig opnieuw rangschikken: de buitenste query rangschikt deze 50 resultaten op basis van de werkelijke berekende afstand en retourneert de top 10 meest relevante overeenkomsten:

Hier volgt een voorbeeld van een herrankering met behulp van deze tweestapsbenadering:

SELECT id
FROM (
    SELECT id, embedding <=> %s::vector AS distance
    FROM demo
    ORDER BY embedding <=> %s::vector asc
    LIMIT 50
) AS t
ORDER BY t.distance
LIMIT 10;

Opmerking

Vervang %s door de queryvector. U kunt azure_ai gebruiken om rechtstreeks in Postgres een queryvector te maken.

Deze aanpak zorgt voor een balans tussen snelheid (via geschatte zoekopdrachten) en nauwkeurigheid (via volledige vectorherrankering), waardoor resultaten van hoge kwaliteit worden gegarandeerd zonder de volledige gegevensset te scannen.

Ondersteuning voor insluitingen met een hoge dimensie

Geavanceerde generatieve AI-toepassingen zijn vaak afhankelijk van high-dimensionale insluitingsmodellen, zoals tekst-insluiten-3-groot om een superieure nauwkeurigheid te bereiken. Traditionele indexeringsmethoden zoals HNSW in pgvector zijn echter beperkt tot vectoren met maximaal 2000 dimensies, waardoor het gebruik van deze krachtige modellen wordt beperkt.

Vanaf pg_diskann v0.6 en hoger ondersteunt DiskANN indexeringsvectoren met maximaal 16.000 dimensies, waardoor het bereik voor AI-workloads met hoge nauwkeurigheid aanzienlijk wordt uitgebreid.

Belangrijk

Schakel Product Quantization in om gebruik te maken van high-dimensionale ondersteuning.

Aanbevolen instellingen:

  • product_quantized: Ingesteld op true
  • pq_param_num_chunks: Stel in op een derde van de insluitingsdimensie voor optimale prestaties.
  • pq_param_training_samples: Automatisch bepaald op basis van de tabelgrootte, tenzij deze expliciet is ingesteld.

Deze verbetering maakt schaalbaar en efficiënt zoeken in grote vectordatasets mogelijk, met behoud van hoge recall en precisie.

Versnel indexopbouw

Probeer de volgende aanbevelingen om de buildtijden van uw index te verbeteren.

Meer geheugen gebruiken

Als u het maken van de index wilt versnellen, verhoogt u het geheugen dat is toegewezen op uw PostgreSQL-server voor de indexbuild. Geef het geheugengebruik op via de maintenance_work_mem parameter.

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

De CREATE INDEX opdracht maakt gebruik van het opgegeven werkgeheugen, afhankelijk van de beschikbare resources, om de index te bouwen.

CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)

Aanbeveling

Schaal uw geheugenbronnen omhoog tijdens de indexbuild om de indexsnelheid te verbeteren en schaal vervolgens weer omlaag wanneer indexering is voltooid.

Parallellisatie gebruiken

Gebruik parallelle werkrollen om het maken van de index te versnellen. Geef het aantal werkrollen op via de parallel_workers opslagparameter van de CREATE TABLE instructie bij het maken van de tabel. U kunt dit nummer later aanpassen met behulp van de SET component van de ALTER TABLE instructie.

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);

De CREATE INDEX opdracht maakt gebruik van het opgegeven aantal parallelle werkrollen, afhankelijk van de beschikbare resources, om de index te bouwen.

CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)

Belangrijk

Het leiderproces kan niet deelnemen aan parallelle indexopbouw.

Als u de index wilt maken met behulp van parallelle werkrollen, stelt u de max_parallel_workersen max_worker_processesmax_parallel_maintenance_workersparameters dienovereenkomstig in. Zie parameters voor het beheren van resourcegebruik en asynchroon gedrag voor meer informatie over deze parameters.

Stel deze parameters in op verschillende granulariteitsniveaus. Als u ze bijvoorbeeld wilt instellen op sessieniveau, voert u de volgende instructies uit:

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

Zie Parameters configureren voor meer informatie over andere opties voor het configureren van deze parameters in Azure Database for PostgreSQL flexibele server.

Opmerking

De server moet opnieuw worden opgestart voordat de parameter max_worker_processes van kracht wordt.

Als de configuratie van deze parameters en de beschikbare resources op de server het starten van de parallelle werkrollen niet toestaat, valt PostgreSQL automatisch terug om de index in de niet-parallel-modus te maken.

Configuratieparameters

Wanneer u een diskann index maakt, geeft u verschillende parameters op om het gedrag ervan te bepalen.

Parameters van de index

  • max_neighbors: Maximum aantal randen per knooppunt in de grafiek. De standaardwaarde is 32. Een hogere waarde kan het ophalen tot op een bepaald punt verhogen.
  • l_value_ib: Grootte van de zoeklijst tijdens de indexbuild. De standaardwaarde is 100. Een hogere waarde maakt de build langzamer, maar de index is van hogere kwaliteit.
  • product_quantized: Maakt product kwantisatie mogelijk voor efficiënter zoeken. De standaardwaarde is onwaar.
  • pq_param_num_chunks: Aantal segmenten voor product kwantisatie. De standaardwaarde is 0, wat betekent dat het systeem automatisch de waarde bepaalt op basis van insluitingsdimensies. Gebruik een derde van de oorspronkelijke insluitingsdimensies.
  • pq_param_training_samples: Het aantal vectoren waarop de PQ-draaitabel moet worden getraind. De standaardwaarde is 0, wat betekent dat het systeem automatisch de waarde bepaalt op basis van de tabelgrootte.
CREATE INDEX demo_embedding_diskann_custom_idx ON demo USING diskann (embedding vector_cosine_ops)
WITH (
 max_neighbors = 48,
 l_value_ib = 100,
 product_quantized=true, 
 pq_param_num_chunks = 0,
 pq_param_training_samples = 0
 );

Extensieparameters

  • diskann.iterative_search: Bepaalt het zoekgedrag.

    Configuraties voor diskann.iterative_search:

    • relaxed_order (standaard): Hiermee kan diskann de graaf iteratief doorzoeken in batches van diskann.l_value_is, totdat het gewenste aantal tuples, mogelijk beperkt door LIMIT clausule, wordt geretourneerd. Deze optie kan ertoe leiden dat de resultaten niet op volgorde zijn.

    • strict_order: Vergelijkbaar met relaxed_order, maar zorgt ervoor dat de resultaten worden geretourneerd in strikte volgorde gesorteerd op afstand.

    • off: maakt gebruik van niet-bindende zoekfunctionaliteit. Er wordt geprobeerd in één stap diskann.l_value_is tuples op te halen. Niet-iteratieve zoekopdrachten kunnen alleen een maximum van diskann.l_value_is vectoren voor een query retourneren, ongeacht de LIMIT clausule of het aantal tuples dat overeenkomt met de query.

    Als u het zoekgedrag voor alle query’s die in de huidige sessie worden uitgevoerd wilt wijzigen naar strict_order, voert u de volgende instructie uit:

    SET diskann.iterative_search TO 'strict_order';
    

    Voer de volgende instructie uit om deze zo te wijzigen dat dit alleen van invloed is op alle query's die worden uitgevoerd in de huidige transactie:

    BEGIN;
    SET LOCAL diskann.iterative_search TO 'strict_order';
    -- All your queries
    COMMIT;
    
  • diskann.l_value_is: L-waarde voor indexscans (standaard ingesteld op 100). Het verhogen van de waarde verbetert de recall, maar kan queries vertragen.

    Als u de L-waarde voor indexscans wilt wijzigen in 20 voor alle query's die in de huidige sessie worden uitgevoerd, voert u de volgende instructie uit:

    SET diskann.l_value_is TO 20;
    

    Voer de volgende instructie uit om deze zo te wijzigen dat dit alleen van invloed is op alle query's die worden uitgevoerd in de huidige transactie:

    BEGIN;
    SET LOCAL diskann.l_value_is TO 20;
    -- All your queries
    COMMIT;
    
Grootte van gegevensset (rijen) Parametertype Naam Aanbevolen waarde
<1 miljoen Indexbouw l_value_ib 100
<1 miljoen Indexbouw max_neighbors 32
<1 miljoen tijd voor queryverwerking diskann.l_value_is 100
 
1M-50M Indexbouw l_value_ib 100
1M-50M Indexbouw max_neighbors 64
1M-50M Indexbouw product_quantized true
1M-50M tijd voor queryverwerking diskann.l_value_is 100
 
>50M Indexbouw l_value_ib 100
>50M Indexbouw max_neighbors 96
>50M Indexbouw product_quantized true
>50M tijd voor queryverwerking diskann.l_value_is 100

Opmerking

Deze parameters kunnen variëren, afhankelijk van de specifieke gegevensset en use-case. Mogelijk moet u experimenteren met verschillende parameterwaarden om de optimale instellingen voor uw specifieke scenario te vinden.

VOORTGANG VAN INDEX AANMAKEN EN OPNIEUW INDEXEREN

Vanaf PostgreSQL 12 kunt u pg_stat_progress_create_index gebruiken om de voortgang van de bewerkingen CREATE INDEX of REINDEX na te gaan.

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

Zie CREATE INDEX-fasen voor meer informatie over de mogelijke fasen waarmee een CREATE INDEX- of REINDEX-bewerking wordt uitgevoerd.

De functie voor indextoegang selecteren

Het vectortype ondersteunt drie typen zoekopdrachten op de opgeslagen vectoren. Selecteer de juiste toegangsfunctie voor uw index, zodat de database uw index kan overwegen bij het uitvoeren van uw query's.

pg_diskann ondersteunt de volgende afstandsoperatoren:

  • vector_l2_ops: <-> Euclidische afstand
  • vector_cosine_ops: <=> Cosinusafstand
  • vector_ip_ops: <#> Inwendig Product

Probleemoplossingsproces

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

  • DiskANN GA-versie v0.6.x introduceert belangrijke wijzigingen in de indeling voor indexmetagegevens. Indexen die met v0.5.x zijn gemaakt, zijn niet compatibel met v0.6.x-invoegbewerkingen. Als u probeert in te voegen in een tabel met een verouderde index, krijgt u een foutmelding, zelfs als de index geldig is.

  • Wanneer u deze fout tegenkomt, lost u deze op door:

    • Optie 1:REINDEX of REDINDEX CONCURRENTLY instructie uitvoeren op de index.

    • Optie 2: De index opnieuw opbouwen.

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

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

  • Wanneer u deze fout tegenkomt, lost u deze op door:
    • Optie 1:REINDEX of REDINDEX CONCURRENTLY instructie uitvoeren op de index.

    • Optie 2: Omdat REINDEX het lang kan duren, biedt de extensie ook een door de gebruiker gedefinieerde functie upgrade_diskann_index(), waarmee uw index sneller wordt bijgewerkt, indien mogelijk.

      Voer de volgende instructie uit om uw index te upgraden:

      SELECT upgrade_diskann_index('demo_embedding_diskann_custom_idx');
      

      Als u alle diskann-indexen in de database wilt bijwerken naar de huidige versie, voert u de volgende instructie uit:

      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';