Accelerating Generative Recommendation via Simple Categorical User Sequence Compression
Сегодня разбираем статью CAUSE, посвящённую проблеме производительности рекомендательных архитектур на длинных последовательностях айтемов. Авторы предлагают агрегировать айтемы в бакеты по некоторому категориальному признаку и затем longterm-историю представлять в модели через эмбеддинги бакетов.
Ключевой вклад работы — механизм сжатия longterm-информации, получивший название CAUSE. На картинке выше изображено, как работает этот механизм:
- айтемы из longterm-истории бьются на бакеты по категориальному признаку, recent-история подаётся в модель полностью;
- берётся максимум V бакетов по последнему таймстемпу айтема внутри;
- внутри бакетов берётся максимум G айтемов, также отсортированных по таймстемпу;
- каждый эмбед айтема внутри бакета пропускают через MLP-проектор, затем их усредняют по размерности бакета и складывают с обучаемым эмбедом бакета;
- дополнительно в начало последовательности ставят аналог CLS-токена, причём все сегменты отделены друг от друга SEP-токенами.
Для задачи next item prediction используют InfoNCE, а для action prediction — cross-entropy loss.
Авторы выбрали датасеты KuaiRand-27K (логи интеракций с короткими видео) и MovieLens-20M (классика рекомендательных датасетов).
Эксперименты проводят на модели HSTU (3 слоя, hidden size 64, 8 attention heads), в качестве метрик берут NDCG@k и MRR, а бейзлайны — стандартный HSTU и подход GenRank, который агрегирует item и action. В результате подход даёт наилучшие метрики даже в сравнении с сетапами с более длинными последовательностями юзеров с ускорением до 6x на инференсе и до 4x на обучении.
Также авторы проводят аблейшны своего подхода: проверяют, что при отсутствии категориальных признаков событий использование кластеров из K-Means как категорий даёт улучшение относительно бейзлайна, а при исключении отдельных частей подхода качество падает.
Главное достоинство CAUSE — логичный и простой метод сжатия истории. Среди моментов для улучшения можно назвать то, что в статье нет оценки внедряемости и онлайн-результатов, а также рассматривается только одна архитектура с небольшим количеством параметров.
@RecSysChannel
Разбор подготовил❣ Никита Степанов
Сегодня разбираем статью CAUSE, посвящённую проблеме производительности рекомендательных архитектур на длинных последовательностях айтемов. Авторы предлагают агрегировать айтемы в бакеты по некоторому категориальному признаку и затем longterm-историю представлять в модели через эмбеддинги бакетов.
Ключевой вклад работы — механизм сжатия longterm-информации, получивший название CAUSE. На картинке выше изображено, как работает этот механизм:
- айтемы из longterm-истории бьются на бакеты по категориальному признаку, recent-история подаётся в модель полностью;
- берётся максимум V бакетов по последнему таймстемпу айтема внутри;
- внутри бакетов берётся максимум G айтемов, также отсортированных по таймстемпу;
- каждый эмбед айтема внутри бакета пропускают через MLP-проектор, затем их усредняют по размерности бакета и складывают с обучаемым эмбедом бакета;
- дополнительно в начало последовательности ставят аналог CLS-токена, причём все сегменты отделены друг от друга SEP-токенами.
Для задачи next item prediction используют InfoNCE, а для action prediction — cross-entropy loss.
Авторы выбрали датасеты KuaiRand-27K (логи интеракций с короткими видео) и MovieLens-20M (классика рекомендательных датасетов).
Эксперименты проводят на модели HSTU (3 слоя, hidden size 64, 8 attention heads), в качестве метрик берут NDCG@k и MRR, а бейзлайны — стандартный HSTU и подход GenRank, который агрегирует item и action. В результате подход даёт наилучшие метрики даже в сравнении с сетапами с более длинными последовательностями юзеров с ускорением до 6x на инференсе и до 4x на обучении.
Также авторы проводят аблейшны своего подхода: проверяют, что при отсутствии категориальных признаков событий использование кластеров из K-Means как категорий даёт улучшение относительно бейзлайна, а при исключении отдельных частей подхода качество падает.
Главное достоинство CAUSE — логичный и простой метод сжатия истории. Среди моментов для улучшения можно назвать то, что в статье нет оценки внедряемости и онлайн-результатов, а также рассматривается только одна архитектура с небольшим количеством параметров.
@RecSysChannel
Разбор подготовил
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥7❤6🔥6👍2
RecIS: Sparse to Dense, A Unified Training Framework for Recommendation Models
Сегодня разберём работу Alibaba под названием RecIS (Recommendation Intelligence System). Это фреймворк для обучения рекомендательных систем, который нужен, чтобы масштабировать «всё и вся» в разных контекстах, оставаясь при этом PyTorch-френдли и пригодными для продакшена.
В рексистемах есть два разных типа нагрузки. В sparse-части, связанной с эмбеддингами, мало вычислений, но много обращений к памяти. В dense-части, наоборот, много вычислений и меньше работы с памятью. В рексистемах по сравнению с другими областями (NLP, CV) ощутимо больше sparse-нагрузки, поэтому оптимизации касаются именно этой части.
В статье обращают внимание, что скорость доступа к памяти на GPU быстро растёт и уже сильно выше, чем на CPU. Долго считалось, что доступ к памяти остаётся боттлнеком и на GPU, но в работе говорят, что память уже не такая и медленная. Отсюда идея, что можно сделать размен в другую сторону — больше обращений к памяти и уменьшение количества вычислений за счёт большего количества операций с ней.
Авторы вводят метрику MBU — максимальная утилизация пропускной способности. Опираются на идею roofline-модели, где оценивается баланс между вычислениями и доступом к памяти. В классическом варианте по горизонтали откладывают число операций на загруженный байт, а по вертикали — количество FLOPs, которые модель может утилизровать.
Для рексистем такая постановка не очень подходит из-за sparse-нагрузки. Важно не количество вычислений, а то, насколько хорошо утилизируется пропускная способность памяти. Поэтому в работе рассматривают bandwidth-based-вариант, где по вертикали откладывается bandwidth, которую может утилизировать модель, а по горизонтали — объём обращений к памяти на количество вычислений.
Одно из применений этой идеи — работа со sparse-эмбеддингами. Стандартно таблица эмбеддингов реплицируется на все GPU: после каждой эпохи градиенты собираются, усредняются и рассылаются обратно. Здесь предлагают шардировать таблицу так, чтобы каждая GPU хранила только свою часть.
На форварде каждая GPU определяет, какие эмбеддинги ей нужны с других устройств, после происходит all-to-all-коммуникация, и карты обмениваются нужной информацией. Затем каждая GPU читает свои эмбеддинги и отправляет их туда, где они нужны.
На бэкварде происходит то же самое: каждая GPU знает, куда нужно записать градиенты, и они пересылаются напрямую в соответствующие шарды. В итоге всё укладывается в две all-to-all-коммуникации, а таблица занимает меньше памяти на каждой видеокарте.
Также делают оптимизации. Есть стандартные вещи, такие как mixed precision, FlashAttention, ZeRO, fused softmax и cross-entropy. Есть специфичные для рекомендаций. Например, если у нескольких embedding-таблиц одинаковая размерность, их объединяют в одну, чтобы оптимизировать доступ к памяти.
Данные хранят в колоночном формате, для sparse-структур используют CSR.
После загрузки данных есть всего четыре типа операций:
- бакетизация / взятие по модулю;
- (мульти)хэширование;
- обрезание истории;
- построение пар фичей.
Каждую фичу представляют как последовательность таких операций. Некоторые из них (например, хэширование по нескольким разным сидам) можно объединить и зафьюзить.
Эксперименты проводят на двух моделях: MSE (предсказание вероятности клика) и LMA (предсказание следующего баннера по истории). По времени обучения RecIS работает быстрее, чем TensorFlow и PyTorch. По метрике MBU тоже более высокая утилизация пропускной способности.
При этом упоминают и проблемы:
- загрузка данных из сети может занимать много времени (сэмплы до ~6GB);
- embedding-таблицы остаются очень большими, в том числе из-за старых объектов;
- в старых фреймворках вроде TensorFlow 1.x есть ограничения на размер тензоров.
В конце авторы делают вывод, что в современных multi-GPU-системах памяти обычно достаточно. И это позволяет сместить баланс: делать больше операций с памятью и меньше вычислений.
@RecSysChannel
Разбор подготовил❣ Семён Паненко
Сегодня разберём работу Alibaba под названием RecIS (Recommendation Intelligence System). Это фреймворк для обучения рекомендательных систем, который нужен, чтобы масштабировать «всё и вся» в разных контекстах, оставаясь при этом PyTorch-френдли и пригодными для продакшена.
В рексистемах есть два разных типа нагрузки. В sparse-части, связанной с эмбеддингами, мало вычислений, но много обращений к памяти. В dense-части, наоборот, много вычислений и меньше работы с памятью. В рексистемах по сравнению с другими областями (NLP, CV) ощутимо больше sparse-нагрузки, поэтому оптимизации касаются именно этой части.
В статье обращают внимание, что скорость доступа к памяти на GPU быстро растёт и уже сильно выше, чем на CPU. Долго считалось, что доступ к памяти остаётся боттлнеком и на GPU, но в работе говорят, что память уже не такая и медленная. Отсюда идея, что можно сделать размен в другую сторону — больше обращений к памяти и уменьшение количества вычислений за счёт большего количества операций с ней.
Авторы вводят метрику MBU — максимальная утилизация пропускной способности. Опираются на идею roofline-модели, где оценивается баланс между вычислениями и доступом к памяти. В классическом варианте по горизонтали откладывают число операций на загруженный байт, а по вертикали — количество FLOPs, которые модель может утилизровать.
Для рексистем такая постановка не очень подходит из-за sparse-нагрузки. Важно не количество вычислений, а то, насколько хорошо утилизируется пропускная способность памяти. Поэтому в работе рассматривают bandwidth-based-вариант, где по вертикали откладывается bandwidth, которую может утилизировать модель, а по горизонтали — объём обращений к памяти на количество вычислений.
Одно из применений этой идеи — работа со sparse-эмбеддингами. Стандартно таблица эмбеддингов реплицируется на все GPU: после каждой эпохи градиенты собираются, усредняются и рассылаются обратно. Здесь предлагают шардировать таблицу так, чтобы каждая GPU хранила только свою часть.
На форварде каждая GPU определяет, какие эмбеддинги ей нужны с других устройств, после происходит all-to-all-коммуникация, и карты обмениваются нужной информацией. Затем каждая GPU читает свои эмбеддинги и отправляет их туда, где они нужны.
На бэкварде происходит то же самое: каждая GPU знает, куда нужно записать градиенты, и они пересылаются напрямую в соответствующие шарды. В итоге всё укладывается в две all-to-all-коммуникации, а таблица занимает меньше памяти на каждой видеокарте.
Также делают оптимизации. Есть стандартные вещи, такие как mixed precision, FlashAttention, ZeRO, fused softmax и cross-entropy. Есть специфичные для рекомендаций. Например, если у нескольких embedding-таблиц одинаковая размерность, их объединяют в одну, чтобы оптимизировать доступ к памяти.
Данные хранят в колоночном формате, для sparse-структур используют CSR.
После загрузки данных есть всего четыре типа операций:
- бакетизация / взятие по модулю;
- (мульти)хэширование;
- обрезание истории;
- построение пар фичей.
Каждую фичу представляют как последовательность таких операций. Некоторые из них (например, хэширование по нескольким разным сидам) можно объединить и зафьюзить.
Эксперименты проводят на двух моделях: MSE (предсказание вероятности клика) и LMA (предсказание следующего баннера по истории). По времени обучения RecIS работает быстрее, чем TensorFlow и PyTorch. По метрике MBU тоже более высокая утилизация пропускной способности.
При этом упоминают и проблемы:
- загрузка данных из сети может занимать много времени (сэмплы до ~6GB);
- embedding-таблицы остаются очень большими, в том числе из-за старых объектов;
- в старых фреймворках вроде TensorFlow 1.x есть ограничения на размер тензоров.
В конце авторы делают вывод, что в современных multi-GPU-системах памяти обычно достаточно. И это позволяет сместить баланс: делать больше операций с памятью и меньше вычислений.
@RecSysChannel
Разбор подготовил
Please open Telegram to view this post
VIEW IN TELEGRAM
❤16👍8🔥8❤🔥4
Как в ARGUS решали проблемы контекста, кросс-доменных знаний и претрейна
Мы уже разбирали статью Scaling Recommender Transformers to One Billion Parameters, в которой представили генеративную модель персонализации ARGUS, от Яндекса. За последний год модель заметно изменилась и адаптировалась под разные домены внутри компании.
О генеративной постановке в рексистемах и развитии ARGUS подробно написал на Хабре руководитель службы рекомендательных технологий Николай Савушкин. Ну а мы рассказываем о трёх ограничениях, с которыми столкнулся подход, и о том, как удалось с ними разобраться.
Проблема 1: офлайн-обработка и позднее связывание
Раньше ARGUS обрабатывал пользовательскую историю офлайн, поэтому видел её только раз в сутки и не учитывал свежие действия. Контекст подключался на последнем шаге — через позднее связывание. Модель прогоняла через трансформер последовательность троек (context, item, action), а контекст следующего документа подставлялся уже на выходе. Из-за этого вся информация о связи между историей и текущим контекстом должна была «протаскиваться» через трансформер, что со временем стало архитектурным боттлнеком.
Решение: перешли на context-aware-токенизацию
Чтобы контекст перестал быть внешней надстройкой, его сделали полноценной частью последовательности. Историю пользователя перестроили в цепочки вида «контекст — связанные события». Следующий документ модель теперь предсказывает именно из контекстного токена. Такой переход убирает позднее связывание и позволяет учитывать контекст с самого начала работы модели. Трансформер пришлось перенести в рантайм, зато модель начала лучше работать в сценариях, где контекст особенно важен, например, в Рекламе, Поиске и doc2doc-рекомендациях.
Проблема 2: не было кросс-сервисных знаний
Изначально ARGUS был монодоменной моделью: данные брали только из текущего сервиса — например, Маркета или Музыки. Одна из главных идей генеративной постановки — научиться использовать обезличенные сигналы о поведении пользователя сразу из нескольких сервисов.
Решение: прокачали кросс-сервисные знания
События из разных сервисов собрали в единую кросс-доменную последовательность и начали обрабатывать одной моделью. Каждое событие представляли через набор признаков: item_id, категории и текстовые фичи. Категориальные признаки кодировались мультихешингом в общую unified-матрицу эмбеддингов, а текстовые — через BoW.
Для каждого домена использовали отдельную башню, которая обрабатывала признаки событий этого домена и комбинировала их через DCNv2. При этом эмбеддинговая матрица оставалась общей. Так смогли нарастить качество, даже не меняя лоссы и процедуры обучения.
Следующим шагом расширили претрейн на несколько доменов: модель начала предсказывать следующий item не только в целевом сервисе, но и в других доменах в истории пользователя. Для этого добавили отдельный Sampled Softmax для каждого домена, а итоговый лосс сделали суммой доменных лоссов. С таким претрейном получили заметный рост качества в downstream-ранжировании.
Также проверили, можно ли отказаться от претрейна и оставить только файн-тюнинг. Оказалось, нет: файн-тюнинг быстро переставал расти, а даже одна эпоха претрейна давала прирост, который не удавалось компенсировать дополнительными эпохами файн-тюнинга.
Проблема 3: нестабильный и сложный этап претрейна
Первоначальный претрейн ARGUS работал, но был сложным и не очень стабильным. Было не до конца понятно, какие части схемы действительно полезны, а какие усложняют обучение.
Решение: упростили претрейн
Выяснилось, что feedback-loss почти не влияет на результат, поэтому его полностью убрали. В итоге в ARGUS оставили только Next-Item Prediction — эта часть оказалась решающей для роста качества.
Больше деталей об экспериментах с ARGUS, разбор отличий от других генеративных моделей и результаты, к которым в итоге пришли авторы, — обо всём этом читайте в хабростатье.
@RecSysChannel
Мы уже разбирали статью Scaling Recommender Transformers to One Billion Parameters, в которой представили генеративную модель персонализации ARGUS, от Яндекса. За последний год модель заметно изменилась и адаптировалась под разные домены внутри компании.
О генеративной постановке в рексистемах и развитии ARGUS подробно написал на Хабре руководитель службы рекомендательных технологий Николай Савушкин. Ну а мы рассказываем о трёх ограничениях, с которыми столкнулся подход, и о том, как удалось с ними разобраться.
Проблема 1: офлайн-обработка и позднее связывание
Раньше ARGUS обрабатывал пользовательскую историю офлайн, поэтому видел её только раз в сутки и не учитывал свежие действия. Контекст подключался на последнем шаге — через позднее связывание. Модель прогоняла через трансформер последовательность троек (context, item, action), а контекст следующего документа подставлялся уже на выходе. Из-за этого вся информация о связи между историей и текущим контекстом должна была «протаскиваться» через трансформер, что со временем стало архитектурным боттлнеком.
Решение: перешли на context-aware-токенизацию
Чтобы контекст перестал быть внешней надстройкой, его сделали полноценной частью последовательности. Историю пользователя перестроили в цепочки вида «контекст — связанные события». Следующий документ модель теперь предсказывает именно из контекстного токена. Такой переход убирает позднее связывание и позволяет учитывать контекст с самого начала работы модели. Трансформер пришлось перенести в рантайм, зато модель начала лучше работать в сценариях, где контекст особенно важен, например, в Рекламе, Поиске и doc2doc-рекомендациях.
Проблема 2: не было кросс-сервисных знаний
Изначально ARGUS был монодоменной моделью: данные брали только из текущего сервиса — например, Маркета или Музыки. Одна из главных идей генеративной постановки — научиться использовать обезличенные сигналы о поведении пользователя сразу из нескольких сервисов.
Решение: прокачали кросс-сервисные знания
События из разных сервисов собрали в единую кросс-доменную последовательность и начали обрабатывать одной моделью. Каждое событие представляли через набор признаков: item_id, категории и текстовые фичи. Категориальные признаки кодировались мультихешингом в общую unified-матрицу эмбеддингов, а текстовые — через BoW.
Для каждого домена использовали отдельную башню, которая обрабатывала признаки событий этого домена и комбинировала их через DCNv2. При этом эмбеддинговая матрица оставалась общей. Так смогли нарастить качество, даже не меняя лоссы и процедуры обучения.
Следующим шагом расширили претрейн на несколько доменов: модель начала предсказывать следующий item не только в целевом сервисе, но и в других доменах в истории пользователя. Для этого добавили отдельный Sampled Softmax для каждого домена, а итоговый лосс сделали суммой доменных лоссов. С таким претрейном получили заметный рост качества в downstream-ранжировании.
Также проверили, можно ли отказаться от претрейна и оставить только файн-тюнинг. Оказалось, нет: файн-тюнинг быстро переставал расти, а даже одна эпоха претрейна давала прирост, который не удавалось компенсировать дополнительными эпохами файн-тюнинга.
Проблема 3: нестабильный и сложный этап претрейна
Первоначальный претрейн ARGUS работал, но был сложным и не очень стабильным. Было не до конца понятно, какие части схемы действительно полезны, а какие усложняют обучение.
Решение: упростили претрейн
Выяснилось, что feedback-loss почти не влияет на результат, поэтому его полностью убрали. В итоге в ARGUS оставили только Next-Item Prediction — эта часть оказалась решающей для роста качества.
Больше деталей об экспериментах с ARGUS, разбор отличий от других генеративных моделей и результаты, к которым в итоге пришли авторы, — обо всём этом читайте в хабростатье.
@RecSysChannel
❤14👍8🔥7👏1