2 бампа версии лежали у меня в заметках месяцами, по строчке на каждый: bge-base-en на bge-base-en-v1.5 и e5-base на e5-base-v2. Примечание bge обещает, что поиск стал лучше. e5 выкладывает v2 вообще без примечания, просто с числом повыше в таблице оценок. Оба выглядят как апгрейд, который берут не думая, как берут очередной патч библиотеки.
Единственный вопрос, который я себе задал, был про то, сколько часов уйдёт на повторное кодирование коллекции. Это та часть, за которую приходит счёт. Что бамп делает с ответами, я не мерил ни разу. Я исходил из того, что версия внутри одного семейства это небольшой шаг, а старые векторы и новые лежат примерно там же. В итоге я прогнал 4 пары, 2 семейства в 2 размерах. Это заняло 5 часов процессора против 1.5 на одну пару.
Стенд
SciFact из BEIR: 5183 документа и 300 тестовых запросов с 339 строками разметки. Точный косинус по нормированным векторам, никакого приблизительного индекса, так что ни одно число ниже не приходит от перестройки графа. Python 3.12.3, torch 2.14.0 на процессоре, sentence-transformers 6.0.1, numpy 2.5.3, 4 ядра, GPU нет. Одно кодирование коллекции занимает от 15 минут на маленьких моделях до 85 минут на базовой. На машине была и другая работа, так что эти минуты стоит читать как порядок величины. Вход обрезан на 512 токенах, e5 получает свои префиксы query: и passage: , bge получает инструкцию к запросу из своей карточки.
Прежде чем чему-то верить, я сверил стенд с опубликованными оценками MTEB на том же датасете. 4 модели из 8 попадают в опубликованное число до 4 знака: e5-base на 0.7308, e5-base-v2 на 0.7194, bge-small-en-v1.5 на 0.7127, e5-small на 0.6560. Ещё 3 расходятся в четвёртом знаке. Особняком стоит bge-base-en-v1.5: у меня выходит 0.7404, ровно то, что называет карточка модели BAAI, а репозиторий результатов MTEB называет 0.7435.
Выдача переставилась, оценка нет
bge-base-en-v1.5 сохраняет 7.81 из старой первой десятки и 85.3% первых мест. nDCG@10 идёт с 0.7323 до 0.7404, recall@10 с 0.8712 до 0.8742. У 240 запросов из 300 nDCG в точности тот же, что был, у 37 лучше, у 23 хуже. То есть на 2.19 места из 10 встал другой документ, а оценка качества шевельнулась в третьем знаке.
e5-small-v2 это громкий случай. Он сохраняет 4.43 из 10 и 59% первых мест. У одного запроса прежний победитель оказывается на месте 1423. nDCG при этом всё равно растёт, с 0.6560 до 0.6875. e5-base-v2 меняет 4.24 места из 10 и набирает меньше версии, которую заменяет: 0.7194 против 0.7308. Ровно то же говорит MTEB.
Перестановка садится туда, где прежний порядок держался на монетке. У bge-base-en у запросов, сохранивших своего победителя, отрыв от второго места был 0.0221 в среднем, а у тех, кто победителя потерял, 0.0033. Этот зазор идёт в одну сторону во всех 4 парах. Чего перевороты стоят, вопрос отдельный, а точек у меня всего 4: в 3 из них запросы, потерявшие победителя, всё равно вышли в плюс, те 44 запроса bge ушли с 0.3959 до 0.4135. Базовая пара e5 это исключение: 80 запросов потеряли победителя и упали с 0.5020 до 0.4451.
2 способа сломаться
Бамп bge сохраняет геометрию. Один и тот же документ в двух версиях стоит сам к себе на косинусе 0.892. Новый запрос по старому индексу даёт nDCG 0.7261 против 0.7323 нативных, то есть устаревший индекс всё ещё отвечает. Уехала шкала. Отсечение cos > 0.8 это как раз то число, которое оседает в конфиге. Через него проходит 97.5% оценок первой десятки до бампа против 1.8% после. 2 случайных документа коллекции стояли на 0.82 в старой версии и стоят на 0.58 в новой. bge-small-en делает то же самое жёстче, с 99.9% до 8.3%.
Про эту часть было объявлено, а я не прочитал. В примечании к выпуску v1.5 сказано, что модели смягчают проблему распределения похожести. Это ровно то самое число. Я прочитал в том же предложении слова про то, что поиск стал лучше, на этом и остановился.
e5 small ломается наоборот. Доля, проходящая через это отсечение, почти не двигается: 98.5% против 98.6%. А один и тот же документ в двух его версиях стоит на косинусе -0.007. Поиск по старому индексу с новым запросом даёт 0.0021 там, где старая модель по своему индексу даёт 0.6560. Я довольно долго искал ошибку знака в своём коде, прежде чем принял это число. Базовая пара e5 стоит посередине: тот же документ на 0.6061, доля выше отсечения с 82.1% до 75.6%.
Одно число тут заслуживает предупреждения, потому что именно на него обычно смотрит дашборд. На бампе e5 small средняя похожесть первого попадания ровная, 0.8682 до и 0.8724 после. По ней нельзя узнать, что пространство уехало под тобой. В по-настоящему сломанном состоянии она не молчит: среднее первое попадание 0.0573, выше 0.8 оказывается 0% первой десятки.
Состояние посередине
Состояние, по которому никто не публикует чисел, это сама миграция. Часами или днями половина коллекции несёт новые векторы, а половина ещё старые. Я собрал такой индекс напрямую: каждый второй документ закодирован заново, остальные не тронуты, запросы от новой модели. Настоящий бэкфилл идёт растущим множеством, поэтому здесь форма задачи, а не её расписание.
У bge-base-en-v1.5 половинный индекс набирает 0.6408, ниже обоих чистых концов. Переэмбедденная половина забирает 83.7% всех мест первой десятки против 48.9% на готовом индексе. Запросы, чей размеченный документ успели переэмбеддить, набирают 0.8011, то есть больше, чем на готовом индексе. Запросы, чей документ ещё ждал, набирают 0.4868. На полном индексе те же 2 группы набирают 0.7335 и 0.7471. Значит разделение делает смешанный индекс. У 9 запросов из 300 разметка лежит в обеих половинах, поэтому они не попали ни в одну группу.
Обе пары e5 доводят это до конца. 100% мест уходит переэмбедденной половине. Запросы, чей документ ещё ждёт, набирают 0.0000, то есть 0 релевантных документов на 1480 мест, которые достаются этим 148 запросам. Почему выигрывает переэмбедденная половина, я могу объяснить только для одного семейства. У e5-base две половины стоят на разных шкалах: средний косинус 0.7289 к новой стороне против 0.4391 к старой, а у e5-small разрыв ещё резче, 0.7774 против -0.0146. У bge-base-en средние идут в обратную сторону, 0.4623 против 0.4861, значит места там забирает не среднее. Что именно, я не знаю.
Поворот вместо перестройки
Про это есть статья, Drift-Adapter (arXiv:2509.23471). Она подгоняет небольшое отображение из нового пространства в старое и заявляет 95-99% от recall полной перестройки. На этих данных ортогональное отображение Прокруста, подогнанное на 4000 пар документов, даёт nDCG 0.7317 для базовой пары bge против 0.7323 нативных, 0.7177 против 0.7308 для базовой e5 и 0.5606 против 0.6560 для маленькой e5. Последнее это 85% пути назад между двумя пространствами, у которых средний косинус на одном и том же документе равен 0.
Я читал это как провал, пока не заметил, что отвечаю на другой вопрос. Статья считает Recall@10 против полной перестройки. На этой метрике данные дают 100.2% для базовой bge, 99.2% для базовой e5, 97.8% для маленькой bge и 86.1% для маленькой e5. 3 пары из моих 4 попадают в заявленную полосу. Хуже их выглядеть заставляла моя собственная рамка.
Мои 4000 пар это и не та небольшая выборка, о которой говорит статья. Это 4000 из 5183 документов того самого индекса, по которому потом идёт поиск. И 214 из 283 размеченных документов лежат среди них. Поэтому я подогнал то же отображение с bge-small-en на неё же саму, где верный ответ это единичная матрица. На 200 парах оно теряет 0.036, 0.6635 против 0.6995, а на 4000 не теряет ничего. Это убивает отговорку, которой мне хотелось: на том размере выборки, что я взял, зазор выше это дрейф, а не цена дешёвой подгонки.
Чего я не проверял
Приблизительного индекса не было, так что числа про то, что добавляет сверху граф HNSW, у меня нет. Одна коллекция, одна область, только английский. Прыжка между вендорами, про который написана большая часть разборов, нет нигде. Модели bge v1.5 я прогнал с инструкцией к запросу, хотя их карточка называет её необязательной.
Что изменилось у меня: версия кодировщика теперь лежит в том же файле, что и любой порог отсечения, а частично закодированный индекс в выдачу не идёт. Переключать обе половины разом и так было планом по другим причинам. Число для альтернативы теперь есть: 0.6408 против 0.7404.