refactor(gpu): убрать мёртвый _reverse_map/_use_gpu из FAISSManager
All checks were successful
Deploy / deploy (push) Successful in 15s

_reverse_map был identity-map (faiss_id == doc_id для IndexIDMap2) —
использовался только как doc.faiss_id = _reverse_map[doc_id], т.е. = doc_id.
Убрал поле, метод _rebuild_reverse_map и его обслуживание в 5 местах;
_use_gpu нигде не читался. -30 строк, функционал тот же.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jze9
2026-08-11 16:57:03 +05:00
parent e328236d0f
commit a2d3625f2a
2 changed files with 7 additions and 41 deletions

View File

@@ -27,10 +27,6 @@ class FAISSManager:
"""Singleton для управления FAISS индексом (IndexIDMap2 поверх IndexFlatIP).""" """Singleton для управления FAISS индексом (IndexIDMap2 поверх IndexFlatIP)."""
_index = None _index = None
# doc_id -> faiss_id. Для IDMap2 faiss_id == doc_id, но маппинг сохраняем
# для совместимости с вызывающим кодом (plagiarism.embed_documents).
_reverse_map: dict[int, int] = {}
_use_gpu: bool = False
@classmethod @classmethod
def _new_index(cls): def _new_index(cls):
@@ -51,34 +47,19 @@ class FAISSManager:
import faiss import faiss
index_path = settings.FAISS_INDEX_PATH index_path = settings.FAISS_INDEX_PATH
if os.path.exists(index_path): if os.path.exists(index_path):
try: try:
loaded = faiss.read_index(index_path) loaded = faiss.read_index(index_path)
if hasattr(loaded, "id_map"): if hasattr(loaded, "id_map"):
cls._index = loaded cls._index = loaded
cls._rebuild_reverse_map() logger.info(f"Загрузка FAISS индекса из {index_path} ({loaded.ntotal} векторов)")
logger.info( return
f"Загрузка FAISS индекса из {index_path} " logger.warning("На диске несовместимый FAISS индекс (без id_map) — пересоздаём")
f"({cls._index.ntotal} векторов)"
)
else:
logger.warning(
"На диске несовместимый FAISS индекс (без id_map) — "
"пересоздаём как IndexIDMap2(IndexFlatIP)"
)
cls._index = cls._new_index()
cls._reverse_map = {}
except Exception as e: except Exception as e:
logger.warning(f"Не удалось загрузить FAISS индекс ({e}) — создаём новый") logger.warning(f"Не удалось загрузить FAISS индекс ({e}) — создаём новый")
cls._index = cls._new_index()
cls._reverse_map = {}
else: else:
logger.info("Создание нового FAISS индекса IndexIDMap2(IndexFlatIP)...") logger.info("Создание нового FAISS индекса IndexIDMap2(IndexFlatIP)...")
cls._index = cls._new_index() cls._index = cls._new_index()
cls._reverse_map = {}
cls._use_gpu = False # FlatIP на CPU достаточно быстр для целевого масштаба
@classmethod @classmethod
def _ensure(cls) -> None: def _ensure(cls) -> None:
@@ -86,18 +67,6 @@ class FAISSManager:
if cls._index is None: if cls._index is None:
cls.load_or_create() cls.load_or_create()
@classmethod
def _rebuild_reverse_map(cls) -> None:
"""Восстановить _reverse_map из id, хранящихся внутри загруженного индекса."""
import faiss
try:
ids = faiss.vector_to_array(cls._index.id_map)
cls._reverse_map = {int(i): int(i) for i in ids}
except Exception as e:
logger.warning(f"Не удалось восстановить reverse_map из индекса: {e}")
cls._reverse_map = {}
@classmethod @classmethod
def search(cls, query_vector: np.ndarray, k: int = 20) -> list[tuple[int, float]]: def search(cls, query_vector: np.ndarray, k: int = 20) -> list[tuple[int, float]]:
"""Поиск k ближайших векторов. """Поиск k ближайших векторов.
@@ -157,9 +126,6 @@ class FAISSManager:
pass pass
cls._index.add_with_ids(vectors, ids) cls._index.add_with_ids(vectors, ids)
for doc_id in doc_ids:
cls._reverse_map[int(doc_id)] = int(doc_id)
logger.info(f"Добавлено {len(doc_ids)} векторов в FAISS. Всего: {cls._index.ntotal}") logger.info(f"Добавлено {len(doc_ids)} векторов в FAISS. Всего: {cls._index.ntotal}")
@classmethod @classmethod

View File

@@ -254,12 +254,12 @@ def embed_documents(doc_ids: list[int]) -> dict[str, Any]:
FAISSManager.add_vectors(vectors, ids) FAISSManager.add_vectors(vectors, ids)
FAISSManager.save() FAISSManager.save()
# Обновить faiss_id в PostgreSQL # Обновить faiss_id в PostgreSQL (для IDMap2 faiss_id == doc_id)
with db_session() as session: with db_session() as session:
for doc_id in ids: for doc_id in ids:
doc = session.get(Document, doc_id) doc = session.get(Document, doc_id)
if doc and doc_id in FAISSManager._reverse_map: if doc:
doc.faiss_id = FAISSManager._reverse_map[doc_id] doc.faiss_id = doc_id
session.commit() session.commit()
logger.info(f"Встроено и проиндексировано {len(ids)} документов") logger.info(f"Встроено и проиндексировано {len(ids)} документов")