Forwarded from Задачи DS - Собеседования, Соревнования, ШАД
Изи стажка в VKВидео✅️
#vk
В начало
Делюсь отзывом о стажировке от выпускника наших курсов. Учусь на 4 курсе бизнес-информатики в ВШЭ. Всё началось с моего друга, он уже работал в вк и дал контакт своего эйчара. Я отправил резюме, и через месяц мне пришла обратная связь на почту... кхе-кхе
и просьба связаться с hr. Списались в tg. Было сказано, мол будет алгоритмическая задачка и теория по ML, но я бы сузил до алгоритмическая задачка и рекомендашки
По сути вышло 3 этапа: созвон с эйчаром, тех-собес на 1.5 часа, финал с командой
Тех.собес
1.собеседующий рассказал, почему пошёл в вк (кстати, лично я кайфанул от прикольной фичи в офисе, такой как безлимитная кола(стоит автомат как в бургер кинге:), иногда засиживался на кофе-поинтах в ноуте из-за этого)
2.Алгоритмическая таска
Дан массив чисел и число k. Нужно вернуть k самых частых элементов
по решению: считаем частоту чисел через хеш-мапу, сортируем пары (число, частота) по убыванию частоты, берём первые k элементов, O(NlogN) асимптотика
3.Блок с рекомендашками
написать функцию, которая вычисляет Precision@K
пользователи часто добавляют айтемы в "смотреть позже", но не смотрят их. Как можно улучшить рекомендации?
можно ранжировать айтемы по вероятности клика(CTR, например), учитывая контекст: время, устройство и историю просмотров, после чего делать A/B-тесты и добавлять разнообразие(избегаем застревания в одной категории), повышая вовлечённость
написать формулы метрик ранжирования, которые помню(написал MAP, nDCG, MRR), обсудили ранговую корреляцию+ попросил рассказать основные подходы к построению рекомендательных систем
Финал
ребята рассказали о себе, я поделился своими пет-проектами; в целом, словили общий вайб
через 3 дня дали офер
По стажке
понравился опыт, лично я дорабатывал алгоритмы рекомендаций, крутил данные, проверял гипотезы и даже пару раз устроил небольшой баг в A/B-тестах (но быстро поправил!)
+ немного помогал внедрять фичи в бекенд
вообще, если попадёте, рекомендую ходить на митапы и задавать глупые(как вам кажется) вопросы, быстрее освоитесь:)
зп: 80к гросс, 3 месяца
@zadachi_ds_chat
#vk
В начало
Делюсь отзывом о стажировке от выпускника наших курсов. Учусь на 4 курсе бизнес-информатики в ВШЭ. Всё началось с моего друга, он уже работал в вк и дал контакт своего эйчара. Я отправил резюме, и через месяц мне пришла обратная связь на почту... кхе-кхе
Ваше резюме заинтересовало
и просьба связаться с hr. Списались в tg. Было сказано, мол будет алгоритмическая задачка и теория по ML, но я бы сузил до алгоритмическая задачка и рекомендашки
По сути вышло 3 этапа: созвон с эйчаром, тех-собес на 1.5 часа, финал с командой
Тех.собес
1.собеседующий рассказал, почему пошёл в вк (кстати, лично я кайфанул от прикольной фичи в офисе, такой как безлимитная кола(стоит автомат как в бургер кинге:), иногда засиживался на кофе-поинтах в ноуте из-за этого)
2.Алгоритмическая таска
Дан массив чисел и число k. Нужно вернуть k самых частых элементов
по решению: считаем частоту чисел через хеш-мапу, сортируем пары (число, частота) по убыванию частоты, берём первые k элементов, O(NlogN) асимптотика
3.Блок с рекомендашками
написать функцию, которая вычисляет Precision@K
def precision_at_k(recommended_items, relevant_items, K):
top_k = recommended_items[:K]
relevant_in_top_k = [item for item in top_k if item in relevant_items]
return len(relevant_in_top_k) / K if K > 0 else 0.0
пользователи часто добавляют айтемы в "смотреть позже", но не смотрят их. Как можно улучшить рекомендации?
можно ранжировать айтемы по вероятности клика(CTR, например), учитывая контекст: время, устройство и историю просмотров, после чего делать A/B-тесты и добавлять разнообразие(избегаем застревания в одной категории), повышая вовлечённость
написать формулы метрик ранжирования, которые помню(написал MAP, nDCG, MRR), обсудили ранговую корреляцию+ попросил рассказать основные подходы к построению рекомендательных систем
Финал
ребята рассказали о себе, я поделился своими пет-проектами; в целом, словили общий вайб
через 3 дня дали офер
По стажке
понравился опыт, лично я дорабатывал алгоритмы рекомендаций, крутил данные, проверял гипотезы и даже пару раз устроил небольшой баг в A/B-тестах (но быстро поправил!)
+ немного помогал внедрять фичи в бекенд
вообще, если попадёте, рекомендую ходить на митапы и задавать глупые(как вам кажется) вопросы, быстрее освоитесь:)
зп: 80к гросс, 3 месяца
@zadachi_ds_chat
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from что-то на DL-ском
Авторы вспомнили мутационные алгоритмы, которые я ненавидела в бакалавриате, когда мы их проходили, и утверждают, что это заменит RLHF
Если коротко АМЕРИКАНСКИЕ УЧЕННЫЕ придумали как заставить модель учиться на своих ошибках от артефактов CoT (ну а что он тупо существует, еще и жалуются ходят, что он не показывает настоящих размышлений модели)
Работает все следующих образом:
1) запускаем модель на минибатч задач по определенному классу
2) собираем с запуска всякие CoT, тул коллы (когда работаем с агентами), ошибки с компиляторов, когда это кодовые задачи и тд
3) другая LLM-ка смотрит на артефакты и выдает экспертное мнение чего не хватало в промпте, чтобы модель получше ПОДУМОЛА
За что лайк: вместо жадного выбора лучшего кандидата (который ведет к локальным оптимумам), GEPA строит Парето-фронт:
💛 Сохраняет всех кандидатов, которые лучше хотя бы на одной задаче
💛 Убирает полностью доминируемых
💛 Стохастически выбирает из оставшихся
Это дает exploration без раздувания пула кандидатов. GEPA также может скрещивать кандидатов. Если один хорошо эволюционировал модуль А, а другой — модуль Б, то берет лучшие части от каждого
В общем то что? Понятное дело, авторы делают ставку на интерпретируемость процесса эволюции, меньшее время подбора систем промптов таким способом в сравнении с RL обучением, но как это работает на самом деле не понятно, ни кода, ни модели, которая победила модель с GRPO, нифига на руках не имеется.
🖼 💅
📖 Папир
Если коротко АМЕРИКАНСКИЕ УЧЕННЫЕ придумали как заставить модель учиться на своих ошибках от артефактов CoT (ну а что он тупо существует, еще и жалуются ходят, что он не показывает настоящих размышлений модели)
Работает все следующих образом:
1) запускаем модель на минибатч задач по определенному классу
2) собираем с запуска всякие CoT, тул коллы (когда работаем с агентами), ошибки с компиляторов, когда это кодовые задачи и тд
3) другая LLM-ка смотрит на артефакты и выдает экспертное мнение чего не хватало в промпте, чтобы модель получше ПОДУМОЛА
За что лайк: вместо жадного выбора лучшего кандидата (который ведет к локальным оптимумам), GEPA строит Парето-фронт:
Это дает exploration без раздувания пула кандидатов. GEPA также может скрещивать кандидатов. Если один хорошо эволюционировал модуль А, а другой — модуль Б, то берет лучшие части от каждого
В общем то что? Понятное дело, авторы делают ставку на интерпретируемость процесса эволюции, меньшее время подбора систем промптов таким способом в сравнении с RL обучением, но как это работает на самом деле не понятно, ни кода, ни модели, которая победила модель с GRPO, нифига на руках не имеется.
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
что-то на DL-ском
Под руководством одного из отцов основателей DL-я🫡 вышла статья, которая по сути является некоторым survey с дополнительным обоснованием через когнитивную психологию
Итак, Chain-of-Thought Is Not Explainability или как модели красиво врут о своих размышлениях…
Итак, Chain-of-Thought Is Not Explainability или как модели красиво врут о своих размышлениях…
Forwarded from Refat Talks: Tech & AI
This media is not supported in your browser
VIEW IN TELEGRAM
🤩 Как новенький LangExtract от Google может помочь в AI работе с доками, RAG и не только
Неделю назад Google тихо выпустил библиотеку, которая решает боль production LLM систем: как гарантировать, что извлеченные данные действительно есть в источнике, а не выдуманы моделью. Ты задаешь примеры что хочешь извлечь из текста (например, даты и суммы из контракта), LangExtract находит все такие элементы и показывает где именно каждый находится в документе, гарантируя что ничего не выдумано. Мне как раз надо было что-то подобное, я полез изучать, потом залез в исходники и залип.
Ключевая инновация - Source Grounding
Каждое извлечение привязано к точным координатам в тексте. Парсите контракт на 50 страниц? Система не просто скажет "срок оплаты 30 дней", но и покажет exact char positions где это написано. Под капотом - умный fuzzy matching алгоритм, который находит источник даже если LLM слегка перефразировал. То есть да, это как NER только без обучения, и как structured outputs, но с точным и надежным определением координат цитаты.
А еще на основе моих тестов эта штука поразительно хорошо и быстро работает с длинными документами.
Ботанский кусок (разверните кому интересно):
Use кейсы для вдохновления:
- Контракты на 100+ страниц - находит все суммы и сроки с точной ссылкой на цитату, можно легко интегрировать в UI "подсветку" фактов
- Медкарты с записями - извлекаем дозировки лекарств с гарантией и визуальным указанием источника
- Data Science стал еще доступнее: на вход тысячи не структурированный документов, на выход - CSV с нужными колонками и точными координатами откуда взял
- Извлекаете из корпоративной wiki, email, Slack: люди, проекты, технологии, их связи. Строим графы знаний - Profit!
Главное: LangExtract не просто надежно извлекает, но еще и доказывает откуда взял каждый факт.
Двигаемся еще ближе от "LLM как магический черный ящик" к "LLM как надежный production инструмент".
Блогпост | Репа
🔥➕🔁
Неделю назад Google тихо выпустил библиотеку, которая решает боль production LLM систем: как гарантировать, что извлеченные данные действительно есть в источнике, а не выдуманы моделью. Ты задаешь примеры что хочешь извлечь из текста (например, даты и суммы из контракта), LangExtract находит все такие элементы и показывает где именно каждый находится в документе, гарантируя что ничего не выдумано. Мне как раз надо было что-то подобное, я полез изучать, потом залез в исходники и залип.
Ключевая инновация - Source Grounding
Каждое извлечение привязано к точным координатам в тексте. Парсите контракт на 50 страниц? Система не просто скажет "срок оплаты 30 дней", но и покажет exact char positions где это написано. Под капотом - умный fuzzy matching алгоритм, который находит источник даже если LLM слегка перефразировал. То есть да, это как NER только без обучения, и как structured outputs, но с точным и надежным определением координат цитаты.
А еще на основе моих тестов эта штука поразительно хорошо и быстро работает с длинными документами.
Ботанский кусок (разверните кому интересно):
Покопался в исходниках, рассказываю суть.
По сути LangExtract = Few-shot Information Extraction + Structured Outputs + Automatic Source Grounding.
В отличие от простого использования structured outputs, автоматически находит точное местоположение типа {"startpos": 41, "endpos": 57}.
Общий принцип:
Документ → [Chunking] → [LLM + Schema] → [alignment phase] → Результат с позициями
Трехуровневый alignment (exact → case-insensitive → fuzzy) покрывает все основные кейсы, результаты потом валидируются.
Поддерживает extraction_passes - это механизм множественных независимых проходов извлечения по документу для повышения recall (полноты). LLM могут "пропускать" некоторые сущности при первом проходе, особенно в длинных текстах, поэтому повторные проходы помогают найти больше информации.
На входе использует example-driven подход - вместо написания промптов вы предоставляете несколько примеров того, что хотите извлечь. Из этих примеров автоматически генерируется JSON schema для structured output и создается few-shot промпт. Поддержка разных LLM провайдеров (Gemini, OpenAI, Ollama) с оптимизациями под каждый.
А с длинными доками хорошо работает за счет трех элегантных решений:
- Intelligent chunking с сохранением границ предложений (не тупое разбиение по токенам)
- Multi-pass extraction - несколько независимых проходов, каждый может найти что-то новое, результаты консолидируются
- Массивная параллелизация - десятки чанков обрабатываются одновременно
Есть встроенная HTML-визуализация с подсветкой найденных элементов прямо в исходном тексте (показана на видео).
Некоторые альтернативы: Instructor/Marvin/Outlines.
Use кейсы для вдохновления:
- Контракты на 100+ страниц - находит все суммы и сроки с точной ссылкой на цитату, можно легко интегрировать в UI "подсветку" фактов
- Медкарты с записями - извлекаем дозировки лекарств с гарантией и визуальным указанием источника
- Data Science стал еще доступнее: на вход тысячи не структурированный документов, на выход - CSV с нужными колонками и точными координатами откуда взял
- Извлекаете из корпоративной wiki, email, Slack: люди, проекты, технологии, их связи. Строим графы знаний - Profit!
Главное: LangExtract не просто надежно извлекает, но еще и доказывает откуда взял каждый факт.
Двигаемся еще ближе от "LLM как магический черный ящик" к "LLM как надежный production инструмент".
Блогпост | Репа
🔥➕🔁
Forwarded from Записки MLEшника
Спустя долгое время отсутствия приношу пост 👀
Наверняка вы когда-нибудь сталкивались с тем, что питонячий код/скрипт зависал во время выполнения. В такие моменты очень хочется знать, собственно, в каком месте это происходит...
Так вот это довольно легко сделать (по крайней мере на Linux) с помощью дебагера gdb
Делается так:
0. Сохраняем локально файл libpython.py. Это нужно, чтобы в gdb стек и код вокруг отображался "по-питонячему" (иначе это будет малопонятный C++).
- Для этого открываем CPython на гитхабе
- Переключаемся с main ветки на tag с версией питона, которым запущен зависший код
- Скачиваем файл libpython.py (например `wget https://raw.githubusercontent.com/python/cpython/refs/tags/v3.13.5/Tools/gdb/libpython.py`)
1. Подключаемся к зависшему питонячему процессу
sudo gdb -p 68653
2. Подключаем файл
source libpython.py
3. Выбираем нужный поток, если их несколько
info threads - показать все
thread 1 - выбрать первый
4. Смотрим стек
py-bt
5. Смотрим код вокруг
py-list
6. Смотрим переменные
py-locals
7. Двигаемся по стеку выше/ниже
py-up
py-down
Все команды можно посмотреть как раз в файле libpython.py, который мы скачивали на шаге 0
Один-два раз это упражнение делаешь - код болеть не будет! 💪
Наверняка вы когда-нибудь сталкивались с тем, что питонячий код/скрипт зависал во время выполнения. В такие моменты очень хочется знать, собственно, в каком месте это происходит...
Так вот это довольно легко сделать (по крайней мере на Linux) с помощью дебагера gdb
Делается так:
0. Сохраняем локально файл libpython.py. Это нужно, чтобы в gdb стек и код вокруг отображался "по-питонячему" (иначе это будет малопонятный C++).
- Для этого открываем CPython на гитхабе
- Переключаемся с main ветки на tag с версией питона, которым запущен зависший код
- Скачиваем файл libpython.py (например `wget https://raw.githubusercontent.com/python/cpython/refs/tags/v3.13.5/Tools/gdb/libpython.py`)
1. Подключаемся к зависшему питонячему процессу
sudo gdb -p 68653
2. Подключаем файл
source libpython.py
3. Выбираем нужный поток, если их несколько
info threads - показать все
thread 1 - выбрать первый
4. Смотрим стек
py-bt
5. Смотрим код вокруг
py-list
6. Смотрим переменные
py-locals
7. Двигаемся по стеку выше/ниже
py-up
py-down
Все команды можно посмотреть как раз в файле libpython.py, который мы скачивали на шаге 0
Один-два раз это упражнение делаешь - код болеть не будет! 💪
Forwarded from Дратути Антон
Можно, кстати, проще (https://wiki.python.org/moin/DebuggingWithGdb)
и можно сразу переходить к пункту 3
gdb python -p pidи можно сразу переходить к пункту 3
Forwarded from Душный NLP
Demons in the Detail: On Implementing Load Balancing Loss for Training Specialized Mixture-of-Expert Models
Сегодня разберём статью от команды Qwen о том, как они придумали новый LBL-лосс для обучения MoE.
В MoE-моделях токены по экспертам распределяет роутер. LBL — вспомогательный лосс, который делает распределение равномерным, чтобы избежать перегрузки одних экспертов и голода других.
Обычно LBL считают на уровне отдельного микробатча каждого DP-ранка, а потом усредняют полученные LBL по всем микробатчам. Но заставлять роутер распределять токены равномерно в рамках одного микро-батча — довольно строгое ограничение. Пара длинных семплов может заполнить весь микро-батч, и тогда, если эти семплы пришли из одного домена, роутер всë равно будет вынужден разослать эти токены равномерно по всем экспертам. Так теряется логика специализации экспертов.
Для того чтобы избежать потери специализации, авторы предлагают считать LBL на уровне глобального батча (global-batch), где больше разнообразия данных. Как? Добавляют шаг коммуникации: синхронизируют нужные для подсчёта LBL статистики роутера по выбору экспертов со всей DP-группы, то есть со всех микробатчей. Рассмотрим пример:
1. Вообразим 2 карты и обучение с DP.
2. А к ним — 4 эксперта и 16 токенов (после пермьюта).
На первой карте токены распределятся по экспертам так: [0, 0, 8, 8]. На второй — [8, 8, 0, 0].
3. Для micro-lbl этот лосс будет на каждой карте ругать роутер за неравномерное распределение токенов.
5. Но если мы соберём глобальную статистику (то есть, сложим вектора распределений со всех карт), то получим [8, 8, 8, 8]. Это идеальная равномерность и macro-lbl на такое не обижается.
6. macro-lbl даёт роутеру больше свободы, что конвертируется в прирост качества.
Авторы отмечают значительный рост производительности при обучении новым методом: модели с глобальной балансировкой показывают лучшие результаты как по лоссам, так и на различных бенчах. А ещё у экспертов появляется настоящая специализация: чёткая и интерпретируемая на доменах (код, математика, разные языки).
Предложенный метод при эффективной реализации совсем не замедляет обучение. Можно собрать статистики каждого слоя и сделать лишь одну незначительную коммуникацию в конце.
Разбор подготовил❣ Даниил Сухой
Душный NLP
Сегодня разберём статью от команды Qwen о том, как они придумали новый LBL-лосс для обучения MoE.
В MoE-моделях токены по экспертам распределяет роутер. LBL — вспомогательный лосс, который делает распределение равномерным, чтобы избежать перегрузки одних экспертов и голода других.
Обычно LBL считают на уровне отдельного микробатча каждого DP-ранка, а потом усредняют полученные LBL по всем микробатчам. Но заставлять роутер распределять токены равномерно в рамках одного микро-батча — довольно строгое ограничение. Пара длинных семплов может заполнить весь микро-батч, и тогда, если эти семплы пришли из одного домена, роутер всë равно будет вынужден разослать эти токены равномерно по всем экспертам. Так теряется логика специализации экспертов.
Для того чтобы избежать потери специализации, авторы предлагают считать LBL на уровне глобального батча (global-batch), где больше разнообразия данных. Как? Добавляют шаг коммуникации: синхронизируют нужные для подсчёта LBL статистики роутера по выбору экспертов со всей DP-группы, то есть со всех микробатчей. Рассмотрим пример:
1. Вообразим 2 карты и обучение с DP.
2. А к ним — 4 эксперта и 16 токенов (после пермьюта).
На первой карте токены распределятся по экспертам так: [0, 0, 8, 8]. На второй — [8, 8, 0, 0].
3. Для micro-lbl этот лосс будет на каждой карте ругать роутер за неравномерное распределение токенов.
5. Но если мы соберём глобальную статистику (то есть, сложим вектора распределений со всех карт), то получим [8, 8, 8, 8]. Это идеальная равномерность и macro-lbl на такое не обижается.
6. macro-lbl даёт роутеру больше свободы, что конвертируется в прирост качества.
Авторы отмечают значительный рост производительности при обучении новым методом: модели с глобальной балансировкой показывают лучшие результаты как по лоссам, так и на различных бенчах. А ещё у экспертов появляется настоящая специализация: чёткая и интерпретируемая на доменах (код, математика, разные языки).
Предложенный метод при эффективной реализации совсем не замедляет обучение. Можно собрать статистики каждого слоя и сделать лишь одну незначительную коммуникацию в конце.
Разбор подготовил
Душный NLP
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Information Retriever
Sampled Softmax for Large-Scale Retrieval.
В рекомендашках на стадии генерации кандидатов часто используются двухбашенные модели, в которых пользователи и айтемы отдельно кодируются в векторы нейросетевыми «башнями», и затем с помощью скалярного произведения определяется, насколько пользователю релевантен тот или иной айтем. Мы умеем быстро находить для пользователя примерный топ айтемов с максимальным скалярным произведением (например, с помощью HNSW), даже для очень больших каталогов с миллионами айтемов.
У таких моделей должна быть способность глобального сравнения — возможность для пользователя сравнивать между собой «скоры» всевозможных айтемов из каталога. Ранжирующие лоссы, на которые учатся верхние стадии, для обучения нам не подходят — при таком обучении у модели нет цели научиться ранжировать для пользователя все айтемы, ей важно научиться ранжировать только то, что обычно попадает к нему в выдачу. Если YouTube обычно показывает испанцам видео на испанском, а итальянцам на итальянском, то модели не нужно уметь сравнивать видео на испанском с видео на итальянском, и она может «наложить» (англ. folding) векторы айтемов из этих двух групп друг на друга в векторном пространстве.
А вот что нам подходит — это softmax-лосс. Можно сформулировать задачу рекомендации в виде экстремальной классификации, в которой каждому айтему соответствует свой класс (экстремальной — потому что много классов). Если пользователь лайкнул трек, то что это был за трек? Считаем для каждого трека некоторый скор (читай «логит»), затем превращаем скоры в вероятностное распределение, применив softmax. Учим модель максимизировать правдоподобие правильного класса — минимизируем кросс-энтропийную функцию потерь. При таком обучении в саму модель заложено, что мы должны уметь делать глобальное ранжирование между всеми айтемами в каталоге.
У такого лосса есть одна «большая» проблема — чем больше каталог, тем сложнее посчитать сам softmax. В знаменателе есть сумма экспонент от логитов по всему каталогу. Нам в целом не нужно считать сам лосс, важен только градиент, но в градиенте эта сумма тоже присутствует. Чтобы это побороть, можно использовать сэмплирование негативов — вместо суммы скоров по всему каталогу считать её по небольшому сэмплированному подмножеству. Популярные стратегии сэмплирования — равномерное (выбираем айтемы из каталога абсолютно случайно) и униграммное (пропорционально популярности айтема). Частный случай униграммного — in-batch сэмплирование: при обучении нейросетей мы набираем «батчи» из положительных пар (пользователь, айтем), и можно для каждого пользователя из батча использовать в качестве негативов чужие позитивы из этого же батча.
Почему же всё-таки недостаточно простого равномерного сэмплирования? Здесь поможет следующая интуиция: «полный» softmax-лосс неявно занимается майнингом негативов — у айтемов из каталога, которым модель даёт высокий скор, большой вклад в градиент. Это отличительное свойство softmax-а — например, у BPR-лосса, если модель сильно ошибается в каком-то айтеме, его вклад в градиент всё равно сильно ограничен. Поэтому, если мы хотим аппроксимировать softmax-лосс, нам важно сэмплировать как можно больше «сложных, информативных» негативов, в которых модель ошибается и у которых был бы большой вклад в градиент. А равномерное сэмплирование, особенно при больших каталогах, будет давать простые негативы. Добиться хорошего качества с равномерными негативами всё равно можно, но понадобится гораздо большее количество негативов, чем при использовании альтернативных, более «сложных» источников негативов.
А вот при униграммном сэмплировании мы получаем популярные айтемы, которые чуть ли не по определению имеют высокий средний скор у пользователей и поэтому представляют из себя более «сложные» негативы. Но и здесь не без проблем :) Что же идёт не так — я расскажу в следующем посте.
P.S.: это я вас так готовлю к посту про статью, которую у нас приняли на RecSys :) А ещё это небольшое переосмысление прошлого поста на ту же тему. Что-то похожее я рассказываю в рамках лекции про нейросетевой кандген в ШАД.
В рекомендашках на стадии генерации кандидатов часто используются двухбашенные модели, в которых пользователи и айтемы отдельно кодируются в векторы нейросетевыми «башнями», и затем с помощью скалярного произведения определяется, насколько пользователю релевантен тот или иной айтем. Мы умеем быстро находить для пользователя примерный топ айтемов с максимальным скалярным произведением (например, с помощью HNSW), даже для очень больших каталогов с миллионами айтемов.
У таких моделей должна быть способность глобального сравнения — возможность для пользователя сравнивать между собой «скоры» всевозможных айтемов из каталога. Ранжирующие лоссы, на которые учатся верхние стадии, для обучения нам не подходят — при таком обучении у модели нет цели научиться ранжировать для пользователя все айтемы, ей важно научиться ранжировать только то, что обычно попадает к нему в выдачу. Если YouTube обычно показывает испанцам видео на испанском, а итальянцам на итальянском, то модели не нужно уметь сравнивать видео на испанском с видео на итальянском, и она может «наложить» (англ. folding) векторы айтемов из этих двух групп друг на друга в векторном пространстве.
А вот что нам подходит — это softmax-лосс. Можно сформулировать задачу рекомендации в виде экстремальной классификации, в которой каждому айтему соответствует свой класс (экстремальной — потому что много классов). Если пользователь лайкнул трек, то что это был за трек? Считаем для каждого трека некоторый скор (читай «логит»), затем превращаем скоры в вероятностное распределение, применив softmax. Учим модель максимизировать правдоподобие правильного класса — минимизируем кросс-энтропийную функцию потерь. При таком обучении в саму модель заложено, что мы должны уметь делать глобальное ранжирование между всеми айтемами в каталоге.
У такого лосса есть одна «большая» проблема — чем больше каталог, тем сложнее посчитать сам softmax. В знаменателе есть сумма экспонент от логитов по всему каталогу. Нам в целом не нужно считать сам лосс, важен только градиент, но в градиенте эта сумма тоже присутствует. Чтобы это побороть, можно использовать сэмплирование негативов — вместо суммы скоров по всему каталогу считать её по небольшому сэмплированному подмножеству. Популярные стратегии сэмплирования — равномерное (выбираем айтемы из каталога абсолютно случайно) и униграммное (пропорционально популярности айтема). Частный случай униграммного — in-batch сэмплирование: при обучении нейросетей мы набираем «батчи» из положительных пар (пользователь, айтем), и можно для каждого пользователя из батча использовать в качестве негативов чужие позитивы из этого же батча.
Почему же всё-таки недостаточно простого равномерного сэмплирования? Здесь поможет следующая интуиция: «полный» softmax-лосс неявно занимается майнингом негативов — у айтемов из каталога, которым модель даёт высокий скор, большой вклад в градиент. Это отличительное свойство softmax-а — например, у BPR-лосса, если модель сильно ошибается в каком-то айтеме, его вклад в градиент всё равно сильно ограничен. Поэтому, если мы хотим аппроксимировать softmax-лосс, нам важно сэмплировать как можно больше «сложных, информативных» негативов, в которых модель ошибается и у которых был бы большой вклад в градиент. А равномерное сэмплирование, особенно при больших каталогах, будет давать простые негативы. Добиться хорошего качества с равномерными негативами всё равно можно, но понадобится гораздо большее количество негативов, чем при использовании альтернативных, более «сложных» источников негативов.
А вот при униграммном сэмплировании мы получаем популярные айтемы, которые чуть ли не по определению имеют высокий средний скор у пользователей и поэтому представляют из себя более «сложные» негативы. Но и здесь не без проблем :) Что же идёт не так — я расскажу в следующем посте.
P.S.: это я вас так готовлю к посту про статью, которую у нас приняли на RecSys :) А ещё это небольшое переосмысление прошлого поста на ту же тему. Что-то похожее я рассказываю в рамках лекции про нейросетевой кандген в ШАД.
Forwarded from Information Retriever
arXiv.org
Correcting the LogQ Correction: Revisiting Sampled Softmax for...
Two-tower neural networks are a popular architecture for the retrieval stage in recommender systems. These models are typically trained with a softmax loss over the item catalog. However, in...
Correcting the LogQ Correction: Revisiting Sampled Softmax for Large-Scale Retrieval.
А вот и наша статья, принятая на RecSys 2025, добралась до arxiv’а! Что мы сделали: улучшили logQ-коррекцию.
Почему это важно: logQ-коррекция активно используется в индустрии для обучения нейросетевых двухбашенных retrieval моделей. Я за свою жизнь в Яндексе неоднократно участвовал в больших и успешных внедрениях нейросетевых кандидатогенераторов, которые не случились бы без logQ-коррекции.
Улучшение связано с тем, как в формуле logQ-коррекции используется положительный айтем (далее именуемый “позитив”). Он появляется в двух местах — и в числителе, и в знаменателе софтмакса. К числителю вопросов нет. А вот в знаменателе есть странности. Например, в исходной статье от Google к позитиву в знаменателе применяется logQ-поправка; а в следующей статье от тех же авторов — уже нет. То есть для сэмплированных негативов в знаменателе logQ-поправка есть, для позитива — нет. А вывод такой формулы нигде не приводится / не обосновывается.
Более того, само использование позитива в знаменателе выглядит сомнительно. Оригинальный вывод формулы, который Bengio проделал в начале нулевых для доисторических языковых моделей, гласит: для оценки знаменателя софтмакса можно насэмплировать айтемы из произвольного распределения Q (обычного называемого proposal distribution) и добавить к ним ту самую “logQ-поправку”. Распределение Q — это как раз и есть то распределение, из которого мы сэмплируем негативы; которое чаще всего является in-batch распределением.
И когда мы рассматриваем конкретный обучающий пример, то есть конкретную пару (user, positive item), и для нее считаем сэмплированный softmax-лосс с logQ-коррекцией, мы не сэмплируем позитив из распределения Q — он приходит к нам детерминированно, с вероятностью 1. А в формуле он используется для Монте-Карло оценки в предположении, что мы сэмплируем его из Q.
Долгое время мы, как и все, просто плыли по течению и использовали logQ-коррекцию в том виде, в каком все ее применяют. Но потом я взялся сделать ту самую лекцию про нейросетевую генерацию кандидатов для ШАДа, в которой в том числе хотел осветить logQ-коррекцию — строго, с математическим выводом. Хотелось также обосновать формулы, использующие позитив в знаменателе, с logQ-поправкой и без.
Когда я в рамках математических выкладок отделил позитив от Монте-Карло сэмплирования, получилась совершенно другая формула! В которой позитива не было в знаменателе софтмакса вообще, но при этом появилось взвешивание сэмплов. Чем меньше модель ошибается на сэмпле (то есть предсказывает большую вероятность позитива), тем меньше вес этого сэмпла.
Мы поставили эксперименты — сначала на своих внутренних больших датасетах, а затем на небольших академических. И подтвердили, что наша формула хорошо работает, причем работает лучше стандартной! На полноценный long paper на RecSys времени не хватило (когда появилось время на написание статьи, до дедлайна было меньше двух недель), поэтому подались на short paper. Статья получила хорошие отзывы и была принята на RecSys, чему мы несказанно рады :)
Ещё хочется немного подсветить остальную ценность статьи. До этого я не видел в академической литературе замеры на публичных датасетах для logQ-коррекции. Мы эти замеры сделали и показали, что популярная в индустрии logQ-коррекция хорошо работает и в академическом сетапе. Кроме того, мы, возможно, первыми на этих датасетах показали пользу от mixed negative sampling (таких замеров я тоже раньше не встречал, но здесь уже меньше уверен).
И последнее — мы сделали две валидации. Было понимание, что без leave-one-out схемы, как бы я ее ни недолюбливал, есть большая вероятность не пройти ревью :) Но делать только leave-one-out валидацию тоже не хотелось. Поэтому сделали также temporal split валидацию. Получилось, что ранжирование моделей c точки зрения качества в этих двух сетапах заметно различается.
Остальные подробности — читайте в статье!
А вот и наша статья, принятая на RecSys 2025, добралась до arxiv’а! Что мы сделали: улучшили logQ-коррекцию.
Почему это важно: logQ-коррекция активно используется в индустрии для обучения нейросетевых двухбашенных retrieval моделей. Я за свою жизнь в Яндексе неоднократно участвовал в больших и успешных внедрениях нейросетевых кандидатогенераторов, которые не случились бы без logQ-коррекции.
Улучшение связано с тем, как в формуле logQ-коррекции используется положительный айтем (далее именуемый “позитив”). Он появляется в двух местах — и в числителе, и в знаменателе софтмакса. К числителю вопросов нет. А вот в знаменателе есть странности. Например, в исходной статье от Google к позитиву в знаменателе применяется logQ-поправка; а в следующей статье от тех же авторов — уже нет. То есть для сэмплированных негативов в знаменателе logQ-поправка есть, для позитива — нет. А вывод такой формулы нигде не приводится / не обосновывается.
Более того, само использование позитива в знаменателе выглядит сомнительно. Оригинальный вывод формулы, который Bengio проделал в начале нулевых для доисторических языковых моделей, гласит: для оценки знаменателя софтмакса можно насэмплировать айтемы из произвольного распределения Q (обычного называемого proposal distribution) и добавить к ним ту самую “logQ-поправку”. Распределение Q — это как раз и есть то распределение, из которого мы сэмплируем негативы; которое чаще всего является in-batch распределением.
И когда мы рассматриваем конкретный обучающий пример, то есть конкретную пару (user, positive item), и для нее считаем сэмплированный softmax-лосс с logQ-коррекцией, мы не сэмплируем позитив из распределения Q — он приходит к нам детерминированно, с вероятностью 1. А в формуле он используется для Монте-Карло оценки в предположении, что мы сэмплируем его из Q.
Долгое время мы, как и все, просто плыли по течению и использовали logQ-коррекцию в том виде, в каком все ее применяют. Но потом я взялся сделать ту самую лекцию про нейросетевую генерацию кандидатов для ШАДа, в которой в том числе хотел осветить logQ-коррекцию — строго, с математическим выводом. Хотелось также обосновать формулы, использующие позитив в знаменателе, с logQ-поправкой и без.
Когда я в рамках математических выкладок отделил позитив от Монте-Карло сэмплирования, получилась совершенно другая формула! В которой позитива не было в знаменателе софтмакса вообще, но при этом появилось взвешивание сэмплов. Чем меньше модель ошибается на сэмпле (то есть предсказывает большую вероятность позитива), тем меньше вес этого сэмпла.
Мы поставили эксперименты — сначала на своих внутренних больших датасетах, а затем на небольших академических. И подтвердили, что наша формула хорошо работает, причем работает лучше стандартной! На полноценный long paper на RecSys времени не хватило (когда появилось время на написание статьи, до дедлайна было меньше двух недель), поэтому подались на short paper. Статья получила хорошие отзывы и была принята на RecSys, чему мы несказанно рады :)
Ещё хочется немного подсветить остальную ценность статьи. До этого я не видел в академической литературе замеры на публичных датасетах для logQ-коррекции. Мы эти замеры сделали и показали, что популярная в индустрии logQ-коррекция хорошо работает и в академическом сетапе. Кроме того, мы, возможно, первыми на этих датасетах показали пользу от mixed negative sampling (таких замеров я тоже раньше не встречал, но здесь уже меньше уверен).
И последнее — мы сделали две валидации. Было понимание, что без leave-one-out схемы, как бы я ее ни недолюбливал, есть большая вероятность не пройти ревью :) Но делать только leave-one-out валидацию тоже не хотелось. Поэтому сделали также temporal split валидацию. Получилось, что ранжирование моделей c точки зрения качества в этих двух сетапах заметно различается.
Остальные подробности — читайте в статье!
Forwarded from Information Retriever
Genrec.pdf
1.6 MB
Turbo ML Conf 2025.
Сегодня выступал на Turbo ML Conf 2025 с докладом про генеративные рексистемы. По сути, это был сиквел к докладу про Аргуса. Рассказывал про свое видение и про наши эксперименты. Cделал отсылку к РЛ :)
Как всегда, было приятно поделиться с коммьюнити мыслями и идеями.
Секцию про кулуары в этот раз писать не буду, могу лишь подчеркнуть, что было много хороших вопросов и обсуждений: и про сегодняшний доклад, и про Аргуса, и про нейросетевое ранжирование. Даже про нашу рексис статью :)
Трансляции не было, запись организаторы выложат позже. Презентацию прикладываю. Я в этот раз чуть поленился с презентацией и советую по возможности посмотреть запись рассказа (когда она появится), там гораздо больше информации.
P.S: а еще пост на линкедине про нашу logQ статью постепенно набирает обороты. Хочется, чтобы как можно больше людей увидели саму статью, поддержитеотечественного производителя отечественную науку лайком! :)
Сегодня выступал на Turbo ML Conf 2025 с докладом про генеративные рексистемы. По сути, это был сиквел к докладу про Аргуса. Рассказывал про свое видение и про наши эксперименты. Cделал отсылку к РЛ :)
Как всегда, было приятно поделиться с коммьюнити мыслями и идеями.
Секцию про кулуары в этот раз писать не буду, могу лишь подчеркнуть, что было много хороших вопросов и обсуждений: и про сегодняшний доклад, и про Аргуса, и про нейросетевое ранжирование. Даже про нашу рексис статью :)
Трансляции не было, запись организаторы выложат позже. Презентацию прикладываю. Я в этот раз чуть поленился с презентацией и советую по возможности посмотреть запись рассказа (когда она появится), там гораздо больше информации.
P.S: а еще пост на линкедине про нашу logQ статью постепенно набирает обороты. Хочется, чтобы как можно больше людей увидели саму статью, поддержите
Forwarded from Information Retriever
RecSys Substack.
Кто-то, возможно, помнит, как я раньше почти каждую неделю делал дайджесты со статьями, в которых обозревал новинки с arXiv.
Начинал я это делать еще внутри Яндекса, почти три года назад, в рамках IR семинара. В какой-то момент обнаружил, что уже есть рассылка с похожим дайджестом от инженера из бигтеха — Sumit Kumar’а. Мы с ним независимо продолжали делать эти рассылки (я — сначала для яндексоидов, потом для вас; а Sumit — для всех). Интересно было наблюдать, что они получались довольно разными. В итоге я писать дайджесты перестал, а Sumit вот все еще продолжает.
Статья про logQ попала в прошлый дайджест Sumit’а, а статья про Аргуса — в текущий, причем аж на первое место, что особенно приятно :) Забавно наблюдать, что на четвертом месте — статья с почти таким же названием от ByteDance.
А еще когда-то давно у меня уже была отчаянная попытка начать писать статьи про рекомендашки — тогда я описал наше первое внедрение трансформера в Маркет. На конференцию статья не прошла, а вот в Substack Sumit’а попала — и это было хорошим утешительным призом :) Статья была не очень хорошо написана (я тогда еще не умел писать статьи, особенно на английском), а вот доклад на Датафесте вышел очень даже неплохой. По ощущениям, именно с него началось мое влияние на рекомендательную индустрию вне Яндекса.
Sumit, кстати, на канал подписан и даже когда-то что-то комментировал. Если ты это читаешь — привет и спасибо :)
Если не успеваете листать архив и вам не хватает дайджестов — подписывайтесь на RecSys Substack Sumit’а. Ссылочка
Кто-то, возможно, помнит, как я раньше почти каждую неделю делал дайджесты со статьями, в которых обозревал новинки с arXiv.
Начинал я это делать еще внутри Яндекса, почти три года назад, в рамках IR семинара. В какой-то момент обнаружил, что уже есть рассылка с похожим дайджестом от инженера из бигтеха — Sumit Kumar’а. Мы с ним независимо продолжали делать эти рассылки (я — сначала для яндексоидов, потом для вас; а Sumit — для всех). Интересно было наблюдать, что они получались довольно разными. В итоге я писать дайджесты перестал, а Sumit вот все еще продолжает.
Статья про logQ попала в прошлый дайджест Sumit’а, а статья про Аргуса — в текущий, причем аж на первое место, что особенно приятно :) Забавно наблюдать, что на четвертом месте — статья с почти таким же названием от ByteDance.
А еще когда-то давно у меня уже была отчаянная попытка начать писать статьи про рекомендашки — тогда я описал наше первое внедрение трансформера в Маркет. На конференцию статья не прошла, а вот в Substack Sumit’а попала — и это было хорошим утешительным призом :) Статья была не очень хорошо написана (я тогда еще не умел писать статьи, особенно на английском), а вот доклад на Датафесте вышел очень даже неплохой. По ощущениям, именно с него началось мое влияние на рекомендательную индустрию вне Яндекса.
Sumit, кстати, на канал подписан и даже когда-то что-то комментировал. Если ты это читаешь — привет и спасибо :)
Если не успеваете листать архив и вам не хватает дайджестов — подписывайтесь на RecSys Substack Sumit’а. Ссылочка
Forwarded from Рекомендательная [RecSys Channel]
Scaling law в рекомендательных системах
Законы масштабирования вышли за рамки NLP и успешно применяются в рекомендательных системах. В наших карточках исследователь Владимир Байкалов затронул последние работы на эту тему. С обзором прошлых статей можно ознакомиться в этом посте.
Работы, упомянутые в карточках:
- Language Models are Unsupervised Multitask Learners
- Scaling Laws for Neural Language Models
- Training Compute-Optimal Large Language Models
- Actions Speak Louder than Words: Trillion-Parameter Sequential Transducers for Generative Recommendations
- Scaling New Frontiers: Insights into Large Recommendation Models
- Unlocking Scaling Law in Industrial Recommendation Systems with a Three-step Paradigm based Large User Model
- Scalable Cross-Entropy Loss for Sequential Recommendations with Large Item Catalogs
- Разбор статьи HSTU в канале «Рекомендательная»
Обзор подготовил❣ Владимир Байкалов
Законы масштабирования вышли за рамки NLP и успешно применяются в рекомендательных системах. В наших карточках исследователь Владимир Байкалов затронул последние работы на эту тему. С обзором прошлых статей можно ознакомиться в этом посте.
Работы, упомянутые в карточках:
- Language Models are Unsupervised Multitask Learners
- Scaling Laws for Neural Language Models
- Training Compute-Optimal Large Language Models
- Actions Speak Louder than Words: Trillion-Parameter Sequential Transducers for Generative Recommendations
- Scaling New Frontiers: Insights into Large Recommendation Models
- Unlocking Scaling Law in Industrial Recommendation Systems with a Three-step Paradigm based Large User Model
- Scalable Cross-Entropy Loss for Sequential Recommendations with Large Item Catalogs
- Разбор статьи HSTU в канале «Рекомендательная»
Обзор подготовил
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM