diff --git a/frigate/data_processing/types.py b/frigate/data_processing/types.py index 2f9c99b52..3e29966c7 100644 --- a/frigate/data_processing/types.py +++ b/frigate/data_processing/types.py @@ -17,7 +17,9 @@ class DataProcessorMetrics: def __init__(self): self.image_embeddings_speed = mp.Value("d", 0.01) + self.image_embeddings_eps = mp.Value("d", 0.0) self.text_embeddings_speed = mp.Value("d", 0.01) + self.text_embeddings_eps = mp.Value("d", 0.0) self.face_rec_speed = mp.Value("d", 0.01) self.face_rec_fps = mp.Value("d", 0.0) self.alpr_speed = mp.Value("d", 0.01) diff --git a/frigate/embeddings/embeddings.py b/frigate/embeddings/embeddings.py index 667da0559..6eb060560 100644 --- a/frigate/embeddings/embeddings.py +++ b/frigate/embeddings/embeddings.py @@ -21,7 +21,7 @@ from frigate.data_processing.types import DataProcessorMetrics from frigate.db.sqlitevecq import SqliteVecQueueDatabase from frigate.models import Event from frigate.types import ModelStatusTypesEnum -from frigate.util.builtin import serialize +from frigate.util.builtin import EventsPerSecond, serialize from frigate.util.path import get_event_thumbnail_bytes from .onnx.jina_v1_embedding import JinaV1ImageEmbedding, JinaV1TextEmbedding @@ -75,6 +75,11 @@ class Embeddings: self.metrics = metrics self.requestor = InterProcessRequestor() + self.image_eps = EventsPerSecond() + self.image_eps.start() + self.text_eps = EventsPerSecond() + self.text_eps.start() + self.reindex_lock = threading.Lock() self.reindex_thread = None self.reindex_running = False @@ -120,6 +125,10 @@ class Embeddings: device="GPU" if config.semantic_search.model_size == "large" else "CPU", ) + def update_stats(self) -> None: + self.metrics.image_embeddings_eps = self.image_eps.eps() + self.metrics.text_embeddings_eps = self.text_eps.eps() + def get_model_definitions(self): # Version-specific models if self.config.semantic_search.model == SemanticSearchModelEnum.jinav2: @@ -178,6 +187,7 @@ class Embeddings: self.metrics.image_embeddings_speed.value = ( self.metrics.image_embeddings_speed.value * 9 + duration ) / 10 + self.image_eps.update() return embedding @@ -199,6 +209,7 @@ class Embeddings: for i in range(len(ids)): items.append(ids[i]) items.append(serialize(embeddings[i])) + self.image_eps.update() self.db.execute_sql( """ @@ -234,6 +245,7 @@ class Embeddings: self.metrics.text_embeddings_speed.value = ( self.metrics.text_embeddings_speed.value * 9 + duration ) / 10 + self.text_eps.update() return embedding @@ -254,6 +266,7 @@ class Embeddings: for i in range(len(ids)): items.append(ids[i]) items.append(serialize(embeddings[i])) + self.text_eps.update() self.db.execute_sql( """ diff --git a/frigate/embeddings/maintainer.py b/frigate/embeddings/maintainer.py index 85b0e6d54..7554b12c6 100644 --- a/frigate/embeddings/maintainer.py +++ b/frigate/embeddings/maintainer.py @@ -236,6 +236,7 @@ class EmbeddingMaintainer(threading.Thread): return camera_config = self.config.cameras[camera] + self.embeddings.update_stats() # no need to process updated objects if face recognition, lpr, genai are disabled if not camera_config.genai.enabled and len(self.realtime_processors) == 0: diff --git a/frigate/stats/util.py b/frigate/stats/util.py index cb7ed75fd..d8dd16504 100644 --- a/frigate/stats/util.py +++ b/frigate/stats/util.py @@ -295,9 +295,15 @@ def stats_snapshot( "image_embedding_speed": round( embeddings_metrics.image_embeddings_speed.value * 1000, 2 ), + "image_embedding": round( + embeddings_metrics.image_embeddings_eps.value, 2 + ), "text_embedding_speed": round( embeddings_metrics.text_embeddings_speed.value * 1000, 2 ), + "text_embedding": round( + embeddings_metrics.text_embeddings_eps.value, 2 + ), } )