Моя волна теперь работает в офлайне: как мы уместили рекомендательную систему в сотню килобайт

Моя волна теперь работает в офлайне: как мы уместили рекомендательную систему в сотню килобайт

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

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

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

Откуда берутся треки без интернета

Приложение использует три источника музыки для офлайн-рекомендаций:

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

Приложение сообщает серверу, какие треки уже есть на устройстве, а сервер присылает дополнительные — те, что соответствуют вашим предпочтениям. Эти треки скачиваются в фоне: ночью, на Wi-Fi и при достаточном заряде. Так мы экономим трафик и не нагружаем устройство.

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

Как работает локальная рекомендательная система

Сердце офлайн-режима — технология TinyML. Это не нейросеть, а миниатюрная виртуальная машина, встроенная в приложение. Она интерпретирует специальный байт-код — скомпилированный код на языке C, который формирует рекомендации на устройстве.

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

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

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

Почему мы не использовали готовые решения

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

WebAssembly тоже рассматривался, но его добавление увеличило бы размер приложения на десятки мегабайт. Для одной функции — слишком дорого. TinyML же занимает всего 30 КБ.

Мы перенесли всю сложность на сервер, а в приложении остался всего один класс из 500 строк. Это сделало систему гибкой, лёгкой и легко обновляемой.

Как это работает в реальной жизни

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

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

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

Для длительных поездок — например, несколько часов в дороге без связи — основную работу выполняет именно локальный код, а не предпросчитанная очередь.

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

Читать оригинал