
Классические рекомендательные системы в крупных компаниях — это десятки микросервисов, каскадная фильтрация и тысячи ручных признаков. Такой стек может надёжно работать годами, но неизбежно упирается в фундаментальную проблему: он перестаёт масштабироваться. Качество выходит на плато — всё меньше отдачи от новых фич, усложнения моделей и наращивания данных.
Генеративная постановка, когда модель восстанавливает целые последовательности пользовательских действий, обещает принести в рекомендации законы масштабирования, снизить операционную сложность и открыть путь к единой кросс‑сервисной модели. Но между обещанием и продакшеном — огромная дистанция. Нужно понять, какая токенизация работает, как устроить претрейн, что делать с контекстом, негативами и задержками в реальных распределённых системах.
Последний год мы адаптировали нашу генеративную модель персонализации ARGUS под разные домены внутри Яндекса, меняли архитектуру, пересобирали обучение и пробовали новые способы интеграции в продакшене. В этой статье я расскажу, какие решения сработали, какие — нет и что нам дала генеративная постановка в реальных рекомендательных системах.
Мотивация и определения
Начнём с того, зачем вообще понадобилась генеративная постановка в рекомендациях и что мы понимаем под генеративными рекомендательными моделями.
У нас в Яндексе есть зрелые рекомендательные системы — в Музыке, Маркете, Рекламе и других продуктах. Исторически они построены вокруг большого набора ручных признаков и специализированных моделей, которые эти признаки обрабатывают. Это эффективно, но довольно быстро «насыщается»: качество перестаёт расти по мере усложнения моделей и наращивания фич. В отличие от областей, где масштабирование — моделей, данных и вычислений — приводит к предсказуемому росту качества.
Генеративная постановка даёт шанс принести эти законы масштабирования в рекомендации.
Есть и вторая причина. Классические рекомендательные системы — это всегда каскад: много микросервисов, сложная последовательная фильтрация кандидатов, дорогое ручное обслуживание фичевого пространства. Такой стек работает, но высокая операционная сложность неизбежно тормозит развитие. Генеративный подход, наоборот, позволяет уменьшить количество моделей и снизить операционную нагрузку на команды.
Третий мотивационный пункт — отсутствие фундаментальных моделей в рекомендациях. Практически все существующие решения внутридоменные: модель обучена на одном продукте, понимает только его данные и плохо переносится в другие сервисы. Генеративная модель, которая учится на последовательностях действий, в принципе может вбирать знания сразу из нескольких доменов и переиспользоваться внутри экосистемы.
Важно, что сама область генеративных рекомендательных моделей ещё очень молодая: терминов немного, единой нотации пока нет. В этой статье под «генеративной рекомендательной моделью» я буду понимать модель, которая задаёт распределение на пользователях.
Если провести аналогию, то разница между дискриминативными и генеративными постановками такая же, как в классическом ML. Дискриминативная модель учит — вероятность реакции пользователя на конкретный документ. Генеративная же пытается моделировать совместное распределение входов и выходов — восстанавливает распределение пользовательских последовательностей целиком.

Чтобы задать такое распределение, нужно формально описать пользователя. Наиболее распространённый подход в индустрии — sequential: мы представляем пользователя как последовательность действий, а дальше применяем любую последовательностную нейросеть, в частности трансформер.

Как и почему мы пришли к созданию ARGUS
Чтобы понять, зачем нам понадобилась собственная генеративная модель рекомендаций, разберём, как устроены популярные подходы. Я буду сравнивать их по четырём критериям:
-
как токенизируется пользовательская история;
-
какая задача моделирования решается;
-
какая архитектура используется;
-
как модель применяется в рекомендательном стеке.
HSTU: полная история действий, но без контента
HSTU моделирует пользователя как последовательность всех взаимодействий — и позитивных, и негативных. Каждое событие раскладывается на два токена:
-
токен документа (item_id);
-
токен реакции пользователя.
Документ описывается только item_id, без контентных признаков. Именно поэтому большая часть триллиона параметров модели — это матрицы эмбеддингов под гигантское пространство ID.
Несмотря на то что модель в статье называют генеративной, она решает дискриминативные задачи: предсказывает либо следующий позитивный документ по истории, либо реакцию на конкретный документ при фиксированной истории. Архитектура — собственный attention‑блок HSTU. В применении это ранжирующая модель, которая заменяет традиционный стек ручных фич.
TIGER (Google): только позитивные действия и иерархическая токенизация
TIGER делает два принципиально других шага:
-
учитываются только позитивные взаимодействия;
-
каждый документ раскладывается на последовательность токенов, соответствующую обходу дерева категорий (иерархическая кластеризация).
То есть item превращается не в один токен, а в путь по дереву. Задача — предсказать следующий позитивный item по истории. Снова дискриминативная постановка. Архитектура — encoder‑decoder Transformer. Применение — генерация кандидатов на раннем этапе каскада.
Чем ARGUS отличается от этих подходов
Мы проектировали ARGUS так, чтобы модель была максимально универсальной внутри экосистемы Яндекса и могла использовать кросс‑доменные знания. Поэтому ключевые решения отличаются от HSTU и TIGER.
-
История действий полная: и позитивы, и негативы.
-
Событие кодируем тройкой: context, item, action. На практике чаще используем simplified‑схему, где всё это упаковано в один токен.
-
Документы описываются двумя каналами: item_id (спарсовая идентификация) и контентные признаки (полное описание документа). На практике смешанная схема даёт значимый прирост качества — это заметное отличие от TIGER и HSTU.
-
Двухступенчатое обучение:
-
претрейн — генеративный, моделирует распределение на пользовательских историях; модель авторегрессивно «прогоняет» последовательность и предсказывает следующий item (любой), а также реакцию пользователя;
-
файн‑тюнинг — дискриминативный, подстраивается под задачу ранжирования внутри продукта.
-
-
Способ применения. ARGUS — это upstream‑модель, которая может работать как:
-
фичегенератор для ранжирующей модели следующего уровня;
-
дополнительный источник кандидатов на стадии candidate generation.
-
Первые продакшен‑версии ARGUS работали офлайн: мы один раз в сутки прогоняли модель в батч‑режиме, строили эмбеддинги пользователей и документов и использовали двухбашенную постановку (скалярное произведение либо лёгкий энкодер). Так ARGUS изначально жил как вспомогательный источник сигналов и кандидатов.
Дальше я расскажу, как мы развили этот рецепт — что поменяли в обучении и какие эффекты это дало на реальных продуктах.
Как мы развили ARGUS и что узнали на внедрениях
После первых внедрений ARGUS стало понятно, какие ограничения мешают модели раскрывать потенциал. Таких ограничений получилось три.
Офлайновое применение и позднее связывание. В первой версии ARGUS пользователь обрабатывался офлайн, и модель видела историю «раз в сутки». Это приводило к двум проблемам:
-
модель не видит самые свежие пользовательские действия — от момента события до попадания в профиль проходит время;
-
вся история сжимается в один вектор, что создаёт существенную потерю информации.
Формально постановка была context‑aware, но на практике контекст учитывался только на последнем шаге — через позднее связывание.
ARGUS брал последовательность троек (context, item, action), пропускал через трансформер, а затем уже на выходе подставлял контекст следующего документа. Вся информация о связи между историей и контекстом должна была «протащиться» через трансформер, и это стало узким местом.
Отсутствие кросс‑сервисных знаний. Изначальная версия ARGUS оставалась монодоменной. Источник данных — только текущий сервис (например, Маркет или Музыка).
При этом одна из ключевых мотиваций генеративной постановки — создание фундаментальной модели, которая собирает обезличенные данные о поведении пользователя в нескольких сервисах и использует эти знания кросс‑доменно.
В первых версиях этот потенциал не был реализован.
Неустойчивая и сложная процедура претрейна. Оригинальная схема претрейна ARGUS была рабочей, но слишком сложной, не до конца понятной и с большим количеством открытых вопросов, суть которых сводится к тому, можно ли улучшить стабильность и упростить процедуру претрейна?
Далее поговорим о том, как мы решали эти три проблемы.
Проблема позднего связывания и рождение context‑aware ARGUS
Чтобы уйти от позднего связывания, нужно было сделать контекст полноценной частью последовательности, а не чем‑то, что подставляется только на финальном шаге. Для этого мы изменили саму токенизацию.
Вместо того чтобы представлять каждое событие как тройку (context, item, action), мы перестроили историю пользователя в виде цепочек «контекст — события этого контекста». Сначала идёт контекстный токен, а затем связанные с ним события. На практике это переход от событийной токенизации к контекстно‑событийной.

Item и feedback по‑прежнему кодируются одним токеном — это сохраняет компактность последовательности. Следующий документ модель предсказывает именно из контекстного токена, что делает контекст центральным элементом моделирования.
Такой переход меняет несколько вещей. Контекст начинает участвовать в работе модели с самого начала, а не подставляется на выходе. Трансформер нужно выполнять в рантайме, потому что надо учитывать текущий контекст пользователя — офлайновая схема больше не подходит.
Длина последовательности растёт умеренно: если в HSTU она увеличивается вдвое, а в полной схеме ARGUS могла вырастать втрое, то здесь она редко превышает двукратный рост и обычно даже меньше, поскольку контекст меняется нечасто и не дублируется, когда не нужно.
На претрейне модель остаётся генеративной: авторегрессивно задаёт распределение на пользовательской истории, предсказывает следующий item (позитивный или негативный) и реакцию пользователя на него. То есть модель уже на претрейне учится распределению на пользовательских историях.
На файн‑тюнинге мы подставляем кандидатов непосредственно к тому контекстному токену, которому они соответствуют. Кандидаты не обязаны присутствовать в истории: например, показы в Маркете мы получаем семплированием. Такой формат совместим с любыми ранжирующими лоссами, и модель корректно их поддерживает.

В реальных распределённых системах между событием и тем, как оно появляется в профиле пользователя, есть задержка. Игнорировать этот лаг нельзя — модель начинает «видеть будущее» и переобучается.
В context‑aware‑постановке это усложняется: при обучении надо одновременно учитывать текущий контекст и не учитывать часть событий, которые ему непосредственно предшествуют. То есть нужна не тривиальная маска, а необычная — треугольная.
Здесь мы столкнулись с тем, что Flash Attention такую маску не поддерживает. Альтернативные реализации сильно замедляют обучение, а собственный Triton Kernel сложен и всё ещё отстаёт по скорости от библиотечных решений.

В итоге лучше всего сработал практический вариант: не моделировать лаг на претрейне и файн‑тюнинге. Лаг добавляется в downstream — когда ARGUS становится фичей финальной модели ранжирования. Претрейн остаётся быстрым и стабильным, а downstream‑модель получает корректно смоделированную задержку, что даёт нужное поведение без усложнения трансформера.
Переход на context‑aware‑токенизацию заметнее всего влияет на домены, где контекст определяет значительную часть поведения, — Рекламу, Поиск, doc2doc‑рекомендации. В них улучшение downstream‑метрик почти двукратное. В доменах с доминирующим персональным фактором, например в Музыке, прирост скромнее, что согласуется с природой сигнала.

Кросс‑сервисные знания и развитие претрейна ARGUS
Второй важный шаг в развитии ARGUS связан с кросс‑сервисными знаниями. В разных продуктах у нас давно накоплено много обезличенных сигналов о поведении пользователя, но долгое время не было нормального способа передать их в модель — только простые ручные эвристики. Генеративная последовательностная постановка позволяет собрать эти сигналы в единую кросс‑доменную последовательность и обрабатывать её одной моделью.
Каждое событие из любого домена мы представляем через набор признаков: item_id, категории и текстовые фичи. Категориальные признаки кодируем мультихешингом в общую unified‑матрицу — одну большую матрицу эмбеддингов для всех доменов. Текстовые признаки группируем вручную по смыслу и для каждой группы используем свой мешок слов.
Для каждого домена у нас отдельная башня: она получает признаки событий этого домена (спарсовые — через мультихешинг, текстовые — через BoW) и комбинирует их через DCNv2. В итоге башни доменно‑специфичны, а эмбеддинговая матрица остаётся общей.

Такое объединение даёт заметный прирост качества: без изменения процедуры обучения и без изменения лоссов достаточно просто добавить события из других сервисов в историю пользователя, и downstream‑модель начинает работать заметно лучше. Эта прибавка достигается без изменения самой постановки и без дополнительной сложности в пайплайне обучения.
После этого мы вернулись к более базовому вопросу: можно ли отказаться от претрейна и оставить только файн‑тюнинг? Интерес возник не только из‑за того, что другие последовательностные рекомендательные модели, такие как HSTU или TIGER, обучаются одностадийно, но и потому, что в LLM‑подходах претрейны обычно играют ключевую роль. Мы хотели понять, насколько двухступенчатая схема действительно необходима именно для ARGUS.
Здесь важно уяснить два момента. Первый — compute‑оптимальность: что выгоднее при фиксированном количестве GPU‑часов — потратить их на претрейн или на большое количество эпох файн‑тюнинга? Второй — достижимость качества: если вообще не ограничивать вычисления, может ли модель, обучавшаяся только на файн‑тюнинге, догнать запретрейненный вариант?

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

В базовой версии претрейна ARGUS используется Sampled Softmax со случайными (uniform) и инбатчевыми негативами, а также logQ‑коррекция, устраняющая смещение от инбатчевого семплирования. Это позволяет эффективно обучать модель на больших данных.
На этой базе мы построили расширенную схему: добавили отдельный Sampled Softmax для каждого альтернативного домена, а итоговый лосс сделали суммой доменных лоссов. Инбатчевые негативы и uniform‑негативы по‑прежнему выбираются внутри домена.
Добавление таких задач в претрейн дало существенный прирост в downstream‑ранжировании. Уже после файн‑тюнинга модель давала значительно лучшие результаты, чем при обучении только на одном домене.

Нужен ли feedback‑loss
Изначальный претрейн включал два лосса: восстановление логирующей политики (предсказание следующего документа в истории, позитивного и негативного) и предсказание реакции пользователя (feedback), когда модель получает текущий контекст и следующий документ и оценивает ожидаемое взаимодействие. Мы проверили, можно ли отказаться от второй части.

Выяснилось, что feedback‑loss почти не влияет на конечное качество, а его наличие усложняет реализацию и снижает стабильность обучения. Поэтому в актуальном рецепте обучения ARGUS мы полностью удалили этот лосс: модель проходит претрейн только на задаче Next‑Item Prediction.

Как правильно работать с негативами
Схема негативов — ключевой элемент обучения трансформеров в рекомендациях. Мы использовали смешанный вариант из инбатчевых негативов и uniform‑негативов и проверили, насколько эта схема обязательна и как она масштабируется.
С точки зрения обучения мы работаем в data‑parallel‑режиме (DDP или FSDP), где у каждого ускорителя свой локальный батч и свои локальные негативы. Пул негативов можно расширить, собрав их с разных устройств через all_gather, и получить более разнообразный пул, одновременно увеличив их количество.

Проблема в том, что стандартные реализации Sampled Softmax материализуют матрицу логитов размером positives × negatives прямо в памяти GPU. При увеличении числа негативов эта матрица становится основным потребителем памяти, и batch‑size приходится уменьшать.
Мы обошли это ограничение с помощью fused‑реализации cross‑entropy (ядро LinkedIn), которая не строит матрицу логитов в явном виде. Она немного медленнее классического варианта, но позволяет резко увеличить число негативов без потери batch‑size.
Эксперименты показали несколько важных вещей:
-
Инбатчевые негативы критичны — отказаться от них нельзя.
-
Uniform‑негативы полезны, но существенно менее значимы: качество downstream‑задачи гораздо меньше зависит от них. Поэтому в претрейне мы можем от uniform‑негативов отказаться.
-
В задачах candidate‑generation их обязательно оставляем, поскольку увеличение числа негативов напрямую влияет на метрику реколлов.

Стратегия семплирования uniform‑негативов тоже имеет значение. Можно семплировать равномерно, из популярных документов или из популярных с учётом затухания по времени. Последний вариант даёт наилучшие результаты. В целом увеличение количества негативов ожидаемо улучшает метрики генерации кандидатов.
Актуальный рецепт претрейна ARGUS
По сравнению с исходной версией претрейна в ARGUS мы пришли к следующему рецепту. Модель продолжает восстанавливать логирующую политику через Next‑Item Prediction, предсказывая все встречающиеся в истории документы независимо от их знака.
Мы добавляем Next‑Item Prediction на события из дополнительных доменов — именно эта часть даёт особенно заметный рост качества. Feedback‑loss полностью исключён: он не приносит выгоды и делает обучение менее стабильным.
Для candidate‑generation используются альтернативные стратегии uniform‑негативов и fused cross‑entropy, тогда как в самом претрейне uniform‑негативы опциональны и могут быть отключены без потерь.
Вместо заключения
Генеративные модели в рекомендациях пока не имеют устоявшейся методологии, но практика показывает: последовательностные подходы в рекомендациях работают не только в теории — прирост видно на реальных задачах. ARGUS для нас — подтверждение того, что сдвиг акцента от ручного фичевого пространства к последовательностному представлению пользователя и использованию кросс‑сервисных данных позволяет моделям лучше масштабироваться с ростом данных и вычислений.
Переработанная токенизация, контекстная постановка и расширенный претрейн дают заметный прирост качества в реальных продуктах. Дополнительно обновлённый рецепт обучения убирает часть инфраструктурных ограничений, которые были у классических стеков.
Спасибо, что прочитали. А если остались вопросы — задавайте их в комментариях.
Если у вас есть интересный МЛ‑кейс и вы хотите о не рассказать, подавайте заявку на выступление на Practical ML Conf.
Автор: penguin-diver


