Привет! Меня зовут Алексей Мельников, я продакт в KION (онлайн-кинотеатр от МТС Digital), занимаюсь фичами, связанными с искусственным интеллектом.
Весной мы писали о фиче пропуска титров. Судя по карме, статья хабровчанам понравилась и это мотивировало нас на написание серии материалов, посвященных другой фиче – автоплею фильмов. Ниже я расскажу, как и зачем мы реализовали эту фичу и что у нее под капотом.
Autoplay позволяет не бросать еще «теплого» зрителя во время просмотра и предлагать ему новый фильм сразу после окончания предыдущего. Система рекомендаций сама подбирает контент, наиболее похожий на тот, что смотрит зритель. Новый фильм запускается в автоматическом режиме при наступлении титров, если пользователь бездействует.
Когда начинаются титры – мы уводим их в pip в левый нижний угол экрана и на бэке показываем постер следующего похожего фильма. В правой нижней части экрана показываем кнопки Следующий фильм и Смотреть титры. И если пользователь бездействует n секунд (этот параметр настраивается) – включаем следующий похожий фильм. Как это выглядит – показываю ниже:
Почему мы внедрили эту фичу?
Предпосылок для создания Autoplay было две:
мы созрели с точки зрения бэка и научились работать с i2i – item to item, подробно об этом ниже;
мы боремся не только с конкурентами, но и за внимание зрителя, который в момент окончания фильма решает, чем ему заняться дальше. Поспать? Погулять? Или посмотреть еще один фильм? Autoplay как раз подталкивает зрителя к дальнейшему просмотру.
А что под капотом?
Об этом подробно рассказывает Глеб Волохов, ведущий ML-разработчик KION:
Для стабильной и надежной работы ML-решений в продакшене необходимы:
полное версионирование моделей;
возможность быстро откатиться до какой-то конкретной версии модели (например, предыдущей);
контроль и хранение истории онлайн и оффлайн – метрик качества;
полная повторяемость пайплайнов в любой момент времени;
удобство и простота разработки для датасаентистов, а также их независимость от бэкенд разработчиков.
Также очень желательно максимально исключить человеческий фактор на всех этапах деплоя.
При построении системы, отвечающей всем нашим требованиям, в качестве центрального компонента был выбран MLFlow. Используя все возможности MLFlow, мы построили полностью автоматический пайплайн, в котором присутствуют следующие компоненты:
MLFlow – центральный компонент, отвечающий за отслеживание экспериментов, метрик, регистрацию моделей, а также, после небольшой доработки, выступающий инициатором автоматической раскатки моделей;
Gitlab репозиторий c dvc (mldatasets) – этот репозиторий используется для хранения датасетов для обучения и их версионирования;
Vanga – микросервис для моделей, обеспечивающий унифицированное API для работы с моделями;
MLTrainer – микросервис, который запускает модели учиться, принимает решение о раскатке и раскатывает новую версию модели в продакшен;
Ailflow – распространенное решение для выстраивания etl-процессов, в нашем случае даги периодически собирают датасеты для обучения и складывают в соответствующий репозиторий, анализируют нужно ли какую-то из моделей поучить и в случае успеха инициируют запуск нашего MLTrainer;
Telegram-чат – используется для информирования.
Остановимся на каждом из компонентов подробнее:
MLFlow
В MLFlow используется бэкенд – postgres 14.0, хранилище для артефактов – S3. Для того, чтобы обеспечить дальнейшую автоматическую раскатку зарегистрированных в MLFlow моделей, на таблицу в БД postgres, отвечающую за регистрацию моделей, были повешены сигналы, которые отлавливаются специальным сервисом. В зависимости от того, в какое состояние с точки зрения MLFlow переходит зарегистрированная модель, – вешаются хуки.
Например, при переходе из состояния 'None' в состояние 'Staging' происходит валидация входных параметров и дальнейшая раскатка микросервиса, отвечающего за API к этой модели. При переходе в состояние 'Archived' модель прекращает свою работу в продакшен контуре. Все действия дублируются ботом в наш служебный чат. В том числе, если в процессе раскатки не прошла какая-то валидация, информация об ошибке будет отправлена в чатик, а модель будет автоматически возвращена в состояние 'None'.
Каждая модель оформляется в виде MLFlow-проекта и имеет два обязательных эндпоинта: train и test. Train – эндпоинт, необходимый для автоматического переобучения модели на новых данных. В качестве обязательных входных аргументов эндпоинт принимает версию датасета из репозитория mldatasets.
Это необходимо для динамического влияния на версию данных, на которых мы хотим обучить нашу модель. Test – также принимает версию датасета и считает оффлайн-метрики, которые отслеживаются в MLFlow. Основываясь на метриках, наш автоматический тренер принимает решение, нужно ли новую версию модели выкатывать в продакшен.
Каждая модель представляет собой набор кода и вспомогательной информации, необходимой датасаентистам. Все для работы хранится в отдельном репозитории, каждая модель в своей ветке. Такой подход к организации работы дал нам следующее:
в любой момент мы можем откатиться на предыдущую версию;
в процессе трекинга наших экспериментов в MLFlow регистрируется и версия коммита, что позволяет на всех этапах отслеживать, что версия модели и версия кода консистентны;
в разных компонентах нашей архитектуры код, необходимый для работы с моделью, подключается как сабмодуль, а версия переключается по информации из MLFlow.
Так мы сделали из MLFlow-сервера единое место для хранения информации о моделях, которое не только любому клиенту может эту информацию предоставить, но и выступает инициатором выкатки и валидации входных данных: полноты и корректности для дальнейшего деплоя.
Mldatasets
Mldatasets – это gitlab-репозиторий с dvc, для которого настроен в s3 bucket с expire – 30 дней. Для каждого проекта своя ветка, а датасеты собираются в него по расписанию дагами из airflow. Даги собирают данные из различных источников (clickhouse, mongo и так далее), предобрабатывают, агрегируют и помещают в нужную ветку. Так появляется единая точка входа для получения датасетов, они единообразны и уже предобработаны. Также получаем жесткую версионированность, что для нас критически важно.
Использование такого репозитория позволяет нам точно знать, на каких датасетах училась какая модель, и, в случае необходимости, где угодно повторить обучение или проанализировать состояние датасетов.
Vanga
Это микросервис, обеспечивающий унифицированное API для взаимодействия с моделями. Микросервис написан на fastapi, обертка на модель подключается как сабмодуль, необходимая версия для каждой конкретной модели берется из MLFlow вместе с некоторой необходимой для раскатки мета-информацией. Например, можно задать вот что: назначение модели (как i2i), персонализацию витрины, включен или выключен режим автотренировки моделей.
В рамках CI запускаются тесты и прочие проверки. Инициатором раскатки выступает хук, повешенный на MLFlow при переводе зарегистрированной в MLFlow модели из состояния 'None' в состояние 'Staging'. В случае неудачного прохождения тестов модель также автоматически переводится в состояние 'None', а сообщение с текстом об ошибке направляется в соответствующий чат.
Airflow
Бэкенд, который отдает для нашего кинотеатра рекомендации i2i забирает их из redis. Наполняется redis дагом, логика работы которого следующая:
узнать, какие модели для i2i находятся в состоянии 'Production' с соответствующей мета-информацией (куда делать запрос);
получить рекомендации от соответствующего экземпляра микросервиса Vanga;
сохранить в Redis.
Также именно даг по расписанию проверяет, есть ли претенденты на обучение, смотрит, кто из моделей еще не учился на актуальной версии датасетов и запускает mltrainer.
MLTrainer
Компонент, отвечающий за переобучение моделей, принятие решений о выкатке новой версии модели и перевод текущей версии в архив. Сервис развернут на собственных мощностях МТС Медиа, оборудованных видеокартами Nvidia Tesla V100.
MLTrainer запускает для модели эндпоинт train, затем test, собирает оффлайн метрики после текущего обучения и предыдущих N обучений активной модели, принимая решение нужно ли текущую версию модели перевести в 'Archived' и раскатить новую версию модели в продакшен. При проседании оффлайн метрик модель не катится в продакшен, а разработчик получает уведомление об этом с ссылкой на run в MLflow.
Вся необходимая документация для работы датасаентистов оформлена при помощи Vuepress, что позволяет быстро найти информацию для работы.
Основной стек: MLFlow, Gitlab CI/CD, Fastapi, TensorFlow, Postgres, S3, Vuepress
Каким был фидбэк от юзеров?
Занимательным. Например, мы обнаружили, что некоторые пользователи, смотрят нон-стопом фильмы на смартфонах. Как мы это выяснили? У нас после просмотра 3 фильмов подряд всплывает сообщение:
И пользователи нажимают смотреть далее. Кстати, этот скрин сделал один из наших разработчиков во время путешествия, когда сам смотрел фильмы подряд без перерыва.
С точки зрения цифр мы получили следующие результаты:
После внедрения фичи мы увеличили один из наших ключевых показателей Total View Time Unique – количество минут смотрения в среднем на одного юзера. А еще мы увеличили среднюю длину сессии.
При этом количество зрителей, которые досматривают рекомендованный контент, находится в пределах 30-40%.
Что дальше?
В будущем мы планируем протестировать гипотезу о том, что пользователю нужен выбор: несколько вариантов контента, которые он может смотреть.
Идея такая – давать ленту с контентом в виде рекомендаций похожих фильмов в момент появления титров.
Кроме того мы планируем улучшать качество модели i2i и рекомендовать не только фильмы, но и сериалы.
Спасибо за внимание! Увидимся в KION!)
Комментарии (7)
mihnik
10.08.2022 07:57+5У меня одного ощущение, что мне рассказывают как меня, против моего желания, заставляют что-то делать(продолжать таращиться в телевизор, даже после окончания фильма), да ещё и при этом хвастаются этим, как большим научно-техническим достижением?
Если что, я могу и сам кнопочку play нажать.
akmelnikov Автор
10.08.2022 09:41Добрый день, Николай. У вас, как у пользователя Кион, есть возможность не смотреть, то что вам предлагают, выйти из плеера и искать другой фильм самостоятельно. Технически статья про item 2 item рекомендации, которые используются во многих местах приложения, не только в автоплей.
Zamuka
10.08.2022 09:55+5Негавижу эту "фичу" на нетфликс. После отличного фильма часто хочется потупить в титры под музыку и подумать, но нет, надо срочно искать пульт и за 5 секунд успеть нажать "смотреть титры". Сделайте хотя-бы возможность в настройках отключить всех этих помошников, которые "знают что мне нужно" лучше меня.
d583605
10.08.2022 13:29Начинал читать статью с такими же мыслями и уже формулировал их для комментария. Остаётся только полностью с вами согласиться. Прекрасно понимаю зачем этот функционал присутствует и включен по умолчанию, и рад за компании, если это работает. Но не могу представить, что бы меня это заставило смотреть ещё одну серию и уж тем более ещё один фильм. Всё таки какие-то планы на следующие полтора часа у меня чаще все есть.
Mike-M
10.08.2022 12:51в момент окончания фильма решает, чем ему заняться дальше. Поспать? Погулять? Или посмотреть еще один фильм?
IMHO, лучшепоспать/погулятьдать глазам отдохнуть.
Rebeiro
торренты наше все