Эмбеддинги: что они меряют и чего не меряют
Близость векторов — это не близость смысла в том виде, в каком её понимает человек. Разбираю, где расходится, почему поиск находит не то и что с этим делать.
Симптом узнаваемый: поиск по базе стабильно находит документы «про то же самое», но не тот, который отвечает на вопрос. Ищут «можно ли отменить заказ после оплаты» — приходит абзац про то, как оформить заказ.
Дело не в плохой модели эмбеддингов. Дело в том, что она меряет не то, что мы от неё ждём.
Что такое близость векторов
Модель эмбеддингов переводит текст в вектор так, чтобы тексты, встречающиеся в похожих контекстах, оказывались рядом. Обучение построено на употреблении: если два фрагмента окружены похожими словами и решают похожие задачи, их векторы сближаются.
Это и есть определение «похожести», которое вы получаете. Не «утверждают одно и то же», не «отвечают на один вопрос», а употребляются похоже.
Разница выглядит академической ровно до первого разбора выдачи.
Где расходится
Отрицание почти не видно. «Возврат возможен» и «возврат невозможен» употребляются в одинаковых контекстах, состоят почти из одних и тех же слов и оказываются рядом в векторном пространстве. Для поиска они взаимозаменяемы, для пользователя — противоположны. Это самая опасная из ошибок, потому что найденный фрагмент выглядит релевантным и модель уверенно строит на нём ответ.
Вопрос и ответ — разные жанры. Вопрос «как отменить заказ» и инструкция «для отмены нажмите…» написаны по-разному: разная длина, разная лексика, разная грамматика. Их векторы могут оказаться дальше друг от друга, чем вопрос и другой вопрос. Отсюда практика хранить рядом с фрагментом сформулированные вопросы, на которые он отвечает, — и искать по ним.
Редкие идентификаторы усредняются. ERR_2041 и ERR_2043 для модели
почти одно и то же: она видит похожую последовательность символов
в похожем окружении. Точное совпадение по редкому токену векторный поиск
не гарантирует, и это причина, по которой в базах с артикулами, кодами
и названиями функций нужен гибрид с обычным полнотекстовым поиском.
Домен смещает всё. Модель, обученная на общем вебе, разложит ваши внутренние термины по общему смыслу слов, а не по вашему. «Карточка» в вашей компании может означать конкретный документ, а для модели это что-то между визиткой и банковской картой.
Что с этим делать
Проверять на отрицаниях специально. В набор для оценки поиска стоит класть пары, отличающиеся одним «не». Если система их не различает — вы это узнаете до того, как узнает пользователь.
Ставить реранкер. Модель, которая смотрит на пару «вопрос + фрагмент» целиком, а не на два независимых вектора, различает отрицание заметно лучше. Она дороже, поэтому и применяется к пятидесяти кандидатам, а не ко всей базе.
Складывать с полнотекстовым поиском. Дешёвая мера, закрывающая целый класс промахов на идентификаторах.
Хранить формулировку вопроса рядом с фрагментом. Работает лучше, чем кажется, и не требует ничего, кроме дисциплины при написании базы.
Мнение, с которым спорят
Смена модели эмбеддингов почти никогда не является главным рычагом. Разница между актуальными моделями на прикладной задаче меньше, чем разница между хорошей и плохой нарезкой документов.
Порядок, в котором я трачу усилия: нарезка, потом гибридный поиск, потом реранкер, потом — если ещё осталась проблема — модель эмбеддингов. На практике до последнего пункта доходят редко.
Где это неверно: если ваш контент на языке или в домене, который модель почти не видела при обучении, смена модели действительно принципиальна и идёт первой. Проверяется просто — глазами на двух десятках запросов: если выдача выглядит случайной, а не «похожей, но не той», дело в модели.
Чего я делать не стал бы
Не стал бы полагаться на порог косинусной близости как на признак релевантности. Абсолютные значения ничего не значат сами по себе: они зависят от модели, от длины текста и от домена. Осмысленно только сравнение кандидатов между собой.
Не стал бы хранить эмбеддинги без исходного текста рядом. Рано или поздно понадобится пересчитать всё на другой модели, и без исходников это превращается в отдельный проект.
Открытый вопрос
Мне неизвестен дешёвый способ поймать смещение домена заранее — до того, как база построена и выдача разочаровала. Пока единственный работающий приём остаётся ручным: взять двадцать реальных вопросов и посмотреть, что приходит. Полдня работы, которые нельзя ничем заменить.