Aktivera och använda DiskANN-tillägget i Azure Database for PostgreSQL flexibel server

DiskANN är en skalbar ungefärlig algoritm för närmaste grannsökning för effektiv vektorsökning i valfri skala. Den erbjuder hög träffsäkerhet, höga frågor per sekund och låg frågesvarstid, även för miljardpunktsdatauppsättningar. Dessa egenskaper gör det till ett kraftfullt verktyg för att hantera stora mängder data.

Mer information om DiskANN finns i DiskANN: Vector Search for Web Scale Search and Recommendation.

Tillägget pg_diskann lägger till stöd för att använda DiskANN för effektiv vektorindexering och sökning.

Aktivera pg_diskann

Om du vill använda pg_diskann tillägget på Azure Database for PostgreSQL flexibel server måste du tillåta tillägget på servernivå. Sedan måste du skapa tillägget för varje databas där du vill använda de funktioner som tillhandahålls av tillägget.

Eftersom pg_diskann har ett beroende av vector tillägget kan du antingen tillåta och skapavector tillägget i samma databas och köra följande kommando:

CREATE EXTENSION IF NOT EXISTS pg_diskann;

Eller så kan du hoppa över att uttryckligen tillåta och skapa vector tillägget och i stället köra det tidigare kommandot som lägger till CASCADE -satsen. Denna klausul i PostgreSQL att köra CREATE EXTENSION implicit på det tillägg det beror på. Detta gör du genom att köra följande kommando:

CREATE EXTENSION IF NOT EXISTS pg_diskann CASCADE;

Kör följande kommando för att släppa tillägget från databasen som du är ansluten till:

DROP EXTENSION IF EXISTS pg_diskann;

Använda diskann-indexåtkomstmetoden

När du har installerat tillägget kan du skapa ett diskann index i en tabellkolumn som innehåller vektordata. Om du till exempel vill skapa ett index i embedding kolumnen i demo tabellen använder du följande kommando:

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)

När du har skapat indexet kan du köra frågor för att hitta närmaste grannar.

Följande fråga hittar de fem närmaste grannarna till vektorn [2.0, 3.0, 4.0]:

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

Postgres bestämmer automatiskt när diskANN-index ska användas. Om du väljer att inte använda indexet i ett scenario där du vill att indexet ska användas kör du följande kommando:

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

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

Viktigt!

Att ställa in enable_seqscan på av avråder planeraren från att använda frågeplanerarens plan för sekventiell skanning om det finns andra tillgängliga metoder. Eftersom den är inaktiverad med kommandot SET LOCAL börjar inställningen endast gälla för den aktuella transaktionen. Efter en COMMIT- eller ROLLBACK-inställning börjar sessionsnivåinställningen gälla igen. Om frågan omfattar andra tabeller avråder inställningen också från att använda sekventiella genomsökningar i alla.

Skala effektivt med kvantisering (förhandsversion)

DiskANN använder produktkvantisering (PQ) för att avsevärt minska vektorernas minnesfotavtryck. Till skillnad från andra kvantiseringstekniker kan PQ-algoritmen komprimera vektorer mer effektivt, vilket avsevärt förbättrar prestandan.  Med hjälp av PQ kan DiskANN behålla mer data i minnet, minska behovet av att komma åt långsammare lagring och använda mindre beräkning vid jämförelse av komprimerade vektorer. Detta resulterar i bättre prestanda och betydande kostnadsbesparingar när du arbetar med större mängder data (> 1 miljon rader).

Viktigt!

Stöd för produktkvantisering i DiskANN är tillgängligt från pg_diskann v0.6 och senare.

Om du vill minska storleken på ditt index och få plats med mer data i minnet använder du PQ:

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

Förbättra noggrannheten när du använder PQ med vektoromrankning

Omrangering med fullständiga vektorer är en teknik som används i söksystem för approximativ närmaste granne (ANN), såsom DiskANN med Product Quantization (PQ), för att förbättra resultatens noggrannhet genom att omordna de N främsta kandidater som hämtats med hjälp av de ursprungliga, okomprimerade vektorerna (i full precision). Den här rerankningstekniken baseras enbart på exakta vektorlikhetsmått (till exempel cosinuslikhet eller Euklidiska avstånd). Den här tekniken är inte samma sak som att ändra rangordning med hjälp av en rangordningsmodell.

För att balansera hastighet och precision i vektorlikhetssökning implementerar du en tvåstegsstrategi för att ändra rangordning när du frågar med DiskANN och produktkvantisering för att förbättra noggrannheten.

  1. Inledande ungefärlig sökning: Den inre frågan använder DiskANN för att hämta de 50 främsta ungefärliga närmaste grannarna baserat på cosinéavståndet mellan de lagrade inbäddningarna och frågevektorn. Det här steget är snabbt och effektivt och utnyttjar DiskANN:s indexeringsfunktioner.

  2. Exakt reranking: Den yttre frågan ordnar om dessa 50 resultat efter deras faktiska beräknade avstånd och returnerar de 10 mest relevanta matchningarna:

Här är ett exempel på att ändra rangordning med den här tvåstegsmetoden:

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;

Anmärkning

Ersätt %s med frågevektorn. Du kan använda azure_ai för att skapa en frågevektor direkt i Postgres.

Den här metoden balanserar hastighet (via ungefärlig sökning) och noggrannhet (via fullständig vektoråterrankning), vilket säkerställer högkvalitativa resultat utan att genomsöka hela datamängden.

Stöd för inbäddningar med hög dimension

Avancerade generativa AI-program förlitar sig ofta på högdimensionella inbäddningsmodeller som text-inbäddning-3-large för att uppnå överlägsen noggrannhet. Traditionella indexeringsmetoder som HNSW i pgvector är dock begränsade till vektorer med upp till 2 000 dimensioner, vilket begränsar användningen av dessa kraftfulla modeller.

Från och med pg_diskann v0.6 och senare stöder DiskANN indexeringsvektorer med upp till 16 000 dimensioner, vilket avsevärt utökar omfånget för AI-arbetsbelastningar med hög noggrannhet.

Viktigt!

Aktivera Product Quantization för att utnyttja högdimensionellt stöd.

Rekommenderade inställningar:

  • product_quantized: Ställ in på true
  • pq_param_num_chunks: Ange till en tredjedel av inbäddningsdimensionen för optimal prestanda.
  • pq_param_training_samples: Bestäms automatiskt baserat på tabellstorlek om inte uttryckligen anges.

Den här förbättringen möjliggör skalbar och effektiv sökning över stora vektordatamängder samtidigt som hög träffsäkerhet och precision bibehålls.

Påskynda indexbygget

Prova följande rekommendationer för att förbättra dina indexversionstider.

Använd mer minne

Öka det minne som allokerats på PostgreSQL-servern för indexversionen för att påskynda skapandet av indexet. Ange minnesanvändningen via parametern maintenance_work_mem .

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

Kommandot CREATE INDEX använder det angivna arbetsminnet, beroende på tillgängliga resurser, för att skapa indexet.

CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)

Tips/Råd

Skala upp dina minnesresurser under indexet för att förbättra indexeringshastigheten och skala sedan ned igen när indexeringen är klar.

Använda parallellisering

Använd parallella arbetare för att påskynda skapandet av indexet. Ange antalet arbetare via parallel_workers lagringsparametern för -instruktionen CREATE TABLE när du skapar tabellen. Du kan justera det här värdet senare med hjälp av SET-satsens ALTER TABLE-klausul.

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

Kommandot CREATE INDEX använder det angivna antalet parallella arbetare, beroende på tillgängliga resurser, för att skapa indexet.

CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)

Viktigt!

Ledarprocessen kan inte delta i parallella indexbyggen.

Om du vill skapa indexet med hjälp av parallella arbetare anger du parametrarna max_parallel_workers, max_worker_processesoch max_parallel_maintenance_workers därefter. Mer information om dessa parametrar finns i parametrar som styr resursanvändning och asynkront beteende.

Ange dessa parametrar på olika kornighetsnivåer. Om du till exempel vill ange dem på sessionsnivå kör du följande instruktioner:

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

Mer information om andra alternativ för att konfigurera dessa parametrar i Azure Database for PostgreSQL flexibel server finns i Konfigurera parametrar.

Anmärkning

Parametern max_worker_processes kräver att en omstart av servern börjar gälla.

Om konfigurationen av dessa parametrar och de tillgängliga resurserna på servern inte tillåter att parallella arbetare startas, faller PostgreSQL automatiskt tillbaka på att skapa indexet i icke-parallelläge.

Konfigurationsparametrar

När du skapar ett diskann index anger du olika parametrar för att styra dess beteende.

Indexparametrar

  • max_neighbors: Maximalt antal kanter per nod i diagrammet. Standardvärdet är 32. Ett högre värde kan förbättra återkallandet upp till en viss punkt.
  • l_value_ib: Storleken på söklistan vid indexbyggning. Standardvärdet är 100. Ett högre värde gör bygget långsammare, men indexet har högre kvalitet.
  • product_quantized: Aktiverar produktkvantisering för effektivare sökning. Standardvärdet är falskt.
  • pq_param_num_chunks: Antal segment för produktkvantisering. Standardvärdet är 0, vilket innebär att systemet automatiskt avgör värdet baserat på inbäddningsdimensioner. Använd en tredjedel av de ursprungliga inbäddningsdimensionerna.
  • pq_param_training_samples: Antal vektorer som PQ-pivottabellen ska tränas på. Standardvärdet är 0, vilket innebär att systemet automatiskt avgör värdet baserat på tabellstorleken.
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
 );

Tilläggsparametrar

  • diskann.iterative_search: Styr sökbeteendet.

    Konfigurationer för diskann.iterative_search:

    • relaxed_order (standard): Låter diskann iterativt söka i grafen i batchar av diskann.l_value_is, tills det önskade antalet tupplar, eventuellt begränsat av LIMIT -satsen, returneras. Det här alternativet kan leda till att resultaten hamnar i fel ordning.

    • strict_order: Liknar relaxed_order, men säkerställer att resultaten returneras i strikt ordning sorterade efter avstånd.

    • off: Använder funktioner för icke-iterativ sökning. Den försöker hämta diskann.l_value_is tupler i ett steg. Icke-iterativ sökning kan bara returnera maximalt antal diskann.l_value_is vektorer för en fråga, oavsett LIMIT satsen eller antalet tupplar som matchar frågan.

    Om du vill ändra sökbeteendet till strict_order för alla frågor som körs i den aktuella sessionen kör du följande instruktion:

    SET diskann.iterative_search TO 'strict_order';
    

    Om du vill ändra den så att den bara påverkar alla frågor som körs i den aktuella transaktionen kör du följande instruktion:

    BEGIN;
    SET LOCAL diskann.iterative_search TO 'strict_order';
    -- All your queries
    COMMIT;
    
  • diskann.l_value_is: L-värde för indexgenomsökning (standardvärdet är 100). Att öka värdet förbättrar minnet, men kan göra sökningar långsammare.

    Om du vill ändra L-värdet för indexgenomsökning till 20 för alla frågor som körs i den aktuella sessionen kör du följande instruktion:

    SET diskann.l_value_is TO 20;
    

    Om du vill ändra den så att den bara påverkar alla frågor som körs i den aktuella transaktionen kör du följande instruktion:

    BEGIN;
    SET LOCAL diskann.l_value_is TO 20;
    -- All your queries
    COMMIT;
    
Datamängdens storlek (rader) Parametertyp Namn Rekommenderat värde
<1 milj. Indexbygge l_value_ib 100
<1 milj. Indexbygge max_neighbors 32
<1 milj. Sökningstid diskann.l_value_is 100
 
1M-50M Indexbygge l_value_ib 100
1M-50M Indexbygge max_neighbors 64
1M-50M Indexbygge product_quantized true
1M-50M Sökningstid diskann.l_value_is 100
 
>50M Indexbygge l_value_ib 100
>50M Indexbygge max_neighbors 96
>50M Indexbygge product_quantized true
>50M Sökningstid diskann.l_value_is 100

Anmärkning

Dessa parametrar kan variera beroende på den specifika datamängden och användningsfallet. Du kan behöva experimentera med olika parametervärden för att hitta de optimala inställningarna för ditt specifika scenario.

Förlopp för CREATE INDEX och REINDEX

Från och med PostgreSQL 12 kan du använda pg_stat_progress_create_index för att kontrollera förloppet för åtgärderna CREATE INDEX eller REINDEX.

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

Mer information om de möjliga faser genom vilka en CREATE INDEX- eller REINDEX-åtgärd utförs finns i SKAPA INDEX-faser.

Välja funktionen för indexåtkomst

Vektortypen stöder tre typer av sökningar på de lagrade vektorerna. Välj rätt åtkomstfunktion för ditt index så att databasen kan ta hänsyn till ditt index när du kör dina frågor.

pg_diskann stöder följande avståndsoperatorer:

  • vector_l2_ops: <-> Euklidiska avstånd
  • vector_cosine_ops: <=> Cosinnavstånd
  • vector_ip_ops: <#> Inre produkt

Felsökning

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

  • DiskANN GA version, v0.6.x introducerar kompatibilitetsbrytande ändringar i indexmetadataformatet. Index som skapats med v0.5.x är inte framåtkompatibla med v0.6.x-infogningsåtgärder. Om du försöker infoga i en tabell med ett inaktuellt index får du ett fel, även om indexet verkar giltigt.

  • När du stöter på det här felet löser du det genom att:

    • Alternativ 1:REINDEX eller REDINDEX CONCURRENTLY kör uttryck på indexet.

    • Alternativ 2: Återskapa indexet.

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

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

  • När du stöter på det här felet löser du det genom att:
    • Alternativ 1:REINDEX eller REDINDEX CONCURRENTLY kör uttryck på indexet.

    • Alternativ 2: Eftersom REINDEX det kan ta lång tid tillhandahåller tillägget även en användardefinierad funktion med namnet upgrade_diskann_index(), som uppgraderar indexet snabbare när det är möjligt.

      Om du vill uppgradera indexet kör du följande instruktion:

      SELECT upgrade_diskann_index('demo_embedding_diskann_custom_idx');
      

      Om du vill uppgradera alla diskann-index i databasen till den aktuella versionen kör du följande instruktion:

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