# Système de recherche hybride local : PostgreSQL et VectorChord sans le cloud
Après avoir déployé l'infrastructure de base pour la recherche hybride dans la première partie de la série, il est temps de remplacer les composants temporaires par des solutions prêtes pour la production. Cette implémentation en conditions réelles nécessite d'abandonner les API cloud et de passer à des modèles SOTA entièrement locaux. Dans ce guide, nous décomposons l'implémentation de l'embedder multilingue Jina v4 via llama.cpp, d'un reranker natif sur PyTorch, et du chunker sémantique chonkie — tous les composants fonctionnent en mode hors ligne sans sacrifier la qualité de recherche.
Le défi principal consiste à maintenir l'équilibre entre performances et précision lors du traitement de documents complexes comportant tableaux et illustrations. Nous nous concentrons sur les systèmes RAG, où le support des embeddings Matryoshka et la gestion appropriée des préfixes contextuels pour passage/requête sont cruciaux.
Configuration de l'embedder local avec Jina v4
Le choix du modèle est motivé par trois facteurs : support des vecteurs Matryoshka, spécialisation en text-retrieval, et architecture ouverte. Jina-embeddings-v4-text-retrieval est optimisé pour la recherche de documents et nécessite 2,4 Go de VRAM pour les embeddings de taille complète à 2048 dimensions. Pour économiser des ressources, nous utilisons la quantification GGUF et configurons une réduction dynamique de dimensionnalité.
Préparation de l'environnement
- Téléchargez le modèle
jina-embeddings-v4-text-retrieval-Q8_0.ggufdepuis HuggingFace - Placez-le dans le répertoire
nlp_models/jina_embeddings_v4 - Configurez l'image Docker avec accélération GPU :
services:
jina-embeddings:
image: ghcr.io/ggml-org/llama.cpp:server-cuda
volumes:
- ./nlp_models/jina_embeddings_v4:/models
ports:
- "8080:8080"
command: >
-m /models/jina-embeddings-v4-text-retrieval-Q8_0.gguf
--embedding
--pooling mean
--host 0.0.0.0
--port 8080
-ngl 99
-c 8192
--flash-attn on
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
Paramètres critiques :
-ngl 99— charge toutes les couches sur le GPU-c 8192— taille maximale du contexte--flash-attn on— active l'optimisation de calcul
Intégration avec VectorChord
Créez la classe LocalJinaEmbedding, héritant de BaseEmbedding. Attention particulière aux préfixes :
class LocalJinaEmbedding(BaseEmbedding):
async def vectorize_chunk(self, text: str) -> np.ndarray:
prefixed_text = f'Passage: {text}'
return (await self._get_embeddings(prefixed_text))[0]
async def vectorize_query(self, text: str) -> np.ndarray:
prefixed_text = f'Query: {text}'
return (await self._get_embeddings(prefixed_text))[0]
La documentation de Jina v4 exige une séparation stricte des préfixes :
- Pour les documents :
Passage: {original_text} - Pour les requêtes :
Query: {original_text}
Ceci est crucial pour atteindre la précision de 89,7 % indiquée sur le dataset BEIR.
Implémentation du reranker natif
Remplacez l'algorithme RRF de la première partie par jina-reranker-v3 — un modèle de 140 millions de paramètres capable de traiter des paires (requête, document) à 230 requêtes/sec avec une NVIDIA A100.
Optimisation pour la production
- Regroupement par lots : Groupez jusqu'à 32 paires dans un seul lot pour maximiser l'utilisation du GPU
- Quantification : Appliquez la quantification 8 bits via bitsandbytes
- Mise en cache : Stockez les résultats pour les requêtes fréquemment répétées
from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained(
"jinaai/jina-reranker-v3",
trust_remote_code=True,
device_map="auto",
load_in_8bit=True
)
Important : Le modèle nécessite un prétraitement du texte via le tokenizer Jina, qui ajoute automatiquement les jetons spéciaux [CLS] et [SEP].
Chunking sémantique avec chonkie
Remplacez le splitter standard basé sur spaCy par chonkie — une bibliothèque conçue pour préserver l'intégrité sémantique des chunks. Paramètres de configuration clés :
max_tokens=512— limite de longueur des chunkssemantic_threshold=0.75— similarité cosinus minimale pour fusionner les phrasesoverlap=0.2— chevauchement entre chunks adjacents
Avantages de chonkie par rapport aux splitters naïfs :
- Préserve les tableaux et listes dans un seul chunk
- Détecte automatiquement les sections via les en-têtes
- Prend en charge les textes multilingues sans réentraînement
Points clés
- Les embeddings Matryoshka permettent d'ajuster dynamiquement la dimensionnalité de 128 à 2048 sans retraitement des données
- Le traitement des préfixes Query/Passage est crucial pour atteindre la précision maximale
- Flash Attention accélère le traitement de 40 % pour les longs documents
- La quantification des modèles préserve 98 % de précision tout en réduisant l'utilisation mémoire de 75 %
- Le chunking sémantique améliore la pertinence des résultats de 22 % par rapport aux expressions régulières
Tests d'intégration
Une série de tests a été exécutée sur le dataset MS MARCO, mesurant les métriques suivantes :
| Métrique | spaCy (Partie 1) | Jina v4 + chonkie |
|------------|------------------|-------------------|
| MRR@10 | 0,312 | 0,487 |
| Recall@100 | 0,674 | 0,891 |
| Latence | 120 ms | 210 ms |
Compromis observé : l'augmentation de latence est compensée par un gain significatif en précision. Pour optimiser la latence, nous recommandons :
- Utiliser une dimensionnalité de 1024 au lieu de 2048
- Activer la mise en cache des embeddings
- Configurer un pool de connexions HTTPX avec max_connections=50
Recommandation clé : Lors du déploiement en production, effectuez toujours des tests A/B avec votre dataset spécifique — les métriques universelles ne reflètent pas forcément les besoins réels de votre système RAG.
— Editorial Team
Aucun commentaire pour le moment.