Моя волна — теперь и в офлайне. Рассказываем, как уместили рекомендательную систему в сотню килобайт. ml.. ml. recsys.. ml. recsys. команда яндекс музыки.. ml. recsys. команда яндекс музыки. рекомендательные системы.. ml. recsys. команда яндекс музыки. рекомендательные системы. яндекс.. ml. recsys. команда яндекс музыки. рекомендательные системы. яндекс. Яндекс музыка.

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

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

Как это работает и что нам пришлось для этого создать — расскажем под катом.

Моя волна — теперь и в офлайне. Рассказываем, как уместили рекомендательную систему в сотню килобайт - 1

Идея полноценного офлайн-режима для Моей волны появилась не сразу. Мы, конечно, давно хотели сделать так, чтобы пользователи могли слушать музыку и без доступа в сеть. Обычно рекомендательные системы в музыкальных стримингах работают только онлайн: если сети нет — пользователь остаётся с набором скачанных треков, а рекомендации перестают адаптироваться к его действиям. В Яндекс Музыке тоже была возможность слушать скачанные треки, находясь без интернета. Для этого был офлайн-режим, который нужно включать отдельно. 

По сути, офлайн-режим — это такой «авиарежим» для Яндекс Музыки: включаешь в конкретные периоды отсутствия связи, чтобы слушать то, что скачалось на устройство. Проблема в том, что связь может пропадать спонтанно, на произвольные промежутки времени. Например, в лифте. У меня есть ещё один пример — личный и очень показательный. Однажды мы ездили в Карелию. Там между глэмпингами есть длинные участки дороги без интернета. И мы были вынуждены либо мириться с полным отсутствием Моей волны в пути, либо регулярно вручную переключаться между рекомендациями и офлайн-режимом. Неудобно.

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

Как это работает? Этот вопрос логично разделить на два других: откуда берётся музыка без интернета и как мы её ранжируем на устройстве. Начнём с более простого.

Откуда берутся треки для Моей волны в офлайне

Приложение Яндекс Музыка использует три источника треков на устройстве:

Кэш Моей волны. Треки, которые недавно играли в онлайне, сохраняются в кэше и могут использоваться офлайн.

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

Проактивная загрузка. Это новый механизм. Теперь приложение сообщает серверу Яндекс Музыки, какие треки уже есть на устройстве, и запрашивает дополнительные «на случай отключения интернета». Наша серверная рекомендательная технология анализирует список треков и присылает список дополнительных композиций, которые соответствуют предпочтениям пользователя и могут пригодиться при отсутствии сети.

Ну а дальше приложение просто скачивает эти треки в фоне. Чтобы не расходовать мобильный интернет, треки скачиваются только при подключении к Wi-Fi. Скачивание происходит ночью, когда устройство стоит на зарядке (или достаточно заряжено). Более того, пользователи могут управлять в настройках объёмом памяти, который Моя волна использует для офлайн-работы. Но отключать полностью не рекомендуем: без этой опции офлайн-рекомендации будут куда менее разнообразными и в потоке точно не будет новых, незнакомых треков.

Моя волна — теперь и в офлайне. Рассказываем, как уместили рекомендательную систему в сотню килобайт - 2

Как устроена технология локальных рекомендаций

В приложении Яндекс Музыки появилась не только проактивная загрузка треков, но и рекомендательная технология TinyML. Вопреки ожиданиям, это не нейросетевая модель, а куда более неожиданное решение. По сути, это очень маленькая виртуальная машина, встроенная в приложение Яндекс Музыки и выполняющая роль интерпретатора для специального байт-кода.

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

Помимо байт-кода, с сервера скачиваются и данные о загруженных треках. Не сами треки, а их векторные представления и другая полезная для рекомендаций техническая информация. Опять же, так мы экономим вычислительные ресурсы устройства, потому что вычисление векторов для треков происходит на сервере, а не локально. Благодаря этому офлайн-версия Моей волны доступна на любом смартфоне, где есть Яндекс Музыка.

Байт-код и данные о треках загружаются с сервера по API раз в три дня или при существенном изменении набора кэшированных треков. Общий объём данных с учётом сжатия обычно меньше 100 КБ, в худшем случае — меньше мегабайта. Система может работать с лимитом до 10 000 треков, но чаще всего это сотни треков.

На этом месте читатели с опытом в мобильной разработке могут спросить: а зачем вы создавали свою TinyML, а не воспользовались уже существующими решениями? Ведь есть проект ONNX, есть нативные ML-библиотеки. С одной стороны, это упростило бы нам работу, не пришлось бы писать свой серверный компилятор. С другой — нам бы пришлось выносить логику работы рекомендаций из байт-кода на клиенты, писать её под каждую платформу. А ещё клиентский код не так-то просто обновить без обновления всего приложения, в отличие от загрузки простого байт-кода по API.

Кто-то может вспомнить ещё и проект WebAssembly, который уже «из коробки» позволяет работать с ML и писать код низкого уровня. Но в этом случае нам пришлось бы встроить его библиотеку в само приложение и увеличить его размер на десятки мегабайт. Столь радикально раздувать размер ради одной единственной функции мы не считаем правильным. TinyML уложился в 30 килобайт.

В общем, альтернативные решения, конечно, есть, но они усложняют клиентский код и недостаточно гибкие для нас. Поэтому мы вынесли все сложности на бэкенд, а в приложение Музыки добавили один единственный класс на 500 строк кода.

Как Моя волна в офлайне работает на практике

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

Помимо байт-кода для локального формирования рекомендаций, сервер также отдаёт предпросчитанную очередь — список треков «что поставить, если интернет отключится прямо сейчас». Это несколько десятков треков, рассчитанных тяжёлыми серверными нейросетями. Эта очередь — палочка-выручалочка для коротких перебоев с сетью вроде поездки на лифте. TinyML может использовать её как основу, но если пользователь начинает пропускать треки, система отбросит предпросчитанную очередь и будет строить рекомендации на основе свежей обратной связи. 

Например, у пользователя в кэше есть и джаз, и металл. Он начинает пропускать металл — TinyML понимает, что настроение изменилось, и переключается на джаз. Всё это происходит локально, без интернета. 

Для длительного офлайн-прослушивания (те самые несколько часов в Карелии) основную работу делает локальный код TinyML, а не предпросчитанная очередь.


Когда мы начинали этот проект, то хотели дать пользователям возможность непрерывно слушать Мою волну, влиять на неё, открывать для себя что-то новое — без оглядки на то, что происходит с интернетом в этот момент. Хочется верить, что у нас получилось.

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

Автор: alsafr

Источник

Rambler's Top100