knowledge-engine / services /archive_inference.py
m97j's picture
feat: authenticated archive inference with bounded CPU execution
f16b727 verified
Raw History Blame Contribute Delete
2.68 kB
"""Stateless inference. This service does not read or write the demo corpus."""
import math
from api.schemas.archive import Embedding, EmbeddingsResponse, TranslationResponse
class ProviderUnavailable(Exception):
pass
class ArchiveInferenceService:
def __init__(self, embedder, translator):
self.embedder = embedder
self.translator = translator
def embed(self, texts, requested_model=None):
model_id = getattr(self.embedder, "compatibility_id", self.embedder.model_name)
if requested_model not in (None, self.embedder.model_name, model_id):
raise ValueError("Requested model is not configured")
output = self.embedder.encode_documents(texts, batch_size=1, max_length=512)
dense_rows = output["dense_vecs"]
sparse_rows = output["lexical_weights"]
if len(dense_rows) != len(texts) or len(sparse_rows) != len(texts):
raise RuntimeError("Invalid embedding result count")
results = []
for dense, sparse in zip(dense_rows, sparse_rows):
vector = [float(value) for value in dense]
if not vector or any(not math.isfinite(value) for value in vector):
raise RuntimeError("Invalid embedding result")
lexical = {}
# BGEM3FlagModel returns vocabulary IDs, not token strings.
for token_id, value in sparse.items():
index = int(token_id)
weight = float(value)
if index < 0 or not math.isfinite(weight) or weight < 0:
raise RuntimeError("Invalid sparse embedding")
lexical[str(index)] = max(lexical.get(str(index), 0), weight)
results.append(Embedding(dense=vector, sparse=lexical))
dimension = len(results[0].dense)
if any(len(item.dense) != dimension for item in results):
raise RuntimeError("Inconsistent embedding dimensions")
return EmbeddingsResponse(model=model_id,
dimension=dimension, embeddings=results)
def translate(self, texts, source_locale, target_locale):
if source_locale == target_locale:
return TranslationResponse(model="identity", translations=list(texts))
model, translations = self.translator.translate(texts, source_locale, target_locale)
if len(translations) != len(texts) or any(not isinstance(text, str) or not text.strip()
or len(text) > 24000 for text in translations):
raise RuntimeError("Invalid translation response")
return TranslationResponse(model=model, translations=translations)