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

Прежде чем проводить поиск по сходству, мы используем нейронные сети для преобразования неструктурированных данных, таких как текст, изображения, видео и аудио, в многомерные числовые векторы, называемые векторами внедрения. Например, мы можем использовать предварительно обученную сверточную нейронную сеть ResNet-50 для преобразования изображения птицы в коллекцию вложений с 2048 измерениями. Здесь мы перечисляем первые три и последние три векторных элемента: [0.1392, 0.3572, 0.1988, ..., 0.2888, 0.6611, 0.2909].

После создания векторов внедрения системы векторного поиска сравнивают пространственное расстояние между входным вектором запроса и векторами в хранилищах векторов. Чем ближе они в космосе, тем больше они похожи.

Популярные технологии векторного поиска

На рынке доступно множество технологий векторного поиска, включая библиотеки машинного обучения, такие как Python NumPy, библиотеки векторного поиска, такие как FAISS, плагины векторного поиска, созданные на основе традиционных баз данных, и специализированные векторные базы данных, такие как Milvus и Zilliz Cloud.

Библиотеки машинного обучения

Использование библиотек машинного обучения — самый простой способ реализовать векторный поиск. Например, мы можем использовать NumPy Python для реализации алгоритма ближайшего соседа менее чем за 20 строк кода.

import numpy as np

# Function to calculate euclidean distance
def euclidean_distance(a, b):
return np.linalg.norm(a - b)

# Function to perform knn
def knn(data, target, k):
# Calculate distances between target and all points in the data
distances = [euclidean_distance(d, target) for d in data]
# Combine distances with data indices
distances = np.array(list(zip(distances, np.arange(len(data)))))

# Sort by distance
sorted_distances = distances[distances[:, 0].argsort()]

# Get the top k closest indices
closest_k_indices = sorted_distances[:k, 1].astype(int)

# Return the top k closest vectors
return data[closest_k_indices]

Мы можем сгенерировать 100 двумерных векторов и найти ближайшего соседа к вектору [0,5, 0,5].

# Define some 2D vectors
data = np.random.rand(100, 2)

# Define a target vector
target = np.array([0.5, 0.5])

# Define k
k = 3

# Perform knn
closest_vectors = knn(data, target, k)

# Print the result
print("The closest vectors are:")
print(closest_vectors)

Библиотеки машинного обучения, такие как Python NumPy, предлагают большую гибкость при низкой цене. Однако у них есть некоторые ограничения. Например, они могут обрабатывать только небольшой объем данных и не обеспечивают их постоянство.

Я рекомендую использовать NumPy или другие библиотеки машинного обучения для векторного поиска только в следующих случаях:

  • Вам нужно быстрое прототипирование.
  • Вас не заботит сохранение данных.
  • Размер ваших данных не превышает миллиона, и вам не требуется скалярная фильтрация.
  • Вам не нужна высокая производительность.

Библиотеки векторного поиска

Библиотеки векторного поиска помогут вам быстро создать высокопроизводительный прототип системы векторного поиска. FAISS – типичный пример. Он имеет открытый исходный код и разработан Meta для эффективного поиска по сходству и плотной векторной кластеризации. FAISS может обрабатывать векторные коллекции любого размера, даже те, которые невозможно полностью загрузить в память. Кроме того, FAISS предлагает инструменты для оценки и настройки параметров. Несмотря на то, что FAISS написан на C++, он предоставляет интерфейс Python/NumPy.

Ниже приведен код примера векторного поиска на основе FAISS:

import numpy as np
import faiss

# Generate some example data
dimension = 64 # dimension of the vector space
database_size = 10000 # size of the database
query_size = 100 # number of queries to perform
np.random.seed(123) # make the random numbers predictable

# Generating vectors to index in the database (db_vectors)
db_vectors = np.random.random((database_size, dimension)).astype('float32')

# Generating vectors for query (query_vectors)
query_vectors = np.random.random((query_size, dimension)).astype('float32')

# Building the index
index = faiss.IndexFlatL2(dimension) # using the L2 distance metric
print(index.is_trained) # should return True

# Adding vectors to the index
index.add(db_vectors)
print(index.ntotal) # should return database_size (10000)

# Perform a search
k = 4 # we want to see 4 nearest neighbors
distances, indices = index.search(query_vectors, k)

# Print the results
print("Indices of nearest neighbors: \n", indices)
print("\nL2 distances to the nearest neighbors: \n", distances)

Библиотеки векторного поиска, такие как FAISS, просты в использовании и достаточно быстры для работы в небольших производственных средах с миллионами векторов. Вы можете повысить производительность их запросов, используя квантование и графические процессоры, а также уменьшая размерность данных.

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

Различные типы векторных баз данных

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

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

  • Существующие реляционные или столбчатые базы данных, включающие плагин векторного поиска. PG Vector является примером.
  • Традиционные поисковые системы с обратным индексом и поддержкой плотного векторного индексирования. ElasticSearch является примером.
  • Облегченные векторные базы данных, построенные на основе библиотек векторного поиска. Хрома является примером.
  • Специальные векторные базы данных. Этот тип базы данных специально разработан и оптимизирован для векторного поиска снизу вверх. Специально созданные векторные базы данных обычно предлагают более продвинутые функции, включая распределенные вычисления, аварийное восстановление и сохранение данных. Милвус — яркий тому пример.

Не все базы данных векторов одинаковы. Каждый стек имеет уникальные преимущества и ограничения, что делает их более или менее подходящими для различных приложений.

Я предпочитаю специализированные векторные базы данных другим решениям, поскольку они являются наиболее эффективным и удобным вариантом, предлагающим множество уникальных преимуществ. В следующих разделах я буду использовать Milvus в качестве примера, чтобы объяснить причины моего предпочтения.

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

Milvus — это распределенная специализированная векторная база данных с открытым исходным кодом, которая может хранить, индексировать, управлять и извлекать миллиарды встраиваемых векторов. Это также одна из самых популярных векторных баз данных для дополненной генерации поиска LLM. Являясь образцовым примером специализированных векторных баз данных, Milvus имеет много уникальных преимуществ со своими аналогами.

Устойчивость данных и экономичное хранение

Хотя предотвращение потери данных является минимальным требованием для базы данных, многие одномашинные и легкие векторные базы данных не уделяют приоритетного внимания надежности данных. Напротив, в специализированных распределенных векторных базах данных, таких как Milvus, приоритетом является устойчивость системы, масштабируемость и постоянство данных за счет разделения хранения и вычислений.

Более того, большинству векторных баз данных, использующих приблизительные индексы ближайшего соседа (ANN), требуется много памяти для выполнения векторного поиска, поскольку они загружают индексы ANN исключительно в память. Однако Milvus поддерживает дисковые индексы, что делает хранение более чем в десять раз более экономичным, чем индексы в памяти.

Оптимальная производительность запросов

Специализированная база данных векторов обеспечивает оптимальную производительность запросов по сравнению с другими вариантами поиска векторов. Например, Milvus в десять раз быстрее обрабатывает запросы, чем плагины векторного поиска. Milvus использует алгоритм ANN вместо алгоритма жестокого поиска KNN для более быстрого поиска векторов. Кроме того, он сегментирует свои индексы, сокращая время, необходимое для создания индекса по мере увеличения объема данных. Такой подход позволяет Milvus легко обрабатывать миллиарды векторов, добавляя и удаляя данные в реальном времени. Напротив, другие надстройки векторного поиска подходят только для сценариев с менее чем десятками миллионов данных и нечастыми добавлениями и удалениями.

Milvus также поддерживает ускорение графического процессора. Внутреннее тестирование показывает, что векторное индексирование с ускорением на графическом процессоре может достигать более 10 000 запросов в секунду при поиске десятков миллионов данных, что как минимум в десять раз быстрее, чем традиционное индексирование на процессоре для производительности запросов на одном компьютере.

Надежность системы

Многие приложения используют векторные базы данных для онлайн-запросов, требующих низкой задержки запроса и высокой пропускной способности. Этим приложениям требуется аварийное переключение на одном компьютере на минутном уровне, а некоторым даже требуется межрегиональное аварийное восстановление для критических сценариев. Традиционные стратегии репликации, основанные на Raft/Paxos, страдают от серьезной траты ресурсов и требуют помощи в предварительном сегментировании данных, что приводит к низкой надежности. Напротив, Milvus имеет распределенную архитектуру, которая использует очереди сообщений K8s для обеспечения высокой доступности, сокращения времени восстановления и экономии ресурсов.

Работоспособность и наблюдаемость

Чтобы лучше обслуживать корпоративных пользователей, векторные базы данных должны предлагать ряд функций корпоративного уровня для повышения удобства работы и наблюдения. Milvus поддерживает несколько методов развертывания, включая диаграмму оператора K8s и Helm, создание docker-compose и установку pip, что делает его доступным для пользователей с различными потребностями. Milvus также предоставляет систему мониторинга и сигнализации на основе Grafana, Prometheus и Loki, улучшающую ее наблюдаемость. Благодаря распределенной облачной архитектуре Milvus является первой в отрасли векторной базой данных, поддерживающей многопользовательскую изоляцию, RBAC, ограничение квот и постепенные обновления. Все эти подходы значительно упрощают управление и мониторинг Milvus.

Начало работы с Milvus в 3 простых шага за 10 минут

Создание векторной базы данных — сложная задача, но использовать ее так же просто, как использовать Numpy и FAISS. Даже студенты, незнакомые с ИИ, смогут реализовать векторный поиск на базе Milvus всего за десять минут. Чтобы воспользоваться масштабируемыми и высокопроизводительными службами векторного поиска, выполните следующие три шага: