Partager via


Activer et utiliser l’extension DiskANN

DiskANN est un algorithme de recherche du plus proche voisin approximatif et évolutif qui permet d’effectuer efficacement une recherche vectorielle à n’importe quelle échelle. Il offre un rappel élevé, des requêtes élevées par seconde et une faible latence de requête, même pour des jeux de données à milliards de points. Ces caractéristiques en font un outil puissant pour gérer de grands volumes de données.

Pour en savoir plus sur DiskANN, consultez DiskANN : Recherche vectorielle pour la recherche à l'échelle du web et la recommandation.

L’extension pg_diskann ajoute la prise en charge de l’utilisation de DiskANN pour une indexation et une recherche efficaces des vecteurs.

Activer pg_diskann

Pour utiliser l’extension pg_diskann sur votre instance de serveur flexible Azure Database pour PostgreSQL, vous devez autoriser l’extension au niveau de l’instance. Vous devez ensuite créer l’extension sur chaque base de données dans laquelle vous souhaitez utiliser les fonctionnalités fournies par l’extension.

Étant donné que pg_diskann est dépendant de l’extension vector, vous autorisez et créez l’extension vector dans la même base de données, puis exécutez la commande suivante :

CREATE EXTENSION IF NOT EXISTS pg_diskann;

Vous pouvez également ignorer explicitement l’autorisation et la création de l’extension vector , puis exécuter à la place la commande précédente ajoutant la CASCADE clause. Cette clause PostgreSQL est destinée à exécuter de manière implicite CREATE EXTENSION sur l'extension dont elle dépend. Pour ce faire, exécutez la commande suivante :

CREATE EXTENSION IF NOT EXISTS pg_diskann CASCADE;

Pour supprimer l’extension de la base de données à laquelle vous êtes actuellement connecté, exécutez la commande suivante :

DROP EXTENSION IF EXISTS pg_diskann;

Utiliser la méthode d’accès à l’index diskann

Une fois l’extension installée, vous pouvez créer un index diskann sur une colonne de table qui contient des données vectorielles. Par exemple, pour créer un index sur la colonne embedding de la table demo, utilisez la commande suivante :

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)

Une fois l’index créé, vous pouvez exécuter des requêtes pour rechercher les voisins les plus proches.

La requête suivante recherche les 5 voisins les plus proches du vecteur [2.0, 3.0, 4.0]:

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

Postgres décide automatiquement quand utiliser l’index DiskANN. S’il choisit de ne pas utiliser l’index dans un scénario dans lequel vous souhaitez l’utiliser, exécutez la commande suivante :

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

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

Important

En réglant enable_seqscan sur désactivé, cela dissuade le planificateur d'utiliser le plan d'analyse séquentiel s'il existe d'autres méthodes disponibles. Étant donné qu’il est désactivé à l’aide de la SET LOCAL commande, le paramètre prend effet uniquement pour la transaction actuelle. Après un COMMIT ou ROLLBACK, le paramètre de niveau de session prend effet à nouveau. Notez que si la requête implique d’autres tables, le paramètre décourage également l’utilisation d’analyses séquentielles dans toutes ces tables.

Mettre à l’échelle efficacement avec quantification (préversion)

DiskANN utilise la quantisation de produit (PQ) pour réduire considérablement l’empreinte mémoire des vecteurs. Contrairement à d’autres techniques de quantisation, l’algorithme PQ peut compresser les vecteurs plus efficacement, ce qui améliore considérablement les performances.  DiskANN utilisant PQ peut conserver davantage de données en mémoire, ce qui réduit la nécessité d’accéder au stockage plus lent, ainsi que d’utiliser moins de calcul lors de la comparaison des vecteurs compressés. Cela entraîne de meilleures performances et des économies significatives lors de l’utilisation de plus grandes quantités de données (> 1 million de lignes)

Pour accéder à la fonctionnalité de quantisation de produit (PQ), inscrivez-vous à la préversion

Accélérer la génération d’index

Nous vous recommandons d’améliorer vos temps de génération d’index de plusieurs façons.

Utilisation d’une mémoire supplémentaire

Pour accélérer la création de l’index, vous pouvez augmenter la mémoire allouée sur votre instance Postgres pour la build d’index. L’utilisation de la mémoire peut être spécifiée via le maintenance_work_mem paramètre.

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

Ensuite, CREATE INDEX la commande utilise la mémoire de travail spécifiée, en fonction des ressources disponibles, pour générer l’index.

CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)

Conseil / Astuce

Vous pouvez effectuer un scale-up de vos ressources de mémoire pendant la génération d’index pour améliorer la vitesse d’indexation, puis effectuer un scale-down lorsque l’indexation est terminée.

Utilisation de la parallélisation

Pour accélérer la création de l'index, vous pouvez utiliser des processus parallèles. Le nombre de travailleurs peut être spécifié par le biais du paramètre de stockage parallel_workers de l'instruction CREATE TABLE, lors de la création de la table. Il peut être ajusté ultérieurement en utilisant la SET clause de l’instruction 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);

La commande CREATE INDEX utilise le nombre spécifié de travailleurs parallèles, en fonction des ressources disponibles, pour construire l’index.

CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)

Important

Le processus leader ne peut pas participer aux builds d’index parallèles.

Si vous souhaitez créer l’index à l’aide de workers parallèles, vous devez également définir les paramètres max_parallel_workers, max_worker_processes et max_parallel_maintenance_workers en conséquence. Pour plus d’informations sur ces paramètres, consultez les paramètres qui contrôlent les utilisations des ressources et le comportement asynchrone.

Vous pouvez définir ces paramètres à différents niveaux de granularité. Par exemple, pour les définir au niveau de la session, vous pouvez exécuter les instructions suivantes :

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

Pour en savoir plus sur les autres options de configuration de ces paramètres dans un serveur flexible Azure Database pour PostgreSQL, consultez Configurer les paramètres du serveur.

Remarque

Le paramètre max_worker_processes nécessite qu’un redémarrage du serveur prenne effet.

Si la configuration de ces paramètres et les ressources disponibles sur le serveur n’autorisent pas le lancement des workers parallèles, PostgreSQL revient automatiquement à créer l’index en mode nonparallel.

Paramètres de configuration

Lors de la création d’un diskann index, vous pouvez spécifier différents paramètres pour contrôler son comportement.

Paramètres d’index

  • max_neighbors: nombre maximal de arêtes par nœud dans le graphique (valeur par défaut : 32). Une valeur plus élevée peut améliorer le rappel jusqu’à un certain point.
  • l_value_ib: Taille de la liste de recherche pendant la génération d’index (valeur par défaut : 100). Une valeur plus élevée ralentit la build, mais l’index serait de meilleure qualité.
  • pq_param_num_chunks: nombre de blocs pour la quantisation du produit (valeur par défaut 0). 0 signifie qu’elle est déterminée automatiquement, en fonction des dimensions d’incorporation. Il est recommandé d’utiliser 1/3 des dimensions d’incorporation d’origine.
  • pq_param_training_samples: Nombre de vecteurs pour l'entraînement de la table pivot PQ (valeur par défaut 0). 0 signifie qu’elle est déterminée automatiquement, en fonction de la taille de la table.
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
 );

Paramètres d’extension

  • diskann.iterative_search: contrôle le comportement de recherche.

    Configurations pour diskann.iterative_search:

    • relaxed_order (valeur par défaut) : permet à diskann d’effectuer une recherche itérative dans les lots de diskann.l_value_is, jusqu’à ce que le nombre souhaité de tuples, éventuellement limité par LIMIT clause, soit généré. Les résultats peuvent être désordonnés.

    • strict_order : Similaire à relaxed_order, diskann permet de rechercher de manière itérative le graphe jusqu’à ce que le nombre souhaité de tuples soit généré. Toutefois, il garantit que les résultats sont retournés dans un ordre strict trié par distance.

    • off : utilise la fonctionnalité de recherche non itératif, ce qui signifie qu'elle tente de récupérer des ensembles de tuples diskann.l_value_is en un seul coup. La recherche non itérative ne peut retourner qu’un maximum de vecteurs diskann.l_value_is pour une requête, quelle que soit la clause LIMIT ou le nombre de tuples qui correspondent à la requête.

    Pour modifier le comportement strict_order de recherche, pour toutes les requêtes exécutées dans la session active, exécutez l’instruction suivante :

    SET diskann.iterative_search TO 'strict_order';
    

    Pour la modifier afin qu’elle affecte uniquement toutes les requêtes exécutées dans la transaction actuelle, exécutez l’instruction suivante :

    BEGIN;
    SET LOCAL diskann.iterative_search TO 'strict_order';
    -- All your queries
    COMMIT;
    
  • diskann.l_value_is: valeur L pour l’analyse d’index (valeur par défaut : 100). L’augmentation de la valeur améliore le rappel, mais peut ralentir les requêtes.

    Pour modifier la valeur L de l’analyse d’index sur 20, pour toutes les requêtes exécutées dans la session active, exécutez l’instruction suivante :

    SET diskann.l_value_is TO 20;
    

    Pour la modifier afin qu’elle affecte uniquement toutes les requêtes exécutées dans la transaction actuelle, exécutez l’instruction suivante :

    BEGIN;
    SET LOCAL diskann.l_value_is TO 20;
    -- All your queries
    COMMIT;
    
Taille du jeu de données (lignes) Type de paramètre Nom Valeur recommandée
<1 M Construction de l'index l_value_ib 100
<1 M Construction de l'index max_neighbors 32
<1 M Temps de requête diskann.l_value_is 100
 
1M-50M Construction de l'index l_value_ib 100
1M-50M Construction de l'index max_neighbors 64
1M-50M Temps de requête diskann.l_value_is 100
 
>50 M Construction de l'index l_value_ib 100
>50 M Construction de l'index max_neighbors 96
>50 M Temps de requête diskann.l_value_is 100

Remarque

Ces paramètres peuvent varier en fonction du jeu de données spécifique et du cas d’usage. Les utilisateurs peuvent avoir à expérimenter différentes valeurs de paramètres pour trouver les paramètres optimaux pour leur scénario particulier.

Progression de CREATE INDEX et REINDEX

Avec PostgreSQL 12 et versions ultérieures, vous pouvez utiliser pg_stat_progress_create_index pour vérifier la progression des opérations CREATE INDEX ou REINDEX.

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

Pour en savoir plus sur les phases possibles à travers lesquelles une opération CREATE INDEX ou REINDEX passe, consultez les phases CREATE INDEX.

Sélection de la fonction d’accès à l’index

Le type de vecteur vous permet d’effectuer trois types de recherches sur les vecteurs stockés. Vous devez sélectionner la fonction d’accès appropriée pour votre index afin que la base de données puisse prendre en compte votre index lors de l’exécution de vos requêtes.

pg_diskann prend en charge les opérateurs de distance suivants :

  • vector_l2_ops : <-> Distance euclidienne
  • vector_cosine_ops : <=> Distance cosinus
  • vector_ip_ops : <#> Produit interne

Résolution des problèmes

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

  • La version de DiskANN GA, v0.6.x introduit des changements cassants dans le format des métadonnées d’index. Les index créés avec v0.5.x ne sont pas compatibles avec les opérations d’insertion de v0.6.x. Toute tentative d’insertion dans une table avec un index obsolète entraîne une erreur, même si l’index apparaît valide.

  • Lorsque vous rencontrez cette erreur, vous pouvez la résoudre en procédant comme suit :

    • Option 1 : Exécution d'une instruction REINDEX ou REDINDEX CONCURRENTLY sur l’index.

    • Option 2 : Reconstruire l’index

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

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

  • Lorsque vous rencontrez cette erreur, vous pouvez la résoudre en :
    • Option 1 : Exécution REINDEX ou REDINDEX CONCURRENTLY instruction sur l’index.

    • Option 2 : Étant donné que REINDEX cela peut prendre beaucoup de temps, l’extension fournit également une fonction définie par l’utilisateur appelée upgrade_diskann_index(), qui met à niveau votre index plus rapidement, lorsque cela est possible.

      Pour mettre à niveau votre index, exécutez l’instruction suivante :

      SELECT upgrade_diskann_index('demo_embedding_diskann_custom_idx');
      

      Pour mettre à niveau tous les index diskann de la base de données vers la version actuelle, exécutez l’instruction suivante :

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