Multimodel_Rag / app /rag /embedder.py
Dhrumil Parikh
deploy GeminiRAG
cdc55f4
Raw
History Blame Contribute Delete
1.91 kB
"""
Text embedding via fastembed (BAAI/bge-small-en-v1.5, runs fully locally).
The model is lazy-loaded into a module-level singleton on first call so the
ONNX Runtime graph is compiled once and reused for all subsequent requests.
No external API calls are made — embeddings are free and work offline.
embed_chunks() — batch-embeds a list of chunk dicts; logs token count and
latency to UsageLog so embedding cost is tracked alongside
Groq/Gemini calls.
embed_query() — single-vector embed for RAG query and RAGAS re-retrieval.
"""
import time
from app.observability.logging import get_logger, log_llm_call
log = get_logger()
_model_instance = None
def _get_model(model_name: str):
global _model_instance
if _model_instance is None:
from fastembed import TextEmbedding
log.info("embedding_model_load", model=model_name)
_model_instance = TextEmbedding(model_name)
return _model_instance
def embed_chunks(
chunks: list[dict],
user_id,
job_id,
settings,
db,
) -> list[list[float]]:
model = _get_model(settings.EMBEDDING_MODEL)
texts = [c["text"] for c in chunks]
start = time.time()
vectors = [v.tolist() for v in model.embed(texts)]
latency_ms = int((time.time() - start) * 1000)
log.info(
"embed_batch_done",
batch_size=len(texts),
latency_ms=latency_ms,
model=settings.EMBEDDING_MODEL,
)
log_llm_call(
user_id=user_id,
job_id=job_id,
endpoint="embed_chunks",
model=settings.EMBEDDING_MODEL,
prompt_tokens=len(" ".join(texts).split()),
completion_tokens=0,
latency_ms=latency_ms,
db=db,
)
return vectors
def embed_query(question: str, settings) -> list[float]:
model = _get_model(settings.EMBEDDING_MODEL)
return next(model.query_embed(question)).tolist()