Привет, это «Артифишл»
Я Артём, техлид ML R&D. Шесть лет учу машины находить нужное в текстах на русском.
Если вы собирали RAG или поиск по документам, возможно, вы уже пользовались нашей работой. С командой мы сделали эмбеддер FRIDA и бенчмарк ruMTEB, на котором сравнивают русскоязычные эмбеддеры. Сейчас делаем поискового агента SMITH и FRIDA-Decisions, модель, которая принимает решения по тексту без генерации. Все лежит в открытом доступе с лицензией MIT.
Что здесь будет:
— как устроены эмбеддинги, поиск и агенты, с честными минусами;
— мои эксперименты с цифрами, включая неудачные;
— тренды и обзоры новых технологий по моей теме;
— кухня R&D: как делаются модели, которыми вы пользуетесь;
— обсуждения с вами в комментариях: как вы применяете AI и чего вам не хватает.
Последнее для меня самое важное. Напишите в комментариях, чем занимаетесь и что у вас сейчас не работает. Буду строить посты на ваших ответах.
Я Артём, техлид ML R&D. Шесть лет учу машины находить нужное в текстах на русском.
Если вы собирали RAG или поиск по документам, возможно, вы уже пользовались нашей работой. С командой мы сделали эмбеддер FRIDA и бенчмарк ruMTEB, на котором сравнивают русскоязычные эмбеддеры. Сейчас делаем поискового агента SMITH и FRIDA-Decisions, модель, которая принимает решения по тексту без генерации. Все лежит в открытом доступе с лицензией MIT.
Что здесь будет:
— как устроены эмбеддинги, поиск и агенты, с честными минусами;
— мои эксперименты с цифрами, включая неудачные;
— тренды и обзоры новых технологий по моей теме;
— кухня R&D: как делаются модели, которыми вы пользуетесь;
— обсуждения с вами в комментариях: как вы применяете AI и чего вам не хватает.
Последнее для меня самое важное. Напишите в комментариях, чем занимаетесь и что у вас сейчас не работает. Буду строить посты на ваших ответах.
👍6
Две вещи, которые эмбеддер не вытянет одним вектором
Эмбеддер сжимает запрос в один вектор и ищет ближайшие тексты. На фактоидных вопросах вроде «кто подписывает акт приемки» это работает отлично. Но есть две ситуации, где одного вектора не хватает, и под каждую мы сделали свое решение.
1. Многошаговые вопросы
«В каком году основали компанию, которая купила X?» Чтобы ответить, сначала нужно найти покупателя и только потом год его основания. Во втором документе нет ни слова из вопроса, и остается только надеяться, что он случайно попадет в топ-k.
Здесь нужен не один поиск, а цепочка: найти, прочитать, переформулировать, искать дальше. Для этого мы сделали поискового агента SMITH. На многошаговом бенчмарке MuSiQue один поиск эмбеддером дает nDCG@10 0.333, а SMITH делает в среднем 5–6 поисков на вопрос и доходит до 0.766.
Фронтирные LLM решают эту задачу так же, через ReAct: подумать, поискать, прочитать, поискать снова. Но SMITH в 8 раз дешевле того же DeepSeek V3.2. Какие проблемы он решает, я подробно рассказывал в выступлении на AI R&D Day.
2. Разные задачи требуют разной «похожести»
Для поиска похожи вопрос и абзац с ответом. Для дедупликации похожи два пересказа одного текста. Для классификации похожи тексты одной темы, даже если они про разное. Один и тот же вектор не может быть хорош во всем сразу.
Поэтому у FRIDA есть префиксы: search_query: и search_document: для поиска, paraphrase: для дублей и перефразов, categorize_topic: для группировки по темам и еще несколько. Модель одна, а поведение переключается словом в начале текста. Забыть префикс или перепутать его — одна из самых частых причин, почему «модель ищет хуже, чем на бенчмарке». Как это оценивать и развивать, я рассказывал в докладе «Оценка и развитие инструктивных способностей эмбеддинг-моделей».
Итого, если поиск не находит то, что точно есть в базе, проверьте две вещи: не многошаговый ли вопрос и тем ли префиксом/инструкцией закодированы тексты.
А как вы решаете многошаговый поиск? И используете ли один эмбеддер для разных задач?
Эмбеддер сжимает запрос в один вектор и ищет ближайшие тексты. На фактоидных вопросах вроде «кто подписывает акт приемки» это работает отлично. Но есть две ситуации, где одного вектора не хватает, и под каждую мы сделали свое решение.
1. Многошаговые вопросы
«В каком году основали компанию, которая купила X?» Чтобы ответить, сначала нужно найти покупателя и только потом год его основания. Во втором документе нет ни слова из вопроса, и остается только надеяться, что он случайно попадет в топ-k.
Здесь нужен не один поиск, а цепочка: найти, прочитать, переформулировать, искать дальше. Для этого мы сделали поискового агента SMITH. На многошаговом бенчмарке MuSiQue один поиск эмбеддером дает nDCG@10 0.333, а SMITH делает в среднем 5–6 поисков на вопрос и доходит до 0.766.
Фронтирные LLM решают эту задачу так же, через ReAct: подумать, поискать, прочитать, поискать снова. Но SMITH в 8 раз дешевле того же DeepSeek V3.2. Какие проблемы он решает, я подробно рассказывал в выступлении на AI R&D Day.
2. Разные задачи требуют разной «похожести»
Для поиска похожи вопрос и абзац с ответом. Для дедупликации похожи два пересказа одного текста. Для классификации похожи тексты одной темы, даже если они про разное. Один и тот же вектор не может быть хорош во всем сразу.
Поэтому у FRIDA есть префиксы: search_query: и search_document: для поиска, paraphrase: для дублей и перефразов, categorize_topic: для группировки по темам и еще несколько. Модель одна, а поведение переключается словом в начале текста. Забыть префикс или перепутать его — одна из самых частых причин, почему «модель ищет хуже, чем на бенчмарке». Как это оценивать и развивать, я рассказывал в докладе «Оценка и развитие инструктивных способностей эмбеддинг-моделей».
Итого, если поиск не находит то, что точно есть в базе, проверьте две вещи: не многошаговый ли вопрос и тем ли префиксом/инструкцией закодированы тексты.
А как вы решаете многошаговый поиск? И используете ли один эмбеддер для разных задач?
👍2
Что не видно в анонсе FRIDA-Decisions
Если вы пришли со стрима, что такое FRIDA-Decisions, вы уже знаете: энкодер на 823M, который выбирает вариант, ставит оценку и отвечает «да» или «нет» без генерации. Мне в ней интереснее всего три вывода, которые она подтверждает.
1. Даже с окном в 512 токенов можно закрыть много практических задач. Маршрутизация обращений, модерация, проверка релевантности — это короткие тексты. Наш бенчмарк razvilka из 15 таких задач тому пример.
2. Для таких решений достаточно модели меньше 1B. FRIDA-Decisions на 823M набирает 0.893, коммерческий TypeSafe Jev 0.897, разница статистически незначима. А модели вдвое больше, на 1.9B, набирают 0.833 и 0.853. Такой размер работает на домашней карте, около 28 мс на RTX 5060 Ti, и даже на CPU.
3. Чтобы обучить такую модель, хватает небольшого бюджета. По вычислениям оно сопоставимо с 50 часами работы одной потребительской карты уровня RTX 5060 Ti. Для достаточного качества кластер не нужен.
При этом мы много обсуждаем, куда расти дальше: увеличить контекст и добавить другие модальности. Веса под MIT на Hugging Face, подробный разбор уже доступен на Хабре.
Если вы уже пробовали FRIDA-Decisions, какие задачи она помогает решать? А какие хотелось бы добавить? Если еще не пробовали, напишите свою задачу.
Если вы пришли со стрима, что такое FRIDA-Decisions, вы уже знаете: энкодер на 823M, который выбирает вариант, ставит оценку и отвечает «да» или «нет» без генерации. Мне в ней интереснее всего три вывода, которые она подтверждает.
1. Даже с окном в 512 токенов можно закрыть много практических задач. Маршрутизация обращений, модерация, проверка релевантности — это короткие тексты. Наш бенчмарк razvilka из 15 таких задач тому пример.
2. Для таких решений достаточно модели меньше 1B. FRIDA-Decisions на 823M набирает 0.893, коммерческий TypeSafe Jev 0.897, разница статистически незначима. А модели вдвое больше, на 1.9B, набирают 0.833 и 0.853. Такой размер работает на домашней карте, около 28 мс на RTX 5060 Ti, и даже на CPU.
3. Чтобы обучить такую модель, хватает небольшого бюджета. По вычислениям оно сопоставимо с 50 часами работы одной потребительской карты уровня RTX 5060 Ti. Для достаточного качества кластер не нужен.
При этом мы много обсуждаем, куда расти дальше: увеличить контекст и добавить другие модальности. Веса под MIT на Hugging Face, подробный разбор уже доступен на Хабре.
Если вы уже пробовали FRIDA-Decisions, какие задачи она помогает решать? А какие хотелось бы добавить? Если еще не пробовали, напишите свою задачу.
👍3
Обрезать эмбеддинги можно и без MRL
Чем больше эмбеддер, тем лучше он обычно ищет. Но с моделью растет и размер вектора, а с ним индекс: миллион документов при 1536 измерениях в float32 занимает ~6 ГБ, при 256 — ~1 ГБ.
Самый простой способ сжать индекс — обрезка: берем первые N компонент и нормируем заново. Под это даже есть метод MRL: модель специально учат, чтобы короткие префиксы вектора работали сами по себе.
Но модель может хорошо переносить обрезку и без MRL. Проверил на RuBQ Retrieval, nDCG@10 ×100:
FRIDA, без MRL: 72.5 → 70.0 (1536 → 256)
Qwen3-Embedding-0.6B, с MRL: 66.6 → 64.9 (1024 → 256)
Индекс FRIDA меньше в 6 раз, а качество ниже всего на 2.5 пункта. Причем на 256 она выше, чем Qwen3 в полных 1024. MRL выигрывает только на 64 и меньше.
Так что если в карточке модели нет MRL, все равно пробуйте сжимать. В SentenceTransformers это один параметр:
А какие методы сжатия индекса используете вы?
Чем больше эмбеддер, тем лучше он обычно ищет. Но с моделью растет и размер вектора, а с ним индекс: миллион документов при 1536 измерениях в float32 занимает ~6 ГБ, при 256 — ~1 ГБ.
Самый простой способ сжать индекс — обрезка: берем первые N компонент и нормируем заново. Под это даже есть метод MRL: модель специально учат, чтобы короткие префиксы вектора работали сами по себе.
Но модель может хорошо переносить обрезку и без MRL. Проверил на RuBQ Retrieval, nDCG@10 ×100:
FRIDA, без MRL: 72.5 → 70.0 (1536 → 256)
Qwen3-Embedding-0.6B, с MRL: 66.6 → 64.9 (1024 → 256)
Индекс FRIDA меньше в 6 раз, а качество ниже всего на 2.5 пункта. Причем на 256 она выше, чем Qwen3 в полных 1024. MRL выигрывает только на 64 и меньше.
Так что если в карточке модели нет MRL, все равно пробуйте сжимать. В SentenceTransformers это один параметр:
model = SentenceTransformer("ai-forever/FRIDA", truncate_dim=256)А какие методы сжатия индекса используете вы?
Индекс строит 9B, запрос кодирует 0.6B
Perplexity выложили pplx-embed-v2-late: две ColBERT-модели, 0.6B и 9B. Каждый токен кодируется вектором на 128 чисел.
Самое интересное не размер, а общее пространство. Документы можно один раз проиндексировать тяжелой 9B, а запросы кодировать маленькой. Цена запроса не меняется, потому что документы все равно в оффлайне считать.
На текстовых доменных задачах такая схема дает +1.6 пункта, это примерно половина разрыва между моделями. При этом на текст у 0.6B работает около 240M активных параметров, остальное эмбеддинги токенов и визуальная часть.
Техрепорт обещают позже. Как мы знаем минус ColBERT подхода, что индекс растет с длиной документа. Что они делают с этим, пока не сообщается.
Веса · блог
Perplexity выложили pplx-embed-v2-late: две ColBERT-модели, 0.6B и 9B. Каждый токен кодируется вектором на 128 чисел.
Самое интересное не размер, а общее пространство. Документы можно один раз проиндексировать тяжелой 9B, а запросы кодировать маленькой. Цена запроса не меняется, потому что документы все равно в оффлайне считать.
На текстовых доменных задачах такая схема дает +1.6 пункта, это примерно половина разрыва между моделями. При этом на текст у 0.6B работает около 240M активных параметров, остальное эмбеддинги токенов и визуальная часть.
Техрепорт обещают позже. Как мы знаем минус ColBERT подхода, что индекс растет с длиной документа. Что они делают с этим, пока не сообщается.
Веса · блог
Perplexity AI
Multimodal embeddings beyond a single vector
A new family of late-interaction models for text and image retrieval, with a shared embedding space across model sizes.
🔥1
Rank1 проигрывал 10 пунктов. Потом авторы прочитали выдачу
Знакомься: Rank1, реранкер, который перед оценкой рассуждает. Его учили почти на 400 тысячах цепочек рассуждений DeepSeek-R1 по запросам MS MARCO, и на задачах, где надо подумать, это заметно помогало.
А потом авторы прогнали его на TREC DL19, классическом бенчмарке для задач поиска, на котором меряют все.
DL19 славится разметкой: на каждый из 43 запросов асессоры NIST вручную оценили около двухсот документов. Если где-то разметке и можно верить, то здесь.
Результат: 66.1 nDCG@10. RankLLaMA, почти такой же реранкер, дает 76.2. Тоже 7B, тоже обучен на MS MARCO, только отвечает сразу, без рассуждений.
Думающая модель отстала на 10 пунктов. Обычно на этом месте пишут, что рассуждения в поиске не помогают, и идут дальше.
Но авторы открыли топ-10 и стали читать.
Оказалось, что 16% документов в топе Rank1 вообще никто не размечал. У RankLLaMA таких было 4%.
Авторы доразметили дыры вручную:
– релевантными оказались 86% неразмеченных документов из топа Rank1
– nDCG@10 Rank1 выросла с 66.1 до 78.6
– RankLLaMA почти не сдвинулась: с 76.2 до 76.9
– и Rank1 оказалась впереди
Сама модель не поменялась. Поменялось только то, что бенчмарк считает правильным ответом.
Самое интересное: та же проблема сидит в любом бенчмарке, по которому ты выбираешь эмбеддер.
Я повторил историю на NanoNQ из NanoBEIR: 50 запросов и в среднем один размеченный документ на запрос.
Взял линейку e5 и LateOn. По исходной разметке картина выглядела уверенной:
– LateOn лучше e5-small на 10.3 пункта: модель выиграла на 18 запросах, проиграла на 6
– из 6 пар плотных моделей значимо различаются 3
Потом я отдал топ-10 всех моделей двум LLM-судьям, Opus и Sonnet, с одним вопросом: отвечает документ на запрос или нет. Судьи совпали в 98.6% случаев.
Релевантных стало 2.4 на запрос вместо 1.1. И победы растаяли:
– LateOn против e5-small: +4.4, но 14 побед и 16 поражений
– из 6 пар значимых не осталось ни одной
Порядок моделей при этом не сдвинулся. Но убери из 50 запросов два, где LateOn выиграла сильнее всего, и первое место займет e5-large.
И это не академический прикол. e5-large после доразметки обходит e5-small на 1.7 пункта при счете 14:14. Поверишь среднему — возьмешь в прод модель в 10 раз тяжелее, с векторами в 2.7 раза длиннее, и будешь платить за прирост, которого, возможно, нет.
Что я делаю, прежде чем сказать «стало лучше»:
– Смотрю на запросы, а не на среднее: сколько выиграл, сколько проиграл, какой интервал. Задевает ноль, значит прироста нет.
– Проверяю, хватает ли запросов. На NanoNQ разница моделей скачет от запроса к запросу на 20–30 пунктов, и чтобы поймать прирост в 5, нужно 150–300 запросов.
– Доразмечаю топ. Отдаю топ-10 обеих моделей двум LLM-судьям с одним промптом и смотрю, насколько они согласны.
Промпт судьи, разметка, код и скрипт, который проверит твою пару моделей, лежат в репозитории.
Знакомься: Rank1, реранкер, который перед оценкой рассуждает. Его учили почти на 400 тысячах цепочек рассуждений DeepSeek-R1 по запросам MS MARCO, и на задачах, где надо подумать, это заметно помогало.
А потом авторы прогнали его на TREC DL19, классическом бенчмарке для задач поиска, на котором меряют все.
DL19 славится разметкой: на каждый из 43 запросов асессоры NIST вручную оценили около двухсот документов. Если где-то разметке и можно верить, то здесь.
Результат: 66.1 nDCG@10. RankLLaMA, почти такой же реранкер, дает 76.2. Тоже 7B, тоже обучен на MS MARCO, только отвечает сразу, без рассуждений.
Думающая модель отстала на 10 пунктов. Обычно на этом месте пишут, что рассуждения в поиске не помогают, и идут дальше.
Но авторы открыли топ-10 и стали читать.
Оказалось, что 16% документов в топе Rank1 вообще никто не размечал. У RankLLaMA таких было 4%.
Авторы доразметили дыры вручную:
– релевантными оказались 86% неразмеченных документов из топа Rank1
– nDCG@10 Rank1 выросла с 66.1 до 78.6
– RankLLaMA почти не сдвинулась: с 76.2 до 76.9
– и Rank1 оказалась впереди
Сама модель не поменялась. Поменялось только то, что бенчмарк считает правильным ответом.
Самое интересное: та же проблема сидит в любом бенчмарке, по которому ты выбираешь эмбеддер.
Я повторил историю на NanoNQ из NanoBEIR: 50 запросов и в среднем один размеченный документ на запрос.
Взял линейку e5 и LateOn. По исходной разметке картина выглядела уверенной:
– LateOn лучше e5-small на 10.3 пункта: модель выиграла на 18 запросах, проиграла на 6
– из 6 пар плотных моделей значимо различаются 3
Потом я отдал топ-10 всех моделей двум LLM-судьям, Opus и Sonnet, с одним вопросом: отвечает документ на запрос или нет. Судьи совпали в 98.6% случаев.
Релевантных стало 2.4 на запрос вместо 1.1. И победы растаяли:
– LateOn против e5-small: +4.4, но 14 побед и 16 поражений
– из 6 пар значимых не осталось ни одной
Порядок моделей при этом не сдвинулся. Но убери из 50 запросов два, где LateOn выиграла сильнее всего, и первое место займет e5-large.
И это не академический прикол. e5-large после доразметки обходит e5-small на 1.7 пункта при счете 14:14. Поверишь среднему — возьмешь в прод модель в 10 раз тяжелее, с векторами в 2.7 раза длиннее, и будешь платить за прирост, которого, возможно, нет.
Что я делаю, прежде чем сказать «стало лучше»:
– Смотрю на запросы, а не на среднее: сколько выиграл, сколько проиграл, какой интервал. Задевает ноль, значит прироста нет.
– Проверяю, хватает ли запросов. На NanoNQ разница моделей скачет от запроса к запросу на 20–30 пунктов, и чтобы поймать прирост в 5, нужно 150–300 запросов.
– Доразмечаю топ. Отдаю топ-10 обеих моделей двум LLM-судьям с одним промптом и смотрю, насколько они согласны.
Промпт судьи, разметка, код и скрипт, который проверит твою пару моделей, лежат в репозитории.
👍1🔥1
