Как мы построили сервис по поиску видеоконтента с помощью текста

Кто мы

Привет, Habr!
Мы — команда нейро-сети.рф, специализирующаяся на разработке AI-сервисов для решения бизнес-задач и внедрения искусственного интеллекта в реальный сектор экономики. Мы специализируемся в GenAI (LLM, Диффузионные модели), NLP, CV, Machine Learning. В этой статье мы хотим поделиться нашим опытом создания сервиса по поиску видеоконтента с помощью текста.

Цель данной статьи — подробно рассказать о процессе создания нашего сервиса, решениях, которые мы приняли на каждом этапе, и о том, какие технологии использовали. Мы хотим показать, как сложные технические задачи могут быть решены простыми и эффективными методами.

Целевая аудитория статьи, и что вы получите в конце статьи:

  • IT-специалистов: получат глубокое понимание технических аспектов реализации сервиса и новых технологий.

  • Продукт-менеджеров: узнают, как подобный сервис может улучшить их продукт, а также о рыночных возможностях и конкурентных преимуществах.

  • Руководителей проектов: получат информацию для оценки рисков и ресурсов.

  • Владельцев IT-бизнесов: найдут стратегии для улучшения маркетинговых кампаний.

Проблема

Рынок коротких видеороликов стремительно растет:

Создателям контента все сложнее быстро находить релевантные видеоролики для маркетинговых целей. Наш сервис помогает им эффективно искать и использовать видеоконтент, оптимизируя процессы создания и продвижения.

Альтернативные решения

Тут представлены сервисы для генерации коротких роликов на основе текста, но они решают ту же проблему, что и мы :

Решение

Повторюсь, я буду объяснять технические моменты в ИИ простым языком для людей, которые не касались этой темы, однако технически подкованные люди тоже могут подчеркнуть для себя технологии и фишки. Для этого расскажу про каждую технологию в общих чертах, а потом более подробнее объясню, поэтому каждый для себя сможет найти полезную информацию.

Постановка задачи

Пользователь вводит текст «собака гуляет на берегу моря», и сервис с помощью магии ИИ должен найти видео, где показано, как собака гуляет на берегу моря —- это задача Text2Video Retrieval, то есть поиск релевантного видео по текстовому запросу

xdx2tow5unxz8isc3wezjca_drg.png

Метрики

Метрики нужны, чтобы понимать качество модели (в нашем случае ИИ), которая находится внутри сервиса и выполняет основную логику. Нам важно, чтобы найденные видеоролики совпадали с запросом пользователя. Также нам важна точность поиска релевантного видео, поэтому будем оптимизировать Precision@k.

Что такое Precision@k простыми словами?

Precision@k — это метрика, которая показывает, насколько хорошо наша модель находит нужные видеоролики среди первых k результатов поиска. Представьте, что вы ищете видео и получаете список из k видео. Precision@k показывает, сколько из этих k видео действительно подходят под ваш запрос. Чем выше precision@k, тем больше подходящих видео среди первых k результатов. Подробнее можно почитать здесь.

yyai4lpo2gokdu3cplvlsrkqlrs.png

Пример. На левой картинке среди 9 первых элементов релевантные 6, Precision@9 = 6/9=0.6. На правой картинки среди 5 первых элементов релевантные 4, Precision@5 = 4/5=0.8.

Данные

Хранилище данных

Для хранения данных мы использовали облачное хранилище Amazon S3. На начальном этапе данные хранились на нашем сервере в базе данных MongoDB. Этот вариант позволил быстро начать работу и выполнить поставленные задачи.

Сбор данных

Для успешного поиска видеоконтента нам нужно было собрать как можно больше видеороликов в базе данных (БД). Чем больше видеороликов, тем выше вероятность найти релевантный контент по запросу пользователя.

Мы рассмотрели три основных подхода к сбору видеоконтента:

1. Сбор видео с определенных сайтов, в том числе YouTube, и их предварительная загрузка в базу данных, с которой видео позже будут извлекаться/подгружаться при вводе запроса пользователем.

ln6yhvfqz_ue0s9ss9-x8qidd_k.png

Плюсы:

  1. Высокая скорость поиска: Видео уже находятся в базе данных, нет необходимости искать их в Интернете.

  2. Высокое качество: Можно заранее проверить качество видео по картинке, звуку и содержанию.

Минусы:

  1. Высокая вероятность ошибки: Если база данных недостаточно насыщена, сервис может не найти нужное видео.

  2. Большое требование к памяти: Нужно много места для хранения видео на сервере.

2. При запросе пользователя сервис начинает поиск видео в Интернете, то есть не заходя в базу данных.

hzr8eo2hh120l_ihlxgqp7thwta.png

Плюсы:

  1. Низкая вероятность ошибки: Можно найти релевантные видео в Интернете и затем выбрать лучшие для пользователя.

  2. Меньше требований к памяти: Видео хранятся в Интернете, не нужно постоянно хранить их на сервере.

Минусы:

  1. Низкое качество найденных роликов: Сложно оценить качество видео в реальном времени.

  2. Низкая скорость: Пользователю придётся ждать не только поиска, но и скачивания видео.

3. Комбинированный подход

hzr8eo2hh120l_ihlxgqp7thwta.png

Используем базу данных для быстрого поиска. Если нужное видео не найдено, начинаем искать его в специализированных источниках в Интернете.

Плюсы:

  1. Баланс скорости и качества: Быстрый поиск в базе данных и возможность найти дополнительные видео в Интернете.

  2. Оптимизация ресурсов: Экономия памяти на сервере за счет хранения только самых релевантных видео.

  3. Гибкость: Возможность адаптироваться к изменяющимся запросам пользователей и обновлению контента.

Минусы:

  1. Сложность реализации: Требуется разработка более сложного алгоритма для интеграции двух методов.

  2. Задержка в поиске: В случае отсутствия нужного видео в базе данных, пользователю придется ждать дополнительное время на поиск в Интернете.

  3. Вопросы качества: Возможны проблемы с оценкой качества видео, найденных в Интернете в режиме реального времени.

Предобработка данных

Мы создали сервис с расчётом на то, что пользователь получит видео длиной 5–10 секунд. Но в Интернете в основном длинные ролики и их нужно делить на сцены. Ввиду нашего алгоритма из них нужно взять несколько картинок. Поэтому мы использовали библиотеку pyscenedetect.

Давайте рассмотрим алгоритм преодобработки видео на реальном примере (видео).

wxl5elbr3hqq5z4dfsyghkjdjfg.png

  1. Делим видео на сцены с помощью pyscenedetect

  2. Каждая сцена делится на картинки

Вот код:

import scenedetect
import torch
import yaml
from PIL import Image
from scenedetect import (
    AdaptiveDetector,
    ContentDetector,
    ThresholdDetector,
    FrameTimecode,
    open_video,
    split_video_ffmpeg,
)
from pathlib import Path
import os

class SceneExtractor:
    def __init__(self):
        self.manager = scenedetect.SceneManager()
        self.detector = scenedetect.ContentDetector()
        self.manager.add_detector(self.detector)
    
    def get_scenes(self, video_path, num_images=3, output_pics_dir=Path("../Pics")):
        # Открываем видео файл
        video = open_video(str(video_path))
        
        # Запускаем процесс обнаружения сцен
        self.manager.detect_scenes(video)
        
        # Получаем список сцен
        scenes_list = self.manager.get_scene_list()
        
        # Инициализируем списки для хранения информации о сценах
        scenes_timecodes = []
        scenes_list_new = []
        
        # Проходим по каждой сцене, чтобы извлечь временные коды начала и конца
        for scene_start, scene_end in scenes_list:
            start_time = scene_start.get_seconds()
            end_time = scene_end.get_seconds()
            
            scenes_timecodes.append((start_time, end_time))
            scenes_list_new.append((scene_start, scene_end))
        
        # Сохраняем изображения для каждой сцены
        imgs_scenes = scenedetect.scene_manager.save_images(
            scenes_list_new,
            video,
            num_images,
            frame_margin=15,
            output_dir=str(output_pics_dir),
            scale=0.25,
        )
        
        # Формируем пути к сохраненным изображениям
        scenes_images_paths = [
            [os.path.join(output_pics_dir, img_name) for img_name in imgs_scene]
            for imgs_scene in list(imgs_scenes.values())
        ]
        
        # Возвращаем временные коды сцен и пути к изображениям
        return scenes_timecodes, scenes_images_paths

Секретный секрет нашего ИИ

После сбора и обработки данных мы подходим к самому интересному — создание алгоритма поиска на основе ИИ.

Разберём основные моменты перед тем, как расскажу про алгоритм.

Vision Language Model — Описываем картинку по нашему желанию

Vision Language Model — нейронная сеть, которая описывает картинку по запросу. Представьте себе коробочку с ИИ внутри. Вы подаёте на вход картинку и запрос «опиши, что изображено на картинке». На выходе вы получаете описание, например: «на картинке два енота обнимают собаку».

njaaexiztrg7vctszqzl2pakinw.png

Таких нейросетей может быть очень большое количество с разным качеством генерации описания картинки. В нашем проекте мы возьмём QWEN-VL — бесплатная модель от Алибабы, которая в приемлемом качестве генерирует текст.

ANN (Approximate Nearest Neighbor): Найдите то, что вам нужно

ANN (Approximate Nearest Neighbor) — это алгоритм поиска ближайших соседей.
Представьте, что у вас есть огромная галерея с миллионами картин. Каждая картина сопровождается текстовым описанием, например: «на картине изображен закат над океаном». Теперь вам нужно найти все картины, которые по описанию похожи на запрос «морской пейзаж при закате».

Вот тут приходит на помощь ANN. Этот алгоритм помогает быстро и эффективно найти текстовые описания, которые наиболее близки к вашему запросу. Он не ищет точное совпадение слов, а находит те описания, которые имеют схожий смысл. Это как если бы вы искали картины по ключевым словам и получили список самых подходящих вариантов, даже если слова в описаниях немного отличаются.

w7mhq0nh6c7vy8b0eeo5e9nq4n0.png

На вход в ANN:

1. Промпт: Это текст, который вы хотите использовать для поиска. Например,»морской пейзаж при закате».

2. База данных описаний: Это коллекция всех текстовых описаний картин, которые у вас есть. Например:

  • »закат над океаном с облаками»

  • »закат над уровнем океана»

  • »Город с закатом и облаками»

  • »Закат над океаном с горами»

  • »Закат над горами»

На выход:

ANN обрабатывает ваш запрос и возвращает список текстовых описаний, которые наиболее близки к вашему запросу. В нашем примере:

При промпте: «морской пейзаж при закате».

Получаем отсортированный список по «похожести»:

  1. Описание 1: «закат над уровнем океана»

  2. Описание 2: «закат над океаном с облаками»

  3. Описание 3: «Город с закатом и облаками»

  4. Описание 4: «Закат над океаном с горами»

  5. Описание 5: «Закат над горами»

Encoder: Превращаем текст в числа

Но вот в чём загвоздка. ANN может работать только с числами, а не с текстом. Представьте себе, что ANN — это робот-исследователь, который понимает только язык чисел. Чтобы он понял ваш запрос, нужно сначала перевести текст на его язык.

Здесь на сцену выходит Encoder. Это нейронная сеть, которая превращает текст в набор чисел, называемый вектором. Зачем это нужно? Векторы позволяют компьютеру понимать и сравнивать тексты. Таких Encoder`ов много, в нашей задаче мы выбрали bge.

Например, когда вы вводите запрос «морской пейзаж при закате», Encoder преобразует его в вектор — что-то вроде этого: [0.1, 0.24, 0.41, … 0.12]. Этот вектор — цифровое представление вашего запроса.

Почему это важно?

Векторы помогают быстро и точно находить видеоконтент, который соответствует вашему запросу. Они работают как координаты на карте: если два вектора находятся близко друг к другу, значит их тексты похожи по смыслу.

woy4dargu9mxp4eotxwoqwojrde.png

На входе:

Промпт: Вы вводите текст «морской пейзаж при закате».

На выходе:

Вектор: Вектор из чисел — [0.1, 0.24, 0.41, … 0.12].

Склеиваем блоки в алгоритм

Итак, у нас есть три ключевых компонента:

  1. Vision Language Model: Нейронная сеть, которая генерирует текст на основе вашего запроса и входящей картинки.

  2. ANN (Approximate Nearest Neighbor): Алгоритм, который находит ближайшие элементы из базы данных по входящему элементу.

  3. Encoder: Нейронная сеть, которая превращает текст в числа.

Теперь давайте соберем всё это вместе и посмотрим, как работает алгоритм.

  1. Формируем Базу Данных:

    1. Предположим, что данные уже собраны. Мы разбили все видео на отдельные кадры и теперь нужно их описать.

      l7gtpf2_mncuc7cb2wlcvx2vvna.png
    2. Vision Language Model создаёт текстовое описание для каждого кадра из нашей Базы Данных.

      y3kngalexdedk-ndlgvuoin4jdm.png
    3. Encoder превращает все текстовые описания в вектора и складывает числовые вектора в Базу Данных.

      ibao-tarwmjlz3vtq-2lq4gmo4a.png
  2. Ищем видео по запросу пользователя — теперь представим, что вы хотите найти видео по запросу «морской пейзаж при закате»:

    1. Промпт: Вы вводите текст «морской пейзаж при закате».

    2. Преобразование: Encoder превращает этот текст в вектор.

    3. Поиск: Сервис сравнивает этот вектор с векторами из базы данных с помощью ANN.

    4. Результат: Вы получаете список ID, которые наиболее точно соответствуют вашему запросу. С помощью этих ID мы подтягиваем нужные видео.

Как ещё пробовали ?

В процессе создания нашего сервиса поиска видеоконтента мы экспериментировали с различными подходами. Один из таких подходов — попытка извлекать векторные представления непосредственно из изображений. Мы решили попробовать отказаться от генерации текстовых описаний и вместо этого использовать векторные представления самих картинок для поиска с помощью ANN.

Представьте себе: у нас есть кадр из видео, скажем, красивый закат над океаном. Вместо того чтобы описывать этот кадр текстом, как, например, «закат над океаном», мы обучили нейросеть создавать векторное представление для изображения. Этот вектор — набор чисел, который должен был описать картинку также эффективно, как и текст.

Почему это может работать?

Идея была проста: если нейросеть сможет эффективно «понимать» картинку, то мы могли бы обойтись без текстовых описаний, что сэкономило бы время и ресурсы на их генерацию. Мы полагали, что такие векторы могли бы быть еще более точными, ведь они создаются напрямую на основе визуальных данных.

В итоге:

Наш эксперимент показал, что использование текстовых описаний картинок более эффективно для поиска нужного видеоконтента. Конечно, это добавляет дополнительный шаг — генерацию описаний, но выигрыши в точности поиска этого стоят.

Как мы обучали ИИ

Зачем нужно обучать ИИ?

Обучение ИИ — это как обучение нового сотрудника. Мы берём уже обученные модели, но их данные могут отличаться от наших. Чтобы наш ИИ понимал данные и точно интерпретировал запросы пользователей, нужно дообучить его на наших данных.

Важность обучения

Обучение моделей на специфических данных улучшает точность и релевантность результатов. Например, если вы бы обучили опытного повара готовить по вашему семейному рецепту блюда

Как мы обучали Encoder с помощью контрастного обучения

Мы дообучили Encoder с помощью контрастного обучения (contrastive learning). Этот метод помогает модели различать похожие и непохожие объекты. Представьте два набора карточек: один с кошками, другой — с собаками. Контрастное обучение помогает модели понять, какие признаки отличают кошек от собак.

Процесс:

  1. Взяли пары текстов и соответствующих изображений из базы данных.

  2. Encoder преобразовывал тексты в вектора.

  3. Использовали контрастное обучение, чтобы научить модель отличать правильные пары (текст и изображение соответствуют) от неправильных (текст и изображение не соответствуют).

Данные мы собрали с помощью копирайтеров и расширили с помощью API OpenAI.

Теперь наш Encoder лучше понимает, как текстовые запросы соотносятся с описаниями картинок от Vision Language Model.

Метрики: как мы измеряли успех

Для оценки качества работы нашей модели мы использовали метрику Precision@k, где k=1, 5, 10. Эта метрика показывает, насколько хорошо модель отбирает нужные видео; чем меньше k, тем строже метрика относится к отбору видео.

— Precision@1: До обучения этот показатель составлял 0.65, а после — 0.74. Это значит, что в 74% случаев первое видео будет релевантным.

— Precision@5: До обучения он составлял 0.84, а после — 0.92. Это значит, что в 92% случаев одно из первых пяти видео будет релевантным.

— Precision@10: До обучения он составлял 0.91, а после — 0.95. Это значит, что в 95% случаев одно из первых десяти видео будет релевантным.

Благодаря дообучению Encoder с помощью контрастного обучения, мы значительно улучшили точность и релевантность поиска видео по текстовым запросам пользователей.

twcguhegsbtrgllctoh2kluvahu.png

Как мы деплоим наш сервис

Немного терминов:

Процесс деплоя — это как финальный этап подготовки спектакля перед его премьерой. Представьте, что у вас есть театральная постановка: сценарий написан, актёры отрепетировали свои роли, декорации готовы. Теперь нужно сделать так, чтобы это было представлено на сцене перед зрителями.

В мире IT деплой — это процесс, когда готовое приложение (или обновления к нему) переносится из среды разработки в рабочую среду, где им могут пользоваться реальные пользователи.

Многоконтейнерное приложение — это приложение (сервис), которое состоит из нескольких отдельных частей (контейнеров). Каждый контейнер выполняет свою задачу. Представьте ресторан, где кухня, бар и касса находятся в разных комнатах. Каждая комната выполняет свою функцию, но вместе они составляют один ресторан.

Docker — это как магическая коробка для вашего приложения. Вы кладёте в неё всё необходимое (код, библиотеки, настройки), и она работает одинаково на любом компьютере. Dockerfile — это рецепт, который описывает, как собрать эту коробку, чтобы ваше приложение всегда было готово к запуску.

Для описания и управления многоконтейнерным приложением используется docker-compose. С его помощью можно объединить несколько контейнеров в одно целое приложение, описав их взаимодействие и зависимости в одном файле (YAML-файле).

Термины закончились, приступим к описанию деплоя сервиса:

Мы используем Docker и docker-compose для деплоя нашего многоконтейнерного приложения. Вот как контейнеры работают у нас:

  1. Бэкенд: Это сердце нашего приложения, которое обрабатывает данные, то есть в этом контейнере хранится наш магический ИИ, который принимает запрос пользователя и отдаёт ID видео. Мы создаем его с помощью специального файла инструкций (Dockerfile). Бэкенд хранит данные в отдельных местах (томах) и использует графические процессоры (GPU) для сложных задач. Если что-то ломается, он сам перезапускается.

  2. База данных: Здесь хранятся все данные нашего приложения. Мы используем готовую программу (образ MongoDB), которая тоже хранит данные в своём месте (томе) и автоматически перезапускается при сбое.

  3. Фронтенд: Это то, что видят пользователи. Он тоже создаётся с помощью файла инструкций (Dockerfile) и ждёт, пока бэкенд будет готов, чтобы взаимодействовать с ним.

docker-compose позволяет описать все части в одном файле (YAML файл). Это упрощает их запуск и управление. Данные и ресурсы хранятся в отдельных хранилищах (томах), что делает систему гибкой и лёгкой для масштабирования. Автоматический перезапуск сервисов обеспечивает стабильную работу.

Взаимодействие между контейнерами:

gw3yguaumqdjvllcuqe6xmv_grg.png

Представьте, что пользователь заходит на наш сайт и вводит запрос, например, «морской пейзаж при закате». Вот как происходит магия за кулисами:

  1. Фронтенд: Это первая точка контакта с пользователем. Фронтенд принимает запрос и передаёт его дальше по цепочке.

  2. Бэкенд: Получив запрос, бэкенд запускает свой ИИ-алгоритм. Этот алгоритм анализирует запрос и обращается к базе данных.

  3. База данных: Здесь хранятся все наши видео. Бэкенд запрашивает нужное видео на основе анализа запроса.

  4. Бэкенд: Получив видео из базы данных, ИИ-алгоритм сопоставляет его с запросом пользователя и генерирует уникальный идентификатор (ID) видео.

  5. Фронтенд: Бэкенд отправляет ID видео обратно на фронтенд, который красиво отображает результат пользователю.

Таким образом, каждый контейнер выполняет свою роль, слаженно работая вместе. Фронтенд принимает запросы, бэкенд обрабатывает их и взаимодействует с базой данных, а затем возвращает результат пользователю.

Итоги

Создание нашего сервиса по поиску видеоконтента на основе текстовых запросов является примером того, как можно применить передовые технологии ИИ для решения актуальных бизнес-задач. Мы обсудили ключевые аспекты разработки, включая выбор подхода к сбору данных, использование технологий для предобработки видео, и построение алгоритмов поиска и обработки текстовых описаний.

Наш сервис позволяет эффективно и быстро находить релевантные видеоролики, что является важным преимуществом в условиях растущего рынка коротких видеороликов. Внедрение AI в процессы поиска и использования видеоконтента способствует оптимизации рабочих процессов, снижению затрат времени и ресурсов, и повышению качества создаваемого контента.

Наш сервис по поиску видеоконтента по тексту может стать основой для многих приложений с короткими видео. Он подходит для создания тик-токов, instagram-stories (соцсеть Instagram принадлежат Meta*, заблокирована и запрещена в России) и других форматов. Вот как он может помочь бизнесу:

  • Автоматизация контента: Маркетологи смогут быстро находить и комбинировать видеоролики, сокращая время на подготовку рекламных кампаний.

  • Персонализированные ролики: Создание видеорекламы для разных сегментов аудитории увеличивает её эффективность.

  • Оптимизация архивов: Медиа-компании смогут быстро находить нужные материалы в видеоархивах.

  • Обзоры продуктов: Автоматическое создание видеороликов с обзорами на основе текстовых описаний и отзывов.

И это не все примеры, где сервис может применяться для автоматизации процесса работы с короткими видеороликами.

Для продакт-менеджеров и владельцев IT-бизнесов наш опыт поможет вдохновиться и станет наглядным примером того, как современные технологии могут решать практические задачи, улучшая пользовательский опыт и повышая конкурентоспособность на рынке.

Будущее улучшение сервиса:

Мы продолжаем развивать наш сервис и видим множество возможностей для его улучшения:

  1. Расширение базы данных видео: Интеграция новых источников видеоконтента увеличит количество доступных видео, повышая вероятность нахождения нужного контента.

  2. Обучение модели: Обучение модели не имеет границ, оно зависит от качества данных, методов обучения и архитектур моделей, которые стоят в основе нашей модели.

  3. Усовершенствование алгоритмов поиска и предобработки: Внедрение новых технологий улучшит скорость и качество поиска.

  4. Интеграция дополнительных метрик оценки качества: Дополнительные метрики помогут точнее оценивать работу сервиса и находить новые пути для его оптимизации.

В итоге наш сервис представляет собой мощный инструмент для поиска и использования видеоконтента, делая его незаменимым для современных IT-бизнесов и профессионалов в сфере цифровых технологий.

Контакты

нейро-сети.рф — Наша команда, мы занимаемся внедрением искусственного интеллекта в бизнес.

@eboutdatascience — Мой личный Telegram-канал, где я рассказываю про ИИ, Data Science, Собеседования, Найм и проектирование ИИ систем.

@ngmdite — Мой Telegram

© Habrahabr.ru