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
❤18👍9🔥9❤🔥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
❤15👍9🔥8👏1
MTGR: Industrial-Scale Generative Recommendation Framework in Meituan
Сегодня разбираем недавнюю статью от Meituan, крупнейшего сервиса доставки в Китае. В ней предлагают архитектуру ранжирования MTGR, которая использует ручные кросс-фичи, но при этом обладает масштабируемостью генеративных моделей.
Авторы выделяют две проблемы:
1. В классических моделях Deep Learning Recommendation (DLRM) вычислительная сложность и инференс масштабируются линейно по числу кандидатов. Если хотим сделать модель тяжелее, втиснуть её в прод становится невозможно по latency.
2. Generative Recommendation Model (GRM) решает проблему масштабирования. Но чтобы это работало, приходится отказываться от кросс-фичей. Авторы показывают, что их удаление настолько просаживает качество, что никакое увеличение параметров это не компенсирует.
Чтобы обойти ограничения, пробуют токенизировать все входные признаки:
- Профиль пользователя (U) — набор токенов, где каждая фича — отдельный токен.
- Историю делят на долгосрочную (S) и краткосрочную (R). Её токенизируют на уровне событий: эмбеддинги фич одного события конкатенируются и прогоняются через MLP.
- Кандидатов (C) токенизируют аналогично, но в них замешивают важные кросс-признаки.
Затем идёт агрегация: вместо обработки пар «пользователь-кандидат» по отдельности, все кандидаты юзера объединяются в один пример. Полученные токены образуют последовательность U → S → R → C. За один forward-pass модель оценивает сразу всех кандидатов, давая сублинейное масштабирование.
Токены подают в модифицированный трансформер HSTU со следующими внедрениями:
- Group-Layer Normalization (GLN). Так как токены имеют разную семантику, нормализация делается независимо для каждой группы (U, S, R, C).
- Dynamic Masking. Кастомная маска защищает от утечки данных. Пользователь и долгая история (U+S) видны всем. Краткосрочная (R) — подчиняется каузальности. Кандидаты (C) видят только предшествующую часть R и не видят других кандидатов.
Над токенами кандидатов на выходе строится MLP для предсказания CTR и CVR.
Авторы применили оптимизации, которые увеличили пропускную способность в 1,6–2,4 раза в сравнении с TorchRec. Также им удалось получить x65 FLOPs на один пример без увеличения затрат на обучение в сравнении с DLRM.
Вместо статических таблиц внедрили динамические хэшированные эмбеддинги, которые позволяют выделять память для новых пользователей/айтемов в реальном времени без переполнения.
Размер батчей сделали динамическим. Семплы с длинной историей объединяются в батчи с меньшим числом семплов. Семплы с короткой историей — в батчи с большим числом семплов. Это даёт примерно одинаковую вычислительную нагрузку на все GPU.
Обучение проводили в bf16 mixed precision с префетчингом. Его разбивали на три потока: copy (загрузка данных), dispatch (lookup эмбеддингов), compute (forward/backward), что позволило перекрывать I/O-операции с вычислениями.
Эксперименты и результаты
Для обучения использовали внутренние логи Meituan, так как открытые датасеты слишком маленькие и в них нет нужных кросс-фичей. В качестве бейзлайнов взяли передовые DLRM-архитектуры: Wukong, UserTower, DNN, MoE, MultiEmbed. Качество оценивали по AUC и GAUC.
По сравнению с лучшим бейзлайном (UserTower-SIM) офлайн-метрики (CTR/CTCVR, AUC/GAUC) улучшились на 0,5–1,5%.
Проверка показала, что все компоненты архитектуры критичны. Отсутствие кросс-фичей просаживает качество сильнее всего — без них MTGR сразу проигрывает старым бейзлайнам. GroupLN и Dynamic Masking также дают значимый прирост в качестве.
Авторы продемонстрировали линейный прирост качества (CTCVR GAUC) от log(flops). Отдельно показали, что модель масштабируется по всем осям: можно наращивать как число слоёв, так и скрытую размерность или длину истории.
В онлайн-эксперименте MTGR даёт +1,9% CTR и +1,02% CTCVR в сравнении с лучшим DLRM-бейзлайном.
@RecSysChannel
Разбор подготовил❣ Влад Аверков
Сегодня разбираем недавнюю статью от Meituan, крупнейшего сервиса доставки в Китае. В ней предлагают архитектуру ранжирования MTGR, которая использует ручные кросс-фичи, но при этом обладает масштабируемостью генеративных моделей.
Авторы выделяют две проблемы:
1. В классических моделях Deep Learning Recommendation (DLRM) вычислительная сложность и инференс масштабируются линейно по числу кандидатов. Если хотим сделать модель тяжелее, втиснуть её в прод становится невозможно по latency.
2. Generative Recommendation Model (GRM) решает проблему масштабирования. Но чтобы это работало, приходится отказываться от кросс-фичей. Авторы показывают, что их удаление настолько просаживает качество, что никакое увеличение параметров это не компенсирует.
Чтобы обойти ограничения, пробуют токенизировать все входные признаки:
- Профиль пользователя (U) — набор токенов, где каждая фича — отдельный токен.
- Историю делят на долгосрочную (S) и краткосрочную (R). Её токенизируют на уровне событий: эмбеддинги фич одного события конкатенируются и прогоняются через MLP.
- Кандидатов (C) токенизируют аналогично, но в них замешивают важные кросс-признаки.
Затем идёт агрегация: вместо обработки пар «пользователь-кандидат» по отдельности, все кандидаты юзера объединяются в один пример. Полученные токены образуют последовательность U → S → R → C. За один forward-pass модель оценивает сразу всех кандидатов, давая сублинейное масштабирование.
Токены подают в модифицированный трансформер HSTU со следующими внедрениями:
- Group-Layer Normalization (GLN). Так как токены имеют разную семантику, нормализация делается независимо для каждой группы (U, S, R, C).
- Dynamic Masking. Кастомная маска защищает от утечки данных. Пользователь и долгая история (U+S) видны всем. Краткосрочная (R) — подчиняется каузальности. Кандидаты (C) видят только предшествующую часть R и не видят других кандидатов.
Над токенами кандидатов на выходе строится MLP для предсказания CTR и CVR.
Авторы применили оптимизации, которые увеличили пропускную способность в 1,6–2,4 раза в сравнении с TorchRec. Также им удалось получить x65 FLOPs на один пример без увеличения затрат на обучение в сравнении с DLRM.
Вместо статических таблиц внедрили динамические хэшированные эмбеддинги, которые позволяют выделять память для новых пользователей/айтемов в реальном времени без переполнения.
Размер батчей сделали динамическим. Семплы с длинной историей объединяются в батчи с меньшим числом семплов. Семплы с короткой историей — в батчи с большим числом семплов. Это даёт примерно одинаковую вычислительную нагрузку на все GPU.
Обучение проводили в bf16 mixed precision с префетчингом. Его разбивали на три потока: copy (загрузка данных), dispatch (lookup эмбеддингов), compute (forward/backward), что позволило перекрывать I/O-операции с вычислениями.
Эксперименты и результаты
Для обучения использовали внутренние логи Meituan, так как открытые датасеты слишком маленькие и в них нет нужных кросс-фичей. В качестве бейзлайнов взяли передовые DLRM-архитектуры: Wukong, UserTower, DNN, MoE, MultiEmbed. Качество оценивали по AUC и GAUC.
По сравнению с лучшим бейзлайном (UserTower-SIM) офлайн-метрики (CTR/CTCVR, AUC/GAUC) улучшились на 0,5–1,5%.
Проверка показала, что все компоненты архитектуры критичны. Отсутствие кросс-фичей просаживает качество сильнее всего — без них MTGR сразу проигрывает старым бейзлайнам. GroupLN и Dynamic Masking также дают значимый прирост в качестве.
Авторы продемонстрировали линейный прирост качества (CTCVR GAUC) от log(flops). Отдельно показали, что модель масштабируется по всем осям: можно наращивать как число слоёв, так и скрытую размерность или длину истории.
В онлайн-эксперименте MTGR даёт +1,9% CTR и +1,02% CTCVR в сравнении с лучшим DLRM-бейзлайном.
@RecSysChannel
Разбор подготовил
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍7🔥6🥰1