Files
mule-image/backend/app/services/vision/onnx_backend.py
dtoro 94c07b1d0d feat: upgrade to SigLIP2 ViT-B/16 for semantic search
Replace OpenCLIP ViT-B/32 (512-d, ~78% recall) with SigLIP2 ViT-B/16
(768-d, ~84% recall) as the default embedding model for significantly
better image-text retrieval quality.

- New SigLIP2Embedder class with 384px input and SigLIP normalization
- ONNX export pipeline for SigLIP2 visual + textual encoders
- Migration 0010: resize embeddings.vector from 512 to 768 dimensions
- Config-driven model selection: "siglip2_vitb16" (default) or
  "openclip_vitb32" (legacy) — both models can coexist
- Content classifier follows the configured embedder family
- Existing embeddings cleared on migration; vision backfill regenerates

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 22:09:16 +02:00

47 lines
1.7 KiB
Python

"""
ONNX Runtime backend — default CPU inference for all vision models.
Each create_* method returns a concrete implementation of the
corresponding ABC from base.py. Models are loaded from ONNX files
under settings.vision.models_dir, downloaded on first boot by
bootstrap_models.py.
"""
import logging
from app.config import VisionSettings
from app.services.vision.base import Embedder, OCREngine, ObjectDetector, FaceProcessor, ContentClassifier
logger = logging.getLogger(__name__)
class ONNXBackend:
"""Factory for ONNX Runtime-based vision model instances."""
def __init__(self, vision_settings: VisionSettings):
self._settings = vision_settings
def create_embedder(self) -> Embedder:
model_name = self._settings.embedder.name
if model_name.startswith("siglip2"):
from app.services.vision.embed import SigLIP2Embedder
return SigLIP2Embedder(self._settings)
else:
from app.services.vision.embed import OpenCLIPEmbedder
return OpenCLIPEmbedder(self._settings)
def create_ocr(self) -> OCREngine:
from app.services.vision.ocr import RapidOCREngine
return RapidOCREngine(self._settings)
def create_detector(self) -> ObjectDetector:
from app.services.vision.detect import YOLOv8Detector
return YOLOv8Detector(self._settings)
def create_face_processor(self) -> FaceProcessor:
from app.services.vision.insightface_processor import InsightFaceProcessor
return InsightFaceProcessor(self._settings)
def create_classifier(self) -> ContentClassifier:
from app.services.vision.classify import CLIPContentClassifier
return CLIPContentClassifier(self._settings)