English translation is not available yet. Showing Russian content.

Как вы делаете RAG для видео (индексация subshots, аудио, ключевые кадры)?

Краткий тезис

RAG для видео — это мультимодальная задача: видео содержит визуальный ряд (кадры), аудиодорожку (речь, звуки) и текстовые метаданные. Типичный пайплайн включает сегментацию видео на subshots, извлечение ключевых кадров (через CLIP или детекторы сцен), транскрипцию аудио (Whisper) и объединение эмбеддингов всех модальностей в единый вектор для поиска. Такой подход позволяет отвечать на вопросы по содержанию видео, используя как визуальную, так и текстовую информацию.


1. Термины: subshot, ключевой кадр, аудиоэмбеддинг

  • Subshot (подсцена) — непрерывный фрагмент видео с минимальным изменением визуального содержания. Разбивка на subshots нужна, чтобы индексировать не всё видео целиком, а логические единицы (сцены, планы).
  • Ключевой кадр (keyframe) — репрезентативный кадр subshot, который лучше всего описывает его визуальное содержание. Обычно выбирается центральный кадр или кадр с максимальной резкостью.
  • Аудиоэмбеддинг — векторное представление аудиосегмента, полученное с помощью модели (например, Whisper, Wav2Vec2). Для RAG чаще используют текстовую транскрипцию (Whisper → текст → текстовый эмбеддинг), но можно и напрямую эмбеддинги аудио.

2. Этап 1: Сегментация видео на subshots

Цель — разбить видео на семантически однородные куски (сцены). Методы:

  • На основе гистограмм кадров: сравниваем гистограммы соседних кадров (по цвету, яркости). Резкое изменение → граница subshot.
  • PySceneDetect (Python-библиотека): использует детекторы ContentDetector (по разнице кадров) и ThresholdDetector (по яркости).
  • Глубокие модели: детекторы сцен на основе CNN (например, TransNetV2) — точнее, но тяжелее.

Пример кода с PySceneDetect:

from scenedetect import open_video, SceneManager, ContentDetector

video = open_video("lecture.mp4")
scene_manager = SceneManager()
scene_manager.add_detector(ContentDetector(threshold=30))
scene_manager.detect_scenes(video)
scene_list = scene_manager.get_scene_list()  # список (start_time, end_time)

Результат: список временных интервалов (subshots). Для каждого subshot извлекаем ключевой кадр (например, средний по времени) и аудиосегмент.


3. Этап 2: Извлечение и эмбеддинг ключевых кадров

Для каждого subshot выбираем один или несколько ключевых кадров. Затем получаем их визуальные эмбеддинги с помощью CLIP (Contrastive Language–Image Pre-training) — модели, которая проецирует изображения и текст в общее пространство.

import clip
import torch
from PIL import Image

model, preprocess = clip.load("ViT-B/32")
image = preprocess(Image.open("keyframe.jpg")).unsqueeze(0)
with torch.no_grad():
    image_features = model.encode_image(image)
    image_features /= image_features.norm(dim=-1, keepdim=True)

Эмбеддинг ключевого кадра — вектор фиксированной размерности (например, 512 для ViT-B/32). Если subshot длинный, можно взять несколько кадров и усреднить их эмбеддинги (или использовать attention).


4. Этап 3: Обработка аудио (Whisper + эмбеддинг)

Аудиодорожку subshot транскрибируем в текст с помощью Whisper (OpenAI). Полученный текст эмбеддируем той же моделью, что и текстовые запросы (например, sentence-transformers/all-MiniLM-L6-v2 или CLIP text encoder).

import whisper
from sentence_transformers import SentenceTransformer

model_whisper = whisper.load_model("base")
result = model_whisper.transcribe("subshot_audio.wav")
text = result["text"]

text_embedder = SentenceTransformer("all-MiniLM-L6-v2")
text_embedding = text_embedder.encode(text)

Если аудио содержит не только речь (музыка, шумы), можно добавить аудиоэмбеддинги (например, через Wav2Vec2) и объединить их с текстовыми.


5. Этап 4: Объединение эмбеддингов (fusion)

У нас есть визуальный эмбеддинг (из ключевых кадров) и текстовый эмбеддинг (из транскрипции). Нужно получить единый вектор для subshot. Основные стратегии:

МетодОписаниеПлюсыМинусы
ConcatenationКонкатенация векторовПростота, сохраняет все признакиРазмерность растёт, может быть избыточно
Weighted averageВзвешенное среднее (например, 0.7 визуальный + 0.3 текстовый)Гибкость, настраивается под данныеВеса нужно подбирать
Attention fusionОбучаемый механизм cross-attention между модальностямиУчитывает взаимосвязьТребует данных для обучения
Late fusionПоиск отдельно по визуальным и текстовым эмбеддингам, затем объединение ранговПростота, не требует единого вектораДва запроса к БД, сложнее ранжирование

Пример взвешенного среднего (после нормализации):

vis_emb = image_features / image_features.norm()
txt_emb = torch.tensor(text_embedding)
txt_emb = txt_emb / txt_emb.norm()
alpha = 0.6
combined_emb = alpha * vis_emb + (1 - alpha) * txt_emb
combined_emb = combined_emb / combined_emb.norm()

Полученные векторы индексируются в векторной БД (FAISS, Milvus, Qdrant) вместе с метаданными (время начала/конца subshot, ссылка на видео).


6. Поиск и генерация ответа

На этапе inference пользователь задаёт текстовый вопрос. Его эмбеддим той же текстовой моделью (например, CLIP text encoder или sentence-transformer). Ищем ближайшие векторы subshots в БД по косинусной близости. Возвращаем top-k subshots.

Далее возможны два подхода:

  • Прямая генерация: передаём LLM транскрипцию + описание ключевых кадров (через captioning) как контекст.
  • Мультимодальный LLM: используем модель, которая принимает и текст, и изображения (например, GPT-4V, LLaVA). Тогда в контекст можно добавить сами ключевые кадры.

7. Проблемы и их решения

ПроблемаРешение
Синхронизация аудио и видеоИспользовать временные метки subshot как единую ось; аудио и видео обрабатываются для одного интервала
Шум в аудиоПрименять фильтрацию (noise reduction) перед Whisper; использовать субтитры, если есть
Длинные видеоИндексировать только subshots, а не всё видео; использовать иерархическую индексацию (сцена → subshot)
Разные модальности не совпадают по смыслуНапример, ведущий говорит одно, а на экране другое. Тогда weighted average может размыть семантику. Лучше late fusion или обучаемый fusion
МасштабированиеДля тысяч часов видео — распределённая обработка (Spark, Ray), параллельное эмбеддирование

8. Метрики оценки видео RAG

Оффлайн-метрики (на размеченном датасете запросов и релевантных subshots):

  • Hit Rate@k — доля запросов, для которых хотя бы один релевантный subshot попал в top-k.
  • MRR — средний обратный ранг первого релевантного subshot.
  • Recall@k — доля всех релевантных subshots, найденных в top-k.

Онлайн-метрики (с LLM):

  • Faithfulness — насколько ответ LLM соответствует найденным subshots (не галлюцинирует).
  • Answer relevance — насколько ответ отвечает на вопрос пользователя.
  • Context relevance — насколько найденные subshots релевантны запросу.

Инструменты: RAGAS, TruLens, DeepEval.


9. Инструменты и библиотеки

ЗадачаИнструмент
Сегментация видеоPySceneDetect, TransNetV2
Визуальные эмбеддингиCLIP (OpenAI), DINOv2, VideoCLIP
Транскрипция аудиоWhisper (OpenAI), Wav2Vec2, Google Speech-to-Text
Текстовые эмбеддингиsentence-transformers, CLIP text encoder
Векторная БДFAISS, Milvus, Qdrant, Pinecone
Мультимодальный LLMGPT-4V, LLaVA, Gemini Pro Vision

10. Сравнение с текстовым RAG

АспектТекстовый RAGВидео RAG
Входные данныеТекст (документы, чанки)Видео (кадры, аудио, субтитры)
МодальностиОдна (текст)Три (визуал, аудио, текст)
Сложность индексацииНизкая (разбить текст на чанки)Высокая (сегментация, извлечение кадров, аудио)
Размер данныхОтносительно малОгромный (видеофайлы)
Метод fusionНе нуженОбязателен (объединение модальностей)
LLM на выходеТекстовый LLMМультимодальный LLM или текстовый + captioning

Пет-проект для закрепления

Задача: Создать систему поиска по видео-лекциям (например, по курсу на YouTube). Пользователь задаёт вопрос, система находит релевантный фрагмент видео и возвращает его с таймкодом и кратким ответом.

Инструменты: Python, PySceneDetect, CLIP, Whisper, sentence-transformers, FAISS, Streamlit (UI).

Шаги:

  1. Скачать 5–10 видео-лекций (можно короткие, по 10–20 минут).
  2. Разбить каждое видео на subshots с помощью PySceneDetect (порог 30–40).
  3. Для каждого subshot извлечь ключевой кадр (средний по времени) и сохранить как JPEG.
  4. Транскрибировать аудио subshot через Whisper (модель base).
  5. Получить визуальный эмбеддинг ключевого кадра через CLIP (ViT-B/32).
  6. Получить текстовый эмбеддинг транскрипции через all-MiniLM-L6-v2.
  7. Объединить эмбеддинги взвешенным средним (α=0.5) и нормализовать.
  8. Индексировать все векторы в FAISS (IndexFlatIP).
  9. Написать простой веб-интерфейс на Streamlit: поле ввода вопроса, кнопка поиска, вывод top-3 subshots с таймкодами и транскрипцией.
  10. Оценить качество на 10–20 тестовых вопросах вручную.

Ожидаемый результат: Работающий прототип, который на вопрос "Что такое attention?" находит фрагмент лекции, где объясняется attention, и показывает его текст и время.


Связь с другими вопросами

ВопросТема
365Как делать RAG для изображений?
367Как делать RAG для аудио?
370Что такое мультимодальный RAG?
371Как объединять результаты из разных модальностей?
372Какие метрики для мультимодального RAG?
373Как обрабатывать длинные видео (часы)?

Навигация