Real-time Machine Learning For Recommendations
Юджин Ян разбирает, как машинное обучение в реальном времени применяется в рекомендательных системах, отталкиваясь от наблюдения Chip Huyen о том, что китайские компании в MLOps опережают американские. Большинству задач достаточно пакетных (batch) рекомендаций — они дешевле и проще в эксплуатации, тогда как рекомендации в реальном времени оправданы, когда поведение клиента контекстно и миссия-ориентировано (шопинг, выбор фильма, реклама, холодный старт новых пользователей). Автор объясняет основы (коллаборативные vs контентные рекомендации, i2i vs u2i, генерация кандидатов и ранжирование) и показывает, как CF и алгоритм Swing от Alibaba позволяют инкрементально обновлять рекомендации; приводятся архитектуры Alibaba 1688, Tencent, YouTube, Instagram и Netflix. У Tencent A/B-тесты дали прирост CTR на 6–8% для новостей и 6–18% для e-commerce. В финале описывается дешёвый MVP: эмбеддинги через word2vec (skip-gram), генерация кандидатов через ANN (ScaNN), ранжирование логистической регрессией с cross-фичами и развёртывание на AWS SageMaker — 30 инстансов m5.xlarge выдают 1200 запросов в секунду с медианной задержкой 25 мс при стоимости около 5,5 тыс. в месяц.
Машинное обучение в реальном времени для рекомендаций
[ teardown machinelearning recsys production 🔥 ] · 21 мин чтения
Несколько недель назад Chip сравнила состояние машинного обучения в реальном времени в Китае и США: пока многие китайские компании уже внедрили real-time ML, американские компании всё ещё оценивают его ценность. Она также писала о переходе ML в реальное время здесь.
Общение с интернет-компаниями в Китае оставляет впечатление, что их MLOps-инфраструктура заметно опережает. Многие интернет-компании в США всё ещё гадают, есть ли ценность в real-time ML. Их китайские коллеги уже делают инференс в реальном времени + онлайн-обучение. Не предвзята ли моя выборка? — Chip Huyen (@chipro) 10 декабря 2020
Этот пост продолжает тему и рассказывает, как real-time ML выглядит на практике. Опираясь на мой опыт и отраслевые статьи/блоги, мы обсудим рекомендации в реальном времени.
Когда рекомендации в реальном времени имеют смысл? А когда нет? Как китайские и американские компании реализовали рекомендатели реального времени? Как спроектировать и реализовать простой MVP?
Примечание: это обсуждение предполагает базовое знание рекомендательных систем, например различие между item-to-item и user-to-item, а также парадигму генерации кандидатов и ранжирования. Не переживайте, если эти термины незнакомы. У нас будет два вводных раздела, которые помогут вам войти в курс дела. Нажмите на 👉 ниже, чтобы начать с первого.
Если вы понимаете разницу между коллаборативными и контентными рекомендациями, а также между item-to-item и user-to-item, можете смело пропустить этот раздел.
Коллаборативные рекомендации основаны на поведении пользователей. Предположим, мне нравится фильм X и не нравится фильм Y. Чтобы порекомендовать мне фильмы, мы сначала находим пользователей, похожих на меня (то есть тех, кому нравится X и не нравится Y). Затем смотрим: какие фильмы понравились им, но я их ещё не смотрел? Эти фильмы и рекомендуются мне. С помощью данных о поведении пользователи могут «сотрудничать», создавая рекомендации друг для друга. Коллаборативная фильтрация — пожалуй, самый известный подход.
Контентные рекомендации основаны на метаданных объектов. Исходя из фильмов, которые я смотрел (и которые мне понравились), контентные рекомендатели предлагают фильмы похожего жанра, периода, режиссёра и т. д. По сравнению с коллаборативными рекомендателями, контентные обычно эффективнее, когда фильм новый и у нас ещё недостаточно данных о поведении пользователей по нему (то есть проблема холодного старта, cold-start).
В item-to-item (i2i) рекомендациях по заданному объекту мы рекомендуем другие объекты. Вот пример i2i-рекомендаций на IMDB — в виджете «More Like This». Это хорошо работает в сценариях, где в центре внимания сам объект (например, страница с детальной информацией о товаре).
Похожие на «День независимости» на IMDB
В user-to-item (u2i) по заданному пользователю мы рекомендуем объекты. Мы видим это на главной странице Netflix, Amazon, Taobao — иногда под названием «Recommended For You». Наши ленты в соцсетях (например, Twitter, LinkedIn, Facebook) — это тоже u2i-рекомендации. В таких сценариях в центре внимания находится пользователь (и его историчные предпочтения).
«Recommended For You» на Amazon
Вместе i2i- и u2i-рекомендации обеспечивают покрытие основной массы пользовательского трафика — через детальные страницы и главные страницы.
Когда (не) стоит использовать рекомендации в реальном времени?
Прежде чем мы слишком воодушевимся, сразу скажу, что большинству сценариев рекомендации в реальном времени не нужны; пакетных (batch) рекомендаций вполне достаточно.
По сравнению с рекомендациями в реальном времени, пакетные рекомендации вычислительно дешевле. Обычно их генерируют раз в день, и они выигрывают от эффекта масштаба пакетной обработки. Затем рекомендации загружаются в key-value-хранилище (например, Redis, DynamoDB) и отдаются по ключу.
Пакетные рекомендации также проще с точки зрения эксплуатации. Кэшируя предвычисленные рекомендации (в нашем key-value-хранилище), мы отделяем вычисление от отдачи. Поэтому даже если этап вычислений упадёт, на клиента это никак не повлияет; мы продолжаем отдавать предыдущую партию (слегка устаревших) рекомендаций. Кэш служит буфером и обеспечивает почти 100% доступность, снижая эксплуатационную нагрузку на команду (например, дежурства, жалобы).
Batch против стриминга на примере аналитики (источник)
Напротив, рекомендации в реальном времени обычно требуют больше вычислений. Например, мы можем агрегировать потоковые события (например, клик, лайк, покупку) и генерировать новые рекомендации по запросу, на основе действий пользователя. (Для сравнения: пакетные рекомендации вычисляют лишь один набор раз в день.) Более того, такие вычисления выполняются индивидуально и не выигрывают от эффекта масштаба. (Тем не менее мы экономим, не генерируя рекомендации для клиентов, которые не заходят в наше приложение.)
Эксплуатировать рекомендации в реальном времени в продакшене также гораздо сложнее. Вместо эфемерных Spark-кластеров (для вычислений) и DynamoDB (для отдачи) нам понадобятся низколатентные высокопроизводительные API с доступностью 24/7. В самом строгом сценарии у нас не будет key-value-хранилища как буфера. Граница между вычислением и отдачей исчезает. Эксплуатационная нагрузка вырастет (читай: нас разбудят посреди ночи из-за сбоя в другом часовом поясе 🚨).
Зачем тогда рекомендации в реальном времени? Они полезны, когда путь клиента миссия-ориентирован и зависит от контекста. Такие «миссии» часто чувствительны ко времени. Спрос в реальном времени быстро угасает; потребность может быть удовлетворена (на сайте конкурента), либо пользователь потеряет интерес. Мы рассмотрим это на двух примерах: шопинг и просмотр фильма.
Шопинг — это миссия-ориентированная активность. Хотя клиент может преимущественно покупать одну категорию товаров, его покупательское поведение часто перемежается побочными «миссиями». Например, если я обычно покупаю одежду, мои u2i-рекомендации в основном будут модными. Однако если мне понадобился новый широкоэкранный монитор и я начинаю его искать, мои u2i-рекомендации должны обновиться как можно скорее, чтобы помочь мне быстро выполнить мою миссию (иначе я уйду в конкурирующее приложение).
В этом сценарии пакетные рекомендации реагируют недостаточно быстро. И даже когда рекомендации обновляются, из-за дисбаланса данных такие связанные с миссией потребности не удовлетворяются (подробнее в разделе 2.1 этой статьи Netflix).
Фильмы, которые мы смотрим, зависят от контекста (хотя наши долгосрочные предпочтения довольно стабильны). Например, мы можем смотреть разные фильмы в зависимости от того, одни ли мы, с друзьями, с романтическим партнёром или с детьми. Это также может зависеть от настроения и времени суток. Как и в случае с шопингом, ежедневные пакетные рекомендации сталкиваются здесь с теми же трудностями.
Помимо приведённых выше примеров, рекомендации в реальном времени также удобны в:
Путешествия (наши места отдыха часто меняются) YouTube (за один день мы смотрим видео про программирование, йогу и рецепты) Показ рекламы (наш интерес чувствителен ко времени; наша концентрация внимания сокращается)
Рекомендации в реальном времени также полезны, когда большинство наших клиентов — новые (то есть холодный старт). Это происходит на этапе привлечения клиентов, например когда мы только что запустили новый продукт или вышли на новый рынок (скажем, e-commerce в Юго-Восточной Азии в 2013–2015 годах).
Представьте, что вы только что скачали приложение для e-commerce. Поскольку мы не знаем ваш пол, главная страница будет содержать смесь категорий для обоих полов — от платьев до мужских рубашек, от GPU до косметики. Если вы кликнете на платье, мы можем немедленно построить персону (что вы женщина) и персонализировать ваш опыт покупок. В этом случае u2i-рекомендации на вашей главной странице склонятся в сторону женских товаров.
Учитывая, что 1 из 4 пользователей бросает мобильные приложения после всего одного использования, быстрая реакция на потребности клиента — с самого первого касания — помогает в привлечении и удержании.
Вводный раздел II: генерация кандидатов и ранжирование
Пропустили первый вводный раздел (коллаборативные vs контентные, item-to-item vs user-to-item)? Нажмите на 👉 здесь.
Большинство современных рекомендателей имеют два ключевых компонента: генерацию кандидатов и ранжирование.
Генерация кандидатов — это быстрый, но грубый способ получить (сотни) объектов-кандидатов из миллионов объектов. Мы жертвуем точностью ради эффективности, чтобы сократить пространство поиска (например, со 100 миллионов до 1000 кандидатов — сокращение на 99,999%). Обычно это делается через фильтры по метаданным (например, категория, бренд) или через метод k ближайших соседей.
Ранжирование — это более медленный, но более точный способ отсортировать и отобрать лучшие объекты-кандидаты. У нас есть свобода включить признаки, которые могли быть невозможны на этапе генерации кандидатов. Такие признаки включают персону пользователя (например, демография, склонность к цене), метаданные объекта (например, атрибуты, статистику вовлечённости), кросс-признаки (например, взаимодействие между каждой парой признаков) и медиа-эмбеддинги.
Ранжирование можно сформулировать либо как задачу классификации, либо как задачу learning to rank. Как задачу классификации — мы можем оценивать кандидатов по вероятности клика или покупки. Логистическую регрессию с кросс-признаками просто реализовать, и её сложно превзойти как базовую модель. Также широко используются деревья решений. Как задачу learning to rank — часто применяются алгоритмы LambdaMart, XGBoost и LightGBM. Нейронные сети также набирают популярность благодаря росту эффективности моделей за счёт дистилляции, прунинга, квантизации и т. д.
Отраслевые примеры рекомендаций в реальном времени
Этот общий справочный материал проливает свет на рекомендательные системы с китайской точки зрения. Он организован по обсуждаемой парадигме, с разделами для генерации кандидатов («Match») и ранжирования («Rank»). В нём также обсуждаются два других компонента: профиль (построение предпочтений пользователя) и постобработка (например, исключение ранее купленных товаров, дедупликация объектов между наборами рекомендаций).
Чтобы увидеть, как рекомендации можно обновлять инкрементально, мы обсудим два алгоритма: скромную коллаборативную фильтрацию (CF) и алгоритм Swing от Alibaba, который её улучшает.
Коллаборативная фильтрация (для i2i-рекомендаций) реализуется с помощью трёх формул ниже. Давайте попробуем понять, что они делают и какая интуиция за ними стоит.
Вес пользователя: вес пользователя обратно пропорционален числу его взаимодействий с объектами (например, кликов, лайков, добавлений в список желаемого). Интуиция: пользователи, которые много просматривают, как правило, менее разборчивы, и потому их поведенческие данные более зашумлены.
Вес объекта: чем больше пользователей взаимодействует с объектом, тем выше его вес.
Оценка схожести объектов: чтобы вычислить схожесть пары объектов, мы суммируем веса пользователей, которые взаимодействовали с обоими объектами, и делим это на произведение весов объектов. Интуиция: чем больше пересечение по взаимодействиям пользователей, тем выше схожесть объектов (аналогично коллаборативной фильтрации через матричную факторизацию или метод чередующихся наименьших квадратов).
Алгоритм Swing отличается тем, что вес (пары пользователей) зависит от числа объектов, с которыми оба они взаимодействовали (в отличие от CF, где веса пользователей постоянны). Чем больше доля объектов, с которыми взаимодействовали оба пользователя (то есть пересечение), тем выше веса пользователей.
Вес пользователя: аналогично коллаборативной фильтрации.
Вес пары пользователей: произведение весов пользователей. Для n пользователей у нас есть n^2 весов пар пользователей.
Оценка схожести объектов: аналогично коллаборативной фильтрации. Ключевое отличие в том, что знаменатель учитывает только пересечение товаров, с которыми взаимодействовали оба пользователя. (В отличие от CF, где учитываются все товары, с которыми взаимодействовал любой пользователь.)
Чтобы было понятнее, вот как мы вычислили бы схожесть объектов в коде:
for i in xrange(0, len(u2items)): wi = math.pow(len(u2items[i]) + 5, -0.35) for j in xrange(i + 1, len(u2items)): intersection = u2items[i] & u2items[j] wj = wi * math.pow(len(u2items[j]) + 5, -0.35) for product_id in intersection: i2i[product_id] = i2i.get(product_id, 0.0) + wj / (1 + len(intersection)) # u2items = массив пользователей и их объектов # u2items[i] = объекты, на которые кликнул пользователь i # u2items[j] = объекты, на которые кликнул пользователь j # intersection = объекты, на которые кликнули и пользователь i, и пользователь j # wj = оценка пары товаров # i2i инкрементально обновляется по мере прохода по пользователям (в продакшене мы не будем использовать цикл)
Интуитивно: если два пользователя с очень разными вкусами (и разными взаимодействиями с товарами) кликают на одну и ту же пару товаров, это говорит о сильной связи между этой парой. И наоборот, если у двух пользователей похожие вкусы (и много общих пар товаров), связь между парой товаров слабее. Это снижает шум от стадного поведения (например, проблема «Гарри Поттера») и выявляет более осмысленные i2i-рекомендации.
Из этих простых уравнений видно, как рекомендации можно инкрементально обновлять в реальном времени. Вместо пакетного умножения матриц веса пользователей и объектов обновляются при каждом взаимодействии клиента, возможно, в key-value-хранилище. Затем веса можно скомбинировать — через суммирование — чтобы обновить i2i-рекомендации.
Эти уравнения можно также адаптировать для вычисления привязанности пользователя к категории, бренду, продавцу, ценовому сегменту и т. д. Такие привязанности затем используются для взвешивания объектов-кандидатов. Например, если у пользователя есть историческое предпочтение к конкретному бренду, мы даём товарам этого бренда больший вес.
Вот пример использования Swing и привязанности к категории в рекомендациях в реальном времени в Alibaba. Эта реализация — для виджета «Recommended For You» на главной странице 1688, B2B-площадки e-commerce. Виджет получает клики от 72% пользователей.
Архитектура рекомендаций в реальном времени для Alibaba 1688 (источник)
Краткий обзор компонентов инфраструктуры:
iGraph: распределённая графовая база данных. Воспринимайте её как key-value-хранилище, где узлы и рёбра — это ключи, а веса — значения. Позволяет эффективно выполнять соединения узлов и рёбер и графовые запросы. Используется для хранения предпочтений пользователей и метаданных объектов (например, весов пользователей и объектов из обсуждаемых алгоритмов). ABFS: Alibaba basic feature server. Используется для вычисления в реальном времени статистических признаков по взаимодействиям пользователей (например, клики, лайки, покупки и т. д.). BE: Basic engine. Высокоэффективные фильтры на уровне объектов и kNN на основе эмбеддингов. Используется для генерации кандидатов. RTP: Real-time prediction. Модели для оценки объектов по различным целям (например, CTR, конверсия). Включает логистическую регрессию, Wide & Deep, Product-based Neural Network и Behavioral Sequence Transformer. Используется для ранжирования. Porsche: распределённое обучение моделей. Используется для офлайн-обучения и валидации. Может также использоваться для обновления параметров модели онлайн, хотя здесь это не применяется. TPP: Taobao personalization platform. Слой абстракции над перечисленными выше компонентами инфраструктуры для повышения продуктивности и удобства разработчиков.
Вот как рекомендации обновляются и отдаются. По мере того как пользователь просматривает приложение:
При каждом взаимодействии с объектом (например, клик, лайк, добавление в корзину, покупка) ABFS вычисляет статистические признаки пользователя и объекта. Они передаются в BE и, опционально, асинхронно обновляются в iGraph. BE генерирует топ-1000 кандидатов на основе признаков пользователя и объекта (то есть предпочтений пользователя, трендов по объектам) из ABFS. На изображении мы видим, что BE использует алгоритмы Swing i2i и c2i (category-to-item). RTP ранжирует 1000 кандидатов. На этом этапе можно добавить признаки, такие как профиль пользователя (пол, возраст, склонность к цене), атрибуты объекта (категория, бренд, продавец), контекст (совпадение с последним кликом/поиском пользователя), кросс-признаки (то есть признаки взаимодействия) и последовательностные признаки (последовательность кликов/категорий). Топ-600 товаров показываются пользователю.
Подход Tencent похож. Суть в том, чтобы разбить item-based CF на два агрегата: счётчик объектов и счётчик пар. Затем схожесть объект-к-объекту вычисляется с использованием этих агрегатов. Таким образом, агрегаты объектов и пар можно инкрементально обновлять и комбинировать для генерации рекомендаций в реальном времени. Их система реализована на Apache Storm и используется в Tencent News, Tencent Videos, YiXun (e-commerce) и QQ ads (мессенджер).
A/B-тесты показали, что рекомендации в реальном времени привели к росту CTR на 6–8% для новостных рекомендаций и на 6–18% для рекомендаций e-commerce.
В статье также описаны приёмы, использованные для решения нескольких задач (перечислены ниже). Настоятельно рекомендую к прочтению.
Границы Хёффдинга для отсечения избыточных событий взаимодействия пользователей Кластеризация на основе демографии для борьбы с проблемами холодного старта Кэширование для обработки высокой нагрузки чтения из-за всплесков трафика Буферы для устранения перекосов в данных (так называемая «проблема горячего объекта»)
Далее мы смотрим на запад и видим, как американские компании реализовали рекомендации в реальном времени.
Сначала вот система рекомендации видео YouTube. К этому моменту нам уже должна быть знакома общая парадигма проектирования.
Архитектура рекомендаций в реальном времени для YouTube (источник)
Для генерации кандидатов применяется приближённый kNN на эмбеддингах видео и поиска, чтобы отобрать сотни видео из миллионов (вероятно, уже миллиардов на сегодняшний день).
Для ранжирования используется глубокая нейронная сеть, чтобы оценить каждое видео и отобрать пару десятков лучших. Дополнительные признаки (например, статистика по запросам и видео, предыдущие взаимодействия пользователя) помогают повысить точность. Нейронная сеть обучается с помощью взвешенной логистической регрессии, где положительные метки взвешиваются по времени просмотра видео (отрицательные метки не взвешиваются). Это отражает бизнес-цель — увеличение ожидаемого времени просмотра на одно показанное видео.
Подход Instagram похож. На этапе генерации кандидатов эмбеддинги аккаунтов используются для выявления аккаунтов, похожих на те, с которыми пользователь ранее взаимодействовал. Из этих аккаунтов-кандидатов они выбирают 500 медиа-кандидатов (например, фото, истории).
Архитектура рекомендаций в реальном времени для Instagram (источник)
Затем эти медиа-кандидаты проходят трёхэтапный процесс ранжирования, в котором используется комбинация техник для сжатия нейросетевых моделей:
Первый проход: дистиллированная модель имитирует поздние этапы с минимальным набором признаков и возвращает топ-150 ранжированных кандидатов. Второй проход: лёгкая нейронная сеть использует полный набор плотных (dense) признаков и возвращает топ-50 ранжированных кандидатов. Финальный проход: глубокая нейронная сеть использует полный набор плотных (dense) и разреженных (sparse) признаков и возвращает топ-25 ранжированных кандидатов (для первой страницы сетки Explore).
В качестве последнего примера рассмотрим, как Netflix переранжирует рекомендации в реальном времени. На большинстве страниц Netflix мы видим несколько строк рекомендаций. В каждой строке рекомендаций — десятки фильмов. Цель — переупорядочить строки рекомендаций (то есть порядок «север-юг») а также фильмы внутри каждой строки (то есть порядок «запад-восток»).
Строки рекомендаций на главном экране Netflix (источник)
Горизонтальные прокрутки (по строкам рекомендаций) используются как сигналы взаимодействия пользователя. Они показали, что вероятность воспроизведения видео положительно коррелирует с числом горизонтальных прокруток.
Связь между горизонтальной прокруткой и вероятностью просмотра (источник)
В отличие от предыдущих примеров, переранжирование выполняется на устройстве клиента, что избавляет от обращения к серверу. (Однако это также не позволяет выполнять генерацию кандидатов.) Поскольку устройства просмотра могут быть маломощными (например, телевизоры), вычисления должны быть лёгкими. Поэтому используемые алгоритмы — простые, но эффективные вероятностные модели. Это позволяет обновлять строки рекомендаций ниже сгиба (то есть не на экране) на лету, по мере того как пользователь выполняет горизонтальную прокрутку выше сгиба.
Итак, мы видим, что рекомендации в реальном времени становятся всё более распространёнными как в Китае, так и в США. Однако доступны ли они только крупным технологическим компаниям? Нет. Вот как дёшево построить MVP.
Как спроектировать и реализовать MVP
После приведённых выше примеров вы, возможно, думаете, что рекомендатели реального времени требуют специализированной инфраструктуры, моделей глубокого обучения и всего такого. Надеюсь убедить вас в обратном.
Мы кратко пройдёмся по тому, как спроектировать и построить MVP, сосредоточившись на том, что обычно считается узким местом рекомендателей реального времени: вычисления и отдача. В отличие от этого, обучение относительно проще и широко обсуждается.
Для начала, я считаю полезным подходить к DS/ML-системам в трёх широких мазках:
Требования (или ограничения): как выглядит успех? Чего мы не можем делать? Методология: как мы будем использовать данные и код для достижения успеха? Реализация: какая инфраструктура нужна в продакшене?
Определяя требования, мы должны отталкиваться от клиента. Как рекомендации в реальном времени улучшат клиентский опыт и, в свою очередь, принесут пользу бизнесу? Какие бизнес-метрики важны? Цели и метрики успеха будут различаться в зависимости от бизнеса и сценария использования и здесь определяться не будут.
Для нашего MVP, пожалуй, важнее требований сами ограничения (то есть как не решать задачу). Вот некоторые ограничения для нашего рекомендателя реального времени:
Задержка (latency): отзывчивость приложения критична для пользовательского опыта. Google обнаружил, что дополнительные 500 мс на генерацию результатов поиска снижали трафик на 20%. Amazon сообщил, что дополнительные 100 мс задержки снижают прибыль на 1%. Поэтому для нашего MVP мы задаём бюджет в 200 мс задержки (без учёта сетевой задержки от пользователей до нашего сервера). Пропускная способность (throughput): чтобы оценить масштабируемость нашего дизайна, мы задаём ожидаемую пропускную способность в 1000 запросов в секунду (QPS), или около 84 миллионов запросов в день. Скорее всего, нам не понадобится 1000 QPS в течение всего дня, так как трафик колеблется. Стоимость (cost): чтобы добиться здорового ROI, стоимость должна быть долей ожидаемой выручки. Предполагая, что рекомендации в реальном времени приносят дополнительные 100 тыс. в месяц, мы задаём инфраструктурный бюджет в 10 тыс. в месяц (то есть 10%).
Нам также следует учесть и другие аспекты, такие как доступность (она же резервирование), безопасность, приватность, этика и т. д. Тем не менее для нашего MVP первые три ограничения — технические и бизнесовые «стоп-факторы», на которых мы и сосредоточимся.
Для обучения эмбеддингов объектов мы применяем простой, но эффективный подход word2vec, а именно модель skip-gram. (Его также используют Instagram, Twitter и Alibaba.) Я писал ранее о том, как создавать эмбеддинги через word2vec и DeepWalk, и здесь не буду вдаваться в детали.
Для генерации кандидатов мы применяем метод k ближайших соседей (как в реализации YouTube). Однако точный kNN медленный, и на этом этапе нам на самом деле не нужна такая точность. Поэтому вместо него мы используем приближённый метод ближайших соседей (ANN).
Существует несколько реализаций ANN с открытым исходным кодом, таких как FAISS от Facebook, ScANN от Google и Hierarchical Navigable Small World Graphs (hnswlib). Мы сравним их по компромиссу recall/задержка. Чтобы имитировать продакшен-условия, каждый запрос состоит из одного эмбеддинга (то есть размер батча = 1). График ниже показывает, что ScaNN превосходит две другие реализации. (FAISS, в частности, оптимизирован под батчевые запросы.)
Бенчмаркинг ANN по recall vs задержка; правый верхний угол лучше.
Установка ScaNN на Mac непростая и заняла несколько мучительных часов, чтобы разобраться. Если вы столкнётесь с проблемами, вам может пригодиться эта пошаговая инструкция.
Кроме того, вот несколько GitHub-issues, которые могут помочь:
TF_SHARED_LIBRARY_NAME set with typos when configure Error: Reason: image not found Building from source shows error (undefined symbol: _Py_ZeroStruct)
Для ранжирования кандидатов мы начинаем с однослойной нейронной сети (читай: логистической регрессии) с кросс-признаками — просто, но трудно превзойти. Кросс-признаки создаются путём комбинирования всех возможных пар признаков для захвата их взаимодействий. Хотя это раздувает пространство признаков, для логистической регрессии это не проблема.
Помимо метрик машинного обучения (то есть recall@k, NDCG, AUC), вероятно, важнее учитывать бизнес-метрики (возвращаясь к требованиям). Разные цели требуют разных метрик:
Если наша цель — повышение вовлечённости или продажа рекламы на основе кликов, мы захотим учитывать абсолютное число кликов, click-thru-rate, среднесуточное число пользователей. Если наша цель — привлечение клиентов, мы захотим оптимизировать первую продажу (например, число проданных единиц, конверсию), среднемесячное число пользователей и будем готовы пожертвовать выручкой. Если наша цель — рост выручки, мы захотим сосредоточиться на выручке за сессию, среднем размере корзины и пожизненной ценности клиента (customer lifetime value).
По опыту, у бизнес-стейкхолдеров обычно конфликтующие цели. Маркетинг хочет совершить первую продажу (независимо от цены товара), клиентский опыт хочет убрать товары низкого качества (даже если они хорошо продаются), а коммерческий отдел хочет максимизировать прибыль (продавая более дорогие товары). Заставить всех договориться о ключевых метриках и ограничениях может быть сложнее, чем улучшить наши модели.
Потребует ли наш MVP специализированной инфраструктуры? Не обязательно. Экономичный подход — использовать инстансы EC2, которые могут горизонтально масштабироваться с балансировщиком нагрузки впереди. Чтобы ещё больше упростить дело, мы можем просто использовать AWS SageMaker.
SageMaker берёт на себя балансировку нагрузки на нескольких инстансах (источник изображения)
Для оценки задержки и пропускной способности у нас есть различные варианты, включая serverless-artillery (гайд AWS) и locust. Несколько нагрузочных тестов показали, что эндпоинт SageMaker на 30 инстансах m5.xlarge смог обслуживать 1200 запросов в секунду без особых усилий. При такой пропускной способности медианная задержка составила 25 мс, а 99-й перцентиль — 65 мс. Ошибок не было ни одной.
Что касается стоимости, инстансы m5.xlarge (16 ГБ RAM, 4 CPU) в US West (Oregon) имеют почасовую ставку $0,269. Запуск 30 инстансов на 28 дней выходит примерно в 5,5 тыс., что вполне укладывается в наш бюджет в 10 тыс. Использование зарезервированных инстансов и/или автомасштабирования может помочь снизить стоимость.
Наш простой MVP намеренно исключает несколько соображений. Например, чтобы другие сервисы могли запрашивать наши эмбеддинги объектов, мы можем захотеть выставить их как отдельный сервис. Это потребует дополнительной инфраструктуры (например, DynamoDB), что увеличит стоимость и эксплуатационную нагрузку. Дополнительный вызов сервиса (для эмбеддингов объектов) также добавит задержку (10–30 мс), хотя её можно минимизировать при хорошей настройке сети. Также: как мы можем выставить наши сервисы генерации кандидатов и ранжирования через универсальные API, чтобы другие пользователи могли комбинировать их по необходимости? Это стоит учесть в долгосрочном роадмапе.
Построить рекомендатель реального времени не обязательно сложно
Надеюсь, это улучшит ваше понимание машинного обучения в реальном времени в контексте рекомендательных систем и продемонстрирует, что это не непреодолимая задача. Библиотеки (например, ScaNN) и управляемые сервисы (например, AWS SageMaker) скрывают большую часть рутины — такой как оптимизация, проверки работоспособности, автомасштабирование, восстановление и т. д. Построение на их основе позволяет создавать эффективный, недорогой real-time ML.
Проектирование и реализация систем машинного обучения могут быть сложными. Если вы создаёте такую систему и хотели бы получить взгляд со стороны или обратную связь, свяжитесь через @eugeneyan или email.
Как выглядит real-time ML на практике? Мы обсуждаем рекомендатели реального времени, опираясь на мой опыт и отраслевые статьи: • Когда это имеет смысл? А когда нет? • Как китайские и американские компании их реализовали? • Как нам спроектировать и построить MVP? https://t.co/hSfRr3q2ie — Eugene Yan (@eugeneyan) 12 января 2021
Источники
推荐系统技术 机器如何“猜你喜欢”?深度学习模型在1688的应用实践 TencentRec: Real-time Stream Recommendation in Practice Deep Neural Networks for YouTube Recommendations Powered by AI: Instagram’s Explore recommender system Using Navigation to Improve Recommendations in Real-Time 为电商而生的知识图谱,如何感应用户需求 The Secret Behind Taobao’s AI-Powered Personalized Recommendations Personalized Bundle List Recommendation Embeddings@Twitter Billion-scale Commodity Embedding for Recommendation in Alibaba Больше статей по рекомендательным системам в репозитории applied-ml
Благодарю Yang Xinyi, Karl Higley, Will Larson и Tushar Chandra за прочтение черновиков. Благодарю Hammad Khan за исправление.
Если вам это оказалось полезным, пожалуйста, цитируйте эту статью так:
Yan, Ziyou. (Jan 2021). Real-time Machine Learning For Recommendations. eugeneyan.com. https://eugeneyan.com/writing/real-time-recommendations/.
или
@article{yan2021realttime, title = {Real-time Machine Learning For Recommendations}, author = {Yan, Ziyou}, journal = {eugeneyan.com}, year = {2021}, month = {Jan}, url = {https://eugeneyan.com/writing/real-time-recommendations/} }
Присоединяйтесь к 11 800+ читателям, которые получают обновления о машинном обучении, RecSys, LLM и инженерии.