Condividi tramite


Abilitare e usare l'estensione DiskANN

DiskANN è un algoritmo di ricerca vicino più vicino scalabile per una ricerca vettoriale efficiente su qualsiasi scala. Offre un elevato richiamo, query elevate al secondo e bassa latenza delle query, anche per set di dati di miliardi di punti. Queste caratteristiche lo rendono uno strumento potente per la gestione di grandi volumi di dati.

Per altre informazioni su DiskANN, vedere DiskANN: ricerca vettoriale per la ricerca e la raccomandazione su scala Web.

L'estensione pg_diskann aggiunge il supporto per l'uso di DiskANN per l'indicizzazione e la ricerca di vettori efficienti.

Abilitare pg_diskann

Per usare l'estensione nell'istanza pg_diskann del server flessibile di Database di Azure per PostgreSQL, è necessario consentire l'estensione a livello di istanza. È quindi necessario creare l'estensione in ogni database in cui si vuole usare la funzionalità fornita dall'estensione.

Poiché pg_diskann ha una dipendenza dall'estensione vector , è possibile consentire e creare l'estensione vector nello stesso database ed eseguire il comando seguente:

CREATE EXTENSION IF NOT EXISTS pg_diskann;

In alternativa, è possibile ignorare esplicitamente l'autorizzazione e la creazione dell'estensione vector ed eseguire invece il comando precedente aggiungendo la CASCADE clausola . PostgreSQL utilizza una clausola per eseguire implicitamente CREATE EXTENSION sull'estensione dalla quale dipende. A tale scopo, utilizzare il seguente comando:

CREATE EXTENSION IF NOT EXISTS pg_diskann CASCADE;

Per eliminare l'estensione dal database a cui si è attualmente connessi, eseguire il comando seguente:

DROP EXTENSION IF EXISTS pg_diskann;

Usare il metodo di accesso all'indice diskann

Dopo aver installato l'estensione, è possibile creare un diskann indice in una colonna di tabella contenente dati vettoriali. Ad esempio, per creare un indice nella embedding colonna della demo tabella, usare il comando seguente:

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)

Dopo aver creato l'indice, è possibile eseguire query per trovare i vicini più vicini.

La query seguente trova i 5 vicini più vicini al vettore [2.0, 3.0, 4.0]:

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

Postgres decide automaticamente quando usare l'indice DiskANN. Se sceglie di non usare l'indice in uno scenario in cui si vuole usarlo, eseguire il comando seguente:

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

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

Importante

Impostare enable_seqscan su disattivata scoraggia il planner dall'usare il piano di scansione sequenziale di Query Planner quando sono disponibili altri metodi. Poiché si disabilita usando il SET LOCAL comando , l'impostazione diventa effettiva solo per la transazione corrente. Dopo un COMMIT o ROLLBACK, l'impostazione del livello di sessione diventa nuovamente effettiva. Si noti che se la query include altre tabelle, l'impostazione sconsiglia anche l'uso di analisi sequenziali in tutte le tabelle.

Scalabilità efficiente con quantizzazione (anteprima)

DiskANN usa la quantizzazione del prodotto (PQ) per ridurre notevolmente il footprint di memoria dei vettori. A differenza di altre tecniche di quantizzazione, l'algoritmo PQ può comprimere i vettori in modo più efficace, migliorando significativamente le prestazioni.  DiskANN che usa PQ può mantenere più dati in memoria, riducendo la necessità di accedere all'archiviazione più lenta, nonché usando meno calcolo durante il confronto dei vettori compressi. Ciò comporta prestazioni migliori e risparmi significativi sui costi quando si lavora con grandi quantità di dati (> 1 milione di righe)

Per ottenere l'accesso alla funzionalità di quantizzazione del prodotto(PQ), iscriversi per l'anteprima

Velocizzare la compilazione dell'indice

Esistono alcuni modi per migliorare i tempi di compilazione dell'indice.

Uso di più memoria

Per velocizzare la creazione dell'indice, è possibile aumentare la memoria allocata nell'istanza di Postgres per la compilazione dell'indice. L'utilizzo della memoria può essere specificato tramite il maintenance_work_mem parametro .

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

Quindi, CREATE INDEX il comando usa la memoria di lavoro specificata, a seconda delle risorse disponibili, per compilare l'indice.

CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)

Suggerimento

È possibile aumentare le risorse di memoria durante la compilazione dell'indice per migliorare la velocità di indicizzazione, quindi ridurre le prestazioni al termine dell'indicizzazione.

Uso della parallelizzazione

Per velocizzare la creazione dell'indice, è possibile utilizzare lavoratori paralleli. Il numero di lavoratori può essere specificato tramite il parametro di archiviazione della dichiarazione parallel_workers quando si crea la tabella. Può essere modificato successivamente usando la clausola SET dell'istruzione ALTER TABLE.

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 Il comando usa quindi il numero specificato di ruoli di lavoro paralleli, a seconda delle risorse disponibili, per compilare l'indice.

CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)

Importante

Il processo leader non può partecipare alle compilazioni di indici paralleli.

Se si vuole creare l'indice usando lavoratori paralleli, è anche necessario impostare i parametri, max_parallel_workers, max_worker_processes, e max_parallel_maintenance_workers di conseguenza. Per altre informazioni su questi parametri, vedere parametri che controllano l'utilizzo delle risorse e il comportamento asincrono.

È possibile impostare questi parametri a livelli di granularità diversi. Ad esempio, per impostarli a livello di sessione, è possibile eseguire le istruzioni seguenti:

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

Per altre informazioni su altre opzioni per configurare questi parametri nel server flessibile di Database di Azure per PostgreSQL, vedere Configurare i parametri del server.

Nota

Per rendere effettivo il parametro max_worker_processes è necessario riavviare il server.

Se la configurazione di questi parametri e le risorse disponibili sul server non consentono l'avvio dei lavoratori paralleli, PostgreSQL ricorre automaticamente alla creazione dell'indice in modalità non parallela.

Parametri di configurazione

Quando si crea un diskann indice, è possibile specificare vari parametri per controllarne il comportamento.

Parametri di indice

  • max_neighbors: numero massimo di archi per nodo nel grafico (il valore predefinito è 32). Un valore più alto può migliorare il richiamo fino a un determinato punto.
  • l_value_ib: dimensioni dell'elenco di ricerca durante la compilazione dell'indice (il valore predefinito è 100). Un valore più elevato rende la compilazione più lenta, ma l'indice sarebbe di qualità superiore.
  • pq_param_num_chunks: numero di blocchi per la quantizzazione del prodotto (il valore predefinito è 0). 0 indica che viene determinato automaticamente, in base alle dimensioni di incorporamento. È consigliabile usare 1/3 delle dimensioni di incorporamento originali.
  • pq_param_training_samples: numero di vettori in cui eseguire il training della tabella pivot PQ (il valore predefinito è 0). 0 indica che viene determinato automaticamente, in base alle dimensioni della tabella.
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
 );

Parametri di estensione

  • diskann.iterative_search: controlla il comportamento di ricerca.

    Configurazioni per diskann.iterative_search:

    • relaxed_order (impostazione predefinita): consente a diskann di cercare in modo iterativo il grafico in batch di diskann.l_value_is, fino a quando non viene restituito il numero desiderato di tuple, possibilmente limitato dalla LIMIT clausola. Potrebbe causare uno sbilanciamento dei risultati.

    • strict_order: simile a relaxed_order, consente a diskann di eseguire una ricerca iterativa nel grafico fino a quando non viene restituito il numero desiderato di tuple. Tuttavia, garantisce che i risultati vengano restituiti in ordine rigoroso ordinati in base alla distanza.

    • off: usa la funzionalità di ricerca non deterministica, il che significa che tenta di recuperare diskann.l_value_is le tuple in un unico passaggio. La ricerca non deterministica può restituire solo un massimo di diskann.l_value_is vettori per una query, indipendentemente dalla LIMIT clausola o dal numero di tuple che corrispondono alla query.

    Per modificare il comportamento di ricerca in strict_order per tutte le query eseguite nella sessione corrente, eseguire l'istruzione seguente:

    SET diskann.iterative_search TO 'strict_order';
    

    Per modificarla in modo che influisca solo su tutte le query eseguite nella transazione corrente, eseguire l'istruzione seguente:

    BEGIN;
    SET LOCAL diskann.iterative_search TO 'strict_order';
    -- All your queries
    COMMIT;
    
  • diskann.l_value_is: valore L per l'analisi dell'indice (il valore predefinito è 100). Aumentare il valore migliora il ricordo, ma può rallentare le interrogazioni.

    Per modificare il valore L per l'analisi dell'indice su 20, per tutte le query eseguite nella sessione corrente, eseguire l'istruzione seguente:

    SET diskann.l_value_is TO 20;
    

    Per modificarla in modo che influisca solo su tutte le query eseguite nella transazione corrente, eseguire l'istruzione seguente:

    BEGIN;
    SET LOCAL diskann.l_value_is TO 20;
    -- All your queries
    COMMIT;
    
Dimensioni del set di dati (righe) Tipo di parametro Nome Valore consigliato
<1 milione Compilazione dell'indice l_value_ib 100
<1 milione Compilazione dell'indice max_neighbors 32
<1 milione Tempo query diskann.l_value_is 100
 
1M-50M Compilazione dell'indice l_value_ib 100
1M-50M Compilazione dell'indice max_neighbors 64
1M-50M Tempo query diskann.l_value_is 100
 
>50M Compilazione dell'indice l_value_ib 100
>50M Compilazione dell'indice max_neighbors 96
>50M Tempo query diskann.l_value_is 100

Nota

Questi parametri possono variare a seconda del set di dati specifico e del caso d'uso. Gli utenti potrebbero dover sperimentare con valori di parametro diversi per trovare le impostazioni ottimali per il proprio scenario specifico.

Stato CREATE INDEX e REINDEX

Con PostgreSQL 12 e versioni successive, è possibile usare pg_stat_progress_create_index per controllare lo stato di avanzamento delle operazioni CREATE INDEX o REINDEX.

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

Per altre informazioni sulle possibili fasi in cui viene eseguita un'operazione CREATE INDEX o REINDEX, vedere Fasi CREATE INDEX.

Selezione della funzione di accesso all'indice

Il tipo di vettore consente di eseguire tre tipi di ricerche sui vettori archiviati. È necessario selezionare la funzione di accesso corretta per l'indice, in modo che il database possa prendere in considerazione l'indice durante l'esecuzione delle query.

pg_diskann supporta gli operatori di distanza seguenti

  • vector_l2_ops: <-> distanza euclidea
  • vector_cosine_ops: <=> distanza coseno
  • vector_ip_ops: <#> prodotto interno

Risoluzione dei problemi

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

  • La versione GA di DiskANN, v0.6.x introduce modifiche significative nel formato dei metadati dell'indice. Gli indici creati con v0.5.x non sono compatibili con le operazioni di inserimento v0.6.x. Il tentativo di inserimento in una tabella con un indice obsoleto genererà un errore, anche se l'indice risulta valido.

  • Quando si verifica questo errore, è possibile risolverlo:

    • Opzione 1: Esecuzione dell'istruzione REINDEX o REDINDEX CONCURRENTLY sull'indice.

    • Opzione 2: Ricompilare l'indice

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

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

  • Quando si verifica questo errore, è possibile risolverlo:
    • Opzione 1: Esecuzione dell'istruzione REINDEX o REDINDEX CONCURRENTLY sull'indice.

    • Opzione 2: Poiché REINDEX potrebbe richiedere molto tempo, l'estensione fornisce anche una funzione definita dall'utente denominata upgrade_diskann_index(), che aggiorna l'indice più velocemente, quando possibile.

      Per aggiornare l'indice, eseguire l'istruzione seguente:

      SELECT upgrade_diskann_index('demo_embedding_diskann_custom_idx');
      

      Per aggiornare tutti gli indici diskann nel database alla versione corrente, eseguire l'istruzione seguente:

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