VideoBackgroundReplacer / tools /startup_selfcheck.py
MogensR's picture
Update tools/startup_selfcheck.py
5e38374
raw
history blame
3.2 kB
#!/usr/bin/env python3
# tools/startup_selfcheck.py
"""
Quiet Startup Self-Check for Hugging Face Space
- Verifies SAM2 + MatAnyone can load and run a tiny inference
- Defaults to ASYNC so UI launches immediately; logs results
- Switch to SYNC by setting env SELF_CHECK_MODE=sync
"""
import logging
import os
import threading
import numpy as np
import torch
# Keep imports lazy so a busted loader doesn't break the Space
def _safe_imports():
from models.loaders.sam2_loader import SAM2Loader
from models.loaders.matanyone_loader import MatAnyoneLoader
return SAM2Loader, MatAnyoneLoader
log = logging.getLogger("selfcheck")
if not log.handlers:
logging.basicConfig(level=logging.INFO)
def run_selfcheck() -> None:
"""Do the actual check; log results. Non-throwing."""
try:
SAM2Loader, MatAnyoneLoader = _safe_imports()
except Exception as e:
log.error(f"❌ Self-check import failure: {e}", exc_info=True)
return
try:
# tiny dummy frame + mask
img = np.zeros((64, 64, 3), dtype=np.uint8)
mask = np.ones((64, 64), dtype=np.float32)
# --- SAM2 ---
try:
sam_loader = SAM2Loader(device="cuda" if torch.cuda.is_available() else "cpu")
sam = sam_loader.load("tiny")
if sam:
sam.set_image(img)
out = sam.predict(point_coords=None, point_labels=None)
m = out["masks"]
log.info(f"βœ… SAM2 OK β€” masks {m.shape} {m.dtype} [{m.min():.3f},{m.max():.3f}]")
else:
log.error("❌ SAM2 failed to load (adapter is None)")
except Exception as e:
log.error(f"❌ SAM2 self-check error: {e}", exc_info=True)
# --- MatAnyone ---
try:
mat_loader = MatAnyoneLoader(device="cuda" if torch.cuda.is_available() else "cpu")
session = mat_loader.load()
if session:
alpha = session(img, mask) # first frame needs a mask (fallback ok)
log.info(f"βœ… MatAnyone OK β€” alpha {alpha.shape} {alpha.dtype} [{alpha.min():.3f},{alpha.max():.3f}]")
else:
log.error("❌ MatAnyone failed to load (session is None)")
except Exception as e:
log.error(f"❌ MatAnyone self-check error: {e}", exc_info=True)
except Exception as e:
log.error(f"❌ Self-check unexpected error: {e}", exc_info=True)
def schedule_startup_selfcheck(mode: str = "async") -> None:
"""
mode: "async" (default) β†’ run in a daemon thread; UI doesn't wait
"sync" β†’ block until check completes (slower startup)
"""
mode = (mode or "async").lower()
if mode == "sync":
log.info("πŸ”Ž Running model self-check (sync)…")
run_selfcheck()
return
def _worker():
try:
log.info("πŸ”Ž Running model self-check (async)…")
run_selfcheck()
except Exception:
# Make absolutely sure this never crashes the app
log.exception("Self-check thread crashed")
t = threading.Thread(target=_worker, name="startup-selfcheck", daemon=True)
t.start()