Конфигурация квантования для HNSW-индекса

HNSW-индекс поддерживает квантование векторов. Квантование позволяет снизить объем памяти(на ~75%), занимаемый индексом, и уменьшить стоимость вычислений при поиске. На текущий момент поддерживается только 8-битное скалярное квантование.

Конфигурация квантования задается через объект quantization_config в определении индекса в поле config и доступна только для HNSW-индекса.

Пример конфигурации

{
  "indexes": [
    {
      "name": "some_hnsw_index",
      // ...
      "config": {
        "dimension": 1024,
        "metric": "cosine",
        // ...
        "quantization_config": {
          "quantization_type": "scalar_quantization_8_bit",
          "quantile": 0.99,
          "sample_size": 30000,
          "quantization_threshold": 150000
        },
        "embedding": {
          "upsert_embedder": {
            "name": "test-embedder",
            "url": "http://127.0.0.1:8000"
          }
        }
      }
    }
  ]
}

Поля quantization_config

Поле Тип Значение по умолчанию Описание
quantization_type string Тип квантования. В настоящее время поддерживается только значение scalar_quantization_8_bit, соответствующее 8-битному скалярному квантованию. Если объект quantization_config отсутствует в конфигурации индекса, квантование отключено
quantile number вычисляется автоматически Квантиль, используемый для определения диапазона отсечения значений компонент векторов перед квантованием. Допустимые значения — от 0.95 до 1.0. Значение по умолчанию вычисляется автоматически на основании размерности векторов в индексе. Изменять этот параметр рекомендуется только в том случае, если известно распределение значений компонент векторов и требуется дополнительная настройка качества поиска, например для достижения ожидаемого recall
sample_size integer 20000 Количество векторов, выбираемых из индекса для формирования выборки, по которой оценивается диапазон значений для квантования. На этой выборке вычисляются минимальные и максимальные значения компонент с учетом quantile, после чего определяется рабочий диапазон квантования.
quantization_threshold integer 100000 Минимальное количество векторов в индексе, начиная с которого запускается фоновое квантование.

Поведение по умолчанию

Для включения квантования достаточно указать только quantization_type(тег reindex:"quantization=sq8" в go-connector):

type Item struct {
	Id      int       `reindex:"id,,pk"`
	VecHnsw [1024]float32 `reindex:"hnsw_idx,hnsw,m=16,ef_construction=200,metric=inner_product,multithreading=1,start_size=1000,quantization=sq8"`
}
curl --location --request POST 'http://127.0.0.1:9088/api/v1/db/vectors_db/namespaces/test_ns/indexes' \
--header 'Content-Type: application/json' \
--data-raw '{
  "name": "hnsw_idx",
  "json_paths": ["VecHnsw"],
  "field_type": "float_vector",
  "index_type": "hnsw",
  "config": {
    "dimension": 1024,
    "metric": "cosine",
    "start_size": 1000,
    "m": 16,
    "ef_construction": 200,
    "quantization_config": {
      "quantization_type": "scalar_quantization_8_bit"
    }
  }
}'

Остальные параметры будут использованы со значениями по умолчанию:

  • quantile — вычисляется автоматически;
  • sample_size20000;
  • quantization_threshold100000.

Обновление и отключение квантования

У пользователя есть возможность обновить параметры заданного конфига(quantile, sample_size, quantization_threshold), но только пока индекс не был квантирован:

err := DB.UpdateIndex(ns, reindexer.IndexDef{
  Name:      hnswIndexName,
  IndexType: "hnsw",
  FieldType: "float_vector",
  // ...
  Config: reindexer.FloatVectorIndexOpts{
    // ...
    QuantizationConfig: &bindings.QuantizationConfig{
      Type:       "scalar_quantization_8_bit",
      Quantile:   0.987,
      SampleSize: 200000,
      Threshold:  1000000,
    },
  },
})
curl --location --request PUT 'http://127.0.0.1:9088/api/v1/db/vectors_db/namespaces/test_ns/indexes' \
--header 'Content-Type: application/json' \
--data-raw '{
  "name": "hnsw_idx",
  "json_paths": ["VecHnsw"],
  "field_type": "float_vector",
  "index_type": "hnsw",
  "config": {
    "dimension": 1024,
    "metric": "cosine",
    "start_size": 10000,
    "m": 16,
    "ef_construction": 200,
    "quantization_config": {
      "quantization_type": "scalar_quantization_8_bit",
      "quantile": 0.987,
      "sample_size": 200000,
      "quantization_threshold": 1000000
    }
  }
}'

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

Отсутствие quantization_config интерпретируется как работа индекса без квантования. Чтобы отключить квантование, необходимо обновить индекс, удалив объект quantization_config из его конфига.

Если квантование уже было выполнено для данного индекса, удаление этой секции рассматривается как сброс конфигурации квантования и загрузка исходных значений float-векторов.