From 76e221f8568f94e3556c4f73a6c972dfc6923384 Mon Sep 17 00:00:00 2001 From: jze9 Date: Wed, 26 Aug 2026 18:37:49 +0500 Subject: [PATCH] =?UTF-8?q?fix(embeddings):=20=D0=BD=D0=B5=20=D1=82=D0=B5?= =?UTF-8?q?=D1=80=D1=8F=D1=82=D1=8C=20=D0=B1=D0=B0=D1=82=D1=87=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D1=82=D0=B0=D0=B9=D0=BC=D0=B0=D1=83=D1=82=D0=B5=20Oll?= =?UTF-8?q?ama,=20=D1=83=D0=BC=D0=B5=D0=BD=D1=8C=D1=88=D0=B8=D1=82=D1=8C?= =?UTF-8?q?=20=D0=BF=D0=B0=D1=87=D0=BA=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ollama обрабатывает тексты в пачке последовательно (один "slot" в llama.cpp, не параллельно) — 64 реальных документа в одном HTTP-запросе регулярно не укладывались в 120с, весь батч падал с ReadTimeout и терялся без ретрая (embed_documents была без bind/max_retries). Теперь: пачка 16, таймаут 300с, задача ретраится до 3 раз при сбое. --- services/worker-gpu/app/config.py | 5 ++++- services/worker-gpu/app/model_manager.py | 5 ++++- services/worker-gpu/app/tasks/plagiarism.py | 18 +++++++++++++++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/services/worker-gpu/app/config.py b/services/worker-gpu/app/config.py index 1406834..91737f8 100644 --- a/services/worker-gpu/app/config.py +++ b/services/worker-gpu/app/config.py @@ -58,7 +58,10 @@ class Settings(BaseSettings): EMBED_BACKEND: str = "ollama" EMBED_MODEL: str = "bge-m3" EMBED_DEVICE: str = "cuda" # используется только при EMBED_BACKEND=sentence_transformers - EMBED_BATCH_SIZE: int = 64 + # Ollama обрабатывает тексты в пачке последовательно (один "slot" в llama.cpp, + # не параллельно) — 64 реальных документа в один HTTP-запрос регулярно не + # укладывались в таймаут. Меньше пачка — короче и надёжнее каждый запрос. + EMBED_BATCH_SIZE: int = 16 EMBED_DIM: int = 1024 # bge-m3; было 768 у paraphrase-multilingual-mpnet-base-v2 # DeepInfra — OpenAI-совместимый инференс BAAI/bge-m3 в облаке, та же модель, # что и на VM109, дешёвый пей-пер-токен. Используется при EMBED_BACKEND=cloud. diff --git a/services/worker-gpu/app/model_manager.py b/services/worker-gpu/app/model_manager.py index 2e4f091..826eb51 100644 --- a/services/worker-gpu/app/model_manager.py +++ b/services/worker-gpu/app/model_manager.py @@ -91,7 +91,10 @@ class ModelManager: response = httpx.post( f"{settings.OLLAMA_URL}/api/embed", json={"model": settings.EMBED_MODEL, "input": batch}, - timeout=120.0, + timeout=300.0, # Ollama обрабатывает тексты в пачке последовательно + # (виден один "slot" в логах llama.cpp), не параллельно — на реальных + # (не тестовых) текстах 64 шт. в 120с не укладывались, отсюда ReadTimeout + # и потеря батча целиком (без ретрая). ) response.raise_for_status() all_vectors.extend(response.json()["embeddings"]) diff --git a/services/worker-gpu/app/tasks/plagiarism.py b/services/worker-gpu/app/tasks/plagiarism.py index 14fc74f..0f38c75 100644 --- a/services/worker-gpu/app/tasks/plagiarism.py +++ b/services/worker-gpu/app/tasks/plagiarism.py @@ -219,8 +219,13 @@ def check_plagiarism( raise self.retry(exc=exc, countdown=120) from exc -@celery_app.task(name="gpu.embed_documents") -def embed_documents(doc_ids: list[int]) -> dict[str, Any]: +@celery_app.task( + name="gpu.embed_documents", + bind=True, + max_retries=3, + default_retry_delay=30, +) +def embed_documents(self, doc_ids: list[int]) -> dict[str, Any]: """ Построить эмбеддинги для документов и добавить их в FAISS индекс. @@ -254,7 +259,14 @@ def embed_documents(doc_ids: list[int]) -> dict[str, Any]: ] ids = [d.id for d in docs] - vectors = ModelManager.encode(texts) + try: + vectors = ModelManager.encode(texts) + except Exception as exc: + # Таймаут/недоступность бэкенда эмбеддингов — не терять батч молча, + # а повторить (раньше падало без ретрая, документы просто выпадали + # из переиндексации). + logger.warning(f"Не удалось построить эмбеддинги для {ids}: {exc}") + raise self.retry(exc=exc) from exc store = get_backend() store.add_vectors(vectors, ids)