• О компании Milvus
  • Начать работу
  • Понятия
  • Руководство пользователя
    • Коллекции
    • Схема и поля данных
    • Вставка и удаление
    • Указатели
      • Плавающие векторные индексы
      • Индексы двоичных векторов
      • Индексы разреженных векторов
      • Скалярные индексы
      • Индексы с поддержкой GPU
    • Поиск
    • Вывод функций и моделей
    • Оптимизация хранения данных
    • Снимки
  • Импорт данных
  • Инструменты искусственного интеллекта
  • Руководство по администрированию
  • Инструменты
  • Интеграции
  • Учебные материалы
  • Часто задаваемые вопросы
  • API Reference

FAISSCompatible with Milvus 3.0.0+

Тип индекса « FAISS » — это пропускной механизм экспертного уровня, доступный в Milvus версии 3.0.0 и более поздних. Он позволяет предоставить строку фабрики индексов Faiss вместо выбора фиксированного типа индекса Milvus.

Используйте FAISS, если у вас уже есть проверенный рецепт Faiss и вам требуется прямой контроль над его составом. Для типичных рецептов, имеющих специальный тип индекса Milvus, предпочтительнее использовать этот специальный тип, поскольку он обладает стабильным и задокументированным набором параметров.

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

Ограничения

  • FAISS Поддерживаются поля типа « FLOAT_VECTOR » и « BINARY_VECTOR ». Не поддерживаются поля типа « FLOAT16_VECTOR », « BFLOAT16_VECTOR », « INT8_VECTOR » и « SPARSE_FLOAT_VECTOR ».

  • Универсальный адаптер FAISS работает на ЦП. Это не тип индекса Faiss для графического процессора.

  • Параметр сборки faiss_index_name является обязательным. Milvus передает его значение в Faiss без преобразования рецепта в специальный тип индекса Milvus.

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

  • Для скалярной фильтрации необходимо, чтобы базовый индекс Faiss поддерживал селектор ID. Тесты Milvus 3.0.0 охватывают фильтрованный поиск с использованием фабрик с плавающей запятой: Flat, IVF64,Flat и HNSW16,Flat. Не следует предполагать, что каждая фабрика поддерживает фильтры или что двоичные индексы FAISS поддерживают скалярную фильтрацию.

  • Итераторы поиска не поддерживаются.

  • Адаптер не обеспечивает извлечение необработанных векторов.

  • Поддержка поиска по диапазону зависит от фабрики. Float Flat имеет покрытие релизом. Не используйте поиск по диапазону с бинарными индексами FAISS.

  • Фабрика может успешно скомпилироваться, но при этом отклонять некоторые операции поиска Milvus. Например, автономная фабрика PQ8x4 отклоняет селектор, используемый при поиске со скалярной фильтрацией. Проверяйте использование без фильтрации отдельно.

  • В Milvus 3.0.0 проверяйте оценки COSINE и пороговые значения для поиска по диапазону после перезагрузки индекса. Knowhere v3.0.6 не восстанавливает состояние косинусной нормализации адаптера FAISS во время десериализации.

Как это работает

FAISS index passthrough workflow Рабочий процесс пропуска индекса FAISS

При построении индекса Milvus передает faiss_index_name, тип векторного поля, метрику и другие параметры построения адаптеру Knowhere FAISS. Адаптер вызывает faiss::index_factory() для полей типа FLOAT_VECTOR или faiss::index_binary_factory() для полей типа BINARY_VECTOR. Результирующий объект представляет собой нативный индекс Faiss, управляемый в рамках обычного жизненного цикла индекса Milvus.

При поиске адаптер преобразует предоставленные параметры, специфичные для конкретного фабричного объекта, в соответствующий объект Faiss SearchParameters. Для поддерживаемых фабрик с плавающей запятой он также передаёт набор битов фильтра Milvus в качестве селектора Faiss. Поддержка селекторов зависит от конкретного фабричного модуля, и выпущенные тесты не обеспечивают скалярную фильтрацию для двоичных индексов FAISS. Именно поэтому рецепт может быть действителен в автономном Faiss, но отклонять операцию, требуемую поисковым путем Milvus.

Необходимые условия

  • Milvus 3.0.0 или более поздней версии
  • PyMilvus 3.0.0 или более поздней версии
  • Знание синтаксиса фабрик индексов Faiss и требований к обучению выбранной фабрики

Инструкции по установке см. в разделе «Установка PyMilvus».

Выберите строку фабрики

Строка фабрики описывает индекс Faiss как последовательность компонентов. Приведенные ниже примеры проверены в тестовой версии Milvus 3.0.0. Этот список не является исчерпывающим.

Строка фабрикиТип поляПоказатели, проверенные в тестах релизной версииПараметры поискаПримечания
FlatFLOAT_VECTORL2, IP, COSINEНетТочный поиск.
IVF64,FlatFLOAT_VECTORL2, IP, COSINEnprobeЭКО с 64 инвертированными списками и несжатыми векторами.
HNSW16,FlatFLOAT_VECTORL2, IP, COSINEefSearchГраф HNSW с плоским хранением векторов.
OPQ16,IVF64,PQ16x4FLOAT_VECTORL2Специфично для фабрикиОбъединяет OPQ, IVF и PQ. Проверьте размер обучающей выборки и коэффициент восстановления на ваших данных.
IVF64,PQ8x4,RFlatFLOAT_VECTORL2nprobe, k_factorИспользует плоский рефайнер после извлечения кандидатов PQ.
PQ8x4FLOAT_VECTORL2НетВстроены тесты на выпуск. Поиск со скалярной фильтрацией завершается сбоем, поскольку индекс отклоняет селектор; проверьте использование без фильтрации отдельно.
BFlatBINARY_VECTORHAMMINGНетТочный поиск по бинарным векторам.

Записи « COSINE » указывают на покрытие тестами сборки и поиска. В Milvus 3.0.0 они не подтверждают правильность оценки или поиска по диапазону после перезагрузки индекса. См. раздел «Ограничения».

Сборка и поиск по индексу с плавающей запятой

В следующем примере создаются 3 000 векторов размером 128. Этого достаточно для обучения рецепта « IVF64,Flat », используемого в примере. Разверните блок настройки и запустите его перед сборкой и поиском по индексу.

Подготовка коллекции векторов с плавающей запятой

import random

from pymilvus import DataType, MilvusClient

client = MilvusClient(uri="http://localhost:19530")
collection_name = "faiss_float_example"

if client.has_collection(collection_name):
    client.drop_collection(collection_name)

rng = random.Random(42)
vectors = [[rng.random() for _ in range(128)] for _ in range(3000)]

schema = client.create_schema(auto_id=False, enable_dynamic_field=False)
schema.add_field("id", DataType.INT64, is_primary=True)
schema.add_field("category", DataType.VARCHAR, max_length=32)
schema.add_field("vector", DataType.FLOAT_VECTOR, dim=128)

client.create_collection(collection_name=collection_name, schema=schema)

rows = [
    {
        "id": i,
        "category": "reference" if i % 2 == 0 else "query",
        "vector": vector,
    }
    for i, vector in enumerate(vectors)
]

client.insert(collection_name=collection_name, data=rows)
client.flush(collection_name=collection_name)

Создание индекса

Установите для параметра « index_type » значение « FAISS » и используйте « faiss_index_name » для выбора нативного рецепта-фабрики Faiss.

index_params = client.prepare_index_params()
index_params.add_index(
    field_name="vector",
    index_name="faiss_ivf_flat",
    index_type="FAISS",
    metric_type="L2",
    params={"faiss_index_name": "IVF64,Flat"},
)

client.create_index(collection_name=collection_name, index_params=index_params)
client.load_collection(collection_name=collection_name)

Строка фабрики IVF64,Flat создает индекс IVF с 64 инвертированными списками и сохраняет несжатые векторы в каждом списке.

Поиск по индексу

Укажите параметры поиска, специфичные для фабрики, внутри search_params.params. Для фабрики IVF параметр nprobe определяет, сколько инвертированных списков просматривает Faiss.

search_params = {
    "params": {"nprobe": 8},
}

results = client.search(
    collection_name=collection_name,
    data=[vectors[0]],
    anns_field="vector",
    filter='category == "reference"',
    search_params=search_params,
    limit=5,
    output_fields=["category"],
)

for hits in results:
    for hit in hits:
        print(hit)

Запрос использует nprobe=8, поэтому Faiss просматривает 8 из 64 инвертированных списков. Фильтр ограничивает результаты сущностями, у которых значение category равно reference.

Создание и поиск по двоичному индексу

Для полей типа « BINARY_VECTOR » используйте строку фабрики двоичных данных, например BFlat, и совместимую двоичную метрику. Разверните блок настройки и запустите его перед созданием и поиском по индексу.

Подготовка коллекции бинарных векторов

import random

from pymilvus import DataType, MilvusClient

client = MilvusClient(uri="http://localhost:19530")
collection_name = "faiss_binary_example"

if client.has_collection(collection_name):
    client.drop_collection(collection_name)

rng = random.Random(7)
vectors = [bytes(rng.getrandbits(8) for _ in range(16)) for _ in range(300)]

schema = client.create_schema(auto_id=False, enable_dynamic_field=False)
schema.add_field("id", DataType.INT64, is_primary=True)
schema.add_field("binary_vector", DataType.BINARY_VECTOR, dim=128)

client.create_collection(collection_name=collection_name, schema=schema)
client.insert(
    collection_name=collection_name,
    data=[{"id": i, "binary_vector": vector} for i, vector in enumerate(vectors)],
)
client.flush(collection_name=collection_name)

Создание индекса

В качестве фабричной строки используйте BFlat, а в качестве метрики — HAMMING для этого примера с бинарными векторами.

index_params = client.prepare_index_params()
index_params.add_index(
    field_name="binary_vector",
    index_name="faiss_binary_flat",
    index_type="FAISS",
    metric_type="HAMMING",
    params={"faiss_index_name": "BFlat"},
)

client.create_index(collection_name=collection_name, index_params=index_params)
client.load_collection(collection_name=collection_name)

Выполните поиск по индексу

BFlat не имеет параметров поиска, специфичных для семейства. При построении запроса на поиск передайте пустое сопоставление params.

search_params = {"params": {}}

results = client.search(
    collection_name=collection_name,
    data=[vectors[0]],
    anns_field="binary_vector",
    search_params=search_params,
    limit=5,
)

for hits in results:
    for hit in hits:
        print(hit)

Каждый 128-мерный двоичный вектор занимает 16 байт. Дополнительные сведения см. в разделе «Двоичный вектор».

Настройка параметров сборки и поиска

Тип индекса « FAISS » имеет один обязательный проходной параметр сборки.

ПараметрРасположениеОписание
faiss_index_nameparams in add_index()Строка фабрики индекса Faiss. Например, IVF64,Flat.

Укажите параметры поиска, специфичные для фабрики, внутри search_params.params. В приведенной ниже таблице перечислены типичные примеры; этот список не является исчерпывающим.

ПараметрПример фабрикиОписание
nprobeIVF64,FlatКоличество инвертированных списков для поиска.
efSearchHNSW16,FlatРазмер списка кандидатов для поиска HNSW.
k_factorIVF64,PQ8x4,RFlatКоличество кандидатов, передаваемых рефинеру, относительно запрошенного top-K.

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

Обработка ошибок и неподдерживаемых операций

  • Если строка фабрики неверна или недоступна в сборке Milvus, построение индекса завершается сбоем. Перед загрузкой коллекции проверьте состояние индекса и причину сбоя.

  • Если тип параметра указан неверно, поиск завершится сбоем. Например, запрос nprobe="invalid" отклоняется, поскольку параметр nprobe должен быть числовым.

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

  • Если фабрика не поддерживает селектор Milvus, фильтрованный поиск может завершиться сбоем, даже если та же фабрика может выполнять поиск в автономной версии Faiss.

  • Не используйте search_iterator() с индексом FAISS.

Что дальше