Рекомендательные системы

Serving рекомендаций

Netflix генерирует рекомендации для 230 миллионов пользователей. Полный ML pipeline занимает 50ms. Умножить на 230M - физически невозможно в real-time. Архитектура serving - это искусство получить персонализацию за 50ms, имея batch данные, aging кэши и streaming события одновременно.

  • **Netflix:** Предвычисляет рекомендации batch-job'ом раз в несколько часов, хранит в Cassandra, обновляет event-driven при значимых сигналах. Feature store хранит 3000+ features. P99 latency главной страницы: менее 100ms.
  • **TikTok:** Kappa архитектура на Flink обрабатывает 10+ миллионов событий в секунду. Рекомендации обновляются за секунды после каждого просмотра. Feature store на ByteKV (собственная разработка) обслуживает миллионы запросов/сек.
  • **Uber:** Feature store Michelangelo хранит pre-computed features для десятков ML моделей (ETA, surge pricing, рекомендации маршрутов). Единый pipeline устраняет training-serving skew для всего ML стека компании.

Предварительные знания

  • Two-stage retrieval и ranking
  • Embeddings и nearest-neighbor search
  • Latency, caching и базовый systems design
  • Candidate Generation
  • Online Learning and A/B Testing

FAISS, ScaNN и обслуживание с низкой задержкой

Обслуживать рекомендации на масштабе означает находить ближайшие к вектору пользователя векторы товаров среди миллионов кандидатов за несколько миллисекунд, что исключает сравнение перебором. В 2017 году Jeff Johnson, Matthijs Douze и Hervé Jégou в Facebook AI Research выпустили FAISS, библиотеку для similarity search на масштабе миллиардов, которая перенесла product quantization и инвертированные индексы на GPU и стала инструментом по умолчанию для векторного retrieval. В 2020 году команда Google опубликовала ScaNN, который сочетает anisotropic quantization loss, настроенный под inner-product search, с быстрым SIMD-скорингом, превзойдя более ранние методы на стандартных бенчмарках. Именно эти библиотеки позволяют индексу кандидатов, построенному во время обучения, отвечать на запросы в реальном времени в жёстком бюджете задержки, и в этом разница между офлайн-моделью и production-рекомендателем.

Latency бюджет: 100ms или потеря пользователя

Amazon посчитал: каждые 100ms дополнительной задержки = 1% потери выручки. Google: 500ms задержки = 20% меньше поисковых запросов. Для рекомендательных систем latency особенно критична: пользователь открыл главную страницу Netflix и ждёт. Если рекомендации не пришли за 100ms - страница показывает статический контент или популярное. Весь сложный ML стек (кандидат-генерация, ранжирование, персонализация) должен укладываться в latency бюджет. Типичный бюджет: 50-100ms P99.

Декомпозиция latency бюджета для Netflix-подобной системы: кандидат-генерация (ANN поиск в embedding space) - 10ms, feature lookup (feature store) - 5ms, ранжирующая модель (inference) - 20ms, business rules (фильтрация, дедупликация) - 5ms, сетевая задержка - 10ms. Итого: 50ms. При P99 каждый этап должен укладываться в бюджет на 99-м перцентиле, а не на среднем.

Почему для latency требований рекомендательных систем используют P99, а не среднее значение?

Caching: когда персонализация ждёт

Полностью персонализированные рекомендации в real-time - дорого. Для миллионов пользователей это невозможно без кэширования. Стратегия multi-layer cache: L1 - предвычисленные рекомендации (batch job раз в час, хранится в Redis), L2 - segment-based рекомендации (пользователи в кластере получают одинаковый список), L3 - популярное (fallback при cache miss). Ключ инсайт: 80% пользователей удовлетворены «достаточно персонализированными» рекомендациями из кэша, обновлённого час назад.

Cache invalidation - классически сложная задача. Триггеры для инвалидации: пользователь посмотрел новый контент (сигнал вкуса), новый контент добавлен в каталог (нужно включить в рекомендации), модель переобучена (все кэши устарели). Стратегия: TTL-based invalidation с event-driven обновлением для high-value сигналов. Kafka событие «пользователь закончил смотреть» -> consumer инвалидирует кэш этого пользователя.

В чём основная задача multi-layer caching для рекомендательных систем?

Feature Store: мост между ML и production

Feature store решает одну из главных проблем ML в production: training-serving skew. Модель обучается на features, вычисленных offline. В production те же features нужно получить за миллисекунды. Без feature store команды строят два разных pipeline: один для обучения (Spark, batch), другой для serving (Python, real-time). Они разъезжаются: разная обработка null-значений, разные типы данных, разная агрегация. Feature store централизует вычисление и хранение: one source of truth для features как при обучении, так и при serving.

Архитектура feature store: offline store (Parquet/Delta Lake) для training data, online store (Redis/DynamoDB) для low-latency serving. Feature pipeline вычисляет значения и синхронизирует оба store. Примеры: Feast (open-source), Tecton, Hopsworks. Netflix Feature Store хранит более 3000 features для рекомендательных систем. Uber Michelangelo Feature Store обслуживает миллионы feature запросов в секунду.

Что такое training-serving skew, и как Feature Store решает эту проблему?

Real-time рекомендации: event-driven обновление

Лучший момент для рекомендации - сразу после значимого сигнала. Пользователь только что посмотрел научпоп ролик - идеальное время показать похожие. Через час контекст потерян. Real-time рекомендательные системы обрабатывают events (просмотр, клик, поиск) и обновляют рекомендации за секунды, а не за часы. Архитектура: Kafka событие -> Flink/Spark Streaming processing -> обновление feature store -> инвалидация кэша -> следующий запрос получает свежие рекомендации.

Lambda architecture для рекомендаций: batch layer (переобучение модели раз в день/неделю), speed layer (обновление контекстных features в real-time), serving layer (объединяет batch модель с real-time features). Kappa architecture упрощает: только один streaming pipeline, который обрабатывает как исторические, так и новые события. TikTok перешёл на Kappa для рекомендаций: единый Flink pipeline обрабатывает 10+ миллионов событий в секунду.

Real-time рекомендации требуют обучения модели в режиме реального времени на каждом новом событии

Real-time рекомендации обычно означают real-time обновление features при использовании модели, обученной offline. Полный online learning модели - редкий случай

Переобучение крупной модели (embedding + ranking) занимает часы. Real-time ценность достигается через быстрое обновление контекстных features (последний просмотр, текущий поиск) при сохранении стабильной batch-обученной модели. Bandits (из rec-11) - исключение: они обновляются real-time, но это лёгкие модели, не deep learning.

В чём разница между Lambda и Kappa архитектурами для real-time рекомендаций?

Ключевые идеи

  • **Latency бюджет** распределяется по этапам pipeline (ANN + feature lookup + inference + rules). P99 latency - рабочая метрика, среднее скрывает хвост распределения, где живут реальные пользователи с плохим опытом.
  • **Multi-layer cache** (персонализированный / сегментный / популярное) позволяет обслуживать 80%+ запросов из кэша без ML inference. Event-driven инвалидация обеспечивает свежесть при значимых сигналах.
  • **Feature Store** устраняет training-serving skew: единый источник features и для обучения, и для serving. Lambda vs Kappa - trade-off между операционной сложностью и унификацией pipeline.

Связанные темы

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

  • Online Learning и A/B Testing — Feature store обеспечивает real-time features для bandit алгоритмов, а interleaving тесты требуют serving инфраструктуры для смешивания кандидатов
  • Approximate Nearest Neighbors — ANN поиск - самый latency-чувствительный этап candidate generation. Выбор алгоритма (FAISS, HNSW, ScaNN) определяет первые 10-20ms latency бюджета

Вопросы для размышления

  • Feature store синхронизирует offline и online хранилища. Что происходит в системе рекомендаций при временной недоступности online store (Redis outage), и как спроектировать graceful degradation?
  • Kappa архитектура обрабатывает историческое переобучение через replay Kafka топика с большим retention. Какие проблемы возникают при replay 1 терабайта исторических событий, и как их решают?
  • Multi-layer cache отдаёт сегментные рекомендации при cache miss персонализированного уровня. Как определить оптимальный размер сегмента: слишком маленький = плохое cache hit ratio, слишком большой = слабая персонализация?

Связанные уроки

  • rec-09 — Сервинг исполняет двухстадийный пайплайн поиска
  • rec-11 — Политики онлайн-обучения разворачиваются на сервинге
  • rec-13 — Паттерны сервинга масштабируются на промышленные системы
  • aie-28-caching-optimization — Те же приемы кэширования, что в LLM-сервинге
  • ds-20-lru-cache — LRU кэширует горячие рекомендации ближе к пользователю
  • dist-12-consistency
Serving рекомендаций

0

1

Войти