La recherche vectorielle paraît simple jusqu’au moment où le corpus devient assez grand pour faire mal.
Quelques milliers d’embeddings tiennent partout. Quelques millions exposent les vrais coûts du retrieval dense : mémoire, reconstructions d’index, filtrage, persistance et charge opérationnelle d’une base vectorielle alors qu’on voulait seulement un index local rapide.
RyanCodrai/turbovec est intéressant parce qu’il attaque ce problème côté systèmes. C’est un index vectoriel écrit en Rust avec des bindings Python, construit sur l’algorithme TurboQuant de Google Research. Le message du projet est clair : un corpus de 10 millions de documents qui prend environ 31 Go en float32 peut tenir autour de 4 Go avec TurboVec, tout en restant plus rapide que FAISS dans les benchmarks présentés par le dépôt.
C’est le type de compromis qui compte pour le RAG local, la recherche privée et les petites équipes qui ne veulent pas transformer chaque charge d’embeddings en projet d’infrastructure managée.
Ce qu’est TurboVec
TurboVec est un index vectoriel compressé.
En pratique, il permet d’écrire :
from turbovec import TurboQuantIndex
index = TurboQuantIndex(dim=1536, bit_width=4)
index.add(vectors)
scores, indices = index.search(query, k=10)
index.write("my_index.tq")
loaded = TurboQuantIndex.load("my_index.tq")
Il existe aussi un IdMapIndex pour garder des identifiants externes stables :
import numpy as np
from turbovec import IdMapIndex
index = IdMapIndex(dim=1536, bit_width=4)
index.add_with_ids(vectors, np.array([1001, 1002, 1003], dtype=np.uint64))
scores, ids = index.search(query, k=10)
index.remove(1002)
La forme est familière si vous avez déjà utilisé FAISS, Annoy, HNSWLib, LanceDB, Chroma ou des vector stores en mémoire. On ajoute des vecteurs, on cherche, on sauvegarde l’index, on le recharge.
La différence vient du modèle de compression. TurboVec s’appuie sur TurboQuant, un quantizer data-oblivious. Il n’a pas besoin d’entraîner un codebook sur votre dataset avant d’indexer. Vous pouvez ajouter des vecteurs directement, continuer à en ajouter plus tard, et éviter une étape de calibration dépendante de la distribution du corpus.
Pour un workflow de production, ce détail compte. L’entraînement et la reconstruction ne sont pas seulement des problèmes mathématiques. Ce sont des événements de déploiement.
Pourquoi TurboQuant est différent de la quantization classique
La product quantization classique apprend souvent des codebooks à partir des données. Cela peut très bien fonctionner, mais cela crée une dépendance entre l’index et la distribution du corpus. Si les données changent, grossissent ou dérivent, il faut penser au réentraînement, à la qualité de calibration et à la représentativité de l’échantillon.
TurboQuant prend une autre route :
- Normaliser les vecteurs pour transformer chaque vecteur en direction.
- Appliquer une rotation orthogonale aléatoire.
- Utiliser la distribution connue des coordonnées après rotation.
- Quantifier les coordonnées avec un quantizer scalaire pré-calculé.
- Packager les bits.
- Scorer les vecteurs compressés directement au moment de la recherche.
Le terme important est “data-oblivious”. Le quantizer vient des mathématiques des directions en grande dimension, pas de votre dataset.
Cela change le modèle opérationnel :
| Quantizer entraîné classique | Index style TurboQuant |
|---|---|
| Nécessite un entraînement de codebook | Pas d’entraînement de codebook |
| Calibration dépendante de l’échantillon | Quantizer indépendant du corpus |
| La croissance peut poser la question d’une reconstruction | Ajout direct de vecteurs |
| Plus lourd à opérer | Cycle de vie local plus simple |
Ce n’est pas magique. Toute compression a un compromis de rappel. Mais c’est une conception très pratique si la priorité est de rendre l’index petit, local, rapide et facile à alimenter.
La mémoire est le gain le plus visible
Le stockage des embeddings devient vite cher.
Un vecteur float32 de 1536 dimensions utilise :
1536 dimensions * 4 octets = 6144 octets par vecteur
À 10 millions de vecteurs, cela représente environ 61 Go pour les vecteurs bruts seuls. Le README de TurboVec utilise un exemple de corpus de 10 millions de documents à environ 31 Go de RAM en float32, puis montre un index compressé autour de 4 Go. Le chiffre exact dépend de la dimension, de la représentation et de ce qui est compté, mais la direction d’ingénierie est claire : le retrieval dense devient beaucoup plus facile à exécuter localement quand l’index se mesure en quelques gigaoctets au lieu de dizaines de gigaoctets.
C’est important pour :
- le RAG local sur une station de travail
- la recherche privée dans un VPC
- la recherche documentaire pour des équipes réglementées
- les expériences sur laptop qui ne devraient pas exiger une base vectorielle hébergée
- les déploiements edge ou air-gapped
La partie la plus intéressante n’est pas seulement “la compression est plus petite”. C’est que la représentation compressée est aussi la représentation de recherche. TurboVec ne compresse pas seulement pour stocker, puis décompresse chaque candidat en float32 pendant la recherche.
La vitesse de recherche fait partie du design
TurboVec utilise Rust pour l’implémentation de l’index et expose des bindings Python pour l’usage quotidien. C’est une bonne séparation pour ce type d’outil :
- Python est l’endroit où vivent la plupart des pipelines RAG, workflows d’embeddings et notebooks.
- Rust donne plus de contrôle sur la mémoire, la persistance et les kernels SIMD.
Le README mentionne des kernels NEON écrits à la main sur ARM et AVX-512BW sur x86, avec une base AVX2 pour les builds x86. Les notes de benchmark comparent TurboVec à FAISS IndexPQ et IndexPQFastScan, avec des résultats où TurboVec bat FAISS FastScan sur ARM et égale ou dépasse la plupart des configurations x86 montrées par le projet.
La position exacte dans un classement compte moins que le point architectural : TurboVec essaie d’être un index local compressé assez rapide pour servir de chemin principal de retrieval.
C’est important parce que beaucoup d’idées de “réduction mémoire” déplacent le coût ailleurs. Si la compression économise la RAM mais ajoute trop de latence, elle ne sert qu’aux tâches offline. TurboVec garde la recherche près du matériel.
Le filtrage est la fonctionnalité dont les systèmes RAG ont réellement besoin
La fonctionnalité la plus pratique de TurboVec est peut-être la recherche filtrée.
Dans un vrai système RAG, on veut rarement “chercher dans tous les vecteurs”. On veut :
- seulement ce tenant
- seulement les documents accessibles à cet utilisateur
- cette fenêtre temporelle
- cette catégorie produit
- cette langue
- cette frontière de conformité
- ce set candidat produit par SQL ou BM25
IdMapIndex supporte une allowlist :
allowed = np.array(
db.execute("SELECT id FROM docs WHERE tenant=?", (tenant_id,)).fetchall(),
dtype=np.uint64,
)
scores, ids = index.search(query, k=10, allowlist=allowed)
Le détail clé du README est que le filtrage se fait dans le kernel SIMD, par blocs. Les blocs sans slots autorisés peuvent être sautés avant le scoring, et les slots non autorisés à l’intérieur d’un bloc scoré sont écartés avant l’insertion dans le heap.
C’est une meilleure forme que le pattern courant :
récupérer 200 résultats denses -> jeter 190 résultats à cause des permissions ou filtres
L’over-fetching crée des problèmes de rappel, de latence et de tuning. Si la couche vectorielle comprend directement l’allowlist, le retrieval hybride devient plus propre :
SQL / BM25 / ACL -> IDs candidats -> reranking dense dans TurboVec
Pour le RAG en production, c’est la fonctionnalité qui transforme TurboVec d’une curiosité de benchmark en composant d’architecture.
Les intégrations framework facilitent l’essai
TurboVec fournit aussi des intégrations pour des frameworks Python courants :
| Framework | Installation | Remplacement |
|---|---|---|
| LangChain | pip install turbovec[langchain] | InMemoryVectorStore |
| LlamaIndex | pip install turbovec[llama-index] | SimpleVectorStore |
| Haystack | pip install turbovec[haystack] | document store en mémoire |
| Agno | pip install turbovec[agno] | surface de type LanceDB |
C’est un bon chemin d’adoption. La plupart des développeurs ne vont pas réécrire leur stack de retrieval juste pour tester un nouvel index. Une interface compatible permet de garder le pipeline stable et de remplacer seulement la couche stockage/recherche.
C’est aussi là que TurboVec trouve sa meilleure place au début : pas comme remplacement de toutes les bases vectorielles, mais comme vector store local et privé pour les applications où la mémoire, la latence et le déploiement air-gapped comptent plus que les fonctionnalités distribuées.
Où j’utiliserais TurboVec
1. RAG local sur une grande collection documentaire
Si vous avez des centaines de milliers ou des millions de chunks et que vous voulez chercher localement sans lancer un service, TurboVec est un candidat naturel.
L’API de persistance est simple, l’usage Python est direct, et la représentation compressée réduit la pression mémoire.
2. Recherche privée dans des environnements réglementés
Les lecteurs de neelshah18.com connaissent bien ce pattern : santé, finance, gouvernement et données internes d’entreprise ne peuvent pas toujours sortir du réseau.
TurboVec est local. Avec un modèle d’embeddings local ou un service interne contrôlé, le retrieval dense peut rester dans la même frontière de confiance.
3. Retrieval hybride avec filtres stricts
Si votre couche de retrieval doit respecter des tenants, ACLs, fenêtres de dates ou catégories, le modèle allowlist est un vrai avantage.
Le design propre est :
- Utiliser SQL, métadonnées ou BM25 pour produire les IDs autorisés.
- Utiliser TurboVec pour reranker densément seulement cet ensemble.
- Envoyer les meilleurs résultats au LLM.
Cela garde les permissions et la logique métier hors de l’index vectoriel, tout en évitant l’over-fetching.
4. Expériences embeddings qui doivent rester économiques
Beaucoup d’équipes commencent avec une base vectorielle hébergée parce que c’est pratique, puis découvrent que leur charge tient sur une machine mais coûte trop cher en float32.
TurboVec donne une autre option : garder l’index local, compressé et rapide avant d’introduire une infrastructure distribuée.
Ce que je vérifierais avant adoption
TurboVec est prometteur, mais il faut l’évaluer comme une dépendance système.
| Question | Pourquoi c’est important |
|---|---|
| Quel rappel obtenez-vous sur vos embeddings ? | Le comportement de compression dépend de la tâche, pas seulement des benchmarks. |
| Quelle largeur de bits est acceptable ? | Les index 2-bit et 4-bit échangent mémoire et qualité différemment. |
| Comment les suppressions et mises à jour se comportent-elles ? | Les IDs stables aident, mais les patterns d’écriture comptent. |
| Avez-vous besoin d’un service distribué ? | TurboVec est surtout un index local, pas une base vectorielle managée complète. |
| Les intégrations couvrent-elles votre pipeline exact ? | Les surfaces drop-in sont utiles, mais chaque framework a ses cas limites. |
Je le benchmarkerais avec les mêmes requêtes, documents, filtres et évaluations de qualité que le système RAG de production. Les benchmarks vectoriels sont utiles, mais la qualité visible par l’utilisateur reste le vrai test.
La tendance : les bases vectorielles deviennent plus spécialisées
La première vague d’infrastructure vectorielle visait surtout à rendre la recherche nearest-neighbor facile à utiliser.
La vague suivante est plus spécialisée :
- index locaux compressés
- reranking dense filtré
- retrieval hybride SQL/BM25/vectoriel
- recherche privée et air-gapped
- couches compatibles avec les frameworks
- kernels CPU spécifiques au lieu de boucles de scoring génériques
TurboVec est clairement dans cette tendance. Il n’essaie pas d’être toutes les fonctionnalités de base de données à la fois. Il se concentre sur une couche étroite mais importante : stocker les embeddings de façon compacte et les chercher rapidement depuis du code local.
C’est une direction utile. Pour beaucoup de systèmes RAG, l’architecture de retrieval ne devrait pas commencer par le choix d’une base hébergée. Elle devrait commencer par la forme des données, la frontière de confidentialité, le modèle de filtrage et le budget de latence.
TurboVec ajoute une nouvelle option à cette conversation.
Conclusion
TurboVec mérite d’être suivi parce qu’il combine trois qualités qui tirent souvent dans des directions différentes :
- forte compression
- ergonomie Python pratique
- performance bas niveau avec Rust et SIMD
Le modèle de recherche filtrée est particulièrement important. Il correspond à la façon dont les vrais systèmes de retrieval fonctionnent : les métadonnées et permissions réduisent d’abord le monde, puis la recherche dense classe les candidats autorisés.
Si vous construisez du RAG local, de la recherche documentaire privée ou un système de retrieval hybride où la RAM et les filtres comptent, TurboVec n’est pas seulement un vector store de plus. C’est un signe que la couche d’index vectoriel devient plus petite, plus rapide et plus réaliste à opérer.