atypique-api / core /meta_meta_optimizer.py
RDS777's picture
Backend v3.0 complet
8e3a425
Raw
History Blame Contribute Delete
6.51 kB
# core/meta_meta_optimizer.py
import math
import shutil
import logging
import importlib.util
from pathlib import Path
from typing import Dict, Any
log = logging.getLogger("vortex.meta_meta")
# Fonctions de benchmark (pour Γ©valuer FellowOptimizer)
BENCH_FUNCS = [
("sphere", lambda p: sum(x**2 for x in p), [(-5.12, 5.12)] * 5, 0.0),
("rastrigin", lambda p: 10 * len(p) + sum(xi**2 - 10 * math.cos(2 * math.pi * xi) for xi in p),
[(-5.12, 5.12)] * 5, 0.0),
("rosenbrock", lambda p: sum(100 * (p[i + 1] - p[i]**2)**2 + (1 - p[i])**2 for i in range(len(p) - 1)),
[(-2.0, 2.0)] * 5, 0.0),
]
class MetaMetaOptimizer:
def __init__(self, kernel, llm_engine, current_optimizer_path: str):
self.kernel = kernel
self.llm = llm_engine
self.path = Path(current_optimizer_path)
self.backup = self.path.with_suffix(".py.bak")
self.proof_system = None # sera injectΓ© plus tard
self.status = {
"last_improvement": None,
"regression_count": 0,
"best_score": float('inf'),
"current_score": float('inf'),
"benchmark_results": {}
}
# ─── Injection du systΓ¨me de preuves ────────────────────────────────
def set_proof_system(self, proof_system):
"""Lie le ProofSystem pour enregistrer les amΓ©liorations."""
self.proof_system = proof_system
# Charger le meilleur score historique
if self.proof_system and self.proof_system.proofs:
best = min(p.get("after", float('inf')) for p in self.proof_system.proofs)
self.status["best_score"] = best
# ─── Benchmark ────────────────────────────────────────────────────────
def _bench_module(self, mod) -> float:
"""Γ‰value un module FellowOptimizer sur les 3 fonctions de benchmark."""
try:
Optimizer = getattr(mod, "FellowOptimizer")
except AttributeError:
return float('inf')
total_score = 0.0
results = {}
for name, func, bounds, opt_v in BENCH_FUNCS:
try:
optimizer = Optimizer(func, bounds, max_evals=100)
best, _ = optimizer.optimize()
error = abs(func(best) - opt_v)
error = min(error, 1000.0)
score = 1.0 - math.tanh(error / 50.0)
total_score += score
results[name] = round(score, 3)
except Exception as e:
log.error(f"[META-META] Erreur benchmark {name}: {e}")
results[name] = 0.0
total_score += 0.0
avg_score = total_score / len(BENCH_FUNCS) if BENCH_FUNCS else 0.0
self.status["benchmark_results"] = results
return round(avg_score, 3)
def _bench_file(self, filepath: Path) -> float:
"""Charge un fichier Python et le benchmark."""
try:
spec = importlib.util.spec_from_file_location("_optimizer_bench", filepath)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return self._bench_module(mod)
except Exception as e:
log.error(f"[META-META] Erreur chargement {filepath}: {e}")
return float('inf')
# ─── Cycle d'amΓ©lioration ────────────────────────────────────────────
async def monitor_and_improve(self) -> Dict[str, Any]:
"""Mesure la performance de l'optimiseur actuel et l'amΓ©liore si possible."""
log.info("[META-META] DΓ©marrage du benchmark...")
# 1. Benchmark du code actuel
current_score = self._bench_file(self.path)
self.status["current_score"] = current_score
log.info(f"[META-META] Score actuel : {current_score:.4f}")
# 2. Comparer avec le meilleur score historique
best_score = self.status.get("best_score", float('inf'))
result = {
"action": "none",
"score": current_score,
"improvement": 0.0
}
if self.proof_system is not None:
version = f"v{len(self.proof_system.proofs) + 1}"
before = best_score if best_score != float('inf') else current_score
after = current_score
if after < before - 0.005: # AmΓ©lioration > 0.5%
self.proof_system.register_improvement(
version=version,
before=before,
after=after,
benchmark="FellowOptimizer (Sphere/Rastrigin/Rosenbrock)"
)
self.status["best_score"] = after
self.status["last_improvement"] = version
result["action"] = "improved"
result["improvement"] = before - after
log.info(f"[META-META] βœ… AmΓ©lioration ! {before:.4f} β†’ {after:.4f}")
else:
# Enregistrement pour suivi
self.proof_system.register_improvement(
version=version,
before=before,
after=after,
benchmark="FellowOptimizer (monitoring)"
)
if after > before:
self.status["regression_count"] += 1
result["action"] = "regression"
result["improvement"] = after - before
log.warning(f"[META-META] ⚠️ RΓ©gression : {before:.4f} β†’ {after:.4f}")
else:
result["action"] = "stable"
log.info(f"[META-META] Stable : {before:.4f} β†’ {after:.4f}")
self.status["current_score"] = after
return result
def rollback(self) -> bool:
"""Restaure le fichier optimiseur depuis la sauvegarde."""
if not self.backup.exists():
log.warning("[META-META] Aucun backup disponible.")
return False
try:
shutil.copy(self.backup, self.path)
log.info("[META-META] Rollback effectué avec succès.")
return True
except Exception as e:
log.error(f"[META-META] Rollback Γ©chouΓ© : {e}")
return False
def get_status(self) -> Dict:
return self.status