Ретрив и ранжирование в рекомендациях
«Спроектируй рекомендации на миллионы товаров» - системный вопрос рексиса. Ответ-каркас один: каскад. Кто пытается гнать одну модель по всему каталогу - не строил ничего живого.
// Запомни бюджет: retrieval - миллионы кандидатов за миллисекунды, ранкер - сотни за десятки миллисекунд.
Каскад: retrieval → ranking → бизнес-слой
Прод-рексис - конвейер: retrieval дёшево достаёт сотни кандидатов из миллионов; ранкер - тяжёлая модель - точно сортирует эти сотни; бизнес-слой накладывает правила: дедуп, фильтры, разнообразие.
Retrieval-источники смешивают: ANN (approximate nearest neighbors) по эмбеддингам, co-visitation («с этим смотрят»), популярное в сегменте, свежее. Один источник - один интент; микс ловит разные.
// Латентность-бюджет диктует архитектуру: тяжёлым фичам место в ранкере, retrieval обязан быть тупым и быстрым.
- каскад
- дешёвый отбор кандидатов → дорогая сортировка → правила
ANN и ранкер
ANN-поиск (HNSW, IVF, ScaNN) находит приближённых ближайших соседей за миллисекунды; цена - небольшая потеря recall против точного перебора, параметры индекса балансируют скорость и полноту.
Ранкер - бустинг или нейронка на фичах пары юзер×айтем: история, контекст, CTR-статистики (click-through rate). Лоссы - pointwise/pairwise/listwise; LambdaMART - эталон табличного learning-to-rank.
// Обучение на логах требует дебиасинга позиции: клики зависят от места показа. Позиция как фича на трейне (и фикс на инференсе) или IPS-взвешивание (inverse propensity scoring), иначе модель выучит «первое место кликают».
- ANN
- приближённый поиск соседей (HNSW/IVF) за миллисекунды
- позиционный дебиасинг
- клик ≠ релевантность: позиция фичей или IPS
- HNSW
- hierarchical navigable small world
- IVF
- inverted file index
Разнообразие и правила поверх скора
Релевантность - не готовая выдача: без диверсификации получишь десять одинаковых товаров. MMR (maximal marginal relevance) или квоты категорий размешивают список почти без потери релевантности.
Фильтры бизнес-слоя обязательны: купленное, отсутствующее на складе, возрастные ограничения - модель об этом не знает и знать не должна.
// Здесь же и exploration: доля показов на новые и неуверенные айтемы, иначе система замыкается в петле своих же прошлых рекомендаций.
- MMR
- перевзвешивание релевантность/непохожесть - разнообразие списка
Как отвечать: «Спроектируй рекомендации для каталога в 10 млн товаров»
Каскад. Retrieval: несколько дешёвых источников - ANN по two-tower эмбеддингам, co-visitation, популярное в сегменте, свежие - суммарно сотни кандидатов за миллисекунды. Ранжирование: бустинг на фичах пары юзер×айтем по этим сотням, обучение на логах с позиционным дебиасингом. Сверху бизнес-слой: фильтры склада и купленного, квоты разнообразия, доля exploration. Оценка: офлайн @K-метрики на time-сплите как фильтр, финальное слово - A/B по продуктовым метрикам с guardrail на разнообразие.
Полный конвейер с бюджетами и оценкой - системный ответ, который и просят «спроектируй».
На чём валят
- −Тяжёлый ранкер по всему каталогу - каскад существует, потому что это невозможно.
- −Обучение на логах без учёта позиции - модель выучит «первое место кликают».
- −Один retrieval-источник - ANN по вкусу не покажет новинки и тренды.
- −Только релевантность без диверсификации - выдача из десяти одинаковых.
Проверьте себя
Пять вопросов из банка по этой подтеме. Всего их 11, остальные разбираются в тренажёре.
- Learning-to-rank: чем pairwise/listwise подход лучше поточечной регрессии релевантности для ранжирования?A)Поточечная регрессия технически неспособна выдать хоть какой-то порядок элементов в выдаче рекомендацийB)Pairwise и listwise работают без разметки релевантности, а поточечный подход её требуетC)Они оптимизируют относительный порядок элементов, а не абсолютную оценку — это ближе к тому, что мерят ранжирующие метрикиD)Разницы по сути нет: все три подхода оптимизируют ровно одну и ту же функцию потерь и дают идентичный порядок выдачи
показать ответ и разбор
+C)Они оптимизируют относительный порядок элементов, а не абсолютную оценку — это ближе к тому, что мерят ранжирующие метрики// разбор: Поточечный подход учит предсказывать абсолютную релевантность каждого элемента отдельно, но пользователю важен порядок в выдаче, а не точность оценки. Pairwise (правильный порядок пар) и listwise (качество всего списка) прямо оптимизируют относительное ранжирование, лучше согласуясь с метриками вроде NDCG. Поэтому в ранкерах они обычно бьют наивную регрессию скора.
- Ранкер обучают на кликах из своей же выдачи. Какую петлю обратной связи это создаёт и чем грозит?A)Никакой петли не возникает: клики являются объективным и несмещённым сигналом истинной релевантности товараB)Позиционный/популярностный биас: верх кликают чаще, петля усиливает; нужны дебиас и explorationC)Основной риск здесь — переполнение хранилища логами кликов, которое лечится регулярной очисткой старых данныхD)Петля лишь ускоряет сходимость обучения ранкера и полезна во всех отношениях без каких-либо негативных побочных эффектов
показать ответ и разбор
+B)Позиционный/популярностный биас: верх кликают чаще, петля усиливает; нужны дебиас и exploration// разбор: Модель показывает товары, по показанному собираются клики, на этих кликах учится следующая модель — замкнутый цикл. Клик зависит от позиции (верх кликают чаще независимо от релевантности) и от прошлой популярности, поэтому модель закрепляет собственные прежние решения: популярное всплывает ещё выше, новое и «хвост» не получают показов. Лечат позиционным дебиасом (IPS, логирование позиций) и exploration.
- Зачем на этапе retrieval берут приближённый поиск соседей (ANN), а не точный перебор?A)Точный перебор по миллионам товаров на каждый запрос слишком медленный; ANN находит почти те же топ-кандидаты в разы быстрееB)ANN возвращает точный результат, просто его проще реализовать в коде, чем полный перебор, и работает он с той же скоростью, что и наивный полный переборC)Приближённый поиск нужен затем, чтобы добавить случайности и разнообразия в выдачуD)Точный перебор запрещён из-за приватности, а ANN якобы обезличивает эмбеддинги пользователей автоматически
показать ответ и разбор
+A)Точный перебор по миллионам товаров на каждый запрос слишком медленный; ANN находит почти те же топ-кандидаты в разы быстрее// разбор: На этапе retrieval нужно из миллионов товаров быстро достать сотни ближайших к вектору запроса. Точный перебор всех расстояний на каждый запрос не укладывается в бюджет задержки. ANN-индексы (HNSW, IVF, PQ) находят почти-ближайших соседей за доли миллисекунды, жертвуя крошечной долей точности ради огромного ускорения — приемлемый размен, ведь ошибки добирает последующий ranking. Случайность и приватность тут ни при чём.
- Что такое in-batch negatives при обучении two-tower ретривера и зачем они?A)Специальные заранее размеченные людьми отрицательные примеры, добавляемые вручную в каждый батч обучения, которые команда разметки заранее готовит вручную под каждую обучаемую модельB)Полный перебор всех непросмотренных товаров как негативов для каждого пользователя на каждом шагеC)Приём, применимый лишь на инференсе: негативы подмешиваются в выдачу для разнообразия рекомендацийD)Товары ДРУГИХ примеров того же батча берут как негативы для данного юзера — дёшево и много негативов сразу
показать ответ и разбор
+D)Товары ДРУГИХ примеров того же батча берут как негативы для данного юзера — дёшево и много негативов сразу// разбор: Two-tower учат сближать вектор юзера с его позитивным товаром и отдалять от негативов. Явно набирать негативы дорого, поэтому берут in-batch: для пары (юзер, его товар) негативами служат товары остальных пар того же батча — они почти наверняка нерелевантны и уже посчитаны, что даёт много дешёвых негативов и эффективный softmax по батчу. Это трюк обучения, не разметка и не инференс; иногда правят на popularity bias.
- Почему тяжёлый ranker может использовать признаки, недоступные лёгкому two-tower ретриверу?A)Не может: ranker и retriever используют один и тот же набор входных признаков, иначе их скоры окажутся несопоставимыми и весь каскад развалитсяB)Ranker работает без признаков, полагаясь на порядковый номер кандидата из retrievalC)Ranker считает совместные (cross) признаки пары юзер-товар и контекст — он оценивает лишь сотни кандидатов, а не весь каталогD)Two-tower, наоборот, богаче признаками, а ranker намеренно упрощают ради максимальной скорости выдачи
показать ответ и разбор
+C)Ranker считает совместные (cross) признаки пары юзер-товар и контекст — он оценивает лишь сотни кандидатов, а не весь каталог// разбор: Two-tower обязан кодировать юзера и товар РАЗДЕЛЬНО (иначе не предрассчитать эмбеддинги и не искать через ANN), поэтому он не видит совместных признаков пары. Ranker оценивает лишь сотни отобранных кандидатов, а не весь каталог, и может позволить себе дорогие cross-признаки (совпадение категорий юзер×товар, свежесть, контекст запроса, взаимодействия) — отсюда его точность. Это следствие каскада, а не произвол.
дальше
Теорию прочитали. Навык ставится повторением
В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.