Найти в Дзене
Математика не для всех

Когда пытаешься сделать семантический поиск по десяткам миллионов текстов, всё упирается не в “умные модели”, а в банальную физику данных

: обычные векторные отпечатки документов в 32-битных числах слишком тяжёлые. Их либо нужно держать в памяти (и тогда это сотни гигабайт), либо постоянно гонять с диска (и тогда теряется скорость). Поэтому практический трюк здесь — хранить один и тот же “портрет” текста сразу в двух очень компактных видах и использовать их по очереди: сначала максимально быстро отфильтровать почти всё, а потом точно проверить совсем немного кандидатов. Для корпуса масштаба Википедии (около 41 млн фрагментов) это делается так. Документ один раз превращают в числовой вектор, а затем делают два “сжатия”. Первое — битовое: от каждого числа оставляют только знак, получая крошечный битовый отпечаток. Из таких отпечатков строится индекс, который реально держать в оперативной памяти даже на 8 ГБ, потому что хранение получается на уровне “несколько байт на координаты”, а не “четыре байта на координату”, и FAISS (библиотека с открытым исходным кодом для эффективного поиска сходства и кластеризации плотных вектор

Когда пытаешься сделать семантический поиск по десяткам миллионов текстов, всё упирается не в “умные модели”, а в банальную физику данных: обычные векторные отпечатки документов в 32-битных числах слишком тяжёлые. Их либо нужно держать в памяти (и тогда это сотни гигабайт), либо постоянно гонять с диска (и тогда теряется скорость). Поэтому практический трюк здесь — хранить один и тот же “портрет” текста сразу в двух очень компактных видах и использовать их по очереди: сначала максимально быстро отфильтровать почти всё, а потом точно проверить совсем немного кандидатов.

Для корпуса масштаба Википедии (около 41 млн фрагментов) это делается так. Документ один раз превращают в числовой вектор, а затем делают два “сжатия”. Первое — битовое: от каждого числа оставляют только знак, получая крошечный битовый отпечаток. Из таких отпечатков строится индекс, который реально держать в оперативной памяти даже на 8 ГБ, потому что хранение получается на уровне “несколько байт на координаты”, а не “четыре байта на координату”, и FAISS (библиотека с открытым исходным кодом для эффективного поиска сходства и кластеризации плотных векторов) прямо поддерживает такие бинарные индексы для поиска по расстоянию между битовыми строками.

Второе сжатие — 8-битное: тот же вектор сохраняют как маленькие целые числа, которые занимают в разы меньше места и удобно лежат на диске.

Дальше запрос обрабатывается в два прохода. Сначала запрос тоже превращается в обычный числовой вектор, после чего из него делают битовый отпечаток и очень быстро находят небольшую горстку самых похожих документов именно по битам. Это работает как “грубый, но молниеносный отбор”: компьютер умеет сравнивать биты пачками, поэтому такой поиск на CPU получается резко быстрее, чем поиск по полным 32-битным векторам. Затем включается точность: для найденных кандидатов с диска подчитываются их 8-битные векторы, и уже по ним пересчитывается финальная близость к исходному (не сжатому) вектору запроса. По сути, “сначала быстро нашли тех, кто похож примерно, потом аккуратно пересчитали только этих”. В демо-реализации для Википедии пересчитываются, например, топ-40 кандидатов и показывается топ-10 результатов, а сами 8-битные векторы хранятся на диске и подгружаются только по мере надобности.

Именно за счёт этого и получается практическая картинка, которая звучит неправдоподобно, пока не увидишь механику: в памяти держится только битовый индекс, а всё “точное” и тяжёлое остаётся на диске и читается микропорциями. В документации к примеру прямо говорится про порядок величин: несколько гигабайт памяти под бинарный индекс и порядка десятков гигабайт диска под бинарные и 8-битные представления, что на фоне “сотен гигабайт” для обычного 32-битного подхода и правда выглядит как другой класс задачи.

Если хочется углубиться без лишней теории, есть хороший разбор этого сценария (41 млн текстов Википедии, быстрый отбор по битам и последующая 8-битная “переоценка” кандидатов) и пояснением, как добирать качество увеличением числа кандидатов для второго шага — это статья Hugging Face про сжатие векторных представлений.