Как внедрить новое поколение рекомендателей трансформаторов
Делиться

Привет, TDS! Меня зовут Кирилл Хрыльченко, я руковожу командой исследований и разработок RecSys в Яндексе. Одна из наших целей — разработка технологий трансформеров в контексте рекомендательных систем, к чему мы стремимся уже пять лет. Не так давно мы достигли нового этапа в развитии рекомендательных технологий, о котором я хотел бы рассказать вам в этой статье.
Актуальность рекомендательных систем в мире легко обосновать: объём контента растёт невероятно быстро, что делает невозможным просмотр всего контента, и нам нужны рекомендательные системы, чтобы справиться с информационной перегрузкой. Музыка, фильмы, книги, товары, видео, публикации, друзья… Но важно помнить, что эти сервисы приносят пользу не только пользователям, но и создателям контента, которым необходимо найти свою целевую аудиторию.
Мы внедрили новое поколение рекомендательных сервисов на нескольких сервисах и активно интегрируем их с другими. Мы значительно повысили качество рекомендаций по всем направлениям.
Если вы инженер машинного обучения, работающий с рекомендациями, эта статья даст вам несколько идей о том, как реализовать аналогичный подход для вашей рекомендательной системы. А если вы пользователь, у вас будет возможность узнать больше о том, как работает эта самая рекомендательная система.
Как работают рекомендательные системы
Проблема рекомендации сама по себе имеет простое математическое определение: для каждого пользователя 
мы хотим выбрать предметы, объекты, документы или продукты 
которые им наверняка понравятся.

Но есть одна загвоздка:
- Каталоги товаров огромны (до миллиардов наименований).
- Число пользователей значительно, и их интересы постоянно меняются.
- Взаимодействие между пользователями и предметами очень слабое.
- Неясно, как определить реальные предпочтения пользователя.
Чтобы эффективно решить проблему рекомендаций, нам необходимо использовать нетривиальные модели, использующие машинное обучение.
Нейронные сети — мощный инструмент машинного обучения, особенно при работе с большими объёмами неструктурированных данных, таких как текст или изображения. В то время как традиционное классическое машинное обучение требует экспертных знаний предметной области и значительного объёма ручной работы (разработка признаков), нейронные сети способны практически автоматически извлекать сложные взаимосвязи и закономерности из необработанных данных.
В области RecSys мы имеем большой объём преимущественно неструктурированных данных (буквально триллионы анонимизированных взаимодействий пользователей с объектами), а также сущностей, основанных на контенте (объекты состоят из заголовков, описаний, изображений, видео и аудио; пользователи могут быть представлены последовательностями событий). Кроме того, крайне важно, чтобы рекомендательная система хорошо работала как с новыми объектами, так и с неактивными пользователями, и кодирование пользователей и объектов через контент помогает этого добиться.
Время, отведенное нам на формирование рекомендаций для пользователя, очень строго ограничено. Каждая миллисекунда на счету! Кроме того, наши ресурсы (с точки зрения оборудования) ограничены, а каталоги, из которых нам нужны рекомендации, довольно обширны. Поэтому рекомендации обычно формируются в несколько этапов:
- Сначала мы выбираем относительно небольшой набор кандидатов из всего каталога, используя легкие модели (этап поиска ).
- Затем мы пропускаем этих кандидатов через более сложные модели, которые используют дополнительную информацию и более интенсивные вычисления для каждого кандидата (этап ранжирования ).
С точки зрения архитектуры модели существенно различаются на разных этапах, что затрудняет обсуждение любого аспекта без ссылки на конкретные этапы рекомендательной системы.

Архитектура двухбашенной нейронной сети очень популярна на этапе поиска. В ней используются пользователи и объекты (в случае поиска информации это запросы и документы, независимо закодированные в векторные представления), а для вычисления степени сходства между ними применяется скалярное произведение.
Можно также сказать, что такие модели «встраивают» пользователей и элементы в общее «семантическое пространство», где семантический аспект представляет собой тот факт, что чем ближе пара пользователь-элемент с точки зрения векторного пространства, тем более они похожи.
Модели с двумя башнями работают быстро. Предположим, пользователь запрашивает рекомендации. Модель с двумя башнями должна рассчитать:
- «Пользовательская башня» один раз за запрос.
- Векторы всех элементов-кандидатов, для которых вы хотите рассчитать сродство пользователя к элементу.
- Скалярные произведения.
Вам даже не нужно пересчитывать векторы элементов-кандидатов для каждого запроса пользователя, поскольку они одинаковы для всех пользователей и редко меняются; например, мы не предполагаем, что название фильма или музыкального трека часто меняется. На практике мы регулярно пересчитываем векторы элементов для всего каталога в офлайн-режиме (например, ежедневно) и загружаем их либо в тот сервис, где нам нужно вычислить скалярное произведение, либо в другой сервис, к которому мы обращаемся онлайн для получения необходимых векторов элементов.
Но я описываю пример использования, когда у вас есть разумное, небольшое количество кандидатов, для которых вы хотите рассчитать аффинитет пользователя к объекту. Это справедливо для этапа ранжирования. Однако на этапе генерации кандидатов задача усложняется: нам нужно рассчитать аффинитет для всех объектов в каталоге, выбрать первые N (где N обычно выражается сотнями или тысячами) с наибольшими значениями аффинитета, а затем передать их на последующие этапы.
Именно здесь модели с двумя башнями оказываются бесценными : мы можем быстро сгенерировать приблизительный топ-N по скалярному произведению, даже для больших каталогов, используя методы приближенного поиска. Мы создаём специальный «индекс» (обычно в виде графа, например, в методе HNSW) для набора уже вычисленных векторов элементов, который мы можем хранить в сервисе и использовать для передачи векторов пользователей, извлекая приблизительный топ для этих векторов.
Создание такого индекса — сложная и трудоёмкая задача (включая отдельную задачу быстрого обновления и перестроения индекса). При этом его всё равно можно выполнить офлайн, а затем загрузить исполняемый файл и индекс на сервис, где мы будем искать кандидатов в среде выполнения.

Как закодировать пользователя в вектор?
Классические алгоритмы решали эту проблему довольно просто: в методах матричной факторизации (например, ALS) вектор пользователя был «обучаемым», представлен параметрами модели и определялся в рамках процедуры оптимизации. В методах совместной фильтрации пользователь-элемент пользователю назначался вектор размерности каталога, в котором i-я координата соответствовала конкретному элементу и отражала частоту взаимодействия пользователя с этим элементом (например, как часто пользователь покупал этот элемент или как он его оценивал).
Современный подход заключается в кодировании пользователей с помощью трансформеров, предполагая, что пользователя можно закодировать в вектор с помощью трансформеров. Мы берём анонимизированную историю пользователя, то есть последовательность событий, и кодируем эти события в векторы, а затем используем трансформер. В самом простом случае события представлены покупками или лайками; однако в других случаях это может быть вся история взаимодействий в экосистеме компании.
Изначально, когда трансформаторы впервые использовались в рекомендациях, исследователи проводили аналогии, основанные на сходстве с НЛП: пользователь подобен предложению, а слова в нем представляют собой покупки, лайки и другие взаимодействия.

Другой тип рекомендательной модели нейронной сети — модели с ранним слиянием. Эти модели не разделяют информацию о пользователе и объекте на два уровня, а обрабатывают всю информацию вместе. То есть, мы объединяем всю информацию о пользователе, объекте и их взаимодействии на раннем этапе. В противоположность этому, модели с двумя уровнями, как говорят, характеризуются поздним слиянием посредством скалярного произведения. Модели с ранним слиянием более выразительны, чем модели с двумя уровнями. Они могут улавливать более сложные сигналы и изучать более нетривиальные зависимости.
Однако их применение вне этапа ранжирования затруднено из-за высокой вычислительной нагрузки и необходимости пересчитывать всю модель для каждого запроса пользователя и каждого кандидата. В отличие от моделей с двумя башнями, они не поддерживают факторизацию вычислений.
Мы используем различные типы архитектуры, включая двухбашенные модели с трансформаторами и модели с ранним слиянием. Мы чаще используем двухбашенные архитектуры, поскольку они высокоэффективны, подходят для всех стадий одновременно и при этом обеспечивают хороший прирост качества при значительно меньших затратах ресурсов.
Мы обучали двухбашенные модели в два этапа:
- Предварительное обучение с использованием контрастного обучения . Мы обучаем модель сопоставлять пользователей с их позитивными взаимодействиями с объектами, используя контрастное обучение.
- Тонкая настройка, ориентированная на задачу . Как и в случае с NLP, тонкая настройка — это подход, ориентированный на задачу. Если модель будет использоваться для ранжирования, мы обучаем её точно ранжировать рекомендации, показываемые пользователю. Мы показали два элемента — один пользователю понравился, другой — нет — и хотим ранжировать элементы в том же порядке. При извлечении задача похожа на предварительную подготовку, но использует дополнительные методы, которые улучшают припоминание кандидатов.
В следующем разделе мы рассмотрим, как этот процесс изменился в наших новых моделях.
Масштабирование рекомендательных систем
Существует ли предел размера рекомендательных моделей, после которого мы больше не видим связанных с размером улучшений качества рекомендаций?
Долгое время наши рекомендательные модели (и не только наши, но и модели в отрасли и академической среде) были очень маленькими, что предполагало, что ответ на этот вопрос — «да».
Однако в глубоком обучении существует гипотеза масштабирования, которая гласит, что по мере увеличения размера модели и увеличения объема данных качество модели должно значительно улучшаться.
Значительная часть прогресса в области глубокого обучения за последнее десятилетие объясняется этой гипотезой. Даже самые ранние успехи в области глубокого обучения были основаны на масштабировании, что связано с появлением обширного набора данных для классификации изображений ImageNet и высокой эффективностью нейронных сетей (AlexNet) на этом наборе данных.
Гипотеза масштабирования еще более очевидна в языковых моделях и обработке естественного языка (NLP): можно предсказать зависимость улучшения качества от объема вычислений и выразить соответствующие законы масштабирования.

Что я имею в виду, когда говорю, что рекомендательные модели можно сделать крупнее?
Существует до четырех различных осей масштабирования.
Встраивание . У нас есть разнообразная информация о пользователях и элементах, поэтому мы имеем доступ к широкому спектру функций, и значительная часть этих функций является категориальной. Пример категориальной функции — идентификатор элемента, идентификатор исполнителя, жанр или язык.
Категориальные признаки имеют очень высокую кардинальность (количество уникальных значений) — достигающую миллиардов — поэтому, если вы сделаете для них большие обучаемые вложения (векторные представления), вы получите огромные матрицы вложений.
Тем не менее, вложения являются узким местом между входными данными и моделью, поэтому для хорошего качества их размер должен быть большим. Например, в Meta* используются матрицы вложений с размерами от 675 миллиардов до 13 триллионов параметров, в то время как Google сообщал о не менее чем 1 миллиарде параметров в YoutubeDNN ещё в 2016 году. Даже Pinterest, долгое время продвигавший вложения индуктивных графов из PinSage [1, 2], недавно начал использовать большие матрицы вложений.
Длина контекста . Десятилетиями инженеры рекомендательных систем занимались созданием признаков. В современных системах ранжирования количество признаков может достигать сотен и даже тысяч, и Яндекс также предлагает такие услуги.
Другим примером «контекста» в модели является история пользователя в преобразователе. Здесь размер контекста определяется длиной истории. Как в промышленности, так и в академической среде это число, как правило, очень невелико, в лучшем случае — несколько сотен событий.
Размер обучающего набора данных. Я уже упоминал, что у нас много данных. Рекомендательные системы создают сотни наборов данных, размер которых сопоставим с обучающим набором данных GPT-3.
В отрасли существует множество вариантов использования огромных наборов данных с миллиардами отображаемых обучающих примеров: 2 миллиарда, 2,1 миллиарда, 3 миллиарда, 60 миллиардов, 100 миллиардов, 146 миллиардов, 500 миллиардов.
Размер кодировщика . Стандарт для моделей раннего слияния будет исчисляться миллионами или десятками миллионов параметров. Согласно документам Google, «упрощённые» версии их моделей Wide&Deep имели от 1 до 68 миллионов параметров для экспериментов [1, 2]. А если использовать двухслойную модель DCN-v2 (популярный слой нейронной сети для моделей раннего слияния) для тысячи непрерывных признаков, мы получим не более 10 миллионов параметров.
Двухбашенные модели чаще всего используют для кодирования пользователя миниатюрные трансформеры: например, два блока-трансформера с размерностью скрытых слоёв, не превышающей пары сотен. Такая конфигурация будет иметь максимум несколько миллионов параметров.
И хотя размеры матриц встраивания и обучающих наборов данных уже достаточно велики, масштабирование длины пользовательской истории и мощности кодировщика модели остаётся открытым вопросом. Есть ли какое-либо значимое масштабирование по этим параметрам?
Этот вопрос крутился у нас в голове в феврале 2024 года. Затем статья исследователей из Meta под названием «Действия говорят громче слов» немного подняла нам настроение.
Авторы представили новую архитектуру кодировщика, названную HSTU, и сформулировали как задачу ранжирования, так и задачу генерации кандидатов в виде генеративной модели. Модель имела очень большую историю (8000 событий!) и обширный обучающий набор данных (100 миллиардов примеров), а кодировщик пользовательской истории был значительно больше предыдущих, состоявших из нескольких миллионов параметров. Однако даже здесь самая большая упомянутая конфигурация кодировщика имеет всего 176 миллионов параметров, и неясно, реализовали ли они её (судя по последующим статьям, не реализовали).
176 миллионов параметров в кодере — это много или мало? Если обратиться к языковым моделям, ответ очевиден: LLM с 176 миллионами параметров в кодере будет значительно уступать по возможностям и качеству решения задач современным моделям SOTA с миллиардами или даже триллионами параметров.
Почему же тогда в рекомендательных системах такие маленькие модели?
Почему мы не можем добиться аналогичного скачка качества, заменив тексты на естественном языке анонимизированными историями пользователей, в которых действия выступают в роли слов? Рекомендательные модели уже достигли своего предела качества, и нам остаётся лишь вносить небольшие постепенные улучшения, корректируя функции и целевые значения.
Это были экзистенциальные вопросы, которые мы задали себе, разрабатывая наш новый подход ARGUS.
RecSys × LLM × RL
Изучив обширную литературу по масштабированию, мы обнаружили, что три основных условия определяют успешность масштабирования нейронной сети:
- Много данных.
- Достаточно выразительная архитектура с большой модельной вместимостью.
- Самая общая и фундаментальная из возможных учебных задач.
Например, LLM — очень выразительные и мощные преобразователи, которые обучаются буквально на основе всех данных в интернете. Более того, задача предсказания следующего слова — это фундаментальная задача, которая, по сути, распадается на ряд задач, связанных с различными областями знаний, включая грамматику, эрудицию, математику, физику и программирование. Все три условия соблюдены!
Если мы рассмотрим рекомендательные системы:
- У нас также много данных: триллионы взаимодействий между пользователями и предметами.
- С таким же успехом мы можем использовать трансформаторы.
- Нам просто нужно найти правильную задачу обучения для масштабирования рекомендательной модели.
Вот что мы сделали.

Есть интересный аспект предобучения больших языковых моделей. Если вы просто спросите о чём-либо предобученного магистра права, он даст усреднённый ответ. Наиболее вероятный ответ, который он встречал в обучающих данных. Этот ответ не обязательно будет хорошим или правильным.
Но если вы добавите подсказку перед вопросом, например: «Представьте, что вы эксперт в X», система начнет выдавать гораздо более релевантные и правильные ответы.
Это связано с тем, что LLM не просто учатся имитировать ответы из интернета; они также приобретают более фундаментальное понимание мира, пытаясь сжать всю информацию из обучающей выборки. Они усваивают закономерности и абстракции. И именно потому, что LLM знает широкий спектр ответов и при этом обладает фундаментальным пониманием мира, мы можем получать от него хорошие ответы.

Мы попытались применить эту логику к рекомендательным системам. Во-первых, необходимо представить рекомендации в виде задачи обучения с подкреплением:
- Рекомендательная система — это агент.
- Действия — это рекомендации. В самом простом случае рекомендательная система рекомендует по одному элементу за раз (например, каждый раз рекомендует один музыкальный трек в приложении потоковой передачи музыки).
- Под средой понимаются пользователи, их поведение, модели поведения, предпочтения и интересы.
- Политика представляет собой распределение вероятностей по элементам.
- Наградой является положительный отзыв пользователя в ответ на рекомендацию.

Есть прямая аналогия с примером LLM. «Ответы из интернета» — это действия прошлых рекомендательных систем (политики ведения журнала), а фундаментальное знание о мире заключается в понимании пользователей, их моделей поведения и предпочтений. Мы хотим, чтобы наша новая модель могла:
- Имитируйте действия прошлых рекомендательных систем.
- Имейте хорошее понимание пользователей.
- Корректировать свои действия для достижения лучшего результата.
Прежде чем перейти к нашему новому подходу, рассмотрим наиболее популярную схему обучения преобразователей рекомендаций: прогнозирование следующего товара. Модель SASRec здесь весьма показательна. Система накапливает историю позитивных взаимодействий пользователя с сервисом (например, покупок), и модель учится предсказывать, какая покупка, скорее всего, будет следующей в последовательности. То есть, вместо прогнозирования следующего токена, как в обработке естественного языка, мы выбираем прогнозирование следующего товара.

Этот подход (SASRec и общее прогнозирование следующего товара) не соответствует описанной мной ранее философии, которая фокусируется на корректировке политики журналирования на основе фундаментальных знаний о мире. Похоже, что для прогнозирования следующей покупки пользователя модель должна работать в соответствии со следующей философией:
- Он должен понимать, что может показать пользователю рекомендательная система, находившаяся в эксплуатации на момент составления прогноза. То есть, он должен иметь хорошую модель поведения политики журналирования (то есть модель, которую можно использовать для имитации).
- Ему необходимо понять, что могло понравиться пользователю из того, что показывала ему предыдущая рекомендательная система, то есть ему необходимо понять его предпочтения, которые являются основополагающими убеждениями о мире.
Но модели, подобные SASRec, не моделируют ничего из этого явным образом. Они не содержат полной информации о прошлых политиках ведения журнала (мы видим только рекомендации с положительными результатами), и мы также не учимся воспроизводить эти политики. Невозможно узнать, что могла бы предложить рекомендательная система в прошлом. В то же время мы не до конца понимаем модель мира или пользователя: мы игнорируем все отрицательные отзывы и учитываем только положительные.
ARGUS: Авторегрессивное генеративное последовательное моделирование пользователей
Авторегрессионное генеративное последовательное моделирование пользователей (ARGUS) — это наш новый подход к обучению преобразователей рекомендаций.
Сначала мы изучаем всю анонимизированную историю пользователя, включая позитивные взаимодействия, а также все остальные взаимодействия. Мы фиксируем суть контекста взаимодействия, время его совершения, использованное устройство, страницу продукта, на которой находился пользователь, настройки персонализации My Vibe и другие важные данные.

История пользователя представляет собой определенную последовательность троек (контекст, элемент, обратная связь), где контекст относится к контексту взаимодействия, элемент представляет собой объект, с которым взаимодействует пользователь, а обратная связь обозначает реакцию пользователя на взаимодействие (например, понравился ли пользователю элемент, купил ли он его и т. д.).
Далее мы определяем две новые задачи обучения, обе из которых выходят за рамки традиционного прогнозирования следующего элемента, широко используемого в промышленности и академических кругах.
Прогноз следующего элемента
Наша первая задача также называется прогнозированием следующего элемента. Анализируя историю и текущий контекст взаимодействия, мы прогнозируем, с каким элементом будет происходить взаимодействие: P(элемент | история; контекст).

- Если история содержит только рекомендательный трафик (события, сгенерированные непосредственно рекомендательной системой), то модель учится имитировать политику ведения журнала (рекомендации от прошлой рекомендательной системы).
- Если есть также органический трафик (любой трафик, отличный от реферального трафика, например трафик из поисковых систем или если пользователь посещает библиотеку и слушает свой любимый трек), мы также получаем более фундаментальные знания о пользователе, не связанные с политикой ведения журнала.
Важно : хотя эта задача называется так же, как в SASRec (прогнозирование следующего элемента), это совсем не то же самое. Мы прогнозируем не только положительные, но и отрицательные взаимодействия, а также учитываем текущий контекст. Контекст помогает нам понять, является ли действие органическим или нет, и если это рекомендация, то на какой поверхности оно находится (место, страница или карусель). Кроме того, это, как правило, снижает уровень шума при обучении модели.
Контекст имеет решающее значение для музыкальных рекомендаций: настроение пользователя и его текущая ситуация оказывают значительное влияние на тип музыки, которую он хочет слушать.
Задача предсказания элемента множества обычно выражается как задача классификации, где элементы исходного множества служат классами. Затем для обучения используется функция потерь кросс-энтропии, где функция softmax применяется к логитам (ненормализованным выходным данным нейронной сети). Для вычисления softmax необходимо вычислить сумму экспонент логитов по всем классам.
Хотя размер словарей в LLM может достигать сотен тысяч элементов в худшем случае, и вычисление softmax не представляет существенной проблемы, в рекомендательных системах это становится проблемой. Здесь каталоги состоят из миллионов или даже миллиардов элементов, и вычисление полного softmax — невыполнимая задача. Это тема для отдельной большой статьи, но в конечном итоге нам приходится использовать сложную функцию потерь, называемую «sampled softmax» с logQ-коррекцией:


- N означает смесь внутрипартийных и однородных негативов
- logQ(n) означает поправку logQ
- Температура Tозначает обученный параметр Eᵀ, ограниченный [0,01, 100].
Прогнозирование обратной связи
Прогнозирование обратной связи — вторая задача обучения. Учитывая историю, текущий контекст и сам элемент, мы прогнозируем обратную связь пользователя: P(обратная связь | история; контекст; элемент).

Первая задача, прогнозирование следующего элемента, учит нас имитировать политики логирования (и понимать пользователей при наличии органического трафика). Задача прогнозирования обратной связи, напротив, сосредоточена исключительно на получении фундаментальных знаний о пользователях, их предпочтениях и интересах.
Это очень похоже на то, как ранжирующий вариант модели из книги «Действия говорят громче слов» обучается на последовательности пар (предмет, действие). Однако здесь токен контекста рассматривается отдельно, и присутствуют не только рекомендательные контексты.
Обратная связь может включать в себя несколько компонентов: понравилось ли вам трек, не понравилось ли, добавили ли в плейлист и какая часть трека была прослушана. Мы предсказываем все типы обратной связи, разлагая их на отдельные функции потерь. В качестве конкретной функции потерь можно использовать любую функцию потерь, включая перекрёстную энтропию или регрессию. Например, бинарной перекрёстной энтропии достаточно, чтобы предсказать наличие лайка.
Хотя некоторые отклики встречаются чаще (лайков обычно гораздо меньше, чем продолжительных прослушиваний), модель хорошо обучается предсказывать все сигналы. Чем больше модель, тем легче ей обучиться всем задачам одновременно, без конфликтов. Более того, частые отклики (прослушивания), напротив, помогают модели научиться имитировать редкие, разрозненные отклики (лайки).

Если объединить все это в одну учебную задачу, то получится следующее:
- Создавайте истории для пользователя из троек (контекст, элемент, отзыв).
- Используйте трансформатор.
- Предсказать следующий элемент на основе скрытого состояния контекста.
- Прогнозируйте реакцию пользователя после взаимодействия с элементом на основе скрытого состояния элемента.

Позвольте мне также прокомментировать, чем это отличается от HSTU. В книге «Действия говорят громче слов» авторы обучают две отдельные модели для генерации и ранжирования кандидатов. Модель генерации кандидатов содержит всю историю, но, как и SASRec, она моделирует только положительные взаимодействия и не учитывает функцию потерь в случаях отрицательного взаимодействия. Модель ранжирования, как упоминалось ранее, обучается для задачи, аналогичной нашему прогнозированию с обратной связью.
Наше решение предлагает более комплексную задачу прогнозирования следующего элемента и более комплексную задачу прогнозирования обратной связи, и модель обучается в обеих функциях одновременно.
Упрощенный АРГУС
У нашего подхода есть одна большая проблема: мы раздуваем историю пользователя. Поскольку каждое взаимодействие с элементом представлено сразу тремя токенами (контекст, элемент, обратная связь), нам пришлось бы передать в преобразователь почти 25 000 токенов для анализа 8192 недавних прослушиваний пользователем.

Можно утверждать, что это всё ещё не имеет значения, и что длина контекста в LLM гораздо больше; однако это не совсем верно. В среднем LLM имеют гораздо меньшее количество токенов, обычно сотни, особенно на этапе предварительного обучения.
В отличие от этого, например, на нашей платформе потоковой музыки пользователи часто имеют тысячи или даже десятки тысяч событий. У нас и так гораздо более длинные контексты, и увеличение их длины в три раза ещё больше влияет на скорость обучения. Чтобы решить эту проблему, мы создали упрощённую версию модели, в которой каждая тройка (контекст, элемент, обратная связь) сжимается в один вектор. С точки зрения формата входных данных она напоминает наши предыдущие поколения моделей-трансформеров, однако мы сохраняем те же две задачи обучения — прогнозирование следующего элемента и прогнозирование обратной связи.
Чтобы предсказать следующий элемент, мы берем скрытое состояние из преобразователя, соответствующего тройке (c, i, f) в прошедшем моменте времени, присоединяем к нему текущий вектор контекста, сжимаем его до меньшей размерности с помощью MLP, а затем используем сэмплированный softmax, чтобы научиться предсказывать следующий элемент.
Чтобы предсказать обратную связь, мы конкатенируем вектор текущего элемента, а затем используем многослойный перцептор (MLP) для прогнозирования всех необходимых целевых переменных. С точки зрения архитектуры рекомендательного преобразователя, наша модель становится менее ориентированной на цель и контекст, однако она по-прежнему работает хорошо, обеспечивая трёхкратное ускорение.
Реализация ARGUS
Модель, обученная в этом двухголовом режиме для обеих задач одновременно (прогнозирование следующего элемента и прогнозирование обратной связи), может быть реализована как есть. Голова NIP отвечает за выбор кандидатов, а голова FP — за окончательное ранжирование.
Но мы не хотели этого делать, по крайней мере, не в нашей первой реализации:
- Нашей целью было реализовать очень большую модель, поэтому мы изначально сосредоточились на офлайн-развёртывании. При офлайн-развёртывании векторы пользователей и элементов пересчитываются ежедневно в рамках отдельного регулярного процесса, и вам нужно вычислить только скалярное произведение в среде выполнения.
- Предобученная версия ARGUS подразумевает доступ к истории пользователя без каких-либо задержек: мы видим все события в его истории вплоть до текущего момента времени, когда делается прогноз. То есть, его необходимо применить во время выполнения.
- Головка NIP предсказывает все взаимодействия пользователя, и модель обычно обучается предсказывать только будущие позитивные взаимодействия для генерации кандидатов. Но прогнозирование позитивных взаимодействий — это эвристическая задача, суррогатное обучение. Возможно, даже лучше использовать голову, которая предсказывает все взаимодействия, поскольку она учится соответствовать рейтингу. Если элемент был рекомендован, это означает, что рейтингу он понравился. Но в данной ситуации мы не были готовы экспериментировать и хотели пойти по проторенному пути.
- Головка FP обучается на основе точечных потерь: понравится ли трек или нет, какая часть трека будет услышана и так далее. Но мы по-прежнему часто обучаем модели парному ранжированию: мы учимся ранжировать элементы, которые были рекомендованы «рядом друг с другом» и получили разные отзывы. Некоторые утверждают, что точечных потерь достаточно для обучения моделей ранжирования, но в данном случае мы не заменяем весь стек ранжирования. Вместо этого мы стремимся добавить новый, мощный признак на основе нейронной сети в финальную модель ранжирования. Если финальная модель ранжирования обучена для конкретной задачи (например, парного ранжирования), то нейронная сеть, генерирующая этот признак, наиболее эффективно обучается для этой задачи; в противном случае финальная модель будет меньше полагаться на наш признак. Соответственно, мы хотели бы предварительно обучить ARGUS для той же задачи, что и исходная модель ранжирования, что позволит нам использовать его в ранжировании.
Существуют и другие варианты использования развёртывания, выходящие за рамки традиционных этапов генерации и ранжирования кандидатов, и мы активно их исследуем. Однако для нашего первого развёртывания мы выбрали офлайн-ранжирование с двумя башнями:
- Мы решили доработать ARGUS, чтобы его можно было использовать как офлайновую модель с двумя башнями. Мы используем её для ежедневного пересчёта векторов пользователей и объектов, а предпочтения пользователей определяются путём скалярного произведения пользователя и объектов.
- Мы предварительно обучили ARGUS задаче парного ранжирования, аналогичной той, на которой обучается финальная модель ранжирования. Это означает, что мы каким-то образом выбрали пары треков, которые пользователь прослушал и оценил по-разному с точки зрения положительных отзывов, и хотим научиться правильно их ранжировать.
Мы создаём такие модели довольно часто: их легко обучать и внедрять с точки зрения ресурсов и затрат на разработку. Однако наши предыдущие модели были значительно меньше и обучались иначе. Не с помощью процедуры ARGUS, а сначала с помощью обычного сопоставительного обучения между пользователями и позитивными данными, а затем были доработаны для решения конкретной задачи.
Наша предыдущая процедура контрастного предобучения подразумевала составление нескольких обучающих примеров для пользователя: если у пользователя было n покупок, то в наборе данных будет n образцов. При этом мы не использовали авторегрессионное обучение. То есть, мы запускали преобразователь n раз во время обучения. Такой подход позволил нам очень гибко создавать пары (пользователь, товар) для обучения, использовать любой формат истории, кодировать контекст вместе с пользователем и учитывать задержки. При прогнозировании лайков мы можем использовать однодневную задержку в истории пользователя. Однако всё работало довольно медленно.
Предварительное обучение в ARGUS использует авторегрессионное обучение, при котором мы обучаемся на основе всех событий в действиях пользователя одновременно за один запуск преобразователя. Это мощный инструмент ускорения, который позволил нам обучать гораздо более крупные модели, используя те же ресурсы.
В ходе тонкой настройки мы также многократно запускали трансформатор для одного пользователя. Это называется обучением на уровне впечатлений, которое использовалось в Meta до HSTU. Если пользователю показывается элемент в определённый момент, мы генерируем выборку вида (пользователь, элемент). Набор данных может содержать большое количество таких показов для одного пользователя, и мы повторно запускаем трансформатор для каждого из них. Для парного ранжирования мы рассматривали тройки вида (пользователь, элемент1, элемент2). Те, которые мы использовали ранее.
Изучив ускорение на этапе предобучения, мы решили использовать аналогичный подход с тонкой настройкой. Мы разработали процедуру тонкой настройки для модели с двумя башнями, чтобы обучить её ранжированию, при которой трансформатор достаточно запустить только один раз.

Допустим, у нас есть вся история пользователя за год и все рекомендации, показанные пользователю за тот же период. Реализуя преобразователь с каузальной маской по всей истории, мы получаем векторные представления пользователя для всех моментов этого года одновременно, что позволяет:
- Отдельно вычислить векторы показанных элементов.
- Проверьте временные метки и сопоставьте показы рекомендаций с векторами пользователей, соответствующими требуемой задержке в доставке истории пользователей.
- Рассчитайте все необходимые скалярные произведения и все члены функции потерь.
И все это одновременно, в течение всего года — за один трансформаторный запуск.
Раньше мы перезапускали преобразователь для каждой пары впечатлений; теперь мы обрабатываем все впечатления сразу за один прогон. Это колоссальное ускорение: в десятки, сотни или даже тысячи раз. Чтобы использовать такую модель с двумя башнями, мы можем просто использовать векторное представление пользователя в последний момент времени (соответствующий последнему событию в истории) в качестве текущего векторного представления. Для элементов мы можем использовать кодировщик, который использовался во время обучения для впечатлений. В процессе обучения мы имитируем однодневную задержку в истории пользователей, а затем запускаем модель в автономном режиме, ежедневно пересчитывая векторы пользователей.
Когда я говорю, что мы обрабатываем всю историю пользователя за год за один запуск трансформатора, я немного ввожу в заблуждение. На самом деле, у нас есть определённое ограничение на максимальную длину истории, которое мы устанавливаем, и пользователь в наборе данных может иметь несколько выборок или фрагментов. При предобучении эти фрагменты не перекрываются.
Однако при тонкой настройке существуют ограничения не только на максимальную длину истории, но и на ее минимальную длину, а также на максимальное количество показов рекомендаций в одном обучающем примере, используемом для обучения модели для ранжирования.
Результаты
В качестве первого эксперимента мы выбрали наш сервис потоковой музыки. Рекомендации здесь играют решающую роль, и у сервиса большое количество активных пользователей. Мы создали гигантский обучающий набор данных, включающий более 300 миллиардов прослушиваний от миллионов пользователей. Это в десятки, а то и сотни раз больше, чем обучающие наборы данных, которые мы использовали ранее.
Что такое тройка (контекст, элемент, обратная связь) в сервисе потоковой передачи музыки?
- Контекст : является ли текущее взаимодействие рекомендацией или органическим. Если это рекомендация, на какой платформе оно находится, и если это My Vibe, каковы настройки.
- Элемент : музыкальный трек. Наиболее важным признаком при кодировании элемента является его идентификатор. Мы используем унифицированные вложения для кодирования признаков с высокой кардинальностью. В данном случае мы берём три хэша по 512 КБ на элемент. В наших экспериментах мы используем фиксированную унифицированную матрицу вложений со 130 миллионами параметров.
- Обратная связь от пользователей : понравился ли трек, какая часть трека была прослушана.
Для оценки качества в автономном режиме мы используем данные за неделю, следующую за периодом обучения, по глобальному временному разрезу.
Для оценки качества предобученной модели мы анализируем значения функции потерь в задачах предобучения: прогнозирование следующего элемента и прогнозирование с обратной связью. То есть мы измеряем, насколько хорошо модель научилась решать поставленные нами задачи. Чем меньше значение, тем лучше.
Важно : Мы рассматриваем историю пользователя за длительный период, но функция потерь рассчитывается только для событий, которые происходят в течение тестового периода.
В процессе тонкой настройки мы учимся правильно ранжировать пары элементов на основе отзывов пользователей, что делает PairAccuracy — метрику, измеряющую долю пар, правильно упорядоченных моделью — подходящей офлайн-метрикой для нас. На практике мы немного переоцениваем пары, основываясь на отзывах: например, пары, в которых пользователю понравился трек, а затем он его пропустил, имеют больший вес, чем пары, в которых он его прослушал и пропустил.
Наш сценарий развертывания предполагает добавление новой мощной функции к итоговому ранкеру. Поэтому мы измеряем относительное увеличение PairAccuracy для итогового ранкера с добавлением новой функции по сравнению с итоговым ранкером без неё. Итоговый ранкер в нашей платформе потоковой музыки — это градиентный буст.
Результаты и измерения A/B-тестирования
Нашей первоначальной целью было масштабирование рекомендательных трансформаторов. Для тестирования масштабирования мы выбрали четыре конфигурации трансформаторов разных размеров, с диапазоном параметров от 3,2 млн до 1,007 млрд.

Мы также решили протестировать производительность архитектуры HSTU. В статье «Действия говорят громче слов» авторы предложили новую архитектуру кодера, которая существенно отличается от архитектуры трансформера. Согласно экспериментам авторов, эта архитектура превосходит трансформеры в задачах выработки рекомендаций.

Масштабирование есть! Каждый новый скачок в размере архитектуры приводит к повышению качества, как на этапе предварительной подготовки, так и при тонкой настройке.
HSTU оказался ничуть не лучше трансформаторов. Мы использовали самую большую конфигурацию, упомянутую авторами в книге «Действия говорят громче слов». Она обладает в полтора раза большим количеством параметров, чем наш трансформатор среднего размера, при примерно таком же качестве.

Представим метрики из таблицы в виде графика. В этом случае мы можем наблюдать закон масштабирования для наших четырёх точек: зависимость качества от логарифма числа параметров выглядит линейной.
Мы провели небольшое исследование абляции, чтобы выяснить, можем ли мы упростить нашу модель или удалить какие-либо части из обучения.

Если удалить предварительное обучение, качество модели снизится.

Если уменьшить продолжительность тонкой настройки, падение станет еще более заметным.

В начале статьи я упоминал, что авторы книги «Действия говорят громче слов» обучили модель на истории длиной 8000 записей. Мы решили попробовать: оказалось, что обработка столь глубокой музыкальной истории пользователя приводит к заметному улучшению рекомендаций. Ранее наши модели использовали максимум 1500–2000 событий. Впервые нам удалось преодолеть этот порог.
Результаты внедрения
Мы работаем над разработкой моделей-трансформеров для музыкальных рекомендаций уже около трёх лет и проделали большой путь. Вот всё, чему мы научились, и как мы продвинулись в разработке моделей-трансформеров для музыкальных рекомендаций за это время.

- Все наши первые три преобразователя работали в автономном режиме. Векторы пользователей и объектов пересчитывались ежедневно. Затем векторы пользователей загружались в хранилище «ключ-значение», а векторы объектов сохранялись в оперативной памяти сервиса, в то время как во время выполнения вычислялось только скалярное произведение. Мы использовали некоторые из этих моделей не только для ранжирования, но и для генерации кандидатов (мы знакомы с построением многоголовых моделей, которые выполняют обе задачи). В подобных случаях индекс HNSW, из которого можно извлечь кандидатов, также находится в оперативной памяти сервиса.
- Первая модель имела только сигнал о лайках, вторая модель имела сигнал о прослушиваниях (включая пропуски), а в третьей модели мы объединили оба типа сигналов (явный и неявный).
- Версия модели v4 представляет собой адаптацию v3, которая реализуется во время выполнения с небольшой задержкой в истории пользователя, ее кодировщик в 6 раз меньше, чем у модели v3.
- Новая модель ARGUS имеет в восемь раз большую длину истории пользователя и в десять раз больший размер кодировщика. Она также использует новый процесс обучения, описанный мной ранее.

TLT — это общее время прослушивания. Вероятность «лайка» отражает вероятность того, что пользователю понравится рекомендация, когда она будет показана. Каждая реализация приводила к росту метрик для наших рекомендаций, адаптированных под пользователя. А первый ARGUS дал примерно такой же прирост метрик, как и все предыдущие реализации вместе взятые!

У My Vibe также есть специальный параметр, для которого мы используем отдельный стек ранжирования: «Незнакомый». Для этого параметра у нас была отдельная реализация ARGUS, которая позволила увеличить общее время прослушивания на 12% и вероятность прослушивания на 10%. Параметр «Незнакомый» используется пользователями, заинтересованными в поиске новых рекомендаций. Значительный рост в этой категории подтверждает, что ARGUS эффективнее справляется с нетривиальными ситуациями.
Мы внедрили ARGUS в музыкальные сценарии на смарт-устройствах и успешно увеличили общее время, проводимое пользователями с активным динамиком, на 0,75%. В данном случае финальный ранкер представляет собой не модель градиентного бустинга, а полномасштабную ранжирующую нейронную сеть. Благодаря этому мы смогли не только использовать один скалярный признак из ARGUS, но и передавать полные векторы пользователей и объектов в качестве входных данных финальному ранкеру. По сравнению с одним скалярным признаком, это увеличило качество ещё в полтора-два раза.
ARGUS уже реализован не только как функция ранжирования, но и для генерации кандидатов. Команда адаптировала офлайн-версию ARGUS в версию для среды выполнения. Эти реализации обеспечили значительный прирост ключевых показателей. Нейронные сети — будущее рекомендательных систем, но впереди ещё долгий путь.
Спасибо за прочтение.
Источник: towardsdatascience.com



























