Webrium
Подписаться

Что такое эмбеддинг: как текст становится вектором

Как эмбеддинги превращают текст в векторы и почему косинусное сходство не решает за вас

Вложенность: токены преобразуются в векторы, из которых формируется общий вектор текстаВектор текста

Эмбеддинг это простыми словами

Эмбеддинг — это, простыми словами, список чисел (вектор), который модель ставит в соответствие тексту так, что близкие по смыслу тексты получают близкие векторы. Эмбеддинги — не удаление служебных слов, не правило определения части речи и не ответ модели. Не сжатие текста тоже: вектор — не архив, из которого текст распаковывается. Но и необратимым это преобразование не назовёшь: короткий текст по вектору обычно в значительной мере восстанавливается. Вектор — не обезличенные данные: права доступа к векторам должны быть те же, что к исходным текстам.

Слово «эмбеддинг» используют в двух значениях. Внутри языковой модели это вектор, который ставится в соответствие каждому токену на входе; что такое токен, объяснено в разборе о токенах. Вместе эти векторы составляют таблицу «номер токена — вектор». Наружу она не выдаётся, но у токена эмбеддинг есть. Эмбеддинг текста — один вектор на весь текст, результат отдельной модели эмбеддингов. Более старый вариант — эмбеддинги слов: один вектор на слово независимо от контекста. Эмбеддинги строят также для изображений и звука, но здесь речь пойдёт только о тексте.

Откуда берутся числа

Модель эмбеддингов пропускает токены текста через свои слои и получает для каждого токена вектор, уже учитывающий соседние токены. Эти пересчитанные векторы она сводит в один вектор текста. Распространённых способов два: усреднение либо вектор одного служебного или последнего токена, встречаются и другие. Поэтому одно слово и целая страница дают векторы с одним и тем же числом координат.

Число координат — размерность вектора — не зависит от длины текста и задана моделью или настройкой вызова. У части моделей её выбирают параметром либо укорачивают вектор, отбрасывая хвост координат. Отдельная координата читаемого смысла не имеет — значение есть только у взаимного расположения векторов. Случайного выбора у модели эмбеддингов нет: на выходе числа, а не слова. Но побитово одинаковый вектор для одного и того же текста не гарантирован: на разном оборудовании, при разной пакетной обработке и у сжатых вариантов модели числа расходятся в младших разрядах.

Что прочитать в описании модели до первого вызова: поддержку языка своего корпуса и режим кодирования запроса и документа. У части поисковых моделей для запроса и для документа предусмотрены разные режимы или разные служебные приставки к тексту, а бывают парные кодировщики — отдельная сеть для запроса и отдельная для документа, обученные вместе. Ни перепутанный режим, ни частичная замена модели при совпавшей размерности ошибки не дают, но последствия разные: перепутанный режим тихо ухудшает выдачу, а сходства между векторами двух разных моделей бессмысленны. При несовпавшей размерности хранилище запись или запрос отклонит. Смена модели требует пересчитать все сохранённые векторы.

Косинусное сходство векторов: что оно считает и чего не видит

Сравниваются два вектора-эмбеддинга. Норма вектора — его геометрическая длина, корень из суммы квадратов координат. Косинусное сходство — скалярное произведение двух векторов, делённое на произведение их норм. Это косинус угла между векторами: значение лежит от минус единицы до единицы и зависит только от направления векторов, не от их норм.

Формула косинусного сходства:

# Учебный счёт на выдуманных числах: не замер и не выход какой-либо модели.
# Настоящие эмбеддинги так коротки не бывают.
a = (3, 4)
b = (4, 3)
dot_product = 3*4 + 4*3  # 24
norm_a = (3**2 + 4**2)**0.5  # 5
norm_b = (4**2 + 3**2)**0.5  # 5
cosine_similarity = dot_product / (norm_a * norm_b)  # 24 / 25 = 0.96
cosine_distance = 1 - cosine_similarity  # 0.04

# Вектор a, растянутый вдвое
a_stretched = (6, 8)
dot_product_stretched = 6*4 + 8*3  # 48
norm_a_stretched = (6**2 + 8**2)**0.5  # 10
cosine_similarity_stretched = dot_product_stretched / (norm_a_stretched * norm_b)  # 48 / 50 = 0.96

Косинусное сходство, косинусная близость — синонимы. Косинусное расстояние — единица минус косинусное сходство, лежит от нуля до двух. У сходства «больше — ближе», у расстояния «меньше — ближе»; сортировка не в ту сторону отдаёт самые далёкие тексты без единой ошибки.

Чего мера не видит: нормы вектора, нулевого вектора, истинности и отрицания. Для нулевого вектора мера не определена: в коде это ошибка, «не число» либо молча подставленный ноль, неотличимый от настоящего результата счёта, — зависит от библиотеки. Что возвращается на пустую строку, тоже зависит от поставщика: ошибка, ненулевой вектор одних служебных токенов, который ничего не значит, либо нулевой вектор, подставленный обвязкой. Проверка у себя: закодировать пустую строку и посмотреть, что пришло; пустые строки отсеивать до счёта в любом случае.

Толкование «ноль — тексты не связаны, минус единица — противоположны по смыслу» для эмбеддингов текста неверно. Утверждение и его отрицание, как и антонимы, стоят в одних и тех же контекстах и обычно получают близкие векторы, а отрицательные значения у текстовых моделей встречаются редко. Окажется ли вопрос ближе к собственному ответу или к похожему вопросу, зависит от обучения модели: модели, обученные на сходство формулировок, сближают вопрос с перефразированным вопросом; модели, обученные на пары «запрос — документ», сближают вопрос с ответом.

До первого запроса нужно выяснить, что возвращает используемая библиотека или хранилище — сходство, расстояние или пересчитанную оценку — и в какую сторону сортировать. «Оценка» в выдаче хранилища или библиотеки — не обязательно косинусное сходство. Это может быть сходство, расстояние, косинус, пересчитанный в диапазон от нуля до единицы, обратная функция от расстояния или скалярное произведение с обратным знаком. Что именно возвращается, написано в описании хранилища; поэтому порог не переносится не только между моделями, но и между хранилищами при одной модели.

Какую меру считать

Косинусное сходство, скалярное произведение и евклидово расстояние гарантированно дают один порядок выдачи для нормированных векторов — тех, у которых норма равна единице с допуском; при этом евклидово расстояние сортируют по возрастанию, а две другие меры — по убыванию. Без нормировки совпадение не гарантировано. Как проверить нормировку у себя: посчитать норму и сравнить с единицей с допуском, а не на точное равенство. Точному равенству единице доверять нельзя даже для нормированного вектора: из-за ограниченной точности дробных чисел посчитанная норма то совпадает с единицей, то отличается от неё в младших разрядах — это зависит от того, в каком формате числа хранятся и чем считается норма. Поэтому используют допуск, который учитывает погрешность вычислений.

Где поиск по сходству подводит

Пара «вопрос — ответ» зависит от того, на что модель обучали. Длинный документ упирается в предел длины входа: он считается в токенах токенизатора самой модели эмбеддингов, а не той модели, что отвечает в чате, и совпадать их счёт не обязан. Предел есть и у модели, и у библиотеки-обёртки, и второй бывает ниже первого. Исходов для более длинного текста три: отказ с ошибкой, тихое обрезание и тихая нарезка на куски с усреднением их векторов. Какой сработает, зависит от сервиса или библиотеки и бывает параметром вызова.

Проверка обрезания без знания поставщика: взять текст заведомо, с большим запасом, длиннее предполагаемого предела, закодировать его, затем закодировать тот же текст, в котором хвост — заключительная часть, вся лежащая далеко за этим пределом, — целиком заменён посторонним текстом на другую тему. Если сходство двух векторов равно единице с точностью до округления, хвост в вектор не попадает. Контроль: такая же замена в начале текста обязана сходство заметно уронить; если не уронила — обрезается начало либо проверка поставлена неверно.

Один вектор на длинный документ с несколькими темами смешивает их, и запрос по одной из тем находит такой документ хуже. Поэтому документ режут на фрагменты и кодируют каждый отдельно. Цена нарезки: фрагмент, вырванный из документа, теряет контекст — местоимение остаётся без того, к чему оно относится, абзац без своего заголовка.

Точные идентификаторы — артикулы, коды ошибок, редкие имена — поиск по векторам находит ненадёжно: для них нужен поиск по совпадению строки, отдельно или вместе с векторным.

Плохая выдача не обязательно означает плохие векторы: порядок диагностики описан в разборе мифов о поиске в агентах.

Тупик

Первым делом выбирают порог — «сходство выше такого-то значит текст подходит» — и берут число из чужого примера. Не помогает, потому что шкала у каждой модели своя: у одной несвязанные тексты дают значения около нуля, у другой заметно выше. Внутри одной модели значения зависят от длины сравниваемых текстов, а число из выдачи хранилища может вообще не быть косинусом, так что порог не переносится даже между хранилищами при одной и той же модели. Порог выглядит настройкой качества, а на деле это число без единицы измерения.

Позиция редакции

Сходство — величина для сортировки, а не для решения «подходит или нет»: брать несколько верхних результатов и отдавать решение следующему шагу — самой языковой модели, которая читает запрос и кандидата вместе. Отдельную модель для такой проверки добавлять не по умолчанию, а когда диагностика показала, что слабое место именно в поиске. Порог, взятый не из собственных размеченных пар, не использовать вовсе.

Неверна, если модель, режим кодирования и вид оценки, которую возвращает хранилище, зафиксированы, а порог откалиброван на собственных размеченных парах. В поиске дублей и при склейке одинаковых обращений решение «да или нет» по порогу — законный рабочий инструмент, потому что проверить следующим шагом каждую пару корпуса не получится, а сортировка там ничего не даёт. Калибруют порог так: берут набор пар с пометкой «одно и то же» или «разное», считают сходство по каждой паре и выбирают порог по тому, какая ошибка дороже — ложная склейка или пропуск. Калибровку повторяют при смене модели, режима кодирования или вида оценки.

С чем это связано

Метка над заголовком говорит, зачем туда идти: продолжить тему, перейти к практике или увидеть возражение.

Текст разделяется на токены перед обработкой нейросетьюТекстТокены
Предыстория

Токены в нейросети: в чём модель считает текст

Токены — основа, на которой строится эмбеддинг: разберётесь, как модель разбивает текст, и поймёте, откуда берутся ограничения контекста и стоимость запросов.

Из потока запросов векторный поиск выигрывает не на всехзапросыпо смыслу
Практика

Векторная база: когда она окупается, а когда хватит обычного поиска

Когда векторный поиск выгоднее обычного — и как за две недели посчитать, окупится ли он для вашей задачи.

Четыре датчика: три показателя поиска в норме, четвёртый — ответы агента — зашкаливает. Метрики поиска красивые, а агент отвечает мимо: поломка живёт не в ретриагент всё ещё мимо
Усиление

Поиск решает меньше, чем принято считать

Почему идеальный поиск не спасает агента от ошибок и где на самом деле искать слабые места в RAG-системе.

Визуализация точного и неточного сложения дробных чисел в двоичной системеТочное сложениеОшибка округления
Углубление

Почему 0.1 + 0.2 не равно 0.3 и как считать деньги

Почему дробные числа в коде ведут себя не так, как на бумаге — и как избежать ошибок в финансовых расчётах.

Письмо по вторникам

Один разбор недели и короткий список того, что изменилось. Без дайджестов на сорок ссылок.

Начните вводить — материалы появятся здесь.

↑↓ выбрать · Enter открыть · Esc закрыть