Переранжировка в RAG: узкий диапазон, в котором кросс-кодеры действительно помогают
Переранкинг в RAG полезен лишь в пределах нижнего предела воспроизводимости и верхнего предела K. Что такое Phantom Hits и как самостоятельно измерить оба этих показателя для своих запросов за один день.
Источники: Reranking in RAG — Cross-Encoders, the K Threshold, and the Recall Ceiling in Production Systems
Кросс-кодер помогает пайплайну RAG лишь в узком диапазоне: уровень воспроизведения на первом этапе должен быть достаточно высоким, а количество кандидатов, передаваемых дальше, — достаточно малым. За пределами этого диапазона либо у реранкера нет чего исправлять, либо он начинает наносить вред. Далее рассматриваются механизм работы, режим сбоя под названием «Phantom Hits» и способ оценки всего этого на собственных данных.
Представьте систему RAG, которая нашла правильный ответ. Ошибок не было, документы не потерялись. Ответ просто находится на 37-й позиции в списке результатов, в то время как большая языковая модель читает только первые пять позиций, поэтому в практическом смысле его просто нет. Сигналов тревоги не поступает, поскольку согласно всем показателям мониторинга запрос был успешным.
Это не особенность какой-то одной реализации. Это следствие способа построения архитектуры. Векторный поиск предназначен для того, чтобы правильный ответ находился среди первых 50–200 кандидатов, а не обязательно в самом верху, поэтому процесс, заканчивающийся извлечением результатов, оставляет качество ответа на усмотрение случая.
Обычной реакцией является добавление механизма переранжирования. Это означает использование кросс-кодера, состоящего примерно из двенадцати строк, небольшого улучшения показателя nDCG, и тогда задача считается решенной. Сама по себе реакция не ошибочна, поскольку переранжирование действительно неэффективно. Ошибка заключается в том, что переранжирование работает в узком диапазоне параметров, который почти никто не измеряет. Далее вы увидите, как функционирует этот более дорогой второй этап, где находятся границы этого диапазона, и как за один день можно выяснить, с какой стороны каждой границы находится ваша система.
Переранжирование — это не лучший векторный поиск
Реранкер представляет собой иную архитектуру, которая активируется только после поиска и применяется к небольшой группе кандидатов.
Би-кодер, используемый в существующих системах векторного поиска, заранее и оффлайн кодирует запрос и каждый документ отдельно. Это обеспечивает высокую скорость обработки и возможность масштабирования до миллионов документов. Однако он никогда не рассматривает запрос и документ вместе.
Кросс-кодер действует наоборот: он считывает их одновременно, по токенам, что позволяет ему обнаруживать отрицания, числовые противоречия и тонкости, недоступные для би-кодера. Взамен ему приходится повторять эту работу для каждого кандидата отдельно в момент запроса.
Это создаёт знакомую двухэтапную схему. Этап поиска дешево сужает список кандидатов до 50–200 вариантов, стремясь к полноте восстановления информации — чтобы не упустить правильный ответ. Затем этап переранжирования сортирует этот небольшой список с более высокими затратами, ставя целью точность: среди оставшихся выбрать действительно лучший вариант.
Второй уровень также не является бесплатным дополнением. При превышении определённого количества кандидатов кросс-кодер начинает воспринимать шум как сигнал, и качество действительно снижается. Решение о необходимости использования этапа переранжирования — это инженерный расчёт, основанный на ваших данных, а не импульсивное решение.
Почему поиск не может быть последним этапом
Симптом, который постоянно возникает в рабочих системах RAG, выглядит так: «модель выдумывает информацию, хотя она уже есть в нашей базе данных». В большинстве случаев при детальном расследовании оказывается, что модель ничего не придумывала сама. Правильный документ находился среди пятидесяти лучших результатов, просто не входил в пять лучших, которые были показаны генератору.
Причина кроется в архитектуре. Би-кодер вычисляет эмбеддинг документа во время индексации, ещё до появления любого вопроса. Во время поиска он сравнивает два сжатых резюме, а не реальный текст запроса с реальным текстом документа.
Классический пример того, что теряется: в запросе указано «дешево», а в документе — «500 долларов за ночь». Для векторов оба понятия относятся к цене гостиничного номера, поэтому они оказываются рядом друг с другом. Противоречие становится заметным только тогда, когда кто-то смотрит на оба текста одновременно, а бай-энкодер по своей сути этого не делает.
Лучшая модель вкладки не решит эту проблему, потому что это осознанный компромисс. Метод поиска максимизирует точность воспроизведения, то есть вероятность того, что нужный документ находится среди возвращаемых результатов, причем делает это дешево для миллионов документов. Помещение нужного документа на первое место просто не входит в его задачи.
Показатели Recall@50 и Precision@5 измеряют разные вещи и отвечают на разные вопросы. Смешивание их приводит к тому, что команды вынуждены использовать дополнительный слой для решения проблемы, с которой он не может справиться.
Недостаток заключается в том, что би-кодер никогда не рассматривает пару вместе, поэтому давайте посмотрим, какие преимущества получает модель, которая действительно учитывает эту пару.
Би-кодер каталогизирует, кросс-кодер читает
Представьте процесс найма. Би-кодер играет роль рекрутера, который сортирует тысячи резюме по папкам ещё до того, как появится описание вакансии: быстро, поверхностно, затем работа завершается. Кросс-кодер выступает в роли руководителя, у которого десять финалистов, и он читает каждое резюме вместе с объявлением, строка за строкой. Только тогда проявляются несоответствия, которые рекрутер не смог заметить.
С точки зрения механизма разница очевидна. Кросс-кодер объединяет запрос и документ в одну последовательность в стандартном формате [CLS] запрос [SEP] документ [SEP] и передаёт её в один трансформер.
Внутри модели работает механизм кросс-аттеншн: каждый токен запроса может взаимодействовать напрямую с каждым токеном документа и наоборот. Результатом является не вектор для сравнения, а отдельный логит — ненормализованное число, показывающее степень уверенности модели в том, что данная пара является релевантной.
Таким образом, би-энкодер генерирует представление, а кросс-энкодер — вердикт. Это разница в том, что модель может вообще увидеть, а не разница в степени.
Из этого сразу следует один вывод: оценку кросс-энкодера невозможно предварительно вычислить и сохранить в индексе, поскольку она зависит от конкретной пары запроса и документа, а не только от самого документа. Каждый запрос требует полного прохождения алгоритма для каждого кандидата, что в десятки-сотни раз дороже, чем сравнение векторов.
Диаграмма, иллюстрирующая двухэтапную архитектуру, наглядно показывает масштаб задачи. По данным статьи Reimers и Gurevych 2019 года «Sentence-BERT», для поиска наиболее похожей пары среди 10 000 предложений требуется около 50 миллионов сравнений, что соответствует примерно 65 часам работы с полной версией модели BERT и примерно 5 секундам с архитектурой в стиле SBERT.
Запомните точную формулировку, поскольку распространяются округленные варианты, такие как «10 миллионов документов и 50 часов». Разница качественная: узким местом является количество пар, которые необходимо оценить, а не размер корпуса данных.
Именно поэтому кросс-кодер никогда не используется в качестве первого этапа. Он не хуже, просто слишком дорог в использовании для обработки всего корпуса. Поскольку его стоимость зависит от количества обрабатываемых пар, всё зависит от того, сколько пар ему передают и на каком этапе обработки он находится.
Два этапа, два бюджета
Механизм переранжирования располагается после этапа поиска и перед большой языковой моделью. Поиск возвращает топ-k кандидатов, где k — это количество документов, передаваемых с одного этапа на следующий, обычно от 50 до 200. Затем механизм переранжирования перестраивает этот список и передает его генератору на позицию от 3 до 20.
Такая каскадная структура возникла не с больших языковых моделей, что свидетельствует о их зрелости. Принцип «дешевый фильтр, затем дорогой судья» происходит из эпохи метода Learning-to-Rank, когда второй этап представлял собой ансамбль деревьев принятия решений, работающих с вручную созданными признаками, а не трансформер. Модули изменились, но архитектура осталась прежней.
У технологии нейронной переранжировки есть конкретная дата появления. В 2019 году статья «Passage Re-ranking with BERT» использовала BERT в качестве бинарного классификатора для пар запросов и текстовых фрагментов, что позволило улучшить показатель MRR@10 на 27 процентов по сравнению с лучшим результатом, имевшимся на тот момент. Именно тогда второй этап обработки перестал считаться частью процесса оптимизации и превратился в отдельный слой.
Самой известной коммерческой реализацией сегодня является флагманский инструмент переранжирования от Cohere. Среди всех версий наибольшие изменения коснулись одного параметра: размер окна входных данных увеличился с нескольких сотен токенов до более чем 32 000, причем для версий v3 и v3.5 он ограничивался 4 096 токенами. Это настоящий сдвиг в дизайне, поскольку он позволяет обрабатывать более крупные фрагменты текста без их обрезки, что делает процесс разбиения на фрагменты менее агрессивным и снижает потерю контекста.
Поставщики реже говорят о том, что будет дальше. Цены на одну и ту же модель во внешних источниках различаются в десять и более раз — от доли цента до двух с половиной долларов за тысячу поисков, в зависимости от того, кто ведет подсчет и что включает в понятие «поиск».
Существует простое правило: если вы не можете самостоятельно воспроизвести расчеты поставщика для своего трафика, у вас нет точных цифр, а только оценки. Также существует ловушка с оплатой: документы, превышающие установленный лимит, делятся на части, и каждая часть взимается отдельно, поэтому один логический запрос на переранжирование может превратиться в несколько отдельных платежей.
Формула, которую следует запомнить, такова: получать данные дешево в больших объемах, затем переориентировывать их по стоимости в узком диапазоне, позволяя большой языковой модели видеть только те данные, которые выдерживают оба критерия. Это кажется безопасным стандартным решением, однако существует порог, за которым оно перестает работать, причем в направлении, которого почти никто не ожидает.
Иллюзорные результаты и момент, когда переориентирование начинает наносить вред
Согласно распространенному мнению, чем больше кандидатов вы предоставляете механизму переориентирования, тем безопаснее результат. Модель более точна, чем векторный поиск, поэтому при количестве кандидатов 500 или 1 000 она определенно не сможет ошибиться. Однако это мнение ошибочно, и доказательства против него имеются.
В статье 2024 года «Drowning in Documents» (Jacob и соавторы) говорится, что по мере увеличения значения K качество реранкеров повышается, достигает пика, а затем заметно снижается. При слепом сканировании всего набора данных простой алгоритм BM25 мог превзойти кросс-кодер, считавшийся лучшим среди доступных. Однако следует учитывать одно ограничение: эти результаты получены при слепом сканировании академических и корпоративных наборов данных, и они мало что говорят о типичной схеме обработки, где значение K обычно составляет несколько сотен.
У этой проблемы есть название — Phantom Hits. Реранкер уверенно присваивает самую высокую оценку документу, не имеющему никакой связи с запросом ни на лексическом, ни на семантическом уровне.
Авторы предполагают возможный источник проблемы и осторожно называют это гипотезой, а не подтвержденной причиной. Они указывают на условия обучения, которые называют смещением из-за воздействия внешних факторов. Модели обучаются с использованием «трудных отрицательных примеров» — документов, которые внешне похожи на правильные ответы, но по сути ошибочны, благодаря чему модель становится экспертом в выявлении микроскопических различий.
Однако в реальных условиях такой экспертный уровень оказывается вредным. Когда модели показывают простой отрицательный пример — просто шум, с которым они едва сталкивались во время обучения, — у них нет опоры, и они начинают угадывать. Модель, обученная различать близнецов, бессильна перед незнакомцем, который входит в комнату.
Противоположный край такой же реальный и не отменяет первого. Несколько независимых анализов указывают на минимальный порог безубыточности для переранжирования примерно на уровне recall@50 = 0,85. Ниже этого показателя нет ничего, что стоило бы сортировать, поскольку правильный документ так и не попадает в список. Точные пороги различаются в зависимости от источников из-за различий в корпусах данных, причем происхождение данных имеет значение: блоги и практический опыт, а не рецензии коллег. Используйте их как гипотезу для тестирования на собственных данных, но никогда не как установленный факт.
Эти два вывода не противоречат друг другу. Они представляют собой два края одного диапазона допустимых значений. При уровне воспроизведения ниже указанного порога у переранжирования нет возможностей для работы. При превышении порога K оно начинает наносить ущерб. Переранжирование — это не монотонное улучшение, и предположение о том, что больше всегда лучше, вновь ведет к ошибке слепого доверия к стандартам поставщика, поскольку в обоих случаях измерения заменяются на местные традиции.
Учитывая, что чрезмерное переранжирование может навредить, а недостаточное — оказаться недостаточным, нам необходимо четкое представление о пределе того, что может исправить этот слой.
Предел воспроизводимости и что на самом деле означают 67 процентов
Инструмент переранжирования — это редактор, а не репортер. Он может переставить материалы, уже собранные кем-то, но не может создать то, что никто не привнес.
Этот принцип, предел воспроизводимости, кажется тривиальным, пока не сталкивается с самой значимой статистикой отрасли. В своем отчете о контекстуальном поиске компания Anthropic описала процесс 2024 года, в ходе которого уровень неудач при извлечении топ-20 записей снизился с 5,7 до 1,9 процента, что соответствует снижению на 67 процентов.
Это число часто цитируется в поддержку использования инструментов переранжирования. Однако при разбивке по этапам оно рассказывает другую историю, хотя это не делает его ложным.
Путь реализации был следующим. Использование контекстуальных эмбеддингов снизило показатель до 3,7 процента; добавление алгоритма BM25 привело его к уровню 2,9, и только затем ранжирование заново снизило показатель до 1,9. Следовательно, именно ранжирование заново обеспечивает снижение с 2,9 до 1,9 процента. Оба показателя имеют смысл, поскольку они отражают разные аспекты: 67 процентов — это результат работы всей системы в целом, а не какого-либо отдельного компонента.
Это различие имеет важное практическое значение. Прежде чем приводить цифру «67 процентов» на обзоре архитектуры, следует понимать, что вы гарантируете эффект от совокупности четырех изменений, причем три из них происходят раньше этапа ранжирования заново и обеспечивают большую часть улучшений.
Сами авторы указывают на этот недостаток: показатели представляют собой средние значения по различным доменам, причем разброс между ними велик. Ещё одно ограничение, вытекающее из имеющихся данных: все значения качества коммерческих инструментов для переранжирования указываются их производителями на основе собственных наборов данных и с использованием собственных методов первоначального поиска. Независимой оценки на уровне всего рынка не существует.
Никакие внешние критерии оценки не позволят определить, как будет работать функция переранжирования в вашей системе, поэтому вам необходимо тестировать её самостоятельно.
Расчёт, который можно выполнить в понедельник утром
Вся сложность этой темы сводится к одной повторяемой процедуре. Именно редкость её применения командами является причиной того, что вопрос «помогает ли переранжирование» продолжает обсуждаться.
Шаг первый: измерьте показатели recall@50 и precision@5 на примере примерно ста маркированных запросов из реальных данных. Используйте собственные логи и собственную комбинацию терминов и целей, а не какие-либо публичные эталоны. Если значение recall@50 значительно ниже 0.85, сначала улучшите процесс поиска с помощью разбиения данных на части, гибридных методов поиска или векторных представлений, вместо того чтобы добавлять дополнительный уровень обработки.
Шаг второй: выявите особенности данных. Высокий показатель recall@50 в сочетании с низким precision@5 — именно такой профиль требует применения алгоритма переранжирования. Подходящий документ присутствует в списке результатов, но его позиция слишком низкая.
Шаг третий: осознанно выберите модель. API, работающий на серверах провайдера, обеспечивает быстрый старт и отсутствие оперативных затрат, но ваши данные покидают вашу инфраструктуру. Самостоятельно размещенный алгоритм переранжирования даёт контроль над затратами и конфиденциальностью, но требует наличия GPU и ухода за оборудованием. Это скорее вопрос соответствия требованиям и бюджета, чем качества модели.
Попробовать его тоже недорого. Локальная переранжировка помещается примерно в дюжину строк:
from sentence_transformers import CrossEncoder
reranker = CrossEncoder("BAAI/bge-reranker-large", max_length=512)
def rerank(query, docs):
pairs = [(query, d.page_content) for d in docs] # pair: query + candidate
scores = reranker.predict(pairs) # one logit per pair
return sorted(zip(docs, scores), key=lambda x: x[1], reverse=True)
Чаще всего встречаются три ошибки. Первая — завышение показателей K «ради безопасности». Вторая — переранжирование после сокращения контекста, из-за чего модель оценивает только начало текста, а не весь документ. Третья — рассмотрение результатов кросс-кодеров как абсолютных порогов для сравнения между запросами, что особенно опасно, поскольку такой подход работает в демо-версии, но терпит неудачу в производственных условиях.
Есть ещё одна менее очевидная проблема: утверждение «переранжировщик не помогает» иногда связано с числовым сбоем, а не с архитектурными недостатками. В руководстве по миграции на Sentence-Transformers описан случай, когда сигмоида, вычисляемая в формате bfloat16, достигала предела своего диапазона, что приводило к сближению лучших результатов и фактической случайной их перестановке. После того как было применено использование формата float32 перед процедурой активации, порядок ранжирования вернулся к нормальному.
Для решения всех этих проблем требуется лишь измерение показателей, без изменений в архитектуре.
Что это означает для архитектора
Возвращаемся к позиции 37. Документ, застрявший там, никогда не был проблемой модели генерации — это была проблема порядка обработки.
- Кросс-энкодер — это не лучшая форма эмбеддинга. Это отдельная архитектура, запускаемая после поиска, которая считывает запрос и документ вместе и возвращает вердикт вместо представления. Улучшения качества эмбеддинга не дают того эффекта, который достигается при совместном рассмотрении пары элементов.
- Переранжирование должно выполняться в одном месте. Поиск остается дешевым и масштабируемым, а переранжирование — дорогим и ограниченным, и именно структура затрат в этой последовательности и составляет суть подхода.
- Увеличение количества кандидатов — это не надежный стандарт. После достижения определенного значения K качество действительно снижается, и причина этого кроется в способе обучения таких моделей.
- Потолок ограничений жесткий. То, что не было возвращено на первом этапе, невозможно восстановить с помощью механизма переранкинга, как бы это ни утверждали производители.
- Ваши данные — эталон. Одного дня, проведенного на расчете показателей recall@50 и precision@5 для сотни маркированных запросов, достаточно, чтобы завершить спор, который в противном случае мог затянуться на недели.
Многие команды считают механизм переранкинга стандартной частью любой системы RAG, добавляемой к ней так же, как кэш. Это ошибочная привычка. Более точная картина проясняется, когда рассматриваются оба порога одновременно: нижняя граница, ниже которой у слоя нет возможностей для корректировки, и верхняя граница, выше которой он начинает портить результаты. Короче говоря, переранкинг является условным процессом, а не автоматическим.
Остается одна проблема. В рассмотренных здесь материалах не приводятся отдельные показатели для польского языка, а все многоязычные цифры представляют собой суммарные данные по десяткам языков. Для корпуса на польском языке или любого более мелкого языка измерение на собственных данных — не просто рекомендуемое действие; это единственный вариант.
Связанные статьи
- Повторная ранжировка в RAG: кросс-энкодеры против оценщиков на основе LLM и их задержки — Как вторичный ранжировщик корректирует порядок кандидатов в RAG, сравнение кросс-энкодеров с оценщиками на основе LLM, затраты на задержку, способы сбоев и способы их оценки.
- Контекстуальный поиск в RAG: что скрывает цифра 67%, каковы затраты и когда техника терпит неудачу — как использование префиксов решает проблему одиноких фрагментов, почему прирост на 67% достигается за счёт трёх последовательных мер, что экономит кэширование промптов и четыре случая, когда эта техника неэффективна.
- Практические заметки: ограничения векторного поиска в RAG — косинусное сходство и др. — Пошаговое руководство по использованию Практических заметок: ограничения векторного поиска в RAG — косинусное сходство и др.: шаблоны контрактов, проверок и готового кода для команд, внедряющих эту схему.
- Проверка системы RAG на наличие устаревших данных, смещений и шумных контекстов — Python-скрипт для аудита процесса поиска в системе RAG: использование «золотых» запросов, критерии релевантности на основе косинуса, проверка смещений по методу Колмогорова-Смирнова и оценка эффективности контекста, а также инструкции по анализу полученных отчетов.
- Пять техник переранжирования данных в системе RAG: от быстрого поиска к точному контексту — Причины, по которым первичный этап поиска не находит нужных ответов, и способы их устранения: использование кросс-кодеров, метода RRF, инструмента Cohere Rerank, модели ColBERT и подхода с использованием больших языковых моделей в качестве судей, а также описание многоуровневой схемы обработки данных.
- Почему переранжирование — это самый экономичный способ добиться значительного улучшения в пайплайне RAG — Получение 50 результатов и их переранжирование до 5: как кросс-кодеры улучшают процесс ранжирования в RAG, каковы преимущества и задержки, когда его стоит пропустить и какой инструмент переранжирования выбрать.