Руководство по оценке ресурсов для ANN
Нагрузки векторного поиска (ANN) обычно в первую очередь ограничены объёмом памяти и ресурсами CPU, а не ёмкостью диска. В этой статье описан практический метод оценки ресурсов, который поможет подобрать конфигурацию кластера векторного поиска Apache Doris до ввода в эксплуатацию.
Быстрая навигация
- Чтобы понять, почему для ANN нужна отдельная оценка, см. Особенности потребления ресурсов ANN.
- Чтобы сразу оценить объём памяти, см. Оценка памяти для HNSW и Оценка памяти для IVF.
- Чтобы оценить потребность в CPU, см. Оценка числа ядер CPU.
- Чтобы узнать о резервировании ресурсов в промышленной эксплуатации, см. Запас ресурсов для промышленной эксплуатации.
- Чтобы выбрать индекс, см. Рекомендации по сценариям.
Общий порядок оценки
Оценку обычно выполняют в следующем порядке:
- Оцените память индекса: рассчитайте объём памяти для постоянного размещения индекса по объёму данных, типу индекса и режиму квантования.
- Оцените число ядер CPU: подберите число ядер CPU с учётом соотношения с объёмом памяти, целевого QPS и задержки.
- Предусмотрите запас ресурсов: оставьте ресурсы для выполнения запросов, доступа к невекторным столбцам и Compaction.
Особенности потребления ресурсов ANN
По сравнению с обычными индексами OLAP для ANN характерны следующие особенности потребления ресурсов:
| Вид ресурсов | Особенности потребления |
|---|---|
| CPU при построении | Высокая загрузка. Сильная нагрузка на CPU во время загрузки данных. |
| Память при построении | Если Segment слишком велик, построение отдельного индекса может завершиться ошибкой из-за нехватки памяти. |
| Память при выполнении запросов | Для высокой производительности запросов обычно требуется, чтобы индекс по возможности постоянно находился в памяти. |
| CPU при выполнении запросов | Сценарии с высоким QPS предъявляют существенные требования к числу ядер CPU. |
Doris поддерживает три режима квантования для снижения потребления памяти: sq8, sq4 и pq. Квантование обычно связано со следующими компромиссами:
- Более медленная загрузка данных: дополнительные затраты на кодирование.
- Возможное замедление запросов: дополнительные затраты на декодирование или восстановление векторов.
- Возможное снижение полноты поиска (recall): кодирование с потерями вносит погрешность.
Необходимые исходные данные
Перед началом оценки подготовьте следующие данные:
| Параметр | Описание |
|---|---|
Размерность вектора D | Число компонентов типа float в одном векторе, например 768. |
Общее число строк N | Общее число векторов, для которых нужно построить индекс. |
| Тип индекса | hnsw / ivf / ivf_on_disk |
| Режим квантования | flat / sq8 / sq4 / pq |
max_degree | Только для HNSW. Определяет число соседей в графе. По умолчанию 32. |
| Целевые QPS и задержка | Используются для оценки числа ядер CPU. |
Оценка памяти для HNSW
Эмпирическая формула при параметрах по умолчанию
При значении по умолчанию max_degree=32:
HNSW_FLAT_Bytes ~= 1.3 * D * 4 * N
Где:
D * 4 * Nпредставляет объём памяти исходных векторов float32.1.3учитывает дополнительные накладные расходы на структуру графа HNSW (около0.3от объёма исходных векторов).
Корректировка при изменении max_degree
Чем больше max_degree, тем выше накладные расходы на структуру графа. Масштабируйте их пропорционально:
HNSW_factor ~= 1 + 0.3 * (max_degree / 32)
HNSW_FLAT_Bytes ~= HNSW_factor * D * 4 * N
Приблизительное сокращение памяти при квантовании
| Режим квантования | Доля памяти относительно FLAT |
|---|---|
sq8 | Около 1/4 |
sq4 | Около 1/8 |
pq | Обычно близка к sq4 (например, pq_m=D/2, pq_nbits=8) |
Примечания об ivf_on_disk
ivf_on_disk использует ту же модель параметров обучения и запросов, что и IVF (nlist / ivf_nprobe), но хранит основное содержимое инвертированных списков на диске и обрабатывает запросы через кеш. При планировании ресурсов приведённую ниже оценку для IVF можно сначала принять за верхнюю границу для случая «индекс полностью в памяти», а затем отдельно подобрать ann_index_ivf_list_cache_limit, исходя из ожидаемого объёма горячих данных, которые нужно постоянно держать в памяти.
Справочные значения (D=768, max_degree=32)
| Число строк | FLAT | SQ8 | SQ4 | PQ (m=384, nbits=8) |
|---|---|---|---|---|
| 1M | 4 GB | 1 GB | 0.5 GB | 0.5 GB |
| 10M | 40 GB | 10 GB | 5 GB | 5 GB |
| 100M | 400 GB | 100 GB | 50 GB | 50 GB |
| 1B | 4000 GB | 1000 GB | 500 GB | 500 GB |
| 10B | 40000 GB | 10000 GB | 5000 GB | 5000 GB |
Оценка памяти для IVF
Накладные расходы на структуру IVF ниже, чем у HNSW, поэтому объём памяти можно приблизительно оценить так:
IVF_FLAT_Bytes ~= D * 4 * N
Доля памяти при квантовании для IVF такая же, как для HNSW:
| Режим квантования | Доля памяти относительно FLAT |
|---|---|
sq8 | Около 1/4 |
sq4 | Около 1/8 |
pq | Обычно близка к sq4 |
Справочные значения (D=768)
| Число строк | FLAT | SQ8 | SQ4 | PQ (m=384, nbits=8) |
|---|---|---|---|---|
| 1M | 3 GB | 0.75 GB | 0.35 GB | 0.35 GB |
| 10M | 30 GB | 7.5 GB | 3.5 GB | 3.5 GB |
| 100M | 300 GB | 75 GB | 35 GB | 35 GB |
| 1B | 3000 GB | 750 GB | 350 GB | 350 GB |
| 10B | 30000 GB | 7500 GB | 3500 GB | 3500 GB |
Оценка числа ядер CPU
Для сценариев с высоким QPS в качестве отправной точки можно использовать следующее эмпирическое соотношение:
16 cores : 64 GB (about 1 core : 4 GB)
Примечание: даже при включённом квантовании потребность в CPU не обязательно снижается в той же пропорции, что и объём памяти индекса. На практике:
- Сначала оцените потребность в CPU по нагрузке, эквивалентной FLAT.
- Затем постепенно уменьшайте число ядер до приемлемого уровня по результатам реальных нагрузочных тестов.
Запас ресурсов для промышленной эксплуатации (не рассчитывайте на использование 100% памяти)
Приведённые выше формулы учитывают только сам индекс ANN, а не все накладные расходы на выполнение SQL. Например:
SELECT id, text, l2_distance_approximate(embedding, [...]) AS dist
FROM tbl
ORDER BY dist
LIMIT N;
Даже при отложенной материализации TopN уровню выполнения всё равно нужна дополнительная память для обработки невекторных столбцов и хранения состояния операторов. Для промышленной эксплуатации рекомендуется:
- Ограничивать память индекса ANN примерно 70% общего объёма памяти машины.
- Использовать оставшуюся память для выполнения запросов, Compaction и других операций доступа к данным.
Рекомендации по сценариям
| Сценарий | Рекомендуемый вариант | Описание |
|---|---|---|
| Приоритет производительности при достаточном объёме памяти | HNSW + FLAT | Лучшие показатели полноты поиска (recall) и задержки. |
| Ограниченный объём памяти | HNSW/IVF + PQ | Обычно обеспечивает более сбалансированное соотношение характеристик, чем SQ8/SQ4. |
| Начальное значение параметра PQ | pq_m = D / 2 | Позже уточните по результатам нагрузочных тестов с оценкой полноты поиска (recall) и задержки. |
| Низкие требования к производительности запросов | Сначала выбрать менее мощную конфигурацию CPU | Также можно использовать стратегию «больше ресурсов CPU во время загрузки данных, сокращение ресурсов после стабилизации». |
Часто задаваемые вопросы
Вопрос 1: Насколько можно сократить объём памяти после включения квантования?
Ответ: для sq8 объём памяти составляет около 1/4 от FLAT, а для sq4 и pq (например, pq_m=D/2, pq_nbits=8) составляет около 1/8. Точное значение также зависит от накладных расходов на структуру графа HNSW.
Вопрос 2: Можно ли сократить ресурсы CPU в той же пропорции, что и память при квантовании?
Ответ: это не рекомендуется. Квантование в основном снижает потребление памяти, а потребность в CPU не уменьшается пропорционально. Рекомендуется сначала оценить потребность в CPU по нагрузке, эквивалентной FLAT, а затем уменьшать ресурсы по результатам нагрузочных тестов.
Вопрос 3: Как меняется объём памяти при увеличении max_degree?
Ответ: накладные расходы на структуру графа HNSW изменяются с коэффициентом 1 + 0.3 * (max_degree / 32). Например, при max_degree=64 коэффициент составляет около 1.6.
Вопрос 4: Какой объём памяти следует закладывать для ivf_on_disk?
Ответ: верхняя граница соответствует случаю «IVF полностью в памяти». Фактический объём постоянно занятой памяти определяется параметром ann_index_ivf_list_cache_limit и может оцениваться отдельно исходя из объёма горячих данных.
Вопрос 5: Почему не следует рассчитывать на использование 100% памяти?
Ответ: помимо индекса ANN, память также расходуют уровень выполнения SQL (невекторные столбцы, состояние операторов), Compaction и другие операции доступа. Рекомендуется оставлять около 30% памяти в резерве и ограничивать память индекса 70% общего объёма памяти.