fix(ml): skip videos in tag_and_embed and backfill
WD14 and SigLIP are image-only. The current backfill enqueues every ImageRecord row, and tag_and_embed retries 3 times (~3 min) on each video before giving up, blocking the serialized ml queue. Worse, videos never get a prediction row, so every subsequent backfill re-enqueues them. - tag_and_embed: early return 'unsupported_format' for video extensions, no retry. - backfill: filter the outerjoin query to exclude video extensions via VIDEO_EXTS from app.utils.image_importer. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+12
-1
@@ -5,7 +5,7 @@ import os
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from sqlalchemy import and_, func
|
from sqlalchemy import and_, func, or_
|
||||||
from sqlalchemy.dialects.postgresql import insert as pg_insert
|
from sqlalchemy.dialects.postgresql import insert as pg_insert
|
||||||
|
|
||||||
from app.celery_app import celery
|
from app.celery_app import celery
|
||||||
@@ -47,6 +47,11 @@ def tag_and_embed(self, image_id: int):
|
|||||||
log.warning(f"tag_and_embed: file missing at {image.filepath}")
|
log.warning(f"tag_and_embed: file missing at {image.filepath}")
|
||||||
return {'status': 'file_missing'}
|
return {'status': 'file_missing'}
|
||||||
|
|
||||||
|
# WD14 + SigLIP are image-only; videos bypass inference entirely.
|
||||||
|
from app.utils.image_importer import VIDEO_EXTS
|
||||||
|
if image.filepath.lower().endswith(VIDEO_EXTS):
|
||||||
|
return {'status': 'unsupported_format'}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
t0 = time.time()
|
t0 = time.time()
|
||||||
raw = wd14.infer_filtered(image.filepath, min_any=WD14_STORE_FLOOR)
|
raw = wd14.infer_filtered(image.filepath, min_any=WD14_STORE_FLOOR)
|
||||||
@@ -102,6 +107,11 @@ def backfill(self, batch_size: int = 50, pause_seconds: float = 0.5):
|
|||||||
"""
|
"""
|
||||||
from app.ml.wd14 import MODEL_VERSION as WD14_VER
|
from app.ml.wd14 import MODEL_VERSION as WD14_VER
|
||||||
from app.ml.siglip import MODEL_VERSION as SIGLIP_VER
|
from app.ml.siglip import MODEL_VERSION as SIGLIP_VER
|
||||||
|
from app.utils.image_importer import VIDEO_EXTS
|
||||||
|
|
||||||
|
video_filter = ~or_(*[
|
||||||
|
func.lower(ImageRecord.filepath).like(f'%{ext}') for ext in VIDEO_EXTS
|
||||||
|
])
|
||||||
|
|
||||||
enqueued_total = 0
|
enqueued_total = 0
|
||||||
last_id = 0
|
last_id = 0
|
||||||
@@ -123,6 +133,7 @@ def backfill(self, batch_size: int = 50, pause_seconds: float = 0.5):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.filter(ImageRecord.id > last_id)
|
.filter(ImageRecord.id > last_id)
|
||||||
|
.filter(video_filter)
|
||||||
.filter(
|
.filter(
|
||||||
(ImageTagPrediction.image_id.is_(None))
|
(ImageTagPrediction.image_id.is_(None))
|
||||||
| (ImageEmbedding.image_id.is_(None))
|
| (ImageEmbedding.image_id.is_(None))
|
||||||
|
|||||||
Reference in New Issue
Block a user