Files
border-red-post-nalati/backend/app/services/embedding_runtime.py
T

50 lines
1.7 KiB
Python

"""Offline, lazy CPU runtime; one encoder call per process, with a fast busy response."""
from functools import lru_cache
from threading import Lock
from fastapi import HTTPException
from app.core.config import settings
from app.services.embedding import LOCAL_MODELS, EmbeddingSpec, LocalEmbeddingProvider
class EmbeddingRuntime:
def __init__(self, spec: EmbeddingSpec, cache_dir, batch_size: int, threads: int):
self.spec = spec
self.cache_dir, self.batch_size, self.threads = cache_dir, batch_size, threads
self._provider = None
self._lock = Lock()
def encode(self, texts: list[str], *, query: bool = False) -> list[list[float]]:
if not self._lock.acquire(blocking=False):
raise HTTPException(503, "本地编码器忙,请稍后重试")
try:
if self._provider is None:
self._provider = LocalEmbeddingProvider(
self.spec,
cache_dir=self.cache_dir,
batch_size=self.batch_size,
threads=self.threads,
offline=True,
)
return self._provider.encode(texts, query=query)
finally:
self._lock.release()
@lru_cache(maxsize=1)
def runtime(spec, cache_dir, batch_size, threads):
return EmbeddingRuntime(spec, cache_dir, batch_size, threads)
def get_embedding_provider():
if not settings.embedding_enabled:
raise HTTPException(503, "本地 Embedding 未启用,请先完成模型缓存和运行环境配置")
return runtime(
LOCAL_MODELS[settings.embedding_model],
settings.embedding_cache_dir,
settings.embedding_batch_size,
settings.embedding_threads,
)