feat(gpu): Qdrant как векторный бэкенд под флагом — снимает SPOF FAISS
FAISS-индекс — файловый синглтон в RAM одного воркера (save на каждую запись, без блокировок, без HA, не горизонтален). Добавлен альтернативный бэкенд Qdrant с тем же classmethod-интерфейсом, выбор через VECTOR_BACKEND — аддитивно и безопасно: дефолт остаётся faiss, ничего не ломается, пока не переключат. - app/qdrant_manager.py — search/add_vectors/save(no-op)/total_vectors поверх qdrant-client (коллекция Cosine, id точки = doc_id, upsert идемпотентен); - app/vector_store.py — get_backend() по настройке; задачи search/plagiarism переведены на него (больше не импортируют FAISSManager напрямую); - app/migrate_faiss_to_qdrant.py — перелив существующих векторов (reconstruct из IndexIDMap2 → upsert), идемпотентно; - docker-compose.prod.yml — сервис qdrant под профилем `qdrant` (по умолчанию не поднимается, ресурсов не ест) + volume; README — раздел про переключение. Тесты (9) гоняют QdrantManager против ВСТРОЕННОГО Qdrant (qdrant-client :memory:, не моки) + диспетчеризацию бэкенда. Всего тестов: 82 (indexer 24, gost 24, gpu 34). Плюсы Qdrant активируются только после явного переключения + миграции. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
25
README.md
25
README.md
@@ -159,6 +159,31 @@ make migrate
|
||||
|
||||
Nginx работает внутри контейнера (`docker-compose.prod.yml`, сервис `nginx`, Dockerfile в `infra/nginx/Dockerfile`) — собирает `services/frontend` в статику и отдаёт её вместе с проксированием `/api/`, `/ws/` на `api:8000` по конфигу `infra/nginx/nginx.conf`. Контейнер монтирует `/etc/letsencrypt` с хоста как read-only — сертификат обновляется на хосте (`certbot renew`), контейнер просто читает его.
|
||||
|
||||
## Векторный бэкенд (FAISS / Qdrant)
|
||||
|
||||
Семантический индекс (уровень 3) спрятан за `app.vector_store.get_backend()` и
|
||||
переключается настройкой `VECTOR_BACKEND` — без изменения кода:
|
||||
|
||||
- **`faiss`** (по умолчанию) — файловый `IndexIDMap2(IndexFlatIP)` в RAM воркера.
|
||||
Просто, но это единая точка отказа и без конкурентной записи.
|
||||
- **`qdrant`** — сетевой сервис: снимает SPOF, допускает конкурентный upsert из
|
||||
нескольких воркеров, переживает рестарт, масштабируется горизонтально.
|
||||
|
||||
Переключение на Qdrant (аддитивно, ничего не ломает до шага 2):
|
||||
|
||||
```bash
|
||||
# 1. Поднять Qdrant (профиль qdrant в docker-compose.prod.yml)
|
||||
docker compose -f docker-compose.prod.yml --profile qdrant up -d qdrant
|
||||
|
||||
# 2. В .env выставить VECTOR_BACKEND=qdrant (QDRANT_URL по умолчанию http://qdrant:6333)
|
||||
|
||||
# 3. Перелить существующие векторы FAISS → Qdrant (идемпотентно)
|
||||
docker compose -f docker-compose.prod.yml exec worker-gpu python -m app.migrate_faiss_to_qdrant
|
||||
|
||||
# 4. Перезапустить GPU-воркер
|
||||
docker compose -f docker-compose.prod.yml up -d worker-gpu
|
||||
```
|
||||
|
||||
## Тестирование и качество кода
|
||||
|
||||
Перед деплоем CI (`.gitea/workflows/deploy.yml`, job `test`) прогоняет два гейта,
|
||||
|
||||
Reference in New Issue
Block a user