496 lines
15 KiB
Markdown
496 lines
15 KiB
Markdown
# Design Document - Correction Système d'Apprentissage FAISS
|
|
|
|
## Overview
|
|
|
|
Ce document décrit l'architecture de correction pour résoudre les problèmes critiques du système d'apprentissage RPA Vision V2. Après 3 jours de tests, le système ne génère aucune suggestion car l'index FAISS n'est jamais construit à partir des tâches sauvegardées. De plus, des processus zombies consomment 3GB+ RAM et l'application ne s'arrête pas proprement.
|
|
|
|
### Problèmes Identifiés
|
|
|
|
1. **Index FAISS vide** : L'index n'est jamais chargé au démarrage ni reconstruit à partir des tâches existantes
|
|
2. **Pas de chargement des tâches** : Les 19+ tâches sauvegardées ne sont jamais chargées dans l'index
|
|
3. **Processus zombies** : Les listeners pynput ne sont pas arrêtés proprement
|
|
4. **Fuite mémoire** : Boucles infinies et tensors GPU non libérés
|
|
5. **Pas de diagnostic** : Aucun outil pour comprendre l'état du système
|
|
|
|
### Solution Proposée
|
|
|
|
1. **Chargement automatique au démarrage** : Scanner et indexer toutes les tâches existantes
|
|
2. **Reconstruction d'index** : Commande pour reconstruire l'index à partir des tâches
|
|
3. **Arrêt propre** : Gestion correcte des threads et listeners
|
|
4. **Gestion mémoire** : Libération des ressources et circuit breakers
|
|
5. **Diagnostic complet** : Outil d'analyse de l'état du système
|
|
|
|
## Architecture
|
|
|
|
### Composants Modifiés
|
|
|
|
1. **EmbeddingsManager** : Ajout de méthodes de reconstruction et chargement
|
|
2. **LearningManager** : Chargement automatique des tâches au démarrage
|
|
3. **Orchestrator** : Arrêt propre des threads et listeners
|
|
4. **main.py** : Initialisation avec chargement des tâches existantes
|
|
|
|
### Nouveaux Composants
|
|
|
|
1. **FAISSIndexBuilder** : Construction et reconstruction de l'index
|
|
2. **SystemDiagnostic** : Diagnostic complet du système d'apprentissage
|
|
3. **MemoryMonitor** : Surveillance et gestion de la mémoire
|
|
4. **CircuitBreaker** : Protection contre les boucles infinies
|
|
|
|
## Components and Interfaces
|
|
|
|
### FAISSIndexBuilder
|
|
|
|
```python
|
|
class FAISSIndexBuilder:
|
|
"""Construit et reconstruit l'index FAISS à partir des tâches."""
|
|
|
|
def __init__(self, embeddings_manager, learning_manager, logger):
|
|
pass
|
|
|
|
def scan_tasks(self) -> List[TaskProfile]:
|
|
"""Scanne tous les dossiers de tâches."""
|
|
pass
|
|
|
|
def load_task_embeddings(self, task: TaskProfile) -> List[np.ndarray]:
|
|
"""Charge les embeddings d'une tâche."""
|
|
pass
|
|
|
|
def rebuild_index(self) -> Dict[str, Any]:
|
|
"""Reconstruit l'index complet."""
|
|
pass
|
|
|
|
def verify_index_integrity(self) -> bool:
|
|
"""Vérifie la cohérence de l'index."""
|
|
pass
|
|
```
|
|
|
|
### SystemDiagnostic
|
|
|
|
```python
|
|
class SystemDiagnostic:
|
|
"""Diagnostic complet du système d'apprentissage."""
|
|
|
|
def check_faiss_index(self) -> Dict[str, Any]:
|
|
"""Vérifie l'état de l'index FAISS."""
|
|
pass
|
|
|
|
def count_tasks(self) -> int:
|
|
"""Compte les tâches sauvegardées."""
|
|
pass
|
|
|
|
def check_consistency(self) -> Dict[str, Any]:
|
|
"""Vérifie la cohérence tâches/embeddings."""
|
|
pass
|
|
|
|
def generate_report(self) -> Dict[str, Any]:
|
|
"""Génère un rapport JSON complet."""
|
|
pass
|
|
```
|
|
|
|
|
|
### MemoryMonitor
|
|
|
|
```python
|
|
class MemoryMonitor:
|
|
"""Surveille et gère la consommation mémoire."""
|
|
|
|
def get_current_memory(self) -> float:
|
|
"""Retourne la mémoire utilisée en GB."""
|
|
pass
|
|
|
|
def check_threshold(self, max_memory_gb: float) -> bool:
|
|
"""Vérifie si le seuil est dépassé."""
|
|
pass
|
|
|
|
def cleanup_caches(self):
|
|
"""Nettoie les caches pour libérer de la mémoire."""
|
|
pass
|
|
|
|
def free_gpu_memory(self):
|
|
"""Libère la mémoire GPU."""
|
|
pass
|
|
```
|
|
|
|
### CircuitBreaker
|
|
|
|
```python
|
|
class CircuitBreaker:
|
|
"""Protection contre les boucles infinies."""
|
|
|
|
def __init__(self, threshold: int = 100, window: float = 1.0):
|
|
pass
|
|
|
|
def record_call(self, function_name: str):
|
|
"""Enregistre un appel de fonction."""
|
|
pass
|
|
|
|
def should_break(self, function_name: str) -> bool:
|
|
"""Vérifie si le circuit doit s'ouvrir."""
|
|
pass
|
|
|
|
def reset(self, function_name: str):
|
|
"""Réinitialise le circuit breaker."""
|
|
pass
|
|
```
|
|
|
|
## Data Models
|
|
|
|
### TaskEmbedding
|
|
|
|
```python
|
|
@dataclass
|
|
class TaskEmbedding:
|
|
"""Représente un embedding de tâche."""
|
|
task_id: str
|
|
embedding: np.ndarray
|
|
metadata: Dict[str, Any]
|
|
timestamp: datetime
|
|
```
|
|
|
|
### DiagnosticReport
|
|
|
|
```python
|
|
@dataclass
|
|
class DiagnosticReport:
|
|
"""Rapport de diagnostic du système."""
|
|
timestamp: datetime
|
|
faiss_index_exists: bool
|
|
faiss_index_size: int
|
|
tasks_count: int
|
|
embeddings_count: int
|
|
consistency_ok: bool
|
|
inconsistencies: List[str]
|
|
memory_usage_gb: float
|
|
recommendations: List[str]
|
|
```
|
|
|
|
### MemoryStats
|
|
|
|
```python
|
|
@dataclass
|
|
class MemoryStats:
|
|
"""Statistiques mémoire."""
|
|
total_mb: float
|
|
used_mb: float
|
|
available_mb: float
|
|
percent: float
|
|
gpu_used_mb: Optional[float]
|
|
```
|
|
|
|
## Correctness Properties
|
|
|
|
*A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.*
|
|
|
|
### Property 1: Index chargé au démarrage
|
|
|
|
*For any* système qui démarre avec des tâches existantes, l'index FAISS doit contenir tous les embeddings de ces tâches après l'initialisation.
|
|
|
|
**Validates: Requirements 1.1**
|
|
|
|
### Property 2: Ajout immédiat à l'index
|
|
|
|
*For any* nouvelle tâche sauvegardée, ses embeddings doivent être immédiatement présents dans l'index FAISS.
|
|
|
|
**Validates: Requirements 1.2**
|
|
|
|
### Property 3: Persistance immédiate
|
|
|
|
*For any* modification de l'index FAISS, les fichiers sur disque doivent être mis à jour dans les 5 secondes.
|
|
|
|
**Validates: Requirements 1.3**
|
|
|
|
### Property 4: Reconstruction automatique
|
|
|
|
*For any* système qui détecte des tâches sans embeddings dans l'index, la reconstruction doit être déclenchée automatiquement.
|
|
|
|
**Validates: Requirements 1.4**
|
|
|
|
### Property 5: Suggestions avec index non-vide
|
|
|
|
*For any* action similaire à une tâche existante, si l'index contient des embeddings, une suggestion doit être retournée.
|
|
|
|
**Validates: Requirements 1.5**
|
|
|
|
### Property 6: Arrêt rapide
|
|
|
|
*For any* signal d'arrêt (Ctrl+C), tous les threads doivent être arrêtés en moins de 5 secondes.
|
|
|
|
**Validates: Requirements 2.1**
|
|
|
|
### Property 7: Libération mémoire
|
|
|
|
*For any* arrêt de l'application, la consommation mémoire du processus doit diminuer de plus de 90% dans les 10 secondes.
|
|
|
|
**Validates: Requirements 2.2**
|
|
|
|
### Property 8: Arrêt synchrone des threads
|
|
|
|
*For any* arrêt demandé, aucun thread de capture ne doit rester actif après la fin de la méthode shutdown().
|
|
|
|
**Validates: Requirements 2.3**
|
|
|
|
### Property 9: Stop explicite des listeners
|
|
|
|
*For any* listener pynput actif, sa méthode stop() doit être appelée avant la fin du programme.
|
|
|
|
**Validates: Requirements 2.4**
|
|
|
|
### Property 10: Threads daemon ou arrêt garanti
|
|
|
|
*For any* thread d'orchestrateur, il doit être soit daemon, soit avoir un mécanisme d'arrêt vérifié.
|
|
|
|
**Validates: Requirements 2.5**
|
|
|
|
|
|
### Property 11: Détection de patterns répétitifs
|
|
|
|
*For any* séquence de 3 actions identiques, un pattern doit être détecté et enregistré.
|
|
|
|
**Validates: Requirements 3.1**
|
|
|
|
### Property 12: Création de tâche après pattern
|
|
|
|
*For any* pattern détecté, une tâche avec signatures doit être créée dans les 2 secondes.
|
|
|
|
**Validates: Requirements 3.2**
|
|
|
|
### Property 13: Indexation des embeddings
|
|
|
|
*For any* tâche créée, ses embeddings multimodaux doivent être présents dans l'index FAISS.
|
|
|
|
**Validates: Requirements 3.3**
|
|
|
|
### Property 14: Suggestions avec confiance élevée
|
|
|
|
*For any* action similaire (similarité > 0.8) à une tâche existante, une suggestion avec confiance > 0.7 doit être proposée.
|
|
|
|
**Validates: Requirements 3.4**
|
|
|
|
### Property 15: Contenu des suggestions
|
|
|
|
*For any* suggestion affichée, elle doit contenir le nom de la tâche et la liste des actions à effectuer.
|
|
|
|
**Validates: Requirements 3.5**
|
|
|
|
### Property 16: Limite mémoire mode shadow
|
|
|
|
*For any* exécution en mode shadow pendant plus de 5 minutes, la consommation mémoire doit rester sous 1GB.
|
|
|
|
**Validates: Requirements 4.1**
|
|
|
|
### Property 17: Limite mémoire mode assist
|
|
|
|
*For any* exécution en mode assist pendant plus de 5 minutes, la consommation mémoire doit rester sous 2GB.
|
|
|
|
**Validates: Requirements 4.2**
|
|
|
|
### Property 18: Libération GPU
|
|
|
|
*For any* génération d'embedding, la mémoire GPU utilisée doit être libérée dans les 2 secondes.
|
|
|
|
**Validates: Requirements 4.3**
|
|
|
|
### Property 19: Buffer limité
|
|
|
|
*For any* moment de l'exécution, le buffer de screenshots ne doit jamais contenir plus de 10 images.
|
|
|
|
**Validates: Requirements 4.4**
|
|
|
|
### Property 20: Alerte mémoire
|
|
|
|
*For any* dépassement du seuil de 2GB, un avertissement doit être loggé et les caches nettoyés.
|
|
|
|
**Validates: Requirements 4.5**
|
|
|
|
### Property 21: Comptage des tâches
|
|
|
|
*For any* exécution du diagnostic, le nombre de tâches retourné doit correspondre au nombre de dossiers dans user_profiles.
|
|
|
|
**Validates: Requirements 5.2**
|
|
|
|
### Property 22: Vérification de cohérence
|
|
|
|
*For any* exécution du diagnostic, toutes les tâches avec embeddings doivent avoir leurs embeddings dans l'index.
|
|
|
|
**Validates: Requirements 5.3**
|
|
|
|
### Property 23: Proposition de reconstruction
|
|
|
|
*For any* incohérence détectée (tâche sans embedding dans l'index), le diagnostic doit proposer une reconstruction.
|
|
|
|
**Validates: Requirements 5.4**
|
|
|
|
### Property 24: Rapport JSON complet
|
|
|
|
*For any* diagnostic terminé, un fichier JSON doit être généré avec toutes les métriques requises.
|
|
|
|
**Validates: Requirements 5.5**
|
|
|
|
### Property 25: Scan complet des tâches
|
|
|
|
*For any* reconstruction lancée, tous les dossiers de tâches existants doivent être scannés.
|
|
|
|
**Validates: Requirements 6.1**
|
|
|
|
### Property 26: Génération d'embeddings manquants
|
|
|
|
*For any* tâche trouvée sans embeddings dans l'index, les embeddings doivent être générés et ajoutés.
|
|
|
|
**Validates: Requirements 6.2**
|
|
|
|
### Property 27: Construction d'index optimisé
|
|
|
|
*For any* reconstruction terminée, un nouvel index FAISS doit être créé avec tous les embeddings.
|
|
|
|
**Validates: Requirements 6.3**
|
|
|
|
### Property 28: Sauvegarde après reconstruction
|
|
|
|
*For any* reconstruction réussie, les fichiers d'index et métadonnées doivent être sauvegardés sur disque.
|
|
|
|
**Validates: Requirements 6.4**
|
|
|
|
### Property 29: Résilience aux erreurs
|
|
|
|
*For any* erreur lors du traitement d'une tâche, la reconstruction doit continuer avec les tâches suivantes.
|
|
|
|
**Validates: Requirements 6.5**
|
|
|
|
### Property 30: Validation norme non-nulle
|
|
|
|
*For any* embedding généré, sa norme L2 doit être strictement positive.
|
|
|
|
**Validates: Requirements 7.1**
|
|
|
|
### Property 31: Validation NaN/Inf
|
|
|
|
*For any* embedding généré, il ne doit contenir ni NaN ni Inf.
|
|
|
|
**Validates: Requirements 7.2**
|
|
|
|
### Property 32: Cohérence embeddings identiques
|
|
|
|
*For any* paire de screenshots identiques, leurs embeddings doivent avoir une similarité cosinus > 0.95.
|
|
|
|
**Validates: Requirements 7.3**
|
|
|
|
### Property 33: Discrimination embeddings différents
|
|
|
|
*For any* paire de screenshots visuellement différents, leurs embeddings doivent avoir une similarité cosinus < 0.8.
|
|
|
|
**Validates: Requirements 7.4**
|
|
|
|
### Property 34: Régénération sur invalide
|
|
|
|
*For any* embedding invalide détecté, une erreur doit être loggée et l'embedding régénéré.
|
|
|
|
**Validates: Requirements 7.5**
|
|
|
|
### Property 35: Activation circuit breaker
|
|
|
|
*For any* fonction appelée plus de 100 fois en 1 seconde, le circuit breaker doit s'activer.
|
|
|
|
**Validates: Requirements 8.1**
|
|
|
|
### Property 36: Log circuit breaker
|
|
|
|
*For any* activation de circuit breaker, un log avec stack trace doit être créé.
|
|
|
|
**Validates: Requirements 8.2**
|
|
|
|
### Property 37: Blocage temporaire
|
|
|
|
*For any* circuit breaker activé, la fonction doit être bloquée pendant 60 secondes.
|
|
|
|
**Validates: Requirements 8.3**
|
|
|
|
### Property 38: Reprise progressive
|
|
|
|
*For any* réinitialisation de circuit breaker, un rate limit doit être appliqué à la reprise.
|
|
|
|
**Validates: Requirements 8.4**
|
|
|
|
### Property 39: Mode dégradé
|
|
|
|
*For any* situation avec 3 circuit breakers actifs simultanément, le système doit passer en mode dégradé.
|
|
|
|
**Validates: Requirements 8.5**
|
|
|
|
## Error Handling
|
|
|
|
### Stratégie Générale
|
|
|
|
1. **Erreurs de chargement** : Logger et continuer avec les tâches suivantes
|
|
2. **Erreurs d'embedding** : Régénérer jusqu'à 3 tentatives
|
|
3. **Erreurs FAISS** : Reconstruire l'index si corrompu
|
|
4. **Erreurs mémoire** : Nettoyer les caches et alerter
|
|
5. **Erreurs de thread** : Forcer l'arrêt après timeout
|
|
|
|
### Gestion des Erreurs Critiques
|
|
|
|
```python
|
|
try:
|
|
# Opération critique
|
|
pass
|
|
except MemoryError:
|
|
memory_monitor.cleanup_caches()
|
|
logger.log_critical("memory_exhausted")
|
|
except FAISSError:
|
|
index_builder.rebuild_index()
|
|
logger.log_critical("faiss_corrupted")
|
|
except ThreadError:
|
|
force_shutdown_threads()
|
|
logger.log_critical("thread_deadlock")
|
|
```
|
|
|
|
## Testing Strategy
|
|
|
|
### Unit Tests
|
|
|
|
- Test de chargement des tâches individuelles
|
|
- Test de génération d'embeddings
|
|
- Test d'ajout à l'index FAISS
|
|
- Test de recherche de similarité
|
|
- Test d'arrêt des threads
|
|
- Test de libération mémoire
|
|
|
|
### Property-Based Tests
|
|
|
|
Nous utiliserons **Hypothesis** pour Python comme bibliothèque de property-based testing. Chaque test sera configuré pour exécuter au minimum 100 itérations.
|
|
|
|
Chaque property-based test doit être tagué avec un commentaire référençant explicitement la correctness property du design document au format : `**Feature: faiss-learning-fix, Property {number}: {property_text}**`
|
|
|
|
Les tests doivent couvrir :
|
|
- Génération aléatoire de tâches et vérification de l'indexation
|
|
- Génération aléatoire d'embeddings et validation
|
|
- Simulation d'arrêts à différents moments
|
|
- Simulation de charges mémoire variables
|
|
- Simulation d'appels répétitifs pour circuit breakers
|
|
|
|
### Integration Tests
|
|
|
|
- Test du flux complet : création tâche → indexation → suggestion
|
|
- Test de reconstruction d'index avec tâches existantes
|
|
- Test d'arrêt propre avec tous les composants actifs
|
|
- Test de diagnostic sur système réel
|
|
- Test de gestion mémoire sous charge
|
|
|
|
## Implementation Notes
|
|
|
|
### Ordre d'Implémentation
|
|
|
|
1. **FAISSIndexBuilder** : Fondation pour tout le reste
|
|
2. **Chargement au démarrage** : Correction immédiate du problème principal
|
|
3. **Arrêt propre** : Correction des processus zombies
|
|
4. **MemoryMonitor** : Protection contre les fuites
|
|
5. **CircuitBreaker** : Protection contre les boucles
|
|
6. **SystemDiagnostic** : Outil de débogage
|
|
|
|
### Points d'Attention
|
|
|
|
1. **Compatibilité** : Ne pas casser le code existant
|
|
2. **Performance** : Chargement rapide au démarrage (<10s)
|
|
3. **Robustesse** : Gérer les tâches corrompues
|
|
4. **Logs** : Tracer toutes les opérations critiques
|
|
5. **Tests** : Valider chaque property avant de continuer
|