Полный алгоритм X в 145 правилах: как нейросеть на 18 голов решает, увидят ли ваш пост
Разбор того, как устроена рекомендательная система платформы. Получилось 145 пунктов, и читается это не как маркетинговый ликбез про охваты, а как развёрнутая техническая спецификация ML-системы с эмбеддингами, мультизадачной нейросетью, классификаторами безопасности и графовыми источниками кандидатов. Собрали суть.
For You состоит из четырёх стадий конвейера. На первой генерация кандидатов вытаскивает около 1500 твитов из множества источников параллельно, примерно поровну из in-network и out-of-network. На второй лёгкий ранкер логистического типа отсекает около 90 процентов кандидатов за миллисекунды. На третьей тяжёлый ранкер прогоняет выживших через глубокую сеть. На четвёртой работают дедупликация, безопасность, разнообразие, реклама, фильтры мьютов и блоков. Если не прошли хотя бы одну стадию, поста никто не увидит.
Сердце системы это тяжёлый ранкер с архитектурой типа MaskNet, постепенно мигрирующий в сторону трансформера. Один общий ствол и 18 выходных голов с весовой бинарной кросс-энтропией на голову. Каждая голова предсказывает свою вероятность: лайк, ответ, ответ автора на ответ с последующим обменом репликами, репост, цитата, dwell time, просмотр половины видео, клик в профиль с последующей активностью, шеринг, добавление в закладки, подписка после поста, хороший клик, хороший клик в профиль, репорт, блок, мьют, not_interested и обобщённая негативная обратная связь v2. Финальный скор это взвешенная сумма этих 18 чисел, причём вес зависит от знака. Один репорт по силе примерно равен минус 369 в скоре. Один лайк это базовая единица. Ответ весит примерно 27 лайков. А самый дорогой положительный сигнал во всей системе это цепочка, в которой автор ответил на чей-то реплай, и автор реплая снова откликнулся, около плюс 75 лайков.
Идентичность пользователя в модели это не его био и не список подписок, а последние примерно 127 событий взаимодействия, поданные в трансформер. Никакого матчинга по био, никаких хардкод-тегов интересов и никакого keyword-таргетинга. Модель никогда не читала ваше био, она читала ваши действия. Поэтому профиль обучается на любом скролле: быстро пролистали пост, записалось negative_not_dwelled_count += 1, и фид постепенно становится дум-скроллом, который вы сами и натренировали.
Кандидаты приходят сразу из нескольких источников. SimClusters группирует аккаунты примерно в 145 тысяч сообществ по паттернам подписок, причём у каждого пользователя отдельные producer и consumer эмбеддинги. TwHIN строит 200-мерные эмбеддинги для пользователей, твитов и рекламы через предсказание связей в гетерогенной графе. UTEG достаёт твиты, с которыми взаимодействовали те, с кем взаимодействуете вы. Earlybird на Lucene держит реалтайм-индекс для быстрого in-network поиска. Real Graph хранит силу связей между аккаунтами, и эти веса затухают без активности, то есть просто подписаться недостаточно, нужно регулярно реагировать на контент.
Контент проходит сразу несколько классификаторов на стадии создания. Slop_score это отдельная Grok vision-language модель, которая оценивает посты на признаки engagement-bait и AI-slop. Шаблоны вроде RT if you agree, name a better X, type YES if гарантированно отлетают по этому классификатору. Безопасность представлена семью отдельными PTOS-классификаторами для NSFW, насилия, харассмента, селф-харма и подобного, и виральность не отменяет фильтрацию. Спам-реплаи вроде Great post или одиночных эмодзи под двумя сотнями аккаунтов в день ловит отдельный классификатор. У видео извлекается аудио через FFmpeg, потом ASR строит транскрипт, и транскрипт уходит в эмбеддинг поста. У картинок работает vision-модель плюс OCR, поэтому мем со встроенным текстом ранжируется в том числе по содержимому надписи.
Есть несколько неочевидных механик, которые сильно меняют поведение системы. Скор нормализуется per viewer, у одного и того же поста разные значения для разных зрителей. Виральность определяется не объёмом лайков, а долей out-of-network реакций. Возраст поста жёстко ограничен часами, после порога твит просто становится неприемлемым для For You, никакого slow burn на платформе нет. Conversation dedup пропускает на FYP только самый сильный пост в треде на конкретного зрителя, а author diversity penalty мультипликативно штрафует каждый следующий пост одного автора в одной ленте. Quote tweet и self-quote создают новые кандидаты с новым возрастом, в отличие от RT и self-reply, поэтому квотинг своего же старого твита это легальный способ перепрокачать контент.
Подписка на Premium даёт мультипликативный буст в ранкере, особенно в ранжировании реплаев. Это не баг восприятия, а коэффициент в коде. Под крупными постами реплаи отдельно оценивает Grok-модель по шкале от 0 до 3, и качественные ответы получают самостоятельное распространение в ленте читателей оригинала. То есть хороший reply game это бесплатная дистрибуция от аккаунтов, на которые вы не подписаны.
Шэдоубана как одного флага в системе нет. То, что обычно называют этим словом, складывается мультипликативно из накопленной истории slop_score, попаданий в PTOS, флагов спам-реплаев, низкого качества недавнего engagement и низкого account-age trust. Это мягкий градиентный даунранкинг, а не бинарный выключатель, и восстанавливается он только устойчиво высокой активностью.
Для разработчика и ML-инженера здесь много знакомого. Multi-task learning с одним стволом и кучей голов, балансировка классов из-за редкости репортов и блоков, кэширование эмбеддингов пользователей и твитов с расписанием обновлений, DPP-реранкер для разнообразия, эпсилон-жадная разведка на 1-5 процентов показов, отдельные ранкеры для пушей, поиска, трендов и списков. На уровне фич видны и dwell-таймы по медиатипам, и Jaccard-сходство по подпискам, и good_click против обычного клика, и good_profile_click отдельно от профильного клика, и negative_feedback_no_dwell для быстрых проскроллов. Демография участвует, но не доминирует над поведенческим эмбеддингом.
Алгоритм: https://t.me/ai_machinelearning_big_data/10145