Drops face recognition, OCR, object detection, and semantic embeddings. The sole remaining vision task is a CLIP-based binary classifier (photography vs other); photos in "other" get needs_review=true so screenshots, documents, memes and scans can be triaged from a new filter pill in the UI. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
52 lines
1.6 KiB
Python
52 lines
1.6 KiB
Python
"""
|
|
Ensure the OpenCLIP ViT-B/32 visual encoder is present on worker boot.
|
|
Exported via export_models.py if missing.
|
|
"""
|
|
import logging
|
|
from pathlib import Path
|
|
|
|
from app.config import settings
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
REQUIRED = [
|
|
("embed/visual.onnx", "OpenCLIP ViT-B/32 visual encoder"),
|
|
]
|
|
|
|
|
|
def bootstrap(models_dir: str | None = None):
|
|
base = Path(models_dir or settings.vision.models_dir)
|
|
base.mkdir(parents=True, exist_ok=True)
|
|
|
|
missing = [(rel, desc) for rel, desc in REQUIRED if not (base / rel).exists()]
|
|
if missing:
|
|
logger.warning("Missing %d model file(s); attempting automatic export", len(missing))
|
|
try:
|
|
from app.services.vision import export_models
|
|
export_models.export_openclip_visual(base)
|
|
except Exception as e:
|
|
logger.error(
|
|
"Export failed: %s. Run `python -m app.services.vision.export_models "
|
|
"--models-dir %s` manually to retry.",
|
|
e, base,
|
|
)
|
|
|
|
still_missing = [(r, d) for r, d in REQUIRED if not (base / r).exists()]
|
|
if still_missing:
|
|
for rel, desc in still_missing:
|
|
logger.error(" still missing: %s — %s", base / rel, desc)
|
|
else:
|
|
logger.info("All model files present in %s", base)
|
|
|
|
try:
|
|
import redis as _redis
|
|
_redis.from_url(settings.redis_url).set("mulita:vision:ready", "1")
|
|
logger.info("Set mulita:vision:ready in Redis")
|
|
except Exception as e:
|
|
logger.warning("Could not set vision readiness flag in Redis: %s", e)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
logging.basicConfig(level=logging.INFO)
|
|
bootstrap()
|