정의:

  • dense_vector 필드 타입은 숫자 값의 밀집 벡터를 저장합니다.
  • 주로 k-최근접 이웃(k-nearest neighbor, kNN) 검색에 사용됩니다.

 

제한사항:

  • 이 필드 타입은 집계(aggregations)나 정렬(sorting)을 지원하지 않습니다.

 

구조:

  • 숫자 값의 배열로 저장됩니다.
  • 기본적으로 float 타입의 element_type을 사용합니다.

 

매핑 예시:

"my_vector": {
  "type": "dense_vector",
  "dims": 3
}
  • "dims": 3은 이 벡터가 3차원임을 나타냅니다.

 

사용 예시: 인덱스 생성 및 매핑 정의

PUT my-index
{
  "mappings": {
    "properties": {
      "my_vector": {
        "type": "dense_vector",
        "dims": 3
      },
      "my_text" : {
        "type" : "keyword"
      }
    }
  }
}

 

 

문서 추가:

PUT my-index/_doc/1
{
  "my_text" : "text1",
  "my_vector" : [0.5, 10, 6]
}

PUT my-index/_doc/2
{
  "my_text" : "text2",
  "my_vector" : [-0.5, 10, 10]
}

 

 

주의사항:

  • 벡터의 차원 수(dims)는 매핑 시 명시적으로 정의해야 하며, 문서마다 일관된 차원 수를 유지해야 합니다.

 

 

Index vectors for kNN search

kNN 검색 정의:

  • 쿼리 벡터와 가장 유사한 k개의 벡터를 찾는 검색 방법입니다.

 

Dense vector 필드의 사용:

  • script_score 쿼리에서 문서 랭킹에 사용될 수 있습니다. (script_score 쿼리는 검색된 문서에서 커스텀 점수를 제공할 수 있는 쿼리임)
  • 모든 문서를 스캔하는 브루트 포스 kNN 검색이 가능합니다.

 

효율적인 kNN 검색:

  • 브루트 포스 방식은 비효율적일 수 있어, 특수한 데이터 구조로 벡터를 인덱싱합니다.
  • search API의 knn 옵션을 통해 빠른 kNN 검색을 지원합니다.

 

동적 매핑:

  • 128에서 4096 사이의 크기를 가진 float 배열은 자동으로 dense_vector로 매핑됩니다.
  • 기본 유사도 메트릭은 코사인 유사도입니다

 

인덱싱 비용:

  • 벡터 인덱싱은 비용이 많이 드는 작업입니다.
  • 인덱싱이 활성화된 벡터 필드가 있는 문서의 색인 생성에 상당한 시간이 걸릴 수 있습니다.

 

인덱싱 설정:

  • 기본적으로 int8_hnsw로 인덱싱됩니다.
  • 유사도 메트릭을 지정할 수 있습니다 (예: dot_product).
PUT my-index-2
{
  "mappings": {
    "properties": {
      "my_vector": {
        "type": "dense_vector",
        "dims": 3,
        "similarity": "dot_product"
      }
    }
  }
}

 

 

인덱싱 비활성화:

  • index 파라미터를 false로 설정하여 인덱싱을 비활성화할 수 있습니다.
PUT my-index-2
{
  "mappings": {
    "properties": {
      "my_vector": {
        "type": "dense_vector",
        "dims": 3,
        "index": false
      }
    }
  }
}

 

 

HNSW 알고리즘:

  • Elasticsearch는 효율적인 kNN 검색을 위해 HNSW(Hierarchical Navigable Small World) 알고리즘을 사용합니다.
  • 이는 근사 방법으로, 결과의 정확성을 일부 희생하여 검색 속도를 향상시킵니다.

 

 

Automatically quantize vectors for kNN search

자동 벡터 양자화의 목적:

  • float 벡터를 검색할 때 필요한 메모리 사용량을 줄이기 위해 사용됩니다.
  • 원래는 dense vector 에서 각 벡터당 float 이니까 4바이트 씀. 여기서는 int8_hnsw 를 써서 1바이트로 줄인거고

 

지원되는 양자화 방법:

  • 현재는 int8 양자화만 지원됩니다.
  • 입력 벡터의 element_type은 반드시 float이어야 합니다.

 

int8_hnsw 인덱스의 특징:

  • 각 float 벡터의 차원을 1바이트 정수로 양자화합니다.
  • 메모리 사용량을 최대 75%까지 줄일 수 있습니다.
  • 정확도가 약간 감소할 수 있습니다.
  • 디스크 사용량은 양자화된 벡터와 원본 벡터를 모두 저장하기 때문에 25% 정도 증가할 수 있습니다.

예시:

PUT my-byte-quantized-index
{
  "mappings": {
    "properties": {
      "my_vector": {
        "type": "dense_vector",
        "dims": 3,
        "index": true,
        "index_options": {
          "type": "int8_hnsw"
        }
      }
    }
  }
}

 

 

References:

+ Recent posts