Dans ce guide, vous allez :
- Découvrir brièvement la recherche vectorielle
- Découvrir les plus proches voisins approximatifs (ANN) et Hierarchical Navigable Small World (HNSW)
- Découvrir Quantised Bit (QBit)
- Utiliser QBit pour effectuer une recherche vectorielle à l’aide du jeu de données DBPedia
Introduction à la recherche vectorielle
Comprendre les embeddings
Plus proches voisins approximatifs (ANN)
Quantisation
- Conserver la copie quantifiée à côté de la colonne d’origine - Cela double l’espace de stockage, mais c’est sans risque, car nous pouvons toujours revenir à la pleine précision
- Remplacer entièrement les valeurs d’origine (en les convertissant vers un type inférieur lors de l’insertion) - Cela permet d’économiser de l’espace et des E/S, mais c’est irréversible
Hierarchical Navigable Small World (HNSW)
Comparaison des approches
QBit en profondeur
Quantised Bit (QBit)
BFloat16, Float32 et Float64 en tirant parti de la manière dont les nombres à virgule flottante sont représentés : sous forme de bits.
Au lieu de stocker chaque nombre dans son intégralité, QBit répartit les valeurs en plans de bits : tous les premiers bits, tous les deuxièmes bits, tous les troisièmes bits, et ainsi de suite.
Cette approche résout la principale limite de la quantification traditionnelle. Il n’est pas nécessaire de stocker des données dupliquées ni de risquer de rendre les valeurs dénuées de sens. Elle évite également les goulots d’étranglement liés à la RAM de HNSW, puisque QBit fonctionne directement sur les données stockées au lieu de maintenir un index en mémoire.
LimitationBien que QBit accélère la recherche vectorielle, sa complexité de calcul reste O(n). En d’autres termes : si votre jeu de données est suffisamment petit pour qu’un index HNSW tienne facilement en RAM, cela reste le choix le plus rapide.
Le type de données
FixedString(N) distincte : des chaînes de longueur fixe de N octets, stockées consécutivement en mémoire, sans séparateur entre elles. Tous ces groupes sont ensuite réunis dans un unique Tuple, qui constitue la structure sous-jacente de QBit.
Exemple : Si l’on part d’un vecteur de 8 éléments Float64, chaque groupe contiendra 8 bits. Comme un Float64 comporte 64 bits, on obtient au final 64 groupes (un pour chaque bit). L’organisation interne de QBit(Float64, 8) ressemble donc à un Tuple de 64 colonnes FixedString(1).
Calcul de la distance
L2DistanceTransposed avec un paramètre de précision :
Optimisation des E/S
Optimisation des calculs
Optimisation de BFloat16
Complexité de Float64
Exemple avec DBpedia
Configuration
Requête de recherche
Comparer les performances à celles d’une recherche par force brute
Comparer les performances à celles d’une recherche par force brute
Idée clé
Conclusion
Adapté de l’article de blog de Raufs Dunamalijevs, publié le 28 octobre 2025