Семантический поиск по видео — поиск сцен по текстовому описанию моментов, мотивов, диалогов. Русскоязычный фокус.
cp .env.example .env # заполнить VIDEO_RAG_OPENROUTER_API_KEY
docker compose up -d # PostgreSQL 16 + Qdrant + API
alembic upgrade head # миграции
# Индексация
video-rag-index --data-dir data/ -c transcripts
video-rag-index --data-dir data/ -c transcripts --preprocess-only # только scene detection
video-rag-index enrich -c frame_descriptions # описания кадров через VLM
video-rag-index enrich -c summaries # итеративные пересказы фильмов
# API
uvicorn video_rag.api.app:app --host 0.0.0.0 --port 8000
curl localhost:8000/api/v1/healthFilm → Scene → SceneImage + SceneExtraMetadata # PostgreSQL
→ vector embeddings # Qdrant
Preprocessor.load(data_dir) → Iterator[RawFilmData]
Preprocessor.build_scenes(films) → list[SceneData]
Preprocessor.persist(scenes, db) → (skips is_indexed=True)
↓
Indexer.index_scenes(scenes) → ContentVectorizer.vectorize → batch upsert → Qdrant
- Preprocessor — PySceneDetect (
ContentDetector), 3 кадра на сцену, сплит длинных сцен (>30с), привязка транскриптов по overlap - Indexer — универсальный: прогоняет сцены через зарегистрированные vectorizers, батч-upsert в Qdrant
Плагинная система: каждый тип живёт в content_types/<type>/vectorizer.py, реализует ContentVectorizer ABC.
| Тип | Описание | Особенности |
|---|---|---|
transcripts |
Эмбеддинги текста транскриптов | Чанкование, батч-энкодинг |
frame_descriptions |
Описания сцен от VLM → эмбеддинги | LLM через OpenRouter, русский промпт |
summaries |
Итеративные пересказы фильмов | requires_full_context=True, cross-scene |
e5_chunks |
Мульти-масштабное чанкование для E5 | Несколько масштабов чанков |
POST /api/v1/search/single → vectorize_query → Qdrant search → PG enrichment → Reranker → SearchResponse
Стратегии поиска — реестр в search/__init__.py, роуты генерируются автоматически. Каждая стратегия реализует SearchStrategy ABC.
Реранкинг: CatBoostSearchReranker — learned-to-rank модель, строит фичи (score deltas, token overlaps, Jaccard, метаданные сцен/фильмов) и переранжирует результаты. Модели в models/.
Agentic chat с tool-use loop через OpenAI-compatible LLM (OpenRouter).
- Инструменты:
search_rag,get_film_info,get_film_scenes,get_scene_images - Стриминг SSE:
text_delta,tool_calls,tool_result,done - История в PostgreSQL:
chat_sessions+chat_messages
POST /api/v1/search/single— семантический поискPOST /api/v1/agent/chat— стриминг чат-агента (SSE)GET /api/v1/agent/sessions— история сессийGET /api/v1/scenes/{id}/images/{idx}— кадры сценGET /— UI поиска,GET /chat— UI чата
| Скрипт | Назначение |
|---|---|
scripts/embed_descriptions.py |
Эмбеддинг описаний кадров |
scripts/embed_transcripts_ru.py |
Эмбеддинг русских транскриптов |
scripts/translate_transcripts.py |
Перевод транскриптов (NLLB) |
scripts/train_catboost_v2.py |
Обучение CatBoost реранкера |
scripts/train_cross_encoder.py |
Fine-tune cross-encoder |
scripts/train_film_ranker.py |
Обучение ранкера фильмов |
scripts/eval_*.py |
Оценка стратегий поиска и реранкинга |
scripts/make_submission*.py |
Генерация сабмишенов |
scripts/load_e5_chunks.py |
Загрузка E5-чанков в Qdrant |
Решение описано в solution.ipynb — fine-tuned multilingual-e5-large + мульти-масштабное чанкование + cross-encoder reranking.
Python 3.12, FastAPI, SQLAlchemy (async + asyncpg), Qdrant, PostgreSQL 16, sentence-transformers, CatBoost, Alembic, Typer, httpx