Files
Geniusia_v2/rebuild_faiss_simple.py
2026-03-05 00:20:25 +01:00

184 lines
5.9 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Script simplifié pour reconstruire l'index FAISS sans dépendances lourdes.
IMPORTANT: Utiliser le Python du venv !
Usage: geniusia2/venv/bin/python rebuild_faiss_simple.py
"""
import pickle
import json
import numpy as np
from pathlib import Path
def rebuild_index():
"""Reconstruit l'index FAISS à partir des tâches existantes."""
print("="*60)
print("🔨 RECONSTRUCTION DE L'INDEX FAISS")
print("="*60)
try:
import faiss
except ImportError:
print("\n❌ FAISS n'est pas installé")
print(" Installation: pip install faiss-cpu")
return
profiles_dir = Path("geniusia2/data/user_profiles")
task_dirs = [d for d in profiles_dir.iterdir() if d.is_dir() and d.name.startswith("task_")]
print(f"\n📁 Nombre de tâches trouvées: {len(task_dirs)}")
# Collecter tous les embeddings et métadonnées
all_embeddings = []
all_metadata = []
total_actions = 0
# Parcourir toutes les tâches
for i, task_dir in enumerate(task_dirs, 1):
signatures_file = task_dir / "signatures.pkl"
metadata_file = task_dir / "metadata.json"
if not signatures_file.exists():
continue
# Charger les métadonnées
task_name = "Unknown"
if metadata_file.exists():
with open(metadata_file, 'r') as f:
metadata = json.load(f)
task_name = metadata.get('task_name', 'Unknown')
# Charger les signatures
with open(signatures_file, 'rb') as f:
signatures = pickle.load(f)
total_actions += len(signatures)
# Ajouter les embeddings
for j, signature in enumerate(signatures):
embedding = signature.get('embedding')
if embedding is not None:
# Convertir en numpy array si nécessaire
if not isinstance(embedding, np.ndarray):
embedding = np.array(embedding)
# S'assurer que c'est float32
embedding = embedding.astype(np.float32)
all_embeddings.append(embedding)
# Créer les métadonnées
meta = {
"task_id": task_dir.name,
"task_name": task_name,
"action_index": j,
"action_type": signature.get('action_type', 'unknown'),
"element_type": signature.get('element_type', ''),
"window": signature.get('window', ''),
"position": signature.get('position', None)
}
all_metadata.append(meta)
if i % 10 == 0:
print(f" Traité {i}/{len(task_dirs)} tâches...")
print(f"\n✅ Traitement terminé:")
print(f" - Tâches traitées: {len(task_dirs)}")
print(f" - Actions totales: {total_actions}")
print(f" - Embeddings collectés: {len(all_embeddings)}")
if len(all_embeddings) == 0:
print("\n❌ Aucun embedding trouvé")
return
# Créer l'index FAISS
print(f"\n🔨 Création de l'index FAISS...")
# Convertir en matrice numpy
embeddings_matrix = np.vstack(all_embeddings)
dimension = embeddings_matrix.shape[1]
print(f" Dimension des embeddings: {dimension}")
print(f" Nombre d'embeddings: {embeddings_matrix.shape[0]}")
# Créer l'index (IndexFlatL2 pour recherche exacte)
index = faiss.IndexFlatL2(dimension)
# Ajouter les embeddings
index.add(embeddings_matrix)
print(f" Index créé avec {index.ntotal} vecteurs")
# Sauvegarder l'index
faiss_dir = Path("geniusia2/data/faiss_index")
faiss_dir.mkdir(parents=True, exist_ok=True)
index_file = faiss_dir / "embeddings.index"
metadata_file = faiss_dir / "metadata.pkl"
print(f"\n💾 Sauvegarde de l'index...")
# Sauvegarder l'index FAISS
faiss.write_index(index, str(index_file))
# Sauvegarder les métadonnées
with open(metadata_file, 'wb') as f:
pickle.dump(all_metadata, f)
# Vérifier la sauvegarde
if index_file.exists() and metadata_file.exists():
index_size = index_file.stat().st_size
meta_size = metadata_file.stat().st_size
print(f"\n✅ Index FAISS créé avec succès!")
print(f" - embeddings.index: {index_size:,} bytes ({index_size/1024:.1f} KB)")
print(f" - metadata.pkl: {meta_size:,} bytes ({meta_size/1024:.1f} KB)")
# Tester la recherche
print(f"\n🔍 Test de recherche...")
# Prendre le premier embedding pour tester
test_embedding = embeddings_matrix[0:1]
# Rechercher les 3 plus proches
distances, indices = index.search(test_embedding, 3)
print(f" Résultats de recherche:")
for i, (dist, idx) in enumerate(zip(distances[0], indices[0])):
meta = all_metadata[idx]
similarity = 1 / (1 + dist) # Convertir distance en similarité
print(f" {i+1}. Similarité: {similarity:.3f} | {meta.get('task_name', 'N/A')} - {meta.get('action_type', 'N/A')}")
else:
print(f"\n❌ Erreur: Index non créé")
def main():
"""Fonction principale."""
print("\n🔧 RECONSTRUCTION DE L'INDEX FAISS\n")
try:
rebuild_index()
print("\n" + "="*60)
print("✅ RECONSTRUCTION TERMINÉE")
print("="*60)
print("\n💡 L'index FAISS est maintenant disponible pour:")
print(" - Recherche de similarité")
print(" - Suggestions d'actions")
print(" - Rejeu intelligent")
except Exception as e:
print(f"\n❌ Erreur: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
main()