Files
Effi/scripts/comfyui-memory-manager.py
T
Folzo f425294473 fix: ComfyUI memory manager - only consider recent history (last 5min)
- Fix bug where old history entries were counted as recent activity
- Added recent_threshold parameter (default 300s)
- is_recent_history() now checks timestamp of last history item
2026-04-12 12:37:18 +02:00

172 lines
6.3 KiB
Python

#!/usr/bin/env python3
# ComfyUI Memory Manager - Redémarre ComfyUI après inactivité
# Usage: python3 comfyui-memory-manager.py [--interval 60] [--timeout 600]
import requests
import time
import argparse
import logging
import subprocess
import sys
import signal
from datetime import datetime, timedelta
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
DEFAULT_INTERVAL = 60
DEFAULT_TIMEOUT = 600
DEFAULT_RECENT_THRESHOLD = 300
COMFYUI_URL = "http://localhost:8188"
CONTAINER_NAME = "comfyui"
class ComfyUIMemoryManager:
def __init__(self, interval=DEFAULT_INTERVAL, timeout=DEFAULT_TIMEOUT, recent_threshold=DEFAULT_RECENT_THRESHOLD):
self.interval = interval
self.timeout = timeout
self.recent_threshold = recent_threshold
self.last_activity = datetime.now()
self.running = True
signal.signal(signal.SIGINT, self.signal_handler)
signal.signal(signal.SIGTERM, self.signal_handler)
def signal_handler(self, signum, frame):
logger.info("Signal reçu, arrêt...")
self.running = False
sys.exit(0)
def get_stats(self):
try:
response = requests.get(f"{COMFYUI_URL}/system_stats", timeout=10)
if response.status_code == 200:
return response.json()
except:
return None
def get_vram_percent(self):
stats = self.get_stats()
if stats and "devices" in stats:
device = stats["devices"][0]
vram_total = device.get("vram_total", 0)
vram_free = device.get("vram_free", 0)
if vram_total > 0:
vram_used = vram_total - vram_free
return (vram_used / vram_total) * 100
return 0
def get_queue_status(self):
try:
response = requests.get(f"{COMFYUI_URL}/queue", timeout=10)
if response.status_code == 200:
data = response.json()
running = len(data.get("queue_running", []))
pending = len(data.get("queue_pending", []))
return running, pending
except:
pass
return 0, 0
def is_recent_history(self):
try:
response = requests.get(f"{COMFYUI_URL}/history?max_items=1", timeout=10)
if response.status_code == 200:
history = response.json()
if history:
last_item = list(history.values())[0]
prompt_time = last_item.get("prompt_time", 0)
if prompt_time:
last_run = datetime.fromtimestamp(prompt_time)
age = (datetime.now() - last_run).total_seconds()
if age < self.recent_threshold:
self.last_activity = last_run
return True
except:
pass
return False
def restart_container(self):
logger.info("🔄 Redémarrage du container ComfyUI...")
try:
subprocess.run(["docker", "restart", CONTAINER_NAME], check=True)
logger.info("✅ Container redémarré")
time.sleep(10)
return True
except Exception as e:
logger.error(f"❌ Erreur redémarrage: {e}")
return False
def run(self):
logger.info(f"🚀 ComfyUI Memory Manager démarré")
logger.info(f" Vérification: {self.interval}s | Timeout: {self.timeout}s | Recent: {self.recent_threshold}s")
while self.running:
try:
vram_percent = self.get_vram_percent()
running, pending = self.get_queue_status()
has_recent_history = self.is_recent_history()
idle_seconds = (datetime.now() - self.last_activity).total_seconds()
if running > 0 or pending > 0:
self.last_activity = datetime.now()
status = "active"
elif has_recent_history:
status = "recent"
else:
status = "idle"
logger.info(f"VRAM: {vram_percent:.1f}% | Queue: {running}r/{pending}p | Idle: {idle_seconds:.0f}s | Status: {status}")
if status == "idle" and vram_percent < 1 and idle_seconds >= self.timeout:
logger.info(f"⏰ Inactivité longue ({idle_seconds:.0f}s >= {self.timeout}s), VRAM libre")
stats = self.get_stats()
if stats:
ram_total = stats["system"]["ram_total"] / (1024**3)
ram_free = stats["system"]["ram_free"] / (1024**3)
ram_used = ram_total - ram_free
logger.info(f"📊 RAM: {ram_used:.1f}GB/{ram_total:.1f}GB")
if ram_used > 5:
logger.info("📊 RAM utilisée élevée, redémarrage pour libérer...")
self.restart_container()
else:
logger.info("📊 RAM déjà basse, pas de redémarrage nécessaire")
self.last_activity = datetime.now()
time.sleep(self.interval)
except Exception as e:
logger.error(f"Erreur: {e}")
time.sleep(self.interval)
logger.info("👋 Manager arrêté")
sys.exit(0)
def main():
parser = argparse.ArgumentParser(description="ComfyUI Memory Manager")
parser.add_argument("--interval", type=int, default=DEFAULT_INTERVAL)
parser.add_argument("--timeout", type=int, default=DEFAULT_TIMEOUT)
parser.add_argument("--recent", type=int, default=DEFAULT_RECENT_THRESHOLD)
parser.add_argument("--debug", action="store_true")
args = parser.parse_args()
if args.debug:
logging.getLogger().setLevel(logging.DEBUG)
manager = ComfyUIMemoryManager(
interval=args.interval,
timeout=args.timeout,
recent_threshold=args.recent
)
manager.run()
if __name__ == "__main__":
main()