Files
rpa_vision_v3/docs/changelog/PHASE11_IVF_OPTIMIZATION_COMPLETE.md
Dom a27b74cf22 v1.0 - Version stable: multi-PC, détection UI-DETR-1, 3 modes exécution
- 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>
2026-01-29 11:23:51 +01:00

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

  1. test_ivf_training - Entraînement automatique
  2. test_nlist_calculation - Calcul de nlist optimal
  3. test_auto_migration_flat_to_ivf - Migration automatique
  4. test_ivf_search_quality - Qualité de recherche IVF
  5. test_ivf_nprobe_effect - Effet de nprobe sur qualité
  6. test_optimize_index - Optimisation périodique
  7. test_save_load_ivf - Sauvegarde/chargement IVF
  8. 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 🎉