[Elasticsearch] ๋ฒกํฐ ๊ฒ์ (kNN, Vector Search)
๊ด๋ จ ํฌ์คํธ
https://blog.naver.com/sssang97/223790220320
Elasticsearch๋ ๋ฒกํฐ ๊ฒ์์ ์ง์ํ๋ ๋ํ์ ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค ํ๋๋ค.
์ฌ์ค ์๋ ์ฃผ ๋ชฉ์ ์ ํ
์คํธ ๊ฒ์์ด๊ธด ํ๋ฐ, ์ด์ฉ๋ค๋ณด๋ Vector search ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก๋ ์ด๋ฆ์ ๊ฝค ๋ ๋ฆฌ๊ฒ ๋์๋ค.
๋ฒกํฐ๊ฒ์์ Elasticsearch 8.0๋ถํฐ ์ง์๋๋ค.
๋ฒค์น๋งํฌ ๊ธฐ์ค์ผ๋ก ๋ณด๋ฉด ์ ๋ฌธ Vector Database๋ค์ ๋นํด์๋ ์ฒ๋ฆฌ๋์ด๋ ๊ธฐ๋ณธ ์ฑ๋ฅ์ด ๋ถ์กฑํ ๋ถ๋ถ์ด ์๊ธด ํ์ง๋ง, ๋น์ ๋ฌธ Vector Database ์ค์์๋ ๊ฐ์ฅ ๋ฐ์ด๋๋ค๋๊ฒ ์ผ๋ฐ์ ์ธ ์ธ์์ธ ๊ฒ ๊ฐ๋ค.
kNN (k-nearest neighor)์ HNSW
Elasticsearch๋ k-nearest neighor์ด๋ผ๋ ์๊ณ ๋ฆฌ์ฆ์ ๊ธฐ๋ฐํด์ ๋ฒกํฐ ๊ฒ์์ ์ง์ํ๋ค.
์๊ณ ๋ฆฌ์ฆ ์์ฒด๋ ๊ต์ฅํ ์ค๋๋ ๋
์์ด๋ค. 1951๋
์ ์ฒ์ ๊ณ ์๋์๋ค.
https://www.ibm.com/kr-ko/think/topics/knn
๊ธฐ๋ณธ์ ์ธ ๊ฐ๋
์์ฒด๋ ๋จ์ํ๋ค.
ํน์ ์์น์์ ๊ฐ์ฅ ๊ฐ๊น์ด ์ด์ 3๊ฐ๊ฐ ํ์ํ๋ค๊ณ ํ๋ฉด, ์ ํด๋ฆฌ๋ ๊ฑฐ๋ฆฌ ๊ธฐ๋ฐ์ผ๋ก ์กฐํ๋ฅผ ํ๋ ๊ฒ์ด๋ค.
๋ฌผ๋ก elasticsearch์ knn์ ์ ํด๋ฆฌ๋ ๊ฑฐ๋ฆฌ ์ธ์๋ ์ฝ์ฌ์ธ๊ณผ dot product๋ฅผ ์ง์ํ๊ธฐ ๋๋ฌธ์, ์์ํ kNN์ด๋ผ๊ณ ํ๊ธฐ๋ ์ด๋ ค์ธ ์๋ ์์ ๊ฒ ๊ฐ๋ค.
์๋ฌดํผ ์ด๊ฑด ๊ฐ๋ ์ ์ธ ์ฉ์ด์ผ ๋ฟ์ด๊ณ , ์ค์ ์ธ๋ฑ์ค ๊ตฌํ์ HNSW ๋ฐฉ๋ฒ๋ก ์ ํตํด ๋ง๋ค์ด์ ธ์๋ค.
๊ทธ๋ผ ๋๊ฐ ์ฌ์ฉํด๋ณด๋ฉด์ ๊ทธ ๊ตฌ์กฐ๋ฅผ ์ง์ด๋ณด๊ฒ ๋ค.
์ธ๋ฑ์ค ์์ฑ
๋ฒกํฐ ๊ฒ์์ฉ ์ธ๋ฑ์ค๋ฅผ ๋ง๋๋ ๊ฒ์ ๊ทธ๋ฆฌ ์ด๋ ต์ง ์๋ค.
###
PUT http://{{HOST}}:{{PORT}}/vector_index
Content-Type: application/json
{
"settings": {},
"mappings": {
"properties": {
"vector": {
"type": "dense_vector",
"dims": 256,
"index": true,
"similarity": "dot_product"
}
}
}
}
###
ํ์
์ "dense_vector"๋ก ๋๊ณ , ๋ฒกํฐ์ ๊ธธ์ด("dims"), ์ ์ฌ๋ ๋ฐฉ๋ฒ์ ์ ํด์ฃผ๋ฉด ๋๋ ๊ฒ์ด๋ค.
์ ๋ฌ๋ฉด 256 ๋ฒกํฐ์ ๋ํด์ dot product ์ ์ฌ๋ ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ๋ ๋ฒกํฐ๊ฐ ์์ฑ๋๋ค.
์ ์ฌ๋ ์๊ณ ๋ฆฌ์ฆ
๋ฐฉ๊ธ ์ ๊ธฐ์๋ dot product๋ฅผ ์ฌ์ฉํ๋๋ฐ, 3๊ฐ์ง์ ๊ธฐ๋ณธ์ ์ธ ์ ์ฌ๋ ์๊ณ ๋ฆฌ์ฆ์ ์ง์ํ๋ค.
- l2_norm - ์ ํด๋ฆฌ๋ ๊ฑฐ๋ฆฌ
- cosine - ์ฝ์ฌ์ธ ์ ์ฌ๋
- dot_product - dot product
์ ๋ชจ๋ฅธ๋ค๋ฉด, ๊ฐ๊ฐ์ ๋ํด์๋ ๋ณ๋ ๋ฌธ์๋ฅผ ์ฐธ์กฐํ๋ ๊ฒ์ ๊ถํ๋ค.
https://blog.naver.com/sssang97/223790220320
HNSW ์ธ๋ฑ์ค ์ต์
Elasticsearch์ ๋ฒกํฐ ๊ตฌํ ๋ฐฉ๋ฒ๋ก ์ HNSW ๋ฟ์ด์ง๋ง, ์ฑ๋ฅ ์๊ตฌ์ฌํญ์ด๋ ์ฌ์ฉ์ฌ๋ก์ ๋ฐ๋ผ์ ์ถ๊ฐ ์กฐ์ ์ ํ ๋ถ๋ถ์ ์๋ค.
์ด๋ฐ ์์ผ๋ก ํ์
์ด๋ ๋
ธ๋์ ๊ฐ์ ๋ฑ์ ๋ฏธ์ธ์กฐ์ ํ ์ ์๋ค.
"type"์ ์ด๋ฐ ๊ฒ๋ค์ด ์๋ค.
- hnsw
- int8_hnsw - ๊ธฐ๋ณธ๊ฐ. ์ ํ๋๋ฅผ ํฌ์ํด์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ 4๋ฐฐ๊น์ง ์ค์
- int4_hnsw - ์ ํ๋๋ฅผ ํฌ์ํด์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ 8๋ฐฐ๊น์ง ์ค์
- bbq_hnsw - ์ ํ๋๋ฅผ ํฌ์ํด์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ 32๋ฐฐ๊น์ง ์ค์
- flat
- int8_flat
- int4_flat
- bbq_flat
flat์ด ๋ถ๋ ๋
์์ ๋จ์๋ฌด์ํ๊ฒ ์ ํํ kNN ๊ฒ์์ ์ํํ๋ ๊ฑฐ๋ผ์, ์ค์ฐจ๊ฐ ์๋ ๋์ ๋งค์ฐ ๋๋ฆฌ๊ฑฐ๋ ๋ฆฌ์์ค๋ฅผ ๊ณผ๋คํ๊ฒ ์๋ชจํ ์ ์๋ค.
hnsw์ด ์ค์ฐจ๊ฐ ์๋ ๋์ ์ฑ๋ฅ์ ๋ณด์ฅํ ์ ์๋ ANN ์ธ๋ฑ์ค ์ค์ ์ด๋ผ์, ๋๊ฐ๋ ์ด๊ฒ๋ค์ ๊ธฐ๋ณธ์ผ๋ก ๊ณ ๋ คํ๋ ๊ฒ์ด ๋ง๋ค.
"m"์ HNSW ๊ทธ๋ํ ๊ตฌ์กฐ์์ ๋
ธ๋๊ฐ ๋ช๊ฐ์ ์ด์๊ณผ ์ฐ๊ฒฐ๋๋์ง๋ฅผ ์ ์ํ๋ค.
์ด๊ฑธ ๋๋ฆฌ๋ฉด ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ๋์ด๋๋ ๋์ ์ ํ๋๊ฐ ํฅ์๋๋ค. ๊ธฐ๋ณธ๊ฐ์ 16์ด๋ค.
"ef_construction"์ ๋ ธ๋๋ฅผ ๊ตฌ์ฑํ ๋ ํ์งํ๋ ํ๋ณด์ ๊ฐ์๋ค. ์ด๊ฒ ์ปค์ง๋ฉด ์ธ๋ฑ์ค ๊ตฌ์ฑ ์๊ฐ์ด ๋๋ ๋์ ์ ์ ํ๋๊ฐ ํฅ์๋๋ค. ๊ธฐ๋ณธ๊ฐ์ 100์ด๋ค.
๋ณดํต ์ต์ ํ๋ฅผ ํ ๋๋ type์ด๋ "ef_construction"๋ ์ ๊ฑด๋๋ฆฌ์ง ์๊ณ , ์ต์ "m"์ ์ ์ ํ ์กฐ์ ํ๊ณ ์ฟผ๋ฆฌํ ๋ ํ๋ณด ์๋ฅผ ์ ์ ํ ์ฃผ๋ ๊ฒ์ ์ฃผ์์ ์ ์ฃผ๊ฒ ๋๋ค.
๋ฐ์ดํฐ ๋ฃ๊ณ ๊ฒ์ํด๋ณด๊ธฐ
๋ฐ์ดํฐ๋ฅผ ์ฝ์
ํ๋ ๊ฒ์ ๊ธฐ์กด ์ธ๋ฑ์ค์ ๋ณ๋ก ๋ค๋ฅด์ง ์๋ค.
dot product์ด๋ ์ผ๋ฐํ๋ ๋ฒกํฐ ๋ฐฐ์ด๋ก ๋ฃ์ด์ฃผ๊ธฐ๋ง ํ๋ฉด ๋๋ค.


๊ฒ์์ ํ ๋๋ ๊ธฐ์กด ์ธ๋ฑ์ค์ ์ข ๋ค๋ฅด๋ค.
knn ์ต์
์ ํตํด ๊ฒ์ ์์ฒญ์ ์ ์ํ๋๋ฐ

์ด๋ฐ ์์ผ๋ก ๊ฐ์ ธ์ฌ ๊ฐ์(k)๊ณผ, ๊ณ ๋ คํ ํ๋ณด๊ตฐ(num_candicaties)๋ฅผ ์ง์ ํด์ค์ผ ํ๋ค.
์ฌ๊ธฐ์๋ ์ฌ์ค num_candidates๊ฐ ์ข ํต์ฌ์ด์๋ค.
Elasticsearch๋ ์๋ค์ํผ ๋ฉํฐ ์ค๋๋ก ๊ตฌ์ฑ๋ ์ ์๋ ๋ถ์ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ค.
์ค๋๊ฐ 2๊ฐ ์๊ณ , ์ค๋๋น ๊ฐ๊ฐ ์ฝ 1000๊ฐ์ ๋ฐ์ดํฐ๊ฐ ๋ถ์ฐ๋์ด์๋ค๊ณ ๊ฐ์ ํด๋ณด์.
๊ทธ๋ฌ๋ฉด ์ด ๊ฒฝ์ฐ์ ์ด๋ค ์์ผ๋ก ๊ฐ์ฅ ์ ์ฌ๋๊ฐ ๋์ 2๊ฐ๋ง ๊ฐ์ ธ์ฌ ์ ์์๊น?
๋ฌํํ๊ฒ ์๊ฐํ๋ค๋ฉด, ์ค๋๋ง๋ค ์ ์ฌ๋๊ฐ ๋์ 2๊ฐ๋ฅผ ๊ฐ์ ธ์จ ๋ค์์, ๊ทธ๊ฑธ ๋ชจ์์ 4๊ฐ ์ค์์ ๋ค์ 2๊ฐ๋ฅผ ์ ๋ณํ๋ ์์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ ๊ฒ์ด๋ค.
๊ทผ๋ฐ ์ค๋๋ง๋ค 2๊ฐ๋ฅผ ์ ํํ๊ธฐ ์ ์, ํ๋ณด๊ตฐ์ ๋๋ต์ ์ผ๋ก ์ถ๋ฆฌ๋ ์์
์ด ์ ์ฒ๋ฆฌ๋ก ๋ค์ด๊ฐ๋ค. ์ฌ๊ธฐ์ ๊ด์ฌํ๋ ๊ฒ์ด num_candidates๋ค.
https://www.elastic.co/search-labs/blog/vector-search-set-up-elasticsearch
num_candicaties์ด 100์ด๋ผ๊ณ ํ๋ฉด, ๊ฐ ์ค๋๋ง๋ค ๊ทผ์ฌํ ๋ญํน ๊ธฐ๋ฐ์ผ๋ก 100๊ฐ๋ฅผ ํ๋ณด๊ตฐ์ผ๋ก ์ถ๋ฆฐ ๋ค์์, ๊ฑฐ๊ธฐ์ ์ค๋๋ณ๋ก ์ ์ฌ๋๊ฐ ๋์ 2๊ฐ๋ฅผ ์กฐํํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ฝ๋๋ค์ดํฐ๊ฐ ์ต์ข
์ ์ธ 2๊ฐ๋ฅผ ๋ฝ์์ ๋ฐํํ๋ ๊ฒ์ด๋ค.
num_candicaties ๊ฐ์ด ๋์์๋ก ํ๋ณด๊ตฐ์ ๋ฒ์๊ฐ ๋์ด์ง๊ธฐ ๋๋ฌธ์ ์ค์ฐจ ๋ฐ์ ํ๋ฅ ์ด ๋จ์ด์ง๋ค๋ ์ฅ์ ์ด ์๋ค. ๋น์ฐํ ๋์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด๋ ๋ฆฌ์์ค ์๋ชจ๊ฐ ๋์ด๋๋ค.
ํ์ง๋ง ์ผ๋ฐ์ ์ธ ๋ฒค์น๋งํฌ์ ์ํ๋ฉด num_candicaties ์ฆ๊ฐ๋ก ์ธํ ๋ฆฌ์์ค ์๋ชจ๋ ๋๋น ์ ํ๋ ์ฆ๊ฐ๋ ๋ฑํ.. ๋์ ๋๋ ์ ๋๋ ์๋๋ผ๊ณ ํ๋ค. ํต์์ ์ผ๋ก k์ ๊ฐ๊ฑฐ๋ 2๋ฐฐ ์ ๋๋ก ์ก๋๊ฒ ์์์ ์ธ ๊ฒ ๊ฐ๋ค.
๊ทธ๋ฆฌ๊ณ k์ num_candicaties ์ต์
์ ๋น๊ต์ ์ต๊ทผ ๋ฒ์ ์ธ Elasticsearch 8.12๋ถํฐ๋ optional ๊ฐ์ผ๋ก ๋ฐ๋์๋ค.
๋ฌธ์์๋ ๋์ถฉ ์จ๋จ๋๋ฐ, num_candicaties๋ฅผ ๋ฏธ์ค์ ํ ๊ฒฝ์ฐ์๋ k*1.5 ๊ฐ์ผ๋ก ์ฒ๋ฆฌ๋๋ค.

์ฐธ์กฐ
https://www.elastic.co/guide/en/elasticsearch/reference/current/dense-vector.html
https://www.elastic.co/search-labs/blog/vector-similarity-techniques-and-scoring
https://danawalab.github.io/elastic/2022/07/08/ES-Similarity-Search.html
https://www.elastic.co/docs/solutions/search/vector/knn
https://www.ibm.com/think/topics/knn
https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm
https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/dense-vector
https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/dense-vector
https://www.elastic.co/search-labs/blog/elasticsearch-knn-and-num-candidates-strategies
https://www.elastic.co/search-labs/blog/vector-search-set-up-elasticsearch
https://www.elastic.co/search-labs/blog/simplifying-knn-search
https://github.com/elastic/elasticsearch/pull/101209/files