mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-10-10 16:52:47 +03:00
Support using GenAI for embeddings / semantic search (#22323)
* Support GenAI for embeddings * Add embed API support * Add support for embedding via genai * Basic docs * undo * Fix sending images * Don't require download check * Set model * Handle emb correctly * Clarification * Cleanup * Cleanup
This commit is contained in:
@@ -28,6 +28,7 @@ from frigate.types import ModelStatusTypesEnum
|
||||
from frigate.util.builtin import EventsPerSecond, InferenceSpeed, serialize
|
||||
from frigate.util.file import get_event_thumbnail_bytes
|
||||
|
||||
from .genai_embedding import GenAIEmbedding
|
||||
from .onnx.jina_v1_embedding import JinaV1ImageEmbedding, JinaV1TextEmbedding
|
||||
from .onnx.jina_v2_embedding import JinaV2Embedding
|
||||
|
||||
@@ -73,6 +74,7 @@ class Embeddings:
|
||||
config: FrigateConfig,
|
||||
db: SqliteVecQueueDatabase,
|
||||
metrics: DataProcessorMetrics,
|
||||
genai_manager=None,
|
||||
) -> None:
|
||||
self.config = config
|
||||
self.db = db
|
||||
@@ -104,7 +106,27 @@ class Embeddings:
|
||||
},
|
||||
)
|
||||
|
||||
if self.config.semantic_search.model == SemanticSearchModelEnum.jinav2:
|
||||
model_cfg = self.config.semantic_search.model
|
||||
|
||||
if not isinstance(model_cfg, SemanticSearchModelEnum):
|
||||
# GenAI provider
|
||||
embeddings_client = (
|
||||
genai_manager.embeddings_client if genai_manager else None
|
||||
)
|
||||
if not embeddings_client:
|
||||
raise ValueError(
|
||||
f"semantic_search.model is '{model_cfg}' (GenAI provider) but "
|
||||
"no embeddings client is configured. Ensure the GenAI provider "
|
||||
"has 'embeddings' in its roles."
|
||||
)
|
||||
self.embedding = GenAIEmbedding(embeddings_client)
|
||||
self.text_embedding = lambda input_data: self.embedding(
|
||||
input_data, embedding_type="text"
|
||||
)
|
||||
self.vision_embedding = lambda input_data: self.embedding(
|
||||
input_data, embedding_type="vision"
|
||||
)
|
||||
elif model_cfg == SemanticSearchModelEnum.jinav2:
|
||||
# Single JinaV2Embedding instance for both text and vision
|
||||
self.embedding = JinaV2Embedding(
|
||||
model_size=self.config.semantic_search.model_size,
|
||||
@@ -118,7 +140,8 @@ class Embeddings:
|
||||
self.vision_embedding = lambda input_data: self.embedding(
|
||||
input_data, embedding_type="vision"
|
||||
)
|
||||
else: # Default to jinav1
|
||||
else:
|
||||
# Default to jinav1
|
||||
self.text_embedding = JinaV1TextEmbedding(
|
||||
model_size=config.semantic_search.model_size,
|
||||
requestor=self.requestor,
|
||||
@@ -136,8 +159,11 @@ class Embeddings:
|
||||
self.metrics.text_embeddings_eps.value = self.text_eps.eps()
|
||||
|
||||
def get_model_definitions(self):
|
||||
# Version-specific models
|
||||
if self.config.semantic_search.model == SemanticSearchModelEnum.jinav2:
|
||||
model_cfg = self.config.semantic_search.model
|
||||
if not isinstance(model_cfg, SemanticSearchModelEnum):
|
||||
# GenAI provider: no ONNX models to download
|
||||
models = []
|
||||
elif model_cfg == SemanticSearchModelEnum.jinav2:
|
||||
models = [
|
||||
"jinaai/jina-clip-v2-tokenizer",
|
||||
"jinaai/jina-clip-v2-model_fp16.onnx"
|
||||
@@ -312,11 +338,12 @@ class Embeddings:
|
||||
# Get total count of events to process
|
||||
total_events = Event.select().count()
|
||||
|
||||
batch_size = (
|
||||
4
|
||||
if self.config.semantic_search.model == SemanticSearchModelEnum.jinav2
|
||||
else 32
|
||||
)
|
||||
if not isinstance(self.config.semantic_search.model, SemanticSearchModelEnum):
|
||||
batch_size = 1
|
||||
elif self.config.semantic_search.model == SemanticSearchModelEnum.jinav2:
|
||||
batch_size = 4
|
||||
else:
|
||||
batch_size = 32
|
||||
current_page = 1
|
||||
|
||||
totals = {
|
||||
|
||||
Reference in New Issue
Block a user