Dela via


Aktivera och använda DiskANN-tillägget

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å din flexibla Azure Database for PostgreSQL-serverinstans måste du tillåta tillägget på instansnivå. 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 tillägget har installerats 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 indexet har skapats kan du köra frågor för att hitta närmaste grannar.

Följande fråga hittar de 5 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 det ska använda det 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!

Om du ställer in enable_seqscan på av, avråder det planeraren från att använda frågehanterarens användning av sekventiell genomsökningsplan om det finns andra tillgängliga metoder. Eftersom det är inaktiverat 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. Observera att om frågan omfattar andra tabeller avråder inställningen också från att använda sekventiella genomsökningar i dem 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.  DiskANN med hjälp av PQ kan behålla mer data i minnet, vilket minskar behovet av att komma åt långsammare lagring, samt 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 kan du använda 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

Reranking med fullständiga vektorer är en teknik som används i ungefärliga söksystem för närmaste granne (ANN) som DiskANN med Product Quantization (PQ) för att förbättra resultatnoggrannheten genom att sortera om de topp-N-hämtade kandidaterna med hjälp av de ursprungliga, okomprimerade (fullprecision) vektorerna. Den här rerankningstekniken baseras enbart på exakta vektorlikhetsmått (t.ex. 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 kan en tvåstegsstrategi implementeras vid frågor 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 metoden i två steg:

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;

Kommentar

%s bör ersättas av 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 nu indexeringsvektorer med upp till 16 000 dimensioner, vilket avsevärt utökar omfånget för AI-arbetsbelastningar med hög noggrannhet.

Viktigt!

Produktkvantisering måste aktiveras för att kunna använda 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

Det finns några sätt som vi rekommenderar för att förbättra dina indexversionstider.

Använda mer minne

För att påskynda skapandet av indexet kan du öka det minne som allokerats på Postgres-instansen för indexversionen. Minnesanvändningen kan anges via parametern maintenance_work_mem .

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

CREATE INDEX Sedan använder kommandot 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

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

Använda parallellisering

För att påskynda skapandet av indexet kan du använda parallella arbetare. Antalet arbetare kan anges via parallel_workers-lagringsparametern för CREATE TABLE-instruktionen när du skapar tabellen. Och det kan justeras senare med 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);

CREATE INDEX Sedan använder kommandot 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!

Leader-processen kan inte delta i parallell indexuppbyggnad.

Om du vill skapa indexet med hjälp av parallella arbetare måste du också ange max_parallel_workersparametrarna , max_worker_processesoch max_parallel_maintenance_workers . Mer information om dessa parametrar finns i parametrar som styr resursanvändning och asynkront beteende.

Du kan ange dessa parametrar på olika kornighetsnivåer. Om du till exempel vill ange dem på sessionsnivå kan du köra 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 serverparametrar.

Kommentar

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 kan du ange 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: Söklistans storlek under indexbyggnad (standardvärdet är 100). Ett högre värde gör bygget långsammare, men indexet skulle ha högre kvalitet.
  • product_quantized: Aktiverar produktkvantisering för effektivare sökning (standardvärdet är falskt).
  • pq_param_num_chunks: Antal delar för produktkvantisering (standardvärdet är 0). 0 innebär att det bestäms automatiskt, baserat på inbäddningsdimensioner. Vi rekommenderar att du använder 1/3 av de ursprungliga inbäddningsdimensionerna.
  • pq_param_training_samples: Antal vektorer som PQ-pivottabellen ska tränas på (standardvärdet är 0). 0 innebär att det bestäms automatiskt, baserat på tabellstorlek.
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. Kan leda till att resultaten är ur ordning.

    • strict_order: På liknande sätt relaxed_orderkan diskann iterativt söka i grafen tills det önskade antalet tupplar returneras. Det säkerställer dock att resultaten returneras i strikt ordning sorterade efter avstånd.

    • off: Använder icke-iterativ sökfunktionalitet, vilket innebär att 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 kör du följande instruktion för alla frågor som körs i den aktuella sessionen:

    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 kör du följande instruktion för alla frågor som körs i den aktuella sessionen:

    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

Kommentar

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

Förlopp för CREATE INDEX och REINDEX

Med PostgreSQL 12 och senare 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 går igenom finns i SKAPA INDEX-faser.

Välja funktionen för indexåtkomst

Med vektortypen kan du utföra tre typer av sökningar på de lagrade vektorerna. Du måste välja rätt åtkomstfunktion för ditt index, så att databasen kan tänka på 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. Ett försök att infoga i en tabell med ett inaktuellt index resulterar i ett fel, även om indexet verkar giltigt.

  • När du stöter på det här felet kan du lösa 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 kan du lösa 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';