226 lines
6.9 KiB
Python
Executable File
226 lines
6.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Outil de debugging pour le système d'embeddings.
|
|
|
|
Permet d'inspecter:
|
|
- Embeddings d'une image
|
|
- Résultats de recherche FAISS
|
|
- Historique de fine-tuning
|
|
- Statistiques du cache
|
|
"""
|
|
|
|
import sys
|
|
import json
|
|
from pathlib import Path
|
|
from PIL import Image
|
|
import numpy as np
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
|
|
from geniusia2.core.embedders import (
|
|
EmbeddingManager,
|
|
FAISSIndex,
|
|
LightweightFineTuner
|
|
)
|
|
|
|
|
|
def debug_embedding(image_path: str):
|
|
"""Debug l'embedding d'une image."""
|
|
print("\n" + "="*70)
|
|
print(f"DEBUG EMBEDDING: {image_path}")
|
|
print("="*70)
|
|
|
|
# Load image
|
|
try:
|
|
img = Image.open(image_path)
|
|
print(f"\n✓ Image chargée: {img.size} {img.mode}")
|
|
except Exception as e:
|
|
print(f"\n❌ Erreur de chargement: {e}")
|
|
return 1
|
|
|
|
# Generate embedding
|
|
print("\nGénération de l'embedding...")
|
|
manager = EmbeddingManager(model_name="clip")
|
|
|
|
import time
|
|
start = time.time()
|
|
embedding = manager.embed(img)
|
|
duration = time.time() - start
|
|
|
|
print(f"✓ Embedding généré en {duration*1000:.1f}ms")
|
|
print(f"\nDétails de l'embedding:")
|
|
print(f" - Dimension: {embedding.shape[0]}")
|
|
print(f" - Norme L2: {np.linalg.norm(embedding):.6f}")
|
|
print(f" - Min: {embedding.min():.6f}")
|
|
print(f" - Max: {embedding.max():.6f}")
|
|
print(f" - Mean: {embedding.mean():.6f}")
|
|
print(f" - Std: {embedding.std():.6f}")
|
|
|
|
# Show first/last values
|
|
print(f"\nPremières valeurs: {embedding[:5]}")
|
|
print(f"Dernières valeurs: {embedding[-5:]}")
|
|
|
|
# Cache stats
|
|
stats = manager.get_stats()
|
|
print(f"\nStatistiques du cache:")
|
|
print(f" - Hit rate: {stats['cache_hit_rate']:.1%}")
|
|
print(f" - Size: {stats['cache_size']}/{stats['cache_capacity']}")
|
|
print(f" - Hits: {stats['cache_hits']}")
|
|
print(f" - Misses: {stats['cache_misses']}")
|
|
|
|
return 0
|
|
|
|
|
|
def debug_faiss_search(image_path: str, index_path: str = "data/workflow_embeddings"):
|
|
"""Debug la recherche FAISS."""
|
|
print("\n" + "="*70)
|
|
print(f"DEBUG FAISS SEARCH")
|
|
print("="*70)
|
|
|
|
# Load image
|
|
try:
|
|
img = Image.open(image_path)
|
|
print(f"\n✓ Image chargée: {img.size}")
|
|
except Exception as e:
|
|
print(f"\n❌ Erreur de chargement: {e}")
|
|
return 1
|
|
|
|
# Load index
|
|
print(f"\nChargement de l'index: {index_path}")
|
|
try:
|
|
manager = EmbeddingManager(model_name="clip")
|
|
index = FAISSIndex(manager.get_dimension())
|
|
index.load(index_path)
|
|
print(f"✓ Index chargé: {len(index)} embeddings")
|
|
except FileNotFoundError:
|
|
print(f"❌ Index non trouvé: {index_path}")
|
|
print(" Créez d'abord un index avec des workflows")
|
|
return 1
|
|
except Exception as e:
|
|
print(f"❌ Erreur de chargement: {e}")
|
|
return 1
|
|
|
|
# Generate embedding
|
|
print("\nGénération de l'embedding...")
|
|
embedding = manager.embed(img)
|
|
print(f"✓ Embedding généré")
|
|
|
|
# Search
|
|
print("\nRecherche des 5 plus similaires...")
|
|
results = index.search(embedding, k=5)
|
|
|
|
if not results:
|
|
print("❌ Aucun résultat trouvé")
|
|
return 1
|
|
|
|
print(f"\n✓ Trouvé {len(results)} résultats:\n")
|
|
|
|
for i, result in enumerate(results, 1):
|
|
print(f"{i}. Similarity: {result['similarity']:.4f}")
|
|
print(f" Distance: {result['distance']:.4f}")
|
|
print(f" Metadata: {json.dumps(result['metadata'], indent=6)}")
|
|
print()
|
|
|
|
return 0
|
|
|
|
|
|
def debug_fine_tuning(checkpoint_path: str = "data/fine_tuning/checkpoint.pkl"):
|
|
"""Debug l'historique de fine-tuning."""
|
|
print("\n" + "="*70)
|
|
print(f"DEBUG FINE-TUNING")
|
|
print("="*70)
|
|
|
|
# Load checkpoint
|
|
print(f"\nChargement du checkpoint: {checkpoint_path}")
|
|
|
|
manager = EmbeddingManager(model_name="clip")
|
|
fine_tuner = LightweightFineTuner(embedder=manager.embedder)
|
|
|
|
if not fine_tuner.load_checkpoint("checkpoint"):
|
|
print(f"❌ Checkpoint non trouvé")
|
|
print(" Le fine-tuning n'a pas encore été exécuté")
|
|
return 1
|
|
|
|
stats = fine_tuner.get_stats()
|
|
|
|
print(f"\n✓ Checkpoint chargé")
|
|
print(f"\nStatistiques:")
|
|
print(f" - Trainings effectués: {stats['training_count']}")
|
|
print(f" - Exemples positifs: {stats['positive_examples']}")
|
|
print(f" - Exemples négatifs: {stats['negative_examples']}")
|
|
print(f" - Total exemples: {stats['total_examples']}")
|
|
print(f" - En cours: {stats['is_training']}")
|
|
|
|
if stats['last_training_time'] > 0:
|
|
import time
|
|
elapsed = time.time() - stats['last_training_time']
|
|
print(f" - Dernier training: il y a {elapsed/60:.1f} minutes")
|
|
|
|
# Show metrics history
|
|
if stats['metrics_history']:
|
|
print(f"\nHistorique des trainings ({len(stats['metrics_history'])}):\n")
|
|
|
|
for metrics in stats['metrics_history'][-5:]: # Last 5
|
|
print(f"Training #{metrics.get('training_number', '?')}:")
|
|
print(f" - Loss: {metrics.get('loss', 'N/A'):.4f}")
|
|
print(f" - Durée: {metrics.get('duration_seconds', 0):.1f}s")
|
|
print(f" - Exemples: +{metrics.get('positive_count', 0)}, "
|
|
f"-{metrics.get('negative_count', 0)}")
|
|
print(f" - Timestamp: {metrics.get('timestamp', 0):.0f}")
|
|
print()
|
|
else:
|
|
print("\n⚠️ Aucun historique de training")
|
|
|
|
return 0
|
|
|
|
|
|
def main():
|
|
"""Main function."""
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(
|
|
description='Outil de debugging pour les embeddings'
|
|
)
|
|
|
|
subparsers = parser.add_subparsers(dest='command', help='Commande à exécuter')
|
|
|
|
# Embedding command
|
|
embed_parser = subparsers.add_parser('embedding', help='Debug un embedding')
|
|
embed_parser.add_argument('image', help='Chemin vers l\'image')
|
|
|
|
# Search command
|
|
search_parser = subparsers.add_parser('search', help='Debug une recherche FAISS')
|
|
search_parser.add_argument('image', help='Chemin vers l\'image')
|
|
search_parser.add_argument(
|
|
'--index',
|
|
default='data/workflow_embeddings',
|
|
help='Chemin vers l\'index FAISS'
|
|
)
|
|
|
|
# Fine-tuning command
|
|
ft_parser = subparsers.add_parser('finetuning', help='Debug le fine-tuning')
|
|
ft_parser.add_argument(
|
|
'--checkpoint',
|
|
default='data/fine_tuning/checkpoint.pkl',
|
|
help='Chemin vers le checkpoint'
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
if not args.command:
|
|
parser.print_help()
|
|
return 1
|
|
|
|
if args.command == 'embedding':
|
|
return debug_embedding(args.image)
|
|
elif args.command == 'search':
|
|
return debug_faiss_search(args.image, args.index)
|
|
elif args.command == 'finetuning':
|
|
return debug_fine_tuning(args.checkpoint)
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|