Поделиться через


Включение и использование расширения DiskANN (предварительная версия)

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

Дополнительные сведения о DiskANN см. в разделе DiskANN: векторный поиск для поиска и рекомендаций в веб-масштабе.

Расширение pg_diskann добавляет поддержку использования DiskANN для эффективного индексирования и поиска векторов.

Включить pg_diskann

Чтобы использовать pg_diskann расширение в гибком экземпляре сервера Базы данных Azure для PostgreSQL, необходимо разрешить расширение на уровне экземпляра. Затем необходимо создать расширение для каждой базы данных, в которой требуется использовать функциональные возможности, предоставляемые расширением.

Внимание

Эта предварительная версия доступна только для недавно развернутых экземпляров гибкого сервера Базы данных Azure для PostgreSQL.

Так как pg_diskann имеет зависимость от vector расширения, можно разрешить и создатьvector расширение в той же базе данных и выполнить следующую команду:

CREATE EXTENSION IF NOT EXISTS pg_diskann;

Кроме того, можно пропустить явное разрешение и создание vector расширения, а затем выполнить предыдущую команду, добавив CASCADE предложение. Это предложение PostgreSQL для неявного запуска CREATE EXTENSION в расширении, которое зависит от него. Для этого выполните следующую команду:

CREATE EXTENSION IF NOT EXISTS pg_diskann CASCADE;

Чтобы удалить расширение из базы данных, к которой вы подключены в данный момент, выполните следующую команду:

DROP EXTENSION IF EXISTS pg_diskann;

Использование метода доступа к индексу diskann

После установки расширения можно создать diskann индекс в столбце таблицы, который содержит векторные данные. Например, чтобы создать индекс в embedding столбце demo таблицы, используйте следующую команду:

CREATE TABLE demo (
 id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
 embedding public.vector(3)
 -- other columns
);

-- insert dummy data
INSERT INTO demo (embedding) VALUES
('[1.0, 2.0, 3.0]'),
('[4.0, 5.0, 6.0]'),
('[7.0, 8.0, 9.0]');

-- create a diskann index by using Cosine distance operator
CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)

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

Следующий запрос находит 5 ближайших соседей к вектору [2.0, 3.0, 4.0]:

SELECT id, embedding
FROM demo
ORDER BY embedding <=> '[2.0, 3.0, 4.0]'
LIMIT 5;

Postgres автоматически решает, когда следует использовать индекс DiskANN. Если он решит не использовать индекс в сценарии, в котором он будет использоваться, выполните следующую команду:

-- Explicit Transcation block to force use for DiskANN index.

BEGIN;
SET LOCAL enable_seqscan TO OFF;
-- Similarity search queries
COMMIT;

Внимание

Установка enable_seqscan в положение "выключено" препятствует планировщику запросов использовать план последовательного сканирования, если доступны другие методы. Так как он отключается с помощью SET LOCAL команды, параметр вступает в силу только для текущей транзакции. После COMMIT или ROLLBACK параметр уровня сеанса вновь вступает в силу. Обратите внимание, что если запрос включает в себя другие таблицы, параметр также не рекомендует использовать последовательные проверки во всех этих таблицах.

Ускорение сборки индекса

Существует несколько способов, которые мы рекомендуем улучшить время сборки индекса.

Использование большего объема памяти

Чтобы ускорить создание индекса, можно увеличить объем памяти, выделенной для экземпляра Postgres для сборки индекса. Использование памяти можно указать с помощью maintenance_work_mem параметра.

-- Set the parameters
SET maintenance_work_mem = '8GB'; -- Depending on your resources

CREATE INDEX Затем команда использует указанную рабочую память в зависимости от доступных ресурсов для построения индекса.

CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)

Подсказка

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

Использование параллелизации

Чтобы ускорить создание индекса, можно использовать параллельные рабочие роли. Число рабочих ролей можно указать с помощью parallel_workers параметра хранилища инструкции CREATE TABLE при создании таблицы. Позже это можно изменить, используя условие выражения SET инструкции ALTER TABLE.

CREATE TABLE demo (
	id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
	embedding public.vector(3)
) WITH (parallel_workers = 4);
ALTER TABLE demo SET (parallel_workers = 8);

CREATE INDEX Затем команда использует указанное число параллельных рабочих ролей в зависимости от доступных ресурсов для построения индекса.

CREATE INDEX demo_embedding_diskann_idx ON demo USING diskann (embedding vector_cosine_ops)

Внимание

Процесс лидера не может участвовать в параллельных сборках индекса.

Если вы хотите создать индекс с помощью параллельного выполнения, необходимо также задать параметры max_parallel_workers, max_worker_processes и max_parallel_maintenance_workers соответствующим образом. Дополнительные сведения об этих параметрах см. в параметрах, которые управляют использованием ресурсов и асинхронным поведением.

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

-- Set the parameters
SET max_parallel_workers = 8;
SET max_worker_processes = 8; -- Note: Requires server restart
SET max_parallel_maintenance_workers = 4;

Дополнительные сведения о других параметрах настройки этих параметров в гибком сервере Базы данных Azure для PostgreSQL см. в статье "Настройка параметров сервера".

Примечание.

Параметр max_worker_processes требует, чтобы сервер перезагрузится.

Если конфигурация этих параметров и доступных ресурсов на сервере не позволяют запускать параллельные задачи, PostgreSQL автоматически возвращается к созданию индекса в непараллельном режиме.

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

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

Параметры индекса

  • max_neighbors: максимальное число ребер на узел в графе (по умолчанию — 32). Более высокое значение может улучшить запоминание до определенного момента.
  • l_value_ib: размер списка поиска во время сборки индекса (по умолчанию — 100). Более высокое значение делает сборку медленнее, но индекс будет иметь более высокое качество.
CREATE INDEX demo_embedding_diskann_custom_idx ON demo USING diskann (embedding vector_cosine_ops)
WITH (
 max_neighbors = 48,
 l_value_ib = 100
 );

Параметры расширения

  • diskann.iterative_search: управляет поведением поиска.

    Конфигурации для diskann.iterative_search:

    • relaxed_order (по умолчанию): позволяет DiskANN итеративно проводить поиск по графу партиями diskann.l_value_is, пока не будет достигнуто требуемое количество кортежей, возможно ограниченное условием LIMIT. Может привести к тому, что результаты не упорядочены.

    • strict_order: подобно relaxed_order, позволяет diskann'у итеративно искать граф, пока не будет получено требуемое количество кортежей. Однако он гарантирует, что результаты возвращаются в строгом порядке, отсортированные по расстоянию.

    • off: использует безитеративную функцию поиска, что означает, что она пытается получить diskann.l_value_is кортежи за один шаг. Неитеративный поиск может возвращать только максимум diskann.l_value_is векторов для запроса независимо от LIMIT предложения или количества кортежей, соответствующих запросу.

    Чтобы изменить поведение strict_order поиска, для всех запросов, выполняемых в текущем сеансе, выполните следующую инструкцию:

    SET diskann.iterative_search TO 'strict_order';
    

    Чтобы изменить его, чтобы он влиял только на все запросы, выполняемые в текущей транзакции, выполните следующую инструкцию:

    BEGIN;
    SET LOCAL diskann.iterative_search TO 'strict_order';
    -- All your queries
    COMMIT;
    
  • diskann.l_value_is: L-значение для сканирования индекса (по умолчанию — 100). Увеличение значения улучшает вспоминание, но может замедлить запросы.

    Чтобы изменить значение L для сканирования индекса на 20, для всех запросов, выполняемых в текущем сеансе, выполните следующую инструкцию:

    SET diskann.l_value_is TO 20;
    

    Чтобы изменить его, чтобы он влиял только на все запросы, выполняемые в текущей транзакции, выполните следующую инструкцию:

    BEGIN;
    SET LOCAL diskann.l_value_is TO 20;
    -- All your queries
    COMMIT;
    
Размер набора данных (строки) Тип параметра Имя Рекомендуемое значение
<1M Сборка индекса l_value_ib 100
<1 млн Сборка индекса max_neighbors 32
<1 млн Время запроса diskann.l_value_is 100
1M-50M Сборка индекса l_value_ib 100
1M-50M Сборка индекса max_neighbors 64
1M-50M Время запроса diskann.l_value_is 100
>50 млн Сборка индекса l_value_ib 100
>50 млн Сборка индекса max_neighbors 96
>50 млн Время запроса diskann.l_value_is 100

Примечание.

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

Ход ВЫПОЛНЕНИЯ CREATE INDEX и REINDEX

Начиная с PostgreSQL 12 и более поздних версий, вы можете использовать pg_stat_progress_create_index для проверки хода выполнения операций CREATE INDEX или REINDEX.

SELECT phase, round(100.0 * blocks_done / nullif(blocks_total, 0), 1) AS "%" FROM pg_stat_progress_create_index;

Дополнительные сведения о возможных этапах, с помощью которых выполняется операция CREATE INDEX или REINDEX, см. в разделе "Этапы CREATE INDEX".

Выбор функции доступа к индексу

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

pg_diskann поддерживает следующие операторы расстояния

  • vector_l2_ops: <-> Евклидеан расстояние
  • vector_cosine_ops: <=> Косинус расстояние
  • vector_ip_ops: <#> внутренний продукт

Устранение неполадок

Ошибка: : diskann index needs to be upgraded to version 2...

При возникновении этой ошибки можно устранить следующим образом:

  • Выполнение REINDEX или REDINDEX CONCURRENTLY команды на индексе.

  • Так как REINDEX это может занять много времени, расширение также предоставляет определяемую пользователем функцию upgrade_diskann_index(), которая обновляет индекс быстрее, когда это возможно.

    Чтобы обновить индекс, выполните следующую инструкцию:

    SELECT upgrade_diskann_index('demo_embedding_diskann_custom_idx');
    

    Чтобы обновить все индексы диска в базе данных до текущей версии, выполните следующую инструкцию:

    SELECT upgrade_diskann_index(pg_class.oid)
    FROM pg_class
    JOIN pg_am ON (pg_class.relam = pg_am.oid)
    WHERE pg_am.amname = 'diskann';