Files
anti-plagiarism/services/worker-gpu/app/celery_app.py
jze9 d8630ca0f9 fix(admin): покрытие L3 мерить по индексу, а не по отметкам в базе
Проверка на живых данных вскрыла, что панель отладки врала в мою же пользу:
показывала 154 046 «документов с эмбеддингом» (87%), тогда как в FAISS реально
93 053 вектора (52.5%). Колонка documents.faiss_id для этого непригодна —
отметка остаётся после пересоздания индекса (смена модели: 768 → 1024) и после
сбоев worker-gpu. Выборочная проверка: у 8 из 20 «отмеченных» вектора нет.

- gpu.index_stats — новая задача, отдаёт реальное содержимое активного
  векторного бэкенда; API спрашивает её для панели отладки;
- панель показывает «векторов в индексе» и отдельно предупреждает о ложных
  отметках (их 60 993), потому что такие документы молча выпадают из L3:
  в индексе их нет, а на пересчёт они не попадут — reembed ищет faiss_id IS NULL;
- scripts/ops/faiss_reconcile.py — сверяет отметки с индексом и обнуляет ложные,
  после чего reembed_missing.py отправляет их на пересчёт. Проверен вживую
  (dry-run на проде: 93 053 в индексе, 60 993 ложных отметок).

Документация: зафиксирована реальная глубина корпуса — полный текст только у
27.5% документов, у 79% меньше 500 отпечатков (уровень аннотации). Система
ловит списывание из того, что есть целиком; это граница, а не поломка.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 17:17:41 +05:00

39 lines
1.0 KiB
Python

"""Celery приложение GPU воркера."""
from celery import Celery
from celery.utils.log import get_task_logger
from app.config import settings
celery_app = Celery(
"worker_gpu",
broker=settings.RABBITMQ_URL,
backend=settings.REDIS_URL,
include=["app.tasks.search", "app.tasks.plagiarism", "app.tasks.stats"],
)
celery_app.conf.update(
task_serializer="json",
result_serializer="json",
accept_content=["json"],
timezone="Europe/Moscow",
enable_utc=True,
task_track_started=True,
# Маршрутизация
task_routes={
"gpu.*": {"queue": "queue.gpu"},
"index.*": {"queue": "queue.index"},
"notify.*": {"queue": "queue.notify"},
"gost.*": {"queue": "queue.gost"},
},
# Надёжность
task_acks_late=True,
task_reject_on_worker_lost=True,
# GPU воркер — только 1 процесс
worker_concurrency=1,
# Результаты хранить 24 часа
result_expires=86400,
)
logger = get_task_logger(__name__)