> For the complete documentation index, see [llms.txt](https://sliu583.gitbook.io/blog/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sliu583.gitbook.io/blog/specific-work/shivarams-group/embeddings/billion-scale-approximate-nearest-neighbor-search.md).

# Billion-scale Approximate Nearest Neighbor Search

## Recorded video&#x20;

{% embed url="<https://matsui528.github.io/cvpr2020_tutorial_retrieval/>" %}

## Nearest Neighbor Search: NN&#x20;

* N D-dim database vectors&#x20;
* Given a query q, find the closest vector from the database&#x20;
* Solution: linear scan, O(ND), slow&#x20;
* Should try this first of all&#x20;

![Problem setting ](/files/-MbdAJNyQ0dU7-BA6PHF)

#### Naive implementation&#x20;

![](/files/-MbdAQPikFrscIllX4NO)

#### Faiss implementation&#x20;

![](/files/-MbdAfB4mgkEZBGwKN_-)

* M = number of query vectors&#x20;
* SIMD (Single-Instruction Multiple Data)&#x20;
  * also known as vectorization
* BLAS (Basic Linear Algebra Subprograms)&#x20;

1. SIMD&#x20;

![](/files/-MbdC67xUOxnGUvnQclJ)

![](/files/-MbdCD2s2P46vcY3yGE5)

Then go into the d >= 4 and d > 0 and the end of the function&#x20;

![](/files/-MbdD9_BC25YUtrmeUnz)

* SIMD codes of faiss are simple and easy to read&#x20;
* Being able to read SIMD codes comes in handy sometimes; why this impl is super fast&#x20;

2\. BLAS&#x20;

![](/files/-MbdDLTXnJ1cOmDOE3NZ)

* Norm: Euclidean norm

![](/files/-MbdDpvlanh3bw8e3XwC)

* k-means: one of the benchmarks for KNN&#x20;
* Faster if using multiple GPU

Some useful reference&#x20;

![](/files/-MbdE5WzwAoGCH-4tMvX)

## Approximate Nearest Neighbor Search: ANN&#x20;

* Faster search&#x20;
* Trade-off: runtime, accuracy, and memory consumption&#x20;
* A sense of scale: billion-scale data on memory&#x20;

![](/files/-Mbd9GTMdfPEJUg28SnR)

#### Application&#x20;

* NN/ANN for CV&#x20;
  * Image retrieval&#x20;
  * Person re-identification&#x20;
  * Clustering&#x20;
  * kNN recognition&#x20;
* Fast construction of bag-of-features
* One of the benchmarks is still SIFT&#x20;

![](/files/-MbdEIxgWl3meUxIK5gK)

### Locality Sensitive Hashing (LSH)

![](/files/-MbdElzXjrbbtOpKn9ZP)

Hash function that we use, generally speaking:&#x20;

![](/files/-MbdFCaJbtuEsKegglYH)

Good sides:

* Math-friendly&#x20;
* Popular in the theory area (FOCS, STOC, ...)

Bad sides:

* Large memory cost&#x20;
  * Need several tables to boost the accuracy&#x20;
  * Need to store the original data (# = N) on memory&#x20;
* Data-dependent methods such as PQ are better for real-world data&#x20;
* Thus, in recent CV papers, LSH has been treated as a classic method&#x20;

![](/files/-MbdFgYcKzIbRNOviBwK)

#### Falconn&#x20;

![](/files/-MbdG-gIUAQwY5RK6PBV)

### Tree / Space Partitioning&#x20;

#### FLANN&#x20;

![](/files/-MbdGOwkOL7a7pOESiXE)

#### Annoy&#x20;

![](/files/-MbdGct7bGTsCAf3hJaJ)

![](/files/-MbdGuMXT1GROV7BxqsX)

![](/files/-MbdH0YdsrNZ-cr9IS0v)

### Graph Traversal&#x20;

* **Very popular** in recent years&#x20;
* Around 2017, it turned out that the graph-traversal-based methods work well for million-scale data&#x20;
* Pioneer&#x20;
  * Navigable Small World Graphs (NSW)
  * Hierarchical NSW (HNSW)&#x20;
* Implementation: nmslib, hnsw, faiss&#x20;

#### Record Phase&#x20;

![](/files/-MbdHpgqiw0SsdsaqlTh)

* Early links can be long
  * In the early phase, there are not many vectors&#x20;
* Such long links encourage a large hop, making the fast convergence for search&#x20;

#### Search Phase&#x20;

Task: find the similar node for the query node&#x20;

![](/files/-MbdIL_LsiEtY-u1lzWq)

* Then, traverse in a greedy manner&#x20;

#### Extension: Hierarchical NSW; HNSW&#x20;

![](/files/-MbdI_4z_0fIk2GWO9b0)

* Sub-sample from bottom to the top&#x20;

#### NMSLIB (Non-Metric Space Library)

![](/files/-MbdIoxbCRyUdk_rN1n3)

#### Other implementation of HNSW

* Hnswlib&#x20;
  * Spin-off library from nmslib
  * Include only hnsw&#x20;
  * Simpler; may be useful if you want to extend hnsw&#x20;
* Faiss&#x20;
  * Libraries for PQ-based methods&#x20;
  * This lib also include hnsw&#x20;

#### Other graph-based approaches&#x20;

![](/files/-MbdJAU1VMPRTNLPVQtr)

### Compressed data&#x20;

#### Basic idea&#x20;

![](/files/-MbdJg50k1f7AVvHJ-fu)

![](/files/-MbdJzChdScWam2BqVN8)

![](/files/-MbdK9UVdhfbpbBIlnzT)

#### Product Quantization: PQ&#x20;

![](/files/-MbdKM1uQRqeXKduETon)

* Split the vector into three parts&#x20;
* For this first 2-D vector, find the closest in this codebook
* Then, record the ID&#x20;

![](/files/-MbdKqfeHghxeZ4nR-6q)

![](/files/-MbdKuKuyTEzrFVrxWOF)

1. Memory Efficient&#x20;

![](/files/-MbdLOUsxbSMnRX7UJRd)

2\. Distance Estimation&#x20;

* First, apply product quantization on the database&#x20;
* Then, get the PQ code&#x20;

![](/files/-MbdLiK7VyCFBeBnpnHA)

![](/files/-MbdLkaYH6rrkUp9KF5O)

![](/files/-MbdLxthUlG-TaxfourW)

![](/files/-MbdMEoJU2Pq84G71JhQ)

#### Deep PQ&#x20;

![](/files/-MbdMTPocZPMCVeScAJH)

![](/files/-MbdMWhjBZlQct1HuOUU)

#### Hamming-based v.s Lookup-based&#x20;

![](/files/-MbdM_oM1h3l-RjQBsq7)

### Billion-scale&#x20;

![](/files/-MbdMlmqnkqWyCY_7Oh-)

#### Inverted Index + PQ: Record&#x20;

![](/files/-MbdN-2LjOkVyJUuRycj)

![](/files/-MbdNQkUnOM7M0I0nJ2d)

![](/files/-MbdNZM50OqPuVmJlmMX)

#### Inverted Index + PQ: Search&#x20;

![](/files/-MbdNk_mHCxZ1UYywY1N)

#### Faiss&#x20;

![](/files/-MbdO4ZvaeIW-GEVg3zq)

![](/files/-MbdOAF5mR9JyST1Rn_O)

#### Graph Traversal

![](/files/-MbdOXJgA5VMrRJ50WSZ)

![](/files/-MbdOqVExoFl6YknO1NK)

## Cheat sheet of choosing index &#x20;

![](/files/-Mbd9qSKQ8ZTC9NK_avC)

### Benchmark&#x20;

![](/files/-MbdQ-OJ8xPEhiVfmnpn)

![](/files/-MbdQ6zSyUqj-_XZqdaZ)

![](/files/-MbdQCfhloHY9UwveMmg)

### Nearest neighbor search engine

![](/files/-MbdQTD1sRoCxFHDZoHK)

### Problems of ANN&#x20;

![](/files/-MbdQZJRY_5bGBgpvnLU)
