Облачная платформаAdvanced

Создание векторного индекса

Язык статьи: Русский
Показать оригинал
Страница переведена автоматически и может содержать неточности. Рекомендуем сверяться с английской версией.

Векторный индекс можно создать, задав размерность вектора, алгоритм индексации (например, HNSW и IVF) и метод измерения сходства (например, косинусное расстояние и евклидово расстояние) в mapping, сформировав оптимальную структуру для индексации данных с богатыми признаками. Векторный поиск уменьшает проклятие размерности при обработке данных в большом масштабе. Используя такие техники, как сжатие на основе квантизации и навигация по многослойному графу, он обеспечивает высокую точность возврата и низкую задержку даже в наборах данных, содержащих десятки миллионов и даже миллиарды записей.

Алгоритмы индексации

Table 1 перечисляет алгоритмы индексации, поддерживаемые CSS vector databases. Выберите алгоритм в соответствии с требованиями вашего сервиса.

Table 1 Алгоритмы индексации для CSS vector databases

Алгоритм

Описание

Когда использовать

Версия кластера

FLAT

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

Он обеспечивает 100 % коэффициент возврата (нулевая потеря точности), но вычислительная нагрузка растет линейно с увеличением объёма данных.

Наборы данных с менее чем 10 000 записей или сценарии, требующие максимальной точности возврата

Elasticsearch: 7.6.2 or 7.10.2

OpenSearch: 1.3.6 or 2.19.0

ГРАФ

Hierarchical Navigable Small Worlds (HNSW), алгоритм индексирования на основе графа для эффективного приближённого поиска ближайших соседей (ANN). Многоуровневая структура навигации по графу ускоряет скорость извлечения.

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

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

Elasticsearch: 7.6.2 or 7.10.2

OpenSearch: 1.3.6 or 2.19.0

GRAPH_PQ

Комбинация HNSW с продуктовой квантизацией (PQ). Разделяя и кодируя векторы, этот подход значительно уменьшает затраты на хранение и память.

Коэффициент сжатия может достигать 1/16 и более. Он обеспечивает небольшой объём памяти, хотя точность снижается при увеличении коэффициента сжатия.

Датасеты до миллиарда записей

Elasticsearch: 7.6.2 or 7.10.2

OpenSearch: 1.3.6 or 2.19.0

GRAPH_SQ8

Комбинация HNSW с 8-битной скалярной квантизацией. 32-битные числа с плавающей точкой сжимаются до 8-битных целых.

Коэффициент сжатия составляет 1/4. Объём памяти значительно снижен, при небольшом снижении точности.

Наборы данных до миллиарда записей

Elasticsearch: 7.10.2

OpenSearch: 2.19.0

GRAPH_SQ4

Комбинация HNSW с 4‑битовой скалярной квантизацией. 32‑битные числа с плавающей точкой сжаты в 4‑битные целые.

Коэффициент сжатия составляет 1/8. Объём памяти значительно снижен, но полнота также значительно уменьшается. GRAPH_SQ4 более вычислительно эффективен, чем GRAPH_SQ8.

Наборы данных до миллиарда записей

Elasticsearch: 7.10.2

OpenSearch: 2.19.0

IVF_GRAPH

Комбинация Inverted File Index (IVF) с HNSW. Векторное пространство разбивается на несколько кластерных подпроcтранств, каждое представлено центроидом. При поиске сканируются только релевантные подпроcтранства.

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

Требуется высокая пропускная способность записи, а операционная сложность, связанная с предварительным построением центроидов, приемлема.

Elasticsearch: 7.6.2 or 7.10.2

OpenSearch: 1.3.6 or 2.19.0

IVF_GRAPH_PQ

Комбинация IVF, HNSW и PQ. Вместимость системы дополнительно увеличивается за счёт сжатия, а накладные расходы системы снижаются.

Требуется высокая пропускная способность записи, и операционная сложность, связанная с предварительным построением центроидов, приемлема.

Elasticsearch: 7.6.2 or 7.10.2

OpenSearch: 1.3.6 or 2.19.0

Caution

Если вы выбираете IVF_GRAPH или IVF_GRAPH_PQ, вам необходимо выполнить (Optional) Pre-Building and Registering Centroid Vectors перед созданием векторного индекса.

Вход в Dev Tools

Войдите в Dev Tools, чтобы выполнить команды DSL.

  • Для кластера Elasticsearch войдите в Kibana
    1. Войдите в консоль управления CSS.
    2. В панели навигации слева выберите Clusters > Elasticsearch.
    3. В списке кластеров найдите целевой кластер и нажмите Kibana в столбце Operation, чтобы войти в консоль Kibana.
    4. В левой панели навигации выберите Dev Tools.

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

  • Для кластера OpenSearch войдите в Dashboards
    1. Войдите в консоль управления CSS.
    2. В панели навигации слева выберите Clusters > OpenSearch.
    3. В списке кластеров найдите целевой кластер и нажмите Dashboards в столбце Operation, чтобы войти в OpenSearch Dashboards.
    4. В левой панели навигации выберите Dev Tools.

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

Создание векторного индекса

Определите сопоставления индекса и укажите параметры алгоритма индексации.

Например, создайте индекс с именем my_index. Этот индекс содержит векторное поле с именем my_vector и текстовое поле с именем my_label. Для векторного поля создаётся графовый индекс, а для измерения сходства используется евклидово расстояние.

PUT my_index
{
"settings": {
"index": {
"vector": true,
"number_of_shards": 1,
"number_of_replicas": 1
}
},
"mappings": {
"properties": {
"my_vector": {
"type": "vector",
"dimension": 2,
"indexing": true,
"algorithm": "GRAPH",
"metric": "euclidean"
},
"my_label": {
"type": "keyword"
}
}
}
}
Table 2 параметры настройки

Параметр

Обязательно

Тип

Значение по умолчанию

Описание

index.vector

Да

Boolean

N/A

Нужно ли включать векторные индексы.

Установите этот параметр в true. Иначе векторные индексы не могут быть созданы.

index.number_of_shards

Нет

Integer

1

Количество шардов индекса. Это значение должно делиться на количество узлов кластера.

Диапазон значений: 1–1024

index.number_of_replicas

Нет

Integer

1

Количество реплик индекса. Реплики повышают доступность данных.

Диапазон значений: от 0 до количества узлов минус 1

index.vector.exact_search_threshold

Нет

Integer

null (без переключения)

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

Диапазон значений: null (отключает автоматическое переключение от поиска с предварительной фильтрацией к поиску перебором) или положительное целое число

index.vector.search.concurrency.enabled

Нет

Boolean

false

Определяет, включать ли параллельный поиск векторов по сегментам. В кластере Elasticsearch каждый шард индекса состоит из нескольких сегментов. По умолчанию каждый сегмент ищется последовательно. Включение параллельного поиска по сегментам уменьшает задержку запросов, но не увеличивает максимальную пропускную способность запросов кластера. Кроме того, это может увеличить среднее использование CPU узлов кластера.

Ограничения: Этот параметр доступен только для кластеров Elasticsearch, образ которых версии не ниже 7.10.2_25.3.0_xxx.

Значение может быть:

  • true: Включает параллельный поиск.
  • false: Выполняет последовательный поиск.

Таблица 3 параметры сопоставления

Параметр

Обязательно

Тип

Значение по умолчанию

Описание

тип

Да

String

N/A

Тип данных поля.

Установите этот параметр в vector, чтобы указать векторные поля.

измерение

Да

Integer

N/A

Количество измерений вектора.

Диапазон значений: 1–4096

indexing

Нет

Boolean

false

Нужно ли включать ускорение векторного индекса.

Допустимые значения:

  • true: Включает ускорение векторного индекса. Когда этот параметр установлен в true, создаётся дополнительный векторный индекс. Алгоритм индексации указывается полем algorithm, и индекс поддерживает векторный поиск.
  • false: Отключает ускорение векторного индекса. Если этот параметр установлен в false, векторные данные записываются только в docvalues, и только ScriptScore и Rescore могут использоваться для векторного запроса.

lazy_indexing

Нет

Boolean

false

Включать ли отложенную векторную индексацию. При включении система отдает приоритет скорости загрузки данных, откладывая построение векторных индексов. Вместо построения индекса в реальном времени система просто сохраняет необработанные данные. После завершения процесса загрузки необходимо выполнить вручную offline index building. Этот параметр предназначен для балансировки пропускной способности записи и нагрузки от индексации. Используйте эту опцию для масштабных офлайн‑миграций данных, когда критична высокая скорость загрузки и возможности поиска в реальном времени не требуются в фазе загрузки.

Ограничения:

  • Этот параметр действует только когда indexing установлен в значение true в mapping.
  • Для кластеров Elasticsearch версия образа должна быть 7.10.2_24.3.3_xxx или новее.
  • Для кластеров OpenSearch версия должна быть 2.19.0.

Значение может быть:

  • true: Включает отложенную индексацию. Пропускная способность записи повышается. Однако до того, как будет вручную запущено и завершено offline index building, данные нельзя запросить через VectorQuery.
  • false: Включает построение индекса в реальном времени. Индексация происходит сразу после загрузки, поэтому данные можно запросить сразу после записи.

алгоритм

Нет

String

GRAPH

Алгоритм векторной индексации.

Ограничения:

  • Этот параметр действует только когда indexing установлен в значение true в mapping.
  • Если вы выбираете IVF_GRAPH или IVF_GRAPH_PQ, вы должны выполнить (Optional) Pre-Building and Registering Centroid Vectors перед созданием векторного индекса.

Диапазон значений: FLAT, GRAPH, GRAPH_PQ, GRAPH_SQ8, GRAPH_SQ4, IVF_GRAPH и IVF_GRAPH_PQ.

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

  • Когда выбран алгоритм GRAPH (GRAPH, GRAPH_PQ, GRAPH_SQ8 или GRAPH_SQ4), вы можете настроить структуру графового индекса и качество построения через Table 4.
  • Когда выбран алгоритм GRAPH_PQ, точность можно контролировать через Table 5.

dim_type

No

String

float

Тип данных вектора.

Значение может быть:

  • binary: двоичное значение
  • float: число с плавающей точкой

metric

No

Строка

euclidean

Метрика векторного расстояния, измеряющая схожесть или расстояние между векторами.

Значение может быть:

  • euclidean: Евклидово расстояние
  • inner_product: расстояние скалярного произведения
  • cosine: косинусное расстояние
  • hamming: Hamming distance, которое может использоваться только когда dim_type установлен в binary.
Table 4 Необязательные параметры для алгоритма индексации GRAPH

Параметр

Обязательно

Тип

Значение по умолчанию

Описание

соседи

No

Integer

64

Максимальное количество соседей для каждого вектора в графовом индексе. Большее значение указывает на более плотную связность графа и приводит к более высокой точности извлечения (recall), но также увеличивает размер файла индекса и замедляет построение индекса и скорость запросов.

Ограничения: Этот параметр действует только когда indexing установлен в true и algorithm является вариантом GRAPH (GRAPH, GRAPH_PQ, GRAPH_SQ8 или GRAPH_SQ4) в сопоставлении.

Диапазон значений: 20–255

shrink

No

Float

1

Степень агрессивности удаления избыточных ребер (pruning) при построении графа. Эта настройка напрямую управляет конечной плотностью графа. Меньшее значение указывает на более агрессивное удаление, более разреженный граф и более высокие скорости извлечения, но может увеличить потерю точности.

Ограничения: Этот параметр действует только когда indexing установлен в true и algorithm является вариантом GRAPH (GRAPH, GRAPH_PQ, GRAPH_SQ8 или GRAPH_SQ4) в сопоставлении.

Диапазон значений: 0.1–10

scaling

No

Integer

50

Коэффициент масштабирования количества узлов в верхних слоях графа HNSW. Эта настройка влияет на слои и распределение узлов по слою в графе HNSW. Правильный коэффициент масштабирования обеспечивает оптимальную эффективность навигации между слоями при извлечении.

Ограничения: Этот параметр действует только когда indexing установлен в true и algorithm является вариантом GRAPH (GRAPH, GRAPH_PQ, GRAPH_SQ8 или GRAPH_SQ4) в сопоставлении.

Диапазон значений: 0–128

efc

No

Integer

200

Сколько ближайших соседей исследовать при вставке нового вектора в граф HNSW. Этот параметр управляет глубиной поиска во время построения индекса. Большое значение приводит к более качественной структуре графа и точности запросов, но замедляет построение индекса.

Ограничения: Этот параметр действует только когда indexing установлен в true и algorithm является вариантом GRAPH (GRAPH, GRAPH_PQ, GRAPH_SQ8 или GRAPH_SQ4) в сопоставлении.

Диапазон значений: 0–100000

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

max_scan_num

No

Integer

10000

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

Ограничения: Этот параметр действует только когда indexing установлен в true и algorithm является вариантом GRAPH (GRAPH, GRAPH_PQ, GRAPH_SQ8 или GRAPH_SQ4) в сопоставлении.

Диапазон значений: 0–1000000

Таблица 5 Необязательные параметры для алгоритма индексации GRAPH_PQ

Параметр

Обязательно

Тип

Значение по умолчанию

Описание

centroid_num

Нет

Integer

255 (соответствует 8-битной квантизации)

Количество центроидов в каждом подпространстве для алгоритма PQ. Этот параметр определяет точность кодирования векторов после квантизации. Большее значение указывает на более точное представление исходных векторов и более высокий recall, но также приводит к небольшому увеличению вычислительных затрат и объёма памяти.

Ограничения: этот параметр действует только когда indexing установлен в true и algorithm установлен в GRAPH_PQ в сопоставлении.

Диапазон значений: 0–65535

fragment_num

Нет

Integer

0: Плагин автоматически задает количество фрагментов в зависимости от размерности вектора.

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

Ограничения: Этот параметр действует только когда indexing установлен в true и algorithm установлен в GRAPH_PQ в сопоставлении.

Диапазон значений: 0–4096

Когда этот параметр установлен в 0, система автоматически вычисляет оптимальное количество сегментов на основе размерности вектора dim.

if dim <= 256:
fragment_num = dim / 4
elif dim <= 512:
fragment_num = dim / 8
else:
fragment_num = 64

(Необязательно) Предварительное построение и регистрация векторов центроидов

Когда алгоритм индексирования установлен в IVF_GRAPH или IVF_GRAPH_PQ, необходимо сначала предварительно построить и зарегистрировать векторы центроидов перед созданием векторного индекса.

IVF_GRAPH и IVF_GRAPH_PQ ускоряют индексирование и запросы в ультра‑крупном наборе данных, содержащем более 1 миллиарда записей. Они позволяют сузить область запроса, разделив векторное пространство на подпространства с помощью кластеризации или случайной выборки. Перед предварительным построением необходимо получить все векторы центроидов посредством кластеризации или случайной выборки. Векторы центроидов предварительно строятся в индекс GRAPH или GRAPH_PQ и затем регистрируются в базе данных векторов CSS. Несколько узлов могут совместно использовать этот индекс. Повторное использование индекса центроидов между шардами эффективно снижает нагрузку на обучение и количество запросов к индексу центроидов, улучшая производительность записи и запросов.

  1. Создайте индекс центроидов.

    Например, выполните следующую команду для создания индекса центроидов с именем my_dict:

    PUT my_dict
    {
    "settings": {
    "index": {
    "vector": true
    },
    "number_of_shards": 1,
    "number_of_replicas": 0
    },
    "mappings": {
    "properties": {
    "my_vector": {
    "type": "vector",
    "dimension": 2,
    "indexing": true,
    "algorithm": "GRAPH",
    "metric": "euclidean"
    }
    }
    }
    }

    Для подробной настройки параметров см. Creating a Vector Index. Обратите внимание на следующие обязательные параметры:

    • index.number_of_shards: Количество шардов индекса должно быть установлено в 1. В противном случае индекс центроидов не может быть зарегистрирован.
    • indexing: Этот параметр должен быть установлен в true для включения ускорения векторного индекса.
    • algorithm: Установите алгоритм индексирования. Установите значение GRAPH для алгоритма IVF_GRAPH и GRAPH_PQ, если используется алгоритм IVF_GRAPH_PQ.

  2. Запишите векторы центроидов в созданный индекс. Запишите векторы центроидов, полученные с помощью выборки или кластеризации, в недавно созданный индекс my_dict.
  3. Вызовите API регистрации.

    Например, выполните следующую команду, чтобы зарегистрировать индекс центроидов как объект Dict с глобально уникальным именем (dict_name):

    PUT _vector/register/my_dict
    {
    "dict_name": "my_dict"
    }
  4. Создайте векторный индекс IVF_GRAPH или IVF_GRAPH_PQ.

    При создании векторного индекса не требуется указывать dimension или metric. Вместо этого указывается зарегистрированный объект Dict. Table 6 описывает ключевые параметры для указания объекта Dict.

    Например, выполните следующую команду для создания векторного индекса IVF_GRAPH:

    PUT my_index
    {
    "settings": {
    "index": {
    "vector": true,
    "sort.field": "my_vector.centroid" # Set the centroid subfield of each vector field as a sorting field.
    }
    },
    "mappings": {
    "properties": {
    "my_vector": {
    "type": "vector",
    "indexing": true,
    "algorithm": "IVF_GRAPH",
    "dict_name": "my_dict",
    "offload_ivf": true
    }
    }
    }
    }
    Table 6 Ключевые параметры для указания объекта Dict

    Параметр

    Обязательно

    Тип

    Значение по умолчанию

    Описание

    dict_name

    Yes

    String

    N/A

    Имя объекта centroid Dict, например, my_dict. Размерности вектора и метод измерения сходства индекса такие же, как у объекта Dict. Повторно настраивать их не требуется.

    offload_ivf

    Yes

    Boolean

    false

    Нужно ли выгружать IVF inverted index в слой движка Elasticsearch/OpenSearch.

    Значение может быть:

    • true: Выгружает IVF inverted index в Elasticsearch/OpenSearch для управления физическим хранением. Это значительно снижает использование off-heap памяти векторным поисковым движком. Также уменьшается нагрузка на CPU и память при записи и слиянии данных при высокой пропускной способности.
    • false: Оставляет IVF inverted index полностью в выделенном буфере памяти векторного поискового движка.

    При обработке наборов данных, содержащих сотни миллионов записей и более, рекомендуется установить этот параметр в true для оптимизации соотношения памяти кластера при сохранении производительности поиска.