Как механизм отзыва векторов Файсса может быстро найти ближайшего соседа

поисковый движок

Добро пожаловать вмоя маленькая станцияповернись~~

задний план

FaissЭто механизм поиска векторов Facebook с открытым исходным кодом, который используется для поиска N векторов, наиболее похожих на определенный вектор.

matthijs

Первый выпуск Faiss был выпущен 23.02.2018, но его автор Matthijs уже опубликовал статью в 2011 году, прежде чем присоединиться к Facebook.статья о поиске ближайшего соседа, Faiss основан на идее этой статьи. После прочтения этой статьи метод индексации Файсса стал ясен.

описание проблемы

Учитывая D-мерный векторxи коллекция\Gamma = y_1,y_2 … y_N, необходимо найтиxk ближайших соседей с кратчайшим расстоянием.

Взяв в качестве примера евклидово расстояние, его можно выразить как:

L = k-argmin_{i=0:N}|| x-y_i ||

В нашем приложенииx \in \Gamma

размер проблемы

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

exhaustive

  1. Построить матрицу расстояний: каждые два вектораxиyФормула для расчета расстояния:\sqrt{\Sigma{(x_i-y_i)^2}}, i\in [1,D], потраченное время равноO(D), матрица расстояний содержитN^2элементов, общее время равноO(D*N^2)
  2. Найдите k ближайших соседей по матрице расстояний.Если используется алгоритм минимальной кучи, временная сложность равнаO((N-k)logk)

ВыбиратьN=2000W, k=1000,D=1000

получить

  • Матрица расстояний содержит 400T элементов, предполагая, что каждое расстояние представляет собой число с плавающей запятой, занимающее 32 бита и занимающее не менее 1600 ТБ пространства.
  • Временная сложность построения матрицы расстояний порядка величины10^{17}
  • Временная сложность нахождения k ближайших соседей по матрице расстояний порядка величины10^9

stronger

Ближайшие соседи Офлайн

Вообще говоря, набор векторов обновляется каждый день, в это время вы можете попытаться сохранить k ближайших соседей, соответствующих каждому вектору напрямую.

vector_store

  1. Построение матрицы расстояний + время поиска N k ближайших соседей равноO(DN^2 + N*(N-k)*logk)
  2. Создание ближайшего соседа в автономном табличном пространствеN*k

в нашем сценарии получить

  1. Порядок времени, отнимающий много времени для поиска N k ближайших соседей, следующий:10^{17}
  2. Место для хранения1600TB(удалить после построения) + 320G (при условии, что каждый индекс представлен целым числом, а дробь - числом с плавающей запятой)

Время на поиск k ближайших соседей: O(1)

stronger

Векторное квантование

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

Так называемое векторное квантование заключается в преобразовании исходного бесконечного пространстваR^Dотображать в конечный набор векторов\mathcal{C} = \{c_i, i\in[1,l]\}в, из нихlявляется натуральным числом. изменить это сR^Dв коллекцию\mathcal{C}Функция обозначается какq,но\forall q(y) \in \mathcal{C}, что в теории информации называется\mathcal{C}для кодовой книги.

Конечно, функция отображения здесь не указана произвольно, и необходимо соблюдать принцип минимальной ошибки.Один из способов - установить функцию оптимизации на минимальную квадратичную ошибкуMSE(q)=\mathbb{E}_X[d(q(y),y)^2]

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

Теперь давайте проанализируем пространственную и временную сложность векторного квантования.

Предположим, мы сопоставляем исходные векторы 2000 Вт с набором размером 20 Вт (в среднем каждая центральная точка представляет 100 векторов, что приводит к большой ошибке)

  1. Матрица расстояний: нужно только хранить корреспонденцию\mathcal{C}Расстояние между векторами, занимаемое пространство равно|| \mathcal{C} ||^2, в этом случае400G \times 4B=1.6T
  2. y \to c \in \mathcal{C}Отношение отображения , если вектор идентифицируется как int, общееN \times 4=80MОЗУ
  3. Временная сложность: временная сложность алгоритма k-средних составляетO(m_{iter}NkD)m_{iter}— количество итераций, N — количество векторов исходного пространства, k — количество центральных точек, а D — размерность вектора. В этом примере временная сложность4m*10^{15}, увеличение количества итераций до 25 уже достигло порядка перебора методом перебора.Пока количество итераций немного увеличивается, временная сложность будет выше.

stronger

Квантование продукта PQ (квантование продукта)

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

product_quantization

Тогда вектор можно разделить наmСуществуют разные части, и для каждой части выполняется векторное квантование.Предполагая среднее деление, размерность каждой части составляетD^*=D/m

вектор[x_1,x_2,…,x_{D^*},…,x_{D-D^*+1},…,x_D], который можно разбить на m групп векторов[x_{i\_1},x_{i\_2},…,x_{i\_D^*}], кодовая книга для каждой группы\mathcal{C_i}, соответствующий квантователь обозначается какq_i,\forall q_i(x_{i*}) \in \mathcal{C_i}. Тогда окончательная глобальная кодовая книга\mathcal{C} = \mathcal{C_1} * \mathcal{C_2} ...* \mathcal{C_m}, от которого происходит название квантования произведения.

Взяв в качестве примера m=4, чтобы достичь уровня 20 Вт в предыдущем разделе,|| \mathcal{C_i} ||Вам нужно всего лишь достичь 22, и вам нужно всего лишь достичь 67, чтобы восстановить уровень 2000 Вт.

к\mathcal{C}В качестве примера возьмем случай достижения порядка 2000 Вт, количество центральных точек кодовой книги в каждой группеk^{*}равно 67, теперь давайте проанализируем соответствующую пространственную и временную сложность

  1. Матрица расстояний между центральными точками: примечание|| \mathcal{C_i} ||заk^*, размер матрицы расстоянийO(m*(k^*)^2). Если расстояние представлено числом с плавающей запятой, матрица расстояний в этом примере составляет около 70M.
  2. y \to c \in \mathcal{C_i}Отношение отображения , если вектор идентифицируется как int, общееm \times N \times 4=320MОЗУ
  3. Временная сложность кластеризации: временная сложность алгоритма k-средних по-прежнемуO(m_{iter} NkD), в этом примере необходимо выполнить k-средних для m групп соответственно, а общая временная сложность равнаO(mNk^*D*m_{iter}), в этом случае5m*10^{12}, что на 3 порядка меньше, чем в предыдущем примере
  4. Временная сложность матрицы расстояний: произведение размерности D на количество элементов матрицы расстояний, т.е.O(Dm(k^*)^2)7 \times 10^{10}

Существенная причина, по которой квантование произведения значительно сокращает занимаемое пространство, заключается в том, что выраженное векторное пространство равно(k^*)^m, но занимает дисковое пространствоmk^*

stronger

Эмпирическое значение, приведенное в статье, равноk^*=256,m=8, соответствующий размер векторного пространства равен2^{64}записаться на прием1.8\times 10^{19}

Вычисление расстояния в сценарии квантования

В сценарии без квантизации расчет расстояния рассчитывается напрямую для двух точек.|| x-y || _2

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

SDC

SDC (вычисление симметричного расстояния): расстояние между двумя векторами измеряется расстоянием между центральными точками двух векторов. Ошибка меньше или равна расстоянию от x до центральной точки + расстоянию от y до центральной точки.

sdc

В сценарии PQ расстояние SDC выражается как:SDC (x,y)= \hat{d}(x,y)=d(q(x),q(y))=\sqrt{\Sigma_j{d(q_j(x),q_j(y))^2}}

Поскольку расстояние между центральными векторами было сохранено (см. предыдущий раздел), для расчета расстояния между x и y вам нужно только просмотреть таблицу Размер таблицы составляет около 70M, и она принимает порядки величин. вычислить матрицу расстояний.10^{10}

Если вы не хотите занимать пространство матрицы расстояний, временная сложность равнаO(Dmk^*), о10^5

ADC

ADC (асимметричное вычисление расстояния): расстояние между x и y измеряется расстоянием между центральными точками, в которых расположены x и y. Используйте свойства треугольников: разница между двумя сторонами меньше, чем между третьей стороной, поэтому ошибка должна быть меньше или равна расстоянию между y и центральной точкой

adc
)

В сценарии PQ расстояние АЦП выражается как:\tilde{d}(x,y)=d(x,q(y))

Пусть i-й элемент вектора x равенu_i(x),ноADC(x,y)=\sqrt{\Sigma_j{d(u_j(x),q_j(y))^2}}

В этом сценарии, если вы хотите получить расстояние, просматривая таблицу, размер матрицы расстояний в процессе подготовки данных составляет околоO(mnk^* )*4=20G(каждый вектор должен вычислять расстояние от каждого вектора центра в m группах), трудоемкий порядок величины10^{13}

Если он рассчитывается напрямую, сложность такая же, как и у версии SDC без просмотра таблицы.O(Dmk^*), о10^5

Если используется стратегия поиска по таблице, АЦП платит больше памяти в случае более высокой точности.

stronger

IVFADC

ivfadc

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

Грубое квантование + остаточное квантование

Поэтому Маттис предложил в статье процесс грубого квантования + остаточное квантование. В частности, сначала необходимо создать набор данных размеромkk^{'}(Предположим, что значение равно 1000) небольшая кодовая книга\mathcal{C_c}, квантователь обозначается какq_c, поэтому каждый вектор будет иметь невязкуr(y)=y-q_c(y). Исходный вектор может иметь особенно большую разность/дисбаланс распределения, но эту проблему можно значительно облегчить, обработав результаты по остаточному принципу.

Правильно сноваr(y)Используя шаг PQ, посколькуr(y)«Энергия» относительно исходного вектора ниже, поэтому моделирование можно выполнить более точно с помощью шага PQ. Обозначим квантователь шага PQ какq_p, то y проходит черезq_c(y)+q_p(y-q_c(y))Представлять. В этом случае расстояние между двумя векторами x, yd(x,y)можно аппроксимировать как

\ddot{d}(x,y) =d (x,q_c(y) + q_p(y-q_c(y))) = d(x - q_c(y) , q_p(y-q_c(y)))  = \sqrt{\Sigma_jd({u_j(x-q_c(y)),q_{p_j}(u_j(y-q_c(y))))^2}}

Помните размер кодовой книги для остаточного квантования какk_p(Возьмите 64 в качестве примера), если вы хотитеu_j(x-q_c(y))Рассчитано заранее, то есть рассчитано заранее для каждого x и всех центральных векторовc \in \mathcal{C_c}расстояние, а временная сложностьO(DNkk^{'} ), пример в этой статье10^{13}, пространственная сложностьO(Nkk^{'}), пример в этой статье: 20G*4B=80GB.

stronger

структура индекса

С помощью инвертированного индекса можно значительно повысить эффективность поиска.

index_1

используется в диссертацииkk^{'}Перевернутый индекс для хранения приблизительной центральной точкиc_iсписок соответствующих векторов\mathcal{L}_i. Каждый вектор представлен в следующем формате, где id — это идентификатор индекса вектора, а code — это соответствующий список индексов центральной точки PQ. Количество центральных точек для каждой группы в PQ равноk^*, тебе нужно\lceil log_2{k^*} \rceilбит, чтобы указать, какая центральная точка, в общей сложностиm*\lceil log_2{k^*} \rceilбиты

index_2

При поиске вы можетеq_cФункция получает все векторы из соответствующего кластера

процесс индексации

index_3

  1. квантователемq_cвекторyсопоставить сq_c(y)
  2. Рассчитать остаткиr(y) = y-q_c(y)
  3. остатокr(y)количественноq_p(r(y)), который содержит m групп
  4. построитьid|codeзапись и добавить вq_c(y)Соответствующий инвертированный список\mathcal{L}
процесс поиска

query_processing

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

  1. рассчитать\mathcal{C_c}Ближайший к входному параметру xwцентральная точка,O((kk-w)*log{w})
  2. Если центральную точку все еще нужно обработать, удалите центральную точку.c_i, и вычислить соответствующийr(x) = q_p(x-c_i). В противном случае перейдите к шагу 6
  3. рассчитатьr(x)Расстояние от центральной точки в каждой группе,O(m*\frac{D}{m}*k^{*}) = O(Dk^*)
  4. Поскольку соответствующий индекс в том же инвертированном индексеq_c(x)иq_c(y)одинаковы, поэтому расстояние между x и y нужно смотреть только на остаточное расстояниеd(r(x),r(y)). так какr(x)Расстояние до каждой центральной точки было рассчитано, поэтому для каждого вектора нужно просмотреть таблицу только m раз. О (м)
  5. Вернуться к шагу 2
  6. Используйте min-heap, чтобы получить K векторов с наименьшим расстоянием, поскольку ожидаемое количество элементов для каждого инвертированного индекса равно\frac{N}{kk^{'}}, так долгоO((\frac{N}{kk^{'}}-K)*logK)

Длительность всего процесса поиска составляет:O((kk^{'}-w)*log{w}) + w*(O(Dk^*)+O(m))+O((\frac{N}{kk^{'}}-K)*logK)

Экспериментальный эффект

ivfadc_performance

sift_performance

stronger

оптимизация

  1. При остаточном квантовании остатки от разных векторов к их соответствующим центрам объединяются для квантования, что фактически подразумевает предположение, что распределения в разных кластерах одинаковы. Это предположение вносит определенную ошибку, но в противном случае объем памяти будет увеличиваться.kk^{'}раз
  2. Различные группировки векторов могут привести к очень разным результатам. Эксперименты в статье показывают, что по сравнению со случайной группировкой связанные поля должны быть помещены в одну и ту же группу, что может повысить точность в 2-3 раза в некоторых сценариях. Перед индексированием векторы могут быть организованы в подходящем порядке с помощью некоторых методов анализа подобия.
  3. wЕсли для него выбрано значение 1, это приведет к поиску только вектора в текущем кластере, и результат может быть намного хуже, чем SDC. Рекомендация автора в статье – принятьw=8, но в разных сценариях сначала нужно выполнить тесты, чтобы достичь баланса между объемом памяти и потреблением времени.

Суммировать

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

Ключ к упрощению расчета:

  1. Вектор-кандидат сводится к вектору окрестности
  2. Выразительная сила, вызванная квантованием продукта, подскочила:ka \ll (a)^k
  3. Матрица расстояний результата квантования произведения предварительно вычисляется, так что вычисление расстояний становится операцией поиска в таблице. (квантование продукта поддерживает допустимые требования к пространству для матрицы расстояний)

Например: Следующие векторы 12, 13 ![пример_1]Боюсь 1-solve.byte IMG.com/to S-talent-i-he 2…)

Сначала выполните грубый расчет кластеризации на них

example_2

Обнаружено, что их идентификаторы кластеров равны 1

example_3

Затем разделите на три группы, чтобы вычислить остатки

example_4

Квантование продукта остатков

example_5

example_6

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

example_7

d(12,13)=\sqrt{(a_{12})^2+(b_{23})^2+(c_{34})^2}

использованная литература:«Квантование произведения для поиска ближайшего соседа»: Lear.in ria LP ES. положить в /pubs/2011/J…