🔥 xAI выложили исходники рекомендательной системы X
Что интересного? 🤔 1️⃣ Python — мозг, Rust — мускулы Архитектура системы — хрестоматийный пример современного HighLoad RecSys. Вся бизнес-логика, пайплайны данных (candidate-pipeline), и сервинг (home-mixer, thunder) написаны на Rust. Но Python (phoenix/) здесь царь абстракций. Именно на нем описана логика обучения, архитектура трансформеров и инференс-модели.
2️⃣ JAX и Haiku вместо PyTorch Первое, что бросается в глаза в папке phoenix/ — это импорты. import haiku as hk, import jax, import jax.numpy as jnp.
xAI не использует стандартный для индустрии PyTorch. Они сидят на стеке Google/DeepMind. — JAX: дает автоматическое дифференцирование и XLA-компиляцию (код летит на TPU/GPU). — Haiku: библиотека для нейронок поверх JAX (наследник Sonnet). Это логично, учитывая, что модель Phoenix (ранжирование) — это, по сути, адаптация их LLM Grok-1.
3️⃣ Смерть Feature Engineering В README прямым текстом написано: "We have eliminated every single hand-engineered feature". Больше никаких user_age * clicks_count. Система скармливает трансформеру "сырую" последовательность действий пользователя (лайки, реплаи, паузы). Python-код просто превращает User Action Sequence в эмбеддинги. Всё. Модель сама учится понимать, что важно.
4️⃣ Главный хак: Candidate Isolation Самое интересное в коде — это реализация Attention Mask в файле grok.py. Задача: прогнать через трансформер батч, состоящий из истории юзера и кандидатов на показ. Проблема: если использовать обычный Attention, кандидаты начнут "подсматривать" друг на друга, и скор одного поста будет зависеть от того, какие еще посты попали в батч. Решение: Masked Attention. В коде это выглядит так: — Кандидаты видят историю юзера. — Кандидаты видят самих себя. — Кандидаты НЕ видят других кандидатов.
grok.py (упрощено)" hx-get="/tags/grok.py (упрощено)" hx-push-url="/tags/grok.py (упрощено)" hx-target="body" hx-swap="innerHTML" >#grok.py (упрощено)def make_recsys_attn_mask(seq_len, candidate_start_offset):
#Causal mask для истории (все видят прошлое)mask = jnp.tril(jnp.ones((seq_len, seq_len)))
#Зануляем область, где кандидаты смотрят друг на другаmask = mask.at[candidate_start_offset:, candidate_start_offset:].set(0)
#Разрешаем кандидатам смотреть только на самих себя (диагональ)idxs = jnp.arange(candidate_start_offset, seq_len) mask = mask.at[idxs, idxs].set(1) return mask Один матричный трюк позволяет скорить сотни постов за один проход модели независимо друг от друга.
Итого: Перед нами эталонный "Two-Tower" retrieval + Transformer ranking. Python здесь используется не как клей, а как инструмент для описания сложной математики (спасибо JAX), в то время как Rust тащит на себе продакшн.