Manticore Search поддерживает возможность добавления эмбеддингов, сгенерированных моделями машинного обучения, к каждому документу, а затем выполнения поиска ближайших соседей по ним. Это позволяет создавать такие функции, как поиск по схожести, рекомендации, семантический поиск и ранжирование релевантности на основе алгоритмов обработки естественного языка (NLP), а также, среди прочего, поиск по изображениям, видео и звуку.
Эмбеддинг — это метод представления данных — таких как текст, изображения или звук — в виде векторов в пространстве высокой размерности. Эти векторы создаются так, чтобы расстояние между ними отражало схожесть представляемых данных. Этот процесс обычно использует алгоритмы, такие как векторные представления слов (например, Word2Vec, BERT) для текста или нейронные сети для изображений. Высокая размерность векторного пространства, с большим количеством компонентов на вектор, позволяет представлять сложные и тонкие взаимосвязи между объектами. Их схожесть оценивается по расстоянию между этими векторами, часто измеряемому с помощью методов, таких как евклидово расстояние или косинусное сходство.
Manticore Search позволяет выполнять поиск k-ближайших соседей (KNN) векторов с использованием библиотеки HNSW. Эта функциональность является частью Manticore Columnar Library.
Для выполнения поиска KNN необходимо сначала настроить таблицу. Векторы с плавающей точкой и поиск KNN поддерживаются только в таблицах реального времени (не в обычных таблицах). Таблица должна содержать как минимум один атрибут float_vector, который служит вектором данных. Необходимо указать следующие свойства:
-
knn_type: обязательный параметр; в настоящее время поддерживается толькоhnsw. -
knn_dims: обязательный параметр, указывающий размерность индексируемых векторов. -
hnsw_similarity: обязательный параметр, указывающий функцию расстояния, используемую индексом HNSW. Допустимые значения:L2- квадрат евклидова расстоянияIP- внутреннее произведениеCOSINE- косинусное сходство
Примечание: При использовании косинусного сходства (
COSINE) векторы автоматически нормализуются при вставке. Это означает, что сохранённые значения векторов могут отличаться от исходных, так как они будут преобразованы в единичные векторы (векторы с математической длиной/модулем 1.0) для эффективного вычисления косинусного сходства. Такая нормализация сохраняет направление вектора при стандартизации его длины. -
hnsw_m: необязательный параметр, определяющий максимальное количество исходящих связей в графе. По умолчанию 16. -
hnsw_ef_construction: необязательный параметр, определяющий компромисс между временем построения и точностью.
- SQL
- Config
create table test ( title text, image_vector float_vector knn_type='hnsw' knn_dims='4' hnsw_similarity='l2' );Query OK, 0 rows affected (0.01 sec)Самый простой способ работать с векторными данными — использовать автоматические эмбеддинги. С этой функцией вы создаёте таблицу с параметрами MODEL_NAME и FROM, а затем просто вставляете текстовые данные — Manticore автоматически генерирует эмбеддинги для вас.
При создании таблицы для автоматических эмбеддингов укажите:
MODEL_NAME: модель эмбеддинга для использованияFROM: какие поля использовать для генерации эмбеддингов (пустое значение означает все текстовые/строковые поля)
Поддерживаемые модели эмбеддингов:
- Sentence Transformers: Любая подходящая модель на базе BERT из Hugging Face (например,
sentence-transformers/all-MiniLM-L6-v2) — не требует API-ключа. Manticore загружает модель при создании таблицы. - OpenAI: Модели эмбеддингов OpenAI, такие как
openai/text-embedding-ada-002— требует параметрAPI_KEY='<OPENAI_API_KEY>' - Voyage: Модели эмбеддингов Voyage AI — требует параметр
API_KEY='<VOYAGE_API_KEY>' - Jina: Модели эмбеддингов Jina AI — требует параметр
API_KEY='<JINA_API_KEY>'
Более подробная информация о настройке атрибута float_vector доступна здесь.
- SQL
Использование sentence-transformers (API-ключ не требуется)
CREATE TABLE products (
title TEXT,
description TEXT,
embedding_vector FLOAT_VECTOR KNN_TYPE='hnsw' HNSW_SIMILARITY='l2'
MODEL_NAME='sentence-transformers/all-MiniLM-L6-v2' FROM='title'
);Использование OpenAI (требуется параметр API_KEY)
CREATE TABLE products_openai (
title TEXT,
description TEXT,
embedding_vector FLOAT_VECTOR KNN_TYPE='hnsw' HNSW_SIMILARITY='l2'
MODEL_NAME='openai/text-embedding-ada-002' FROM='title,description' API_KEY='...'
);Использование всех текстовых полей для эмбеддингов (параметр FROM пуст)
CREATE TABLE products_all (
title TEXT,
description TEXT,
embedding_vector FLOAT_VECTOR KNN_TYPE='hnsw' HNSW_SIMILARITY='l2'
MODEL_NAME='sentence-transformers/all-MiniLM-L6-v2' FROM=''
);При использовании автоматических эмбеддингов не указывайте поле вектора в операторе INSERT. Эмбеддинги генерируются автоматически из текстовых полей, указанных в параметре FROM.
- SQL
Вставка только текстовых данных — эмбеддинги генерируются автоматически
INSERT INTO products (title) VALUES
('machine learning artificial intelligence'),
('banana fruit sweet yellow');Вставка нескольких полей — все используются для эмбеддинга, если FROM='title,description'
INSERT INTO products_openai (title, description) VALUES
('smartphone', 'latest mobile device with advanced features'),
('laptop', 'portable computer for work and gaming');Вставка пустого вектора (документ исключается из поиска по векторам)
INSERT INTO products (title, embedding_vector) VALUES
('no embedding item', ());Поиск работает так же — укажите текст запроса, и Manticore сгенерирует эмбеддинги и найдёт похожие документы:
- SQL
- JSON
SELECT id, knn_dist() FROM products WHERE knn(embedding_vector, 3, 'machine learning');+------+------------+
| id | knn_dist() |
+------+------------+
| 1 | 0.12345678 |
| 2 | 0.87654321 |
+------+------------+
2 rows in set (0.00 sec)В качестве альтернативы вы можете вручную вставлять заранее вычисленные векторные данные, убедившись, что они соответствуют размерности, указанной при создании таблицы. Также можно вставить пустой вектор; это означает, что документ будет исключён из результатов поиска по векторам.
Важно: При использовании hnsw_similarity='cosine' векторы автоматически нормализуются при вставке до единичных векторов (векторов с математической длиной/модулем 1.0). Эта нормализация сохраняет направление вектора при стандартизации его длины, что необходимо для эффективных вычислений косинусного сходства. Это означает, что сохранённые значения будут отличаться от ваших исходных значений.
- SQL
- JSON
insert into test values ( 1, 'yellow bag', (0.653448,0.192478,0.017971,0.339821) ), ( 2, 'white bag', (-0.148894,0.748278,0.091892,-0.095406) );Query OK, 2 rows affected (0.00 sec)Теперь вы можете выполнять поиск KNN с помощью оператора knn в формате SQL или JSON. Оба интерфейса поддерживают одинаковые основные параметры, обеспечивая единообразный опыт независимо от выбранного формата:
- SQL:
select ... from <table name> where knn ( <field>, <k>, <query vector> [,<options>] ) - JSON:
POST /search { "table": "<table name>", "knn": { "field": "<field>", "query": "<text or vector>", "k": <k>, "ef": <ef>, "rescore": <rescore>, "oversampling": <oversampling> } }
Параметры:
field: Имя атрибута с плавающей точкой, содержащего векторные данные.k: Количество документов для возврата, ключевой параметр для индексов Hierarchical Navigable Small World (HNSW). Определяет количество документов, которые должен вернуть один индекс HNSW. Однако фактическое количество документов в итоговых результатах может варьироваться. Например, если система работает с таблицами в реальном времени, разбитыми на дисковые чанки, каждый чанк может вернутьkдокументов, что приведёт к общему числу, превышающему заданноеk(так как суммарное количество будетnum_chunks * k). С другой стороны, итоговое количество документов может быть меньшеk, если после запросаkдокументов некоторые из них отфильтровываются по определённым атрибутам. Важно отметить, что параметрkне применяется к ramchunks. В контексте ramchunks процесс извлечения работает иначе, и поэтому параметрkне влияет на количество возвращаемых документов.query: (Рекомендуемый параметр) Поисковый запрос, который может быть:- Текстовой строкой: Автоматически преобразуется в эмбеддинги, если для поля настроены авто-эмбеддинги. Вернёт ошибку, если авто-эмбеддинги не настроены.
- Массивом векторов: Работает так же, как
query_vector.
query_vector: (Устаревший параметр) Поисковый вектор в виде массива чисел. Поддерживается для обратной совместимости. Примечание: Используйте либоquery, либоquery_vector, не оба одновременно.ef: необязательный размер динамического списка, используемого во время поиска. Более высокийefобеспечивает более точный, но более медленный поиск.rescore: Включает повторный расчёт KNN (по умолчанию отключён). Установите1в SQL илиtrueв JSON для включения повторного расчёта. После завершения поиска KNN с использованием квантизированных векторов (с возможным оверсемплингом) расстояния пересчитываются с использованием оригинальных (полной точности) векторов, и результаты пересортировываются для улучшения точности ранжирования.oversampling: Устанавливает множитель (число с плавающей точкой), на который умножаетсяkпри выполнении поиска KNN, что приводит к выбору большего количества кандидатов, чем требуется, с использованием квантизированных векторов. По умолчанию оверсемплинг не применяется. Эти кандидаты могут быть повторно оценены, если включён повторный расчёт. Оверсемплинг также работает с неквантизированными векторами. Поскольку он увеличиваетk, что влияет на работу индекса HNSW, это может вызвать небольшое изменение точности результатов.
Документы всегда сортируются по расстоянию до поискового вектора. Любые дополнительные критерии сортировки, которые вы укажете, применяются после этого основного условия сортировки. Для получения расстояния существует встроенная функция knn_dist().
- SQL
- JSON
select id, knn_dist() from test where knn ( image_vector, 5, (0.286569,-0.031816,0.066684,0.032926), { ef=2000, oversampling=3.0, rescore=1 } );+------+------------+
| id | knn_dist() |
+------+------------+
| 1 | 0.28146550 |
| 2 | 0.81527930 |
+------+------------+
2 rows in set (0.00 sec)Индексы HNSW должны быть полностью загружены в память для выполнения поиска KNN, что может привести к значительному потреблению памяти. Для уменьшения использования памяти можно применить скалярное квантование — метод сжатия высокоразмерных векторов путём представления каждого компонента (измерения) ограниченным числом дискретных значений. Manticore поддерживает 8-битное и 1-битное квантование, что означает, что каждый компонент вектора сжимается с 32-битного float до 8 бит или даже 1 бита, уменьшая использование памяти в 4 или 32 раза соответственно. Эти сжатые представления также позволяют быстрее вычислять расстояния, так как больше компонентов вектора можно обработать за одну SIMD-инструкцию. Хотя скалярное квантование вводит некоторую погрешность, это часто оправданный компромисс между точностью поиска и эффективностью ресурсов. Для ещё лучшей точности квантование можно сочетать с повторным расчётом и оверсемплингом: выбирается больше кандидатов, чем запрошено, и расстояния для этих кандидатов пересчитываются с использованием оригинальных 32-битных float-векторов.
Поддерживаемые типы квантования:
8bit: Каждый компонент вектора квантован до 8 бит.1bit: Каждый компонент вектора квантован до 1 бита. Используется асимметричное квантование: векторы запроса квантованы до 4 бит, а хранимые векторы — до 1 бита. Такой подход обеспечивает большую точность, чем более простые методы, хотя и с некоторыми потерями в производительности.1bitsimple: Каждый компонент вектора квантован до 1 бита. Этот метод быстрее, чем1bit, но обычно менее точен.
- SQL
create table test ( title text, image_vector float_vector knn_type='hnsw' knn_dims='4' hnsw_similarity='l2' quantization='1bit');Query OK, 0 rows affected (0.01 sec)ПРИМЕЧАНИЕ: Поиск похожих документов по id требует Manticore Buddy. Если не работает, убедитесь, что Buddy установлен.
Нахождение документов, похожих на конкретный, на основе его уникального идентификатора — распространённая задача. Например, когда пользователь просматривает определённый элемент, Manticore Search может эффективно определить и отобразить список элементов, наиболее похожих на него в векторном пространстве. Вот как это можно сделать:
- SQL:
select ... from <table name> where knn ( <field>, <k>, <document id> ) - JSON:
POST /search { "table": "<table name>", "knn": { "field": "<field>", "doc_id": <document id>, "k": <k> } }
Параметры:
field: Это имя атрибута с плавающей точкой, содержащего векторные данные.k: Это количество документов для возврата и ключевой параметр для индексов Hierarchical Navigable Small World (HNSW). Он указывает количество документов, которые должен вернуть один индекс HNSW. Однако фактическое количество документов в итоговых результатах может варьироваться. Например, если система работает с таблицами в реальном времени, разделёнными на дисковые чанки, каждый чанк может вернутьkдокументов, что приведёт к общему числу, превышающему указанноеk(так как суммарное количество будетnum_chunks * k). С другой стороны, итоговое количество документов может быть меньшеk, если после запросаkдокументов некоторые из них отфильтровываются по определённым атрибутам. Важно отметить, что параметрkне применяется к ramchunks. В контексте ramchunks процесс извлечения работает иначе, и поэтому параметрkне влияет на количество возвращаемых документов.document id: Идентификатор документа для поиска по сходству KNN.
- SQL
- JSON
select id, knn_dist() from test where knn ( image_vector, 5, 1 );+------+------------+
| id | knn_dist() |
+------+------------+
| 2 | 0.81527930 |
+------+------------+
1 row in set (0.00 sec)Manticore также поддерживает дополнительную фильтрацию документов, возвращаемых поиском KNN, либо по полнотекстовому совпадению, фильтрам атрибутов, либо по обоим критериям.
- SQL
- JSON
select id, knn_dist() from test where knn ( image_vector, 5, (0.286569,-0.031816,0.066684,0.032926) ) and match('white') and id < 10;+------+------------+
| id | knn_dist() |
+------+------------+
| 2 | 0.81527930 |
+------+------------+
1 row in set (0.00 sec)