4. StorageIntermédiaire

Bases de Données Vectorielles : Stocker et Rechercher des Embeddings

1 février 2025
14 min de lecture
Équipe de Recherche Ailog

Guide complet sur les bases de données vectorielles pour le RAG : comparaison des options populaires, stratégies d'indexation et optimisation des performances.

TL;DR

  • Pour le prototypage : ChromaDB (intégré, configuration zéro)
  • Pour la production : Pinecone (géré) ou Qdrant (auto-hébergé)
  • Besoin de recherche hybride : Weaviate ou Elasticsearch
  • Métrique clé : Latence de requête <100ms pour une bonne UX
  • Testez les bases vectorielles sur Ailog sans infrastructure

Qu'est-ce qu'une Base de Données Vectorielle ?

Une base de données vectorielle est une base de données spécialisée optimisée pour stocker et rechercher des vecteurs de haute dimension (embeddings). Contrairement aux bases de données traditionnelles qui recherchent par correspondances exactes ou plages, les bases de données vectorielles trouvent des éléments par similarité sémantique.

Capacités de Base

  1. Stockage de vecteurs : Stocker efficacement des millions de vecteurs de haute dimension
  2. Recherche de similarité : Trouver les voisins les plus proches dans l'espace vectoriel
  3. Filtrage de métadonnées : Combiner recherche sémantique et filtres traditionnels
  4. Scalabilité : Gérer des milliards de vecteurs avec faible latence
  5. Opérations CRUD : Créer, lire, mettre à jour, supprimer des vecteurs

Pourquoi Pas une Base de Données Classique ?

Les bases de données traditionnelles ont du mal avec la recherche vectorielle :

Problème : Malédiction de la dimensionnalité

  • Les espaces de haute dimension se comportent de manière contre-intuitive
  • Les métriques de distance deviennent moins significatives
  • La recherche exhaustive est O(n×d) - trop lent à grande échelle

Solution Base Vectorielle : Approximate Nearest Neighbor (ANN)

  • Indexation spécialisée (HNSW, IVF, etc.)
  • Temps de recherche sous-linéaire : O(log n) typique
  • Échanger l'exactitude contre la vitesse (rappel >99%)

Bases de Données Vectorielles Populaires

Pinecone

Type : Service cloud géré

Avantages :

  • Entièrement géré, pas d'infrastructure
  • Facile à utiliser, excellente DX
  • Auto-scaling
  • Haute performance
  • Bonne documentation

Inconvénients :

  • Coût à grande échelle
  • Verrouillage fournisseur
  • Auto-hébergement limité

Tarification :

  • Starter : Gratuit (1 index, 100K vecteurs)
  • Standard : ~70 $/mois (1M vecteurs, 1 pod)
  • Entreprise : Sur mesure

Meilleur pour :

  • Prototypes rapides
  • Production sans surcharge ops
  • Quand le budget le permet

Weaviate

Type : Open source, auto-hébergeable

Avantages :

  • Open source (Apache 2.0)
  • Recherche hybride (vecteur + mots-clés)
  • API GraphQL
  • Support multi-tenancy
  • Communauté active

Inconvénients :

  • Configuration plus complexe
  • Surcharge auto-hébergement
  • Courbe d'apprentissage

Hébergement :

  • Auto-hébergé : Gratuit (coûts d'infrastructure)
  • Weaviate Cloud : À partir de 25 $/mois

Meilleur pour :

  • Exigence d'auto-hébergement
  • Besoins de recherche hybride
  • Filtrage complexe

Qdrant

Type : Open source, basé Rust

Avantages :

  • Très rapide (performance Rust)
  • Capacités de filtrage riches
  • Bon SDK Python
  • Déploiement Docker facile
  • Support de snapshots

Inconvénients :

  • Écosystème plus petit que d'autres
  • Offre gérée moins mature

Hébergement :

  • Auto-hébergé : Gratuit
  • Qdrant Cloud : À partir de 25 $/mois

Meilleur pour :

  • Applications critiques en performance
  • Exigences de filtrage complexes
  • Auto-hébergement facile

Chroma

Type : Open source, intégré

Avantages :

  • Mode intégré (pas de serveur nécessaire)
  • API simple
  • Bon pour le développement
  • Gratuit et open source

Inconvénients :

  • Échelle limitée
  • Pas de support multi-utilisateurs en mode intégré
  • Moins de fonctionnalités que d'autres

Meilleur pour :

  • Développement et prototypage
  • Applications petite échelle
  • Cas d'usage intégrés

Milvus

Type : Open source, cloud-native

Avantages :

  • Hautement scalable (milliards de vecteurs)
  • Plusieurs types d'index
  • Architecture cloud-native
  • Support GPU

Inconvénients :

  • Configuration complexe
  • Gourmand en ressources
  • Courbe d'apprentissage plus raide

Hébergement :

  • Auto-hébergé : Gratuit
  • Zilliz Cloud (géré) : Tarification personnalisée

Meilleur pour :

  • Production à grande échelle
  • Exigences multi-index
  • Quand l'échelle est la préoccupation principale

PostgreSQL + pgvector

Type : Extension pour PostgreSQL

Avantages :

  • Utiliser l'infrastructure PostgreSQL existante
  • Garanties ACID
  • Riche écosystème SQL
  • Intégration facile

Inconvénients :

  • Pas optimisé pour échelle massive
  • Plus lent que bases vectorielles spécialisées
  • Limité à des millions, pas des milliards

Coût :

  • Gratuit (extension)
  • Coûts d'hébergement Postgres

Meilleur pour :

  • Déjà utiliser PostgreSQL
  • Besoin de garanties transactionnelles
  • Échelle modérée (< 1M vecteurs)

Matrice de Comparaison

Base de donnéesGéréOpen SourceÉchelleMeilleure Fonctionnalité
PineconeÉlevéeFacilité d'utilisation
WeaviateÉlevéeRecherche hybride
QdrantÉlevéePerformance
ChromaFaibleSimplicité
MilvusTrès ÉlevéeScalabilité
pgvectorMoyenneIntégration SQL

Stratégies d'Indexation

HNSW (Hierarchical Navigable Small Worlds)

Comment ça marche :

  • Structure de graphe multi-couches
  • Propriétés de petit monde navigable
  • Recherche gloutonne du haut vers le bas

Caractéristiques :

  • Recherche rapide : O(log n)
  • Rappel élevé (95-99%)
  • Gourmand en mémoire
  • Construction d'index lente

Paramètres :

DEVELOPERpython
index_config = { 'M': 16, # Connexions par noeud (compromis: rappel vs mémoire) 'ef_construction': 64 # Largeur de recherche pendant construction (plus = meilleur rappel) } search_params = { 'ef': 32 # Largeur de recherche au moment de la requête (plus = meilleur rappel, plus lent) }

Réglage :

  • M : 8-64 (16 par défaut). Plus = meilleur rappel, plus de mémoire
  • ef_construction : 64-512. Plus = meilleure qualité d'index, construction plus lente
  • ef : 32-512. Plus = meilleur rappel, recherche plus lente

Meilleur pour :

  • Exigences de rappel élevé
  • Charges de travail à forte lecture
  • Quand la mémoire est disponible

IVF (Inverted File Index)

Comment ça marche :

  • Grouper les vecteurs en partitions (cellules de Voronoï)
  • Rechercher uniquement les partitions proches
  • Approche du grossier au fin

Paramètres :

DEVELOPERpython
index_config = { 'nlist': 100, # Nombre de clusters (√n à 4×√n typique) } search_params = { 'nprobe': 10 # Nombre de clusters à rechercher }

Réglage :

  • nlist : sqrt(N) typique. Plus = recherche plus rapide, construction plus lente
  • nprobe : 1 à nlist. Plus = meilleur rappel, recherche plus lente

Meilleur pour :

  • Très grands ensembles de données
  • Compromis de rappel acceptable
  • Quand la mémoire est limitée

Flat (Force Brute)

Comment ça marche :

  • Comparer la requête à chaque vecteur
  • Plus proches voisins exacts
  • Pas d'indexation requise

Caractéristiques :

  • Rappel 100%
  • Temps de recherche O(n)
  • Pas de surcharge d'index

Meilleur pour :

  • Petits ensembles de données (< 10K vecteurs)
  • Résultats exacts requis
  • Évaluation vérité terrain

HNSW vs IVF

AspectHNSWIVF
VitesseTrès rapideRapide
RappelPlus élevé (98-99%)Plus bas (90-95%)
MémoireÉlevéePlus basse
Temps constructionLentMoyen
Mises à jourCoûteusesMoins chères
Meilleure échelleMillionsMilliards

Filtrage de Métadonnées

Combiner similarité vectorielle avec filtres traditionnels.

Pré-filtrage

Filtrer d'abord, puis rechercher les vecteurs.

DEVELOPERpython
# Filter by metadata, then vector search within results results = db.query( vector=query_embedding, filter={"category": "electronics", "price": {"$lt": 1000}}, limit=10 )

Avantages :

  • Application exacte des filtres
  • Pas de résultats non pertinents

Inconvénients :

  • Peut trop réduire l'ensemble de candidats
  • Plus lent si le filtre est sélectif

Post-filtrage

Rechercher les vecteurs d'abord, puis filtrer les résultats.

DEVELOPERpython
# Vector search first, filter results results = db.query( vector=query_embedding, limit=100 # Overfetch ) filtered = [r for r in results if r.metadata.get('category') == 'electronics'][:10]

Avantages :

  • Obtenir toujours k résultats (si disponibles)
  • Recherche vectorielle plus rapide

Inconvénients :

  • Peut gaspiller du calcul sur résultats filtrés
  • Moins efficace

Hybride (HNSW-IF)

Approche moderne : indexation consciente des filtres.

DEVELOPERpython
# Efficient combined search results = db.query( vector=query_embedding, filter={"category": "electronics"}, limit=10, filter_strategy="hnsw_if" # Filter-aware HNSW traversal )

Comment ça marche :

  • La traversée du graphe HNSW respecte les filtres
  • Sauter les noeuds filtrés pendant la recherche
  • Le meilleur des deux approches

Meilleur pour :

  • Systèmes RAG en production
  • Quand le filtrage est courant
  • Supporté par Qdrant, Weaviate

Métriques de Distance

Similarité Cosinus

Mesure l'angle entre les vecteurs.

DEVELOPERpython
similarity = dot(a, b) / (norm(a) * norm(b))

Plage : [-1, 1] (plus élevé = plus similaire)

Meilleur pour :

  • Embeddings normalisés
  • Choix le plus courant
  • Embeddings de texte

Distance Euclidienne (L2)

Distance en ligne droite.

DEVELOPERpython
distance = sqrt(sum((a - b) ** 2))

Plage : [0, ∞] (plus bas = plus similaire)

Meilleur pour :

  • Embeddings non normalisés
  • Embeddings d'image
  • Quand la magnitude compte

Produit Scalaire

Simple multiplication.

DEVELOPERpython
score = dot(a, b)

Plage : [-∞, ∞] (plus élevé = plus similaire)

Meilleur pour :

  • Embeddings normalisés (équivalent au cosinus)
  • Calcul le plus rapide
  • Quand les vecteurs sont normalisés

Note : Pour vecteurs normalisés :

  • Similarité cosinus ≈ Produit scalaire (mis à l'échelle)
  • Produit scalaire est plus rapide (pas de division)
  • Utiliser produit scalaire si vecteurs normalisés

Optimisation des Performances

Opérations par Lots

Télécharger/requêter par lots pour meilleur débit.

DEVELOPERpython
# Mauvais : Un à la fois for vector in vectors: db.upsert(vector) # Bon : Par lots db.upsert_batch(vectors, batch_size=100)

Opérations Asynchrones

Paralléliser les opérations I/O-bound.

DEVELOPERpython
import asyncio async def batch_search(queries): tasks = [db.search_async(q) for q in queries] return await asyncio.gather(*tasks) results = asyncio.run(batch_search(query_batch))

Stratégies d'Indexation

Indexation incrémentale :

  • Ajouter vecteurs au fur et à mesure
  • Bon pour données dynamiques
  • Maintient la qualité d'index

Ré-indexation par lots :

  • Reconstruire l'index périodiquement
  • Meilleure qualité d'index
  • Temps d'arrêt requis

Indexation double :

  • Écrire dans deux index
  • Basculer atomiquement
  • Zéro temps d'arrêt
  • Double coût de stockage

Sharding

Diviser les données entre plusieurs instances.

DEVELOPERpython
# Route by document ID def get_shard(doc_id, num_shards=4): return hash(doc_id) % num_shards # Parallel search across shards async def search_all_shards(query): tasks = [ search_shard(shard_id, query) for shard_id in range(num_shards) ] results = await asyncio.gather(*tasks) return merge_and_rank(results)

Mise en Cache

Mettre en cache les requêtes fréquentes.

DEVELOPERpython
from functools import lru_cache @lru_cache(maxsize=1000) def search_cached(query_text, k=5): embedding = embed(query_text) return db.search(embedding, limit=k)

Surveillance et Observabilité

Métriques Clés

Métriques de Performance :

  • Latence de requête (p50, p95, p99)
  • Débit d'indexation
  • Utilisation CPU/mémoire

Métriques de Qualité :

  • Recall@k
  • Precision@k
  • Feedback utilisateur (pouce haut/bas)

Métriques Opérationnelles :

  • Taille d'index
  • Nombre de vecteurs
  • Taux de requêtes
  • Taux d'erreur

Instrumentation

DEVELOPERpython
import time def search_with_metrics(query_vector): start = time.time() try: results = db.search(query_vector, limit=10) latency = time.time() - start metrics.record('vector_search_latency', latency) metrics.record('vector_search_success', 1) return results except Exception as e: metrics.record('vector_search_error', 1) raise

Sauvegarde et Récupération

Stratégie de Snapshot

DEVELOPERpython
# Regular snapshots def backup_database(db, backup_path): snapshot = db.create_snapshot() snapshot.save(backup_path) # Restore from snapshot def restore_database(db, backup_path): db.restore_snapshot(backup_path)

Sauvegardes Incrémentales

DEVELOPERpython
# Track changes since last backup last_backup_time = get_last_backup_time() changed_vectors = db.get_vectors_since(last_backup_time) backup_incremental(changed_vectors)

Stratégies de Migration

Migration Sans Temps d'Arrêt

DEVELOPERpython
# 1. Set up new database new_db = setup_new_database() # 2. Backfill data async def migrate(): vectors = old_db.scan_all() await new_db.upsert_batch(vectors) # 3. Dual-write during migration def write_both(vector): old_db.upsert(vector) new_db.upsert(vector) # 4. Validate new database assert validate_migration(old_db, new_db) # 5. Switch reads to new database db = new_db # 6. Decommission old database old_db.shutdown()

Optimisation des Coûts

Calculer les Coûts

DEVELOPERpython
# Storage costs num_vectors = 1_000_000 dimensions = 768 bytes_per_vector = dimensions * 4 # float32 storage_gb = (num_vectors * bytes_per_vector) / (1024 ** 3) storage_cost_monthly = storage_gb * 0.10 # 0,10 $/GB typique # Query costs (for managed services) queries_per_month = 10_000_000 cost_per_1k_queries = 0.05 query_cost_monthly = (queries_per_month / 1000) * cost_per_1k_queries total_monthly = storage_cost_monthly + query_cost_monthly

Tactiques d'Optimisation

  1. Réduire les dimensions : Utiliser des modèles d'embedding plus petits
  2. Quantization : Stocker les vecteurs en précision inférieure (int8 au lieu de float32)
  3. Stockage hiérarchisé : Données chaudes/tièdes/froides
  4. Mise en cache : Réduire les requêtes redondantes
  5. Opérations par lots : Réduire la surcharge par opération

Choisir une Base de Données Vectorielle

Cadre de Décision

Prototypage / POC :

  • Chroma (intégré) ou Pinecone (cloud)
  • Facilité d'utilisation > performance

Production (Petite Échelle < 1M vecteurs) :

  • pgvector (si utilisant Postgres)
  • Pinecone (simplicité gérée)
  • Qdrant (performance auto-hébergée)

Production (Échelle Moyenne 1-100M vecteurs) :

  • Qdrant ou Weaviate (auto-hébergé)
  • Pinecone (géré)

Production (Grande Échelle > 100M vecteurs) :

  • Milvus
  • Weaviate
  • Pinecone distribué

Recherche Hybride Requise :

  • Weaviate (meilleur support hybride)
  • Elasticsearch avec plugin vecteur

Besoin SQL :

  • pgvector

Chemin de Migration

Commencez simple, montez en échelle au besoin :

  1. Développement : Chroma (intégré)
  2. MVP : Pinecone ou pgvector
  3. Échelle : Qdrant ou Weaviate (auto-hébergé)
  4. Échelle massive : Milvus ou configuration distribuée

Conseil d'Expert d'Ailog : Ne sur-optimisez pas prématurément votre choix de base vectorielle. Nous avons fait tourner des systèmes RAG en production servant des millions de requêtes sur Pinecone et Qdrant auto-hébergé. La base de données est rarement le goulot - les mauvaises stratégies de découpage ou d'embedding le sont. Commencez avec ChromaDB pour le prototypage, passez à Pinecone pour la simplicité ou Qdrant pour le contrôle. Ne considérez Milvus/Weaviate que quand vous servez 10M+ requêtes/mois.

Comparer les Bases Vectorielles sur Ailog

Testez différentes bases de données vectorielles avec vos vraies données :

Ailog supporte :

  • ChromaDB, Pinecone, Qdrant, Weaviate
  • Benchmarks de performance avec vos documents
  • Projections de coûts basées sur votre échelle
  • Migration en un clic entre bases

Essayez toutes les bases vectorielles gratuitement →

Prochaines Étapes

Avec les embeddings stockés et recherchables, le prochain défi est de récupérer le contexte le plus pertinent. Les stratégies de récupération avancées incluant recherche hybride, expansion de requêtes et reranking sont couvertes dans le prochain guide.

Tags

base-de-données-vectorielleindexingsimilarity searchperformance

Articles connexes

Ailog Assistant

Ici pour vous aider

Salut ! Pose-moi des questions sur Ailog et comment intégrer votre RAG dans vos projets !