- Frontend v4 accessible sur réseau local (192.168.1.40) - Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard) - Ollama GPU fonctionnel - Self-healing interactif - Dashboard confiance Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
9.2 KiB
9.2 KiB
Phase 11 - Optimisation FAISS IVF ✅ COMPLÉTÉ
Date: 24 Novembre 2024
Tasks: 11.2, 11.3
📋 Résumé
Implémentation complète de l'optimisation FAISS avec index IVF pour améliorer les performances de recherche de similarité sur de grands volumes d'embeddings.
✅ Tâches Complétées
Task 11.2 : Implémenter caching d'embeddings ✅
Fichier: core/embedding/embedding_cache.py
Implémentation de deux systèmes de cache :
1. EmbeddingCache - Cache LRU général
- Politique d'éviction LRU (Least Recently Used)
- Taille maximale configurable (1000 embeddings par défaut)
- Limite de mémoire (500 MB par défaut)
- Statistiques détaillées (hits/misses/evictions/hit_rate)
- Invalidation sélective par clé ou pattern
- Estimation de l'utilisation mémoire
2. PrototypeCache - Cache spécialisé pour prototypes
- Optimisé pour les prototypes de WorkflowNodes
- Politique d'éviction basée sur la fréquence d'utilisation
- Tracking des accès et timestamps
- Statistiques d'utilisation
Features:
- ✅ Cache LRU avec éviction automatique
- ✅ Gestion de la mémoire
- ✅ Statistiques de performance
- ✅ Invalidation intelligente
Task 11.3 : Optimiser FAISS avec index IVF ✅
Fichier: core/embedding/faiss_manager.py
Optimisation majeure du système FAISS avec support IVF complet.
Améliorations Implémentées
1. Migration Automatique Flat → IVF
# Migration automatique quand >10k embeddings
if self.auto_optimize and self.index_type == "Flat":
if self.index.ntotal >= self.migration_threshold:
self._migrate_to_ivf()
- Détection automatique du seuil (10 000 embeddings)
- Migration transparente sans perte de données
- Préservation des métadonnées
- Calcul automatique du nlist optimal
2. Entraînement Automatique IVF
# Collecte de vecteurs pour entraînement
if self.index_type == "IVF" and not self.is_trained:
self.training_vectors.append(vector_float32)
if len(self.training_vectors) >= 100:
self._train_ivf_index()
- Collecte automatique des premiers 100 vecteurs
- Entraînement automatique dès que suffisant de données
- Ajout automatique des vecteurs d'entraînement à l'index
3. Calcul Optimal de nlist
def _calculate_nlist(self, n_vectors: int) -> int:
"""Règle empirique: nlist = sqrt(n_vectors)"""
nlist = int(np.sqrt(n_vectors))
return max(100, min(nlist, 65536))
- Formule empirique :
nlist = √n_vectors - Contraintes : min=100, max=65536
- Adaptation dynamique à la taille de l'index
4. Optimisation Périodique
def optimize_index(self):
"""Recalculer nlist optimal et réentraîner si nécessaire"""
optimal_nlist = self._calculate_nlist(n_vectors)
if abs(optimal_nlist - current_nlist) / current_nlist > 0.5:
# Reconstruire l'index avec nlist optimal
- Détection de nlist sous-optimal (>50% de différence)
- Reconstruction automatique de l'index
- Réentraînement avec tous les vecteurs
5. Support GPU (Préparé)
def _setup_gpu(self):
"""Configurer les ressources GPU si disponibles"""
ngpus = faiss.get_num_gpus()
if ngpus > 0:
self.gpu_resources = faiss.StandardGpuResources()
- Détection automatique des GPUs disponibles
- Migration CPU ↔ GPU transparente
- Fallback automatique sur CPU si GPU indisponible
6. DirectMap pour Reconstruction
# Activer DirectMap pour permettre reconstruct()
index.make_direct_map()
- Permet la reconstruction de vecteurs depuis l'index
- Nécessaire pour l'optimisation périodique
- Activé automatiquement sur tous les index IVF
Paramètres Configurables
FAISSManager(
dimensions=512,
index_type="IVF", # "Flat", "IVF", "HNSW"
metric="cosine", # "cosine", "l2", "ip"
nlist=None, # Auto si None
nprobe=8, # Nombre de clusters à visiter
use_gpu=False, # Utiliser GPU si disponible
auto_optimize=True # Migration auto Flat→IVF
)
Statistiques Enrichies
stats = manager.get_stats()
# {
# "dimensions": 512,
# "index_type": "IVF",
# "metric": "cosine",
# "total_vectors": 15000,
# "is_trained": True,
# "nlist": 122,
# "nprobe": 8,
# "optimal_nlist": 122,
# "nlist_efficiency": 1.0,
# "use_gpu": False
# }
🧪 Tests
Fichier: tests/unit/test_faiss_ivf_optimization.py
8 Tests Complets - Tous Passent ✅
- ✅ test_ivf_training - Entraînement automatique
- ✅ test_nlist_calculation - Calcul de nlist optimal
- ✅ test_auto_migration_flat_to_ivf - Migration automatique
- ✅ test_ivf_search_quality - Qualité de recherche IVF
- ✅ test_ivf_nprobe_effect - Effet de nprobe sur qualité
- ✅ test_optimize_index - Optimisation périodique
- ✅ test_save_load_ivf - Sauvegarde/chargement IVF
- ✅ test_stats_with_ivf - Statistiques IVF
$ pytest tests/unit/test_faiss_ivf_optimization.py -v
======================== 8 passed in 3.84s ========================
📊 Performances Attendues
Comparaison Flat vs IVF
| Métrique | Flat | IVF (nlist=100, nprobe=8) |
|---|---|---|
| Recherche (10k vecteurs) | ~50ms | ~5-10ms |
| Recherche (100k vecteurs) | ~500ms | ~10-20ms |
| Recherche (1M vecteurs) | ~5s | ~20-50ms |
| Mémoire | 100% | ~100% + overhead |
| Précision | 100% | ~95-99% |
Recommandations
- < 10k embeddings : Utiliser Flat (recherche exacte)
- 10k - 100k embeddings : Utiliser IVF avec nprobe=8
- > 100k embeddings : Utiliser IVF avec nprobe=16-32
- > 1M embeddings : Considérer IVF avec GPU
🔧 Utilisation
Exemple 1 : Migration Automatique
from core.embedding.faiss_manager import FAISSManager
# Créer index Flat avec auto-migration
manager = FAISSManager(
dimensions=512,
index_type="Flat",
auto_optimize=True # Migration auto vers IVF
)
# Ajouter des embeddings
for i in range(15000):
vector = compute_embedding(data[i])
manager.add_embedding(f"emb_{i}", vector)
# Automatiquement migré vers IVF après 10k embeddings
print(manager.index_type) # "IVF"
Exemple 2 : IVF Direct
# Créer index IVF directement
manager = FAISSManager(
dimensions=512,
index_type="IVF",
metric="cosine",
nlist=100, # Sera ajusté automatiquement
nprobe=8 # Compromis vitesse/qualité
)
# Ajouter embeddings (entraînement auto après 100)
for i in range(1000):
manager.add_embedding(f"emb_{i}", vectors[i])
# Rechercher
results = manager.search_similar(query_vector, k=10)
Exemple 3 : Optimisation Périodique
# Après avoir ajouté beaucoup de vecteurs
manager.optimize_index()
# Vérifier l'efficacité
stats = manager.get_stats()
print(f"nlist efficiency: {stats['nlist_efficiency']:.2%}")
Exemple 4 : Avec Cache
from core.embedding.embedding_cache import EmbeddingCache, PrototypeCache
# Créer caches
embedding_cache = EmbeddingCache(max_size=1000, max_memory_mb=500)
prototype_cache = PrototypeCache(max_size=100)
# Utiliser avec FAISS
def get_embedding(embedding_id):
# Vérifier cache d'abord
vector = embedding_cache.get(embedding_id)
if vector is not None:
return vector
# Charger depuis FAISS
vector = load_from_faiss(embedding_id)
# Mettre en cache
embedding_cache.put(embedding_id, vector)
return vector
# Statistiques
stats = embedding_cache.get_stats()
print(f"Hit rate: {stats['hit_rate']:.2%}")
📈 Impact sur le Système
Avant (Flat uniquement)
- ❌ Recherche lente sur >10k embeddings
- ❌ Pas de cache
- ❌ Pas d'optimisation automatique
Après (IVF + Cache)
- ✅ Recherche 10-50x plus rapide avec IVF
- ✅ Cache LRU réduit les accès disque
- ✅ Migration automatique Flat→IVF
- ✅ Optimisation périodique automatique
- ✅ Support GPU préparé
- ✅ Statistiques détaillées
🎯 Prochaines Étapes
La Task 11.4 est la suivante :
- 11.4 : Optimiser détection UI avec ROI
📝 Notes Techniques
Choix de nprobe
Le paramètre nprobe contrôle le compromis vitesse/qualité :
- nprobe=1 : Très rapide, qualité ~80%
- nprobe=8 : Bon compromis, qualité ~95%
- nprobe=16 : Plus lent, qualité ~98%
- nprobe=nlist : Équivalent à Flat (100%)
DirectMap
L'activation de DirectMap permet :
- Reconstruction de vecteurs depuis l'index
- Nécessaire pour
optimize_index() - Overhead mémoire : ~8 bytes par vecteur
Normalisation
Pour la métrique cosine :
- Vecteurs normalisés automatiquement
- Utilise inner product (IP) en interne
- Distance = similarité cosinus
✅ Validation
- Task 11.2 : Cache d'embeddings implémenté
- Task 11.3 : Optimisation IVF complète
- 8/8 tests passent
- Migration automatique fonctionne
- Entraînement automatique fonctionne
- Optimisation périodique fonctionne
- Sauvegarde/chargement IVF fonctionne
- Statistiques enrichies
- Documentation complète
Phase 11 (Optimisation FAISS) : 100% COMPLÈTE 🎉