← Retour au blog

Lorsque vous n'avez pas besoin d'une base de données vectorielles

Par ··10 min de lecture
vector database
vector db
open source vector database
retrieval
rag

Recherchez ce terme et la première page contient une documentation rédigée par les sociétés vendant la chose. Ce n’est pas une critique de la documentation, qui est généralement excellente, mais cela signifie que chaque résultat partage un principe : que vous choisissez une base de données vectorielle. La question précédente, à savoir si la charge de travail en a besoin, reçoit une réponse oui sur chaque page en raison de la personne qui les a écrites.

Il en faut souvent un. Ce n'est souvent pas non plus le cas, et les cas sont séparables à l'avance plutôt que par migration et découverte. Ce qui suit est la décision plutôt qu'un classement : ce que vous obtenez gratuitement avant d'ajouter quoi que ce soit, ce qu'un index achète réellement, le comportement qui interrompt plus de démos de récupération que tout autre, et les trois choses spécifiques qui changent lorsqu'une extension Postgres cesse d'être la bonne réponse.

La base de référence est meilleure que ce que la plupart des comparaisons admettent

Si vos données résident déjà dans Postgres, le point de départ honnête est pgvector, et ce qu'il vaut la peine de savoir, c'est ce qu'il fait sans aucun index. Sa documentation est directe à ce sujet : pgvector effectue par défaut une recherche exacte du voisin le plus proche, ce qui permet un rappel parfait.

Un rappel parfait est une garantie plus forte que tout ce qu'offre un système approximatif, et cela vaut la peine de s'y attarder un instant, car la majeure partie de la discussion dans cet espace porte sur la récupération du rappel qui a été donné en premier lieu. Une analyse par force brute de vos intégrations renvoie les voisins les plus proches. Il n’y a pas de réglage, pas d’étape de formation, pas d’objectif de rappel à négocier et rien à mesurer, car il n’y a pas d’erreur à mesurer.

Ce que cela coûte, c'est une analyse proportionnelle au nombre de lignes. C'est tout le commerce, et cela signifie que la question utile n'est pas de savoir quelle base de données mais à quelle taille et à quel taux de requête une analyse exacte cesse d'être abordable pour mon budget de latence. Il s'agit d'une question contenant un numéro que seule votre charge de travail peut fournir, et à laquelle il est possible de répondre en un après-midi avec le corpus dont vous disposez déjà.

Ce qu'achète un indice et ce qu'il change en douceur

L'ajout d'un index rend la recherche approximative, échangeant un peu de rappel contre de la vitesse. La documentation de pgvector signale clairement la conséquence : vous verrez des résultats différents pour les requêtes après avoir ajouté un index approximatif.

Cette phrase mérite plus d’attention qu’elle n’en reçoit habituellement, car c’est le moment où la récupération cesse d’être déterministe et commence à être un paramètre de qualité. Avant l'index, le système renvoyait la bonne réponse. Après cela, le système renvoie une bonne réponse la plupart du temps, et la fréquence des erreurs est désormais un paramètre qui vous appartient. Rien ne vous prévient lorsque cela ne va pas. La requête réussit, les résultats semblent plausibles et le document dont vous aviez besoin n'y figure tout simplement pas.

C'est à ce moment-là que l'évaluation cesse d'être facultative, et c'est le même argument que nous faisons concernant la construction d'un ensemble d'évaluation à partir de vos propres échecs plutôt qu'à partir d'un catalogue de métriques. Un indice approximatif introduit un mode de défaillance invisible de l’extérieur et n’apparaît que comme un modèle répondant moins bien qu’il ne le devrait. Si vous ne pouvez pas distinguer un échec de récupération d'un problème de génération, vous ne pouvez pas non plus déboguer.

Le comportement qui interrompt les démos de récupération

Voici celui qu'il faut connaître avant de construire quoi que ce soit, car il représente une part disproportionnée des systèmes qui fonctionnent dans un ordinateur portable et échouent en production.

La véritable récupération n’est presque jamais une simple recherche de similarité. Il s'agit d'une recherche de similarité avec des conditions attachées : les documents de ce client, cette plage de dates, cette langue, pas ceux archivés. L’hypothèse naturelle est que le filtre restreint les candidats et que la recherche s’étend ensuite sur ce qui reste. pgvector documente l'ordre inverse : le filtrage est appliqué après l'analyse de l'index, ce qui signifie qu'un index approximatif peut renvoyer moins de lignes correspondantes que ce que vous avez demandé.

Pensez à ce que cela produit. Vous demandez dix résultats pour un locataire, l'index renvoie ses meilleurs candidats dans l'ensemble du tableau, le filtre les supprime presque tous car la plupart appartiennent à d'autres locataires, et vous récupérez deux documents. Pas une erreur. Deux documents, et un modèle qui y répond avec assurance. Plus votre filtre est strict, plus la situation empire, ce qui est exactement à l'envers de l'intuition selon laquelle une requête plus étroite est une requête plus facile.

La documentation donne les deux sorties. Les index exacts fonctionnent bien pour les conditions qui correspondent à un faible pourcentage de lignes, et pour les filtres plus larges, il existe des analyses d'index itératives, qui continuent d'analyser une plus grande partie de l'index jusqu'à ce que suffisamment de résultats soient trouvés. Les deux sont de véritables correctifs. Le fait est que vous devez savoir que le problème existe, et qu’une charge de travail multi-tenant filtrée est précisément la forme qui la rend la plus dure.

HNSW ou IVFFlat, comme décision plutôt que comme classement

Deux types d'index, et le compromis entre eux est documenté plutôt que mystérieux, ce qui en fait l'un des choix les plus faciles de la pile.

HNSW a de meilleures performances de requête que IVFFlat en termes de compromis entre vitesse et rappel, et le paie avec des temps de construction plus lents et plus de mémoire. Il ne nécessite également aucune étape de formation, il peut donc être créé sur une table vide, ce qui compte plus qu'il n'y paraît : cela signifie que l'index existe avant l'arrivée des données et que vous ne gérez pas une reconstruction comme étape de déploiement.

IVFFlat a des temps de construction plus rapides et utilise moins de mémoire, avec des performances de requête inférieures. Il doit être créé une fois que le tableau contient des données, car il fonctionne en divisant les vecteurs en listes et en recherchant les plus proches, et il ne peut pas choisir ces divisions sans voir la distribution. Son nombre de listes est fonction de la taille de la table, la documentation suggérant des lignes divisées par 1 000 jusqu'à environ un million de lignes et la racine carrée du nombre de lignes au-delà.

La décision dépend donc principalement de la ressource qui est rare. Si la latence des requêtes est la contrainte et que vous pouvez vous permettre la mémoire, HNSW. Si la mémoire ou le temps de construction sont la contrainte, ou si la table est souvent reconstruite, IVFFlat. Il n’y a pas non plus d’engagement architectural comme l’est l’adoption d’un service séparé, ce qui est le véritable argument pour faire ce choix avant le plus grand.

Trois choses qui changent lorsque Postgres cesse d'être la réponse

Un magasin vectoriel dédié gagne sa place lorsque l’un de ces éléments devient réalité. Pas lorsque le corpus semble volumineux, ni lorsque le diagramme d'architecture semble plus sérieux.

L'analyse ne correspond plus au budget de latence, mesuré plutôt que supposé. Il s'agit d'un cas simple et le seul dont traitent la plupart des articles de comparaison. Cela arrive plus tard que prévu, car une analyse exacte de quelques centaines de milliers d’intégrations sur un matériel raisonnable est souvent assez rapide pour un produit interactif, et une base de données que vous exploitez déjà vaut beaucoup de latence.

L'index ne tient plus en mémoire à côté de tout ce que fait la base de données. C'est le cas qui force en fait la plupart des migrations, et il s'agit d'une question de contention plutôt que de vecteurs. Un index graphique a besoin de mémoire et il est en concurrence avec l'ensemble de travail de la charge de travail transactionnelle partageant cette instance. La récupération se dégrade alors exactement sous la charge qui la rend importante. Un magasin séparé est en partie une décision de correction et surtout une décision d'isolement.

La forme de récupération cesse d'être une recherche du voisin le plus proche. Notation hybride par rapport à un index de mots clés, étapes de reclassement, partitionnement par locataire, recherche filtrée là où le filtre effectue la majeure partie de la sélection, mises à jour en direct à un rythme qui maintient l'index en perpétuelle reconstruction. Chacun est possible à assembler, et à un moment donné, les assembler est le projet plutôt qu'un détail de celui-ci, ce qui est le signal honnête que l'outil spécialisé est spécialisé pour une raison.

Si aucun des trois n'est vrai, une migration vous offre une dépendance opérationnelle, une deuxième histoire de cohérence et un pipeline de synchronisation entre vos enregistrements et leurs intégrations. C'est dans ce pipeline que l'on voit le plus d'incidents de production dans ce domaine : pas de mauvais rappels, mais des plongements qui silencieusement ne correspondent plus aux lignes qu'ils sont censés décrire.

Que mesurer avant de déménager

La décision ci-dessus nécessite quatre nombres et tous proviennent de votre propre système, c'est pourquoi aucun article de comparaison ne peut vous les fournir.

Mesurez la taille du corpus dont vous disposez réellement et la taille que vous aurez dans un an, pas celle indiquée dans le dossier de financement. Mesurez la latence de recherche exacte selon la simultanéité réelle de vos requêtes, avec un filtre attaché, car le chemin filtré est celui qui sera exécuté. Mesurez le rappel par rapport à la recherche exacte une fois que vous ajoutez un index, en utilisant des requêtes tirées du trafic réel plutôt que d'un benchmark, puisque le rappel sur votre distribution est le seul rappel qui affecte vos utilisateurs. Et mesurez la fréquence à laquelle le corpus change, car le taux de mise à jour détermine davantage le choix de l'index que la taille.

Alors passez l’appel. La structure de la décision est stable même si les produits qu'elle contient ne le sont pas, et un système construit sur un arbre de décision peut être redécidé lorsque l'une des entrées change. Un système construit sur un classement doit être reconstruit lorsque le classement bouge.

C'est la même approche que nous adoptons pour le travail d'intégration en général : le choix défendable est celui dont le raisonnement survit à la prochaine version, et le raisonnement ici concerne votre corpus et la forme de votre requête plutôt que la matrice de fonctionnalités de quiconque. Si vous êtes plus tôt que cela et que vous décidez encore à quoi sert la couche de récupération, travail de construction personnalisé commence par cette question plutôt que par le magasin.

Articles similaires