메서드와 엔진

메서드와 엔진 (Methods and engines)

메서드(method)는 근사 k-NN 검색에서 색인 시 벡터 데이터를 구성하고 검색 시 이를 탐색하는 데 사용되는 알고리즘을 정의해요. OpenSearch는 다음 메서드를 지원해요.

  • HNSW (Hierarchical Navigable Small World): 벡터 사이의 연결로 이루어진 계층적 그래프 구조를 만들어요. 알고리즘에 대한 자세한 내용은 Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs 문서를 참고하세요.
  • IVF (Inverted File Index): 클러스터링을 기반으로 벡터를 버킷으로 구성하고, 검색 중에는 버킷의 일부만 검색해요.

엔진(engine)은 이러한 메서드를 구현하는 라이브러리예요. 서로 다른 엔진이 같은 메서드를 구현할 수 있으며, 때로는 최적화나 특성에 차이가 있어요. 예를 들어 HNSW는 지원되는 모든 엔진으로 구현되며, 각각 고유한 장점을 가져요.

OpenSearch는 다음 엔진을 지원해요.

  • Lucene: 네이티브 검색 라이브러리로, 효율적인 필터링 기능을 갖춘 HNSW 구현을 제공해요.
  • Faiss (Facebook AI Similarity Search): HNSW와 IVF 메서드를 모두 구현하는 포괄적인 라이브러리로, 추가적인 벡터 압축 옵션을 제공해요.
  • NMSLIB (Non-Metric Space Library): HNSW의 레거시 구현이에요(현재 deprecated).
  • JVector: disk_ann 메서드를 사용해 DiskANN 방식 검색을 순수 Java로 구현하며, 동시 삽입, 증분 병합, 네이티브 곱 양자화(PQ)를 지원해요. opensearch-jvector 플러그인을 통해 제공돼요.

출처: 문서

본문

메서드 정의 예시

메서드 정의는 다음 구성 요소를 포함해요.

  • 메서드의 이름(예: hnsw 또는 ivf)
  • 메서드가 빌드되는 space_type(예: l2 또는 cosinesimil)
  • 메서드를 구현할 엔진(예: faiss 또는 lucene)
  • 해당 구현에 특화된 파라미터 맵

다음 예시는 l2 space type, faiss 엔진, 메서드별 파라미터로 hnsw 메서드를 구성해요.

PUT test-index
{
  "settings": {
    "index": {
      "knn": true,
      "knn.algo_param.ef_search": 100
    }
  },
  "mappings": {
    "properties": {
      "my_vector1": {
        "type": "knn_vector",
        "dimension": 1024,
        "method": {
          "name": "hnsw",
          "space_type": "l2",
          "engine": "faiss",
          "parameters": {
            "ef_construction": 128,
            "m": 24
          }
        }
      }
    }
  }
}

모든 메서드/엔진 조합이 각 space를 지원하는 것은 아니에요. 지원되는 space 목록은 특정 엔진의 섹션을 참고하세요.

공통 파라미터 (Common parameters)

다음 파라미터는 모든 메서드 정의에 공통적으로 적용돼요.

매핑 파라미터 필수 기본값 인덱스 생성 후 업데이트 설명
name 예 N/A 아니요 최근접 이웃 메서드예요. 유효 값은 hnsw, ivf, flat, disk_ann이에요. 모든 엔진 조합이 각 메서드를 지원하는 것은 아니에요. 지원 메서드 목록은 특정 엔진 섹션을 참고하세요.
space_type 아니요 l2 아니요 벡터 사이의 거리를 계산하는 데 사용되는 벡터 공간이에요. 유효 값은 l1, l2, linf, cosinesimil, innerproduct, hamming, hammingbit이에요. 모든 메서드/엔진 조합이 각 space를 지원하는 것은 아니에요. 지원 space 목록은 특정 엔진 섹션을 참고하세요. 참고: 이 값은 매핑의 최상위 레벨에서도 지정할 수 있어요. 자세한 내용은 Spaces 문서를 참고하세요.
engine 아니요 faiss 아니요 색인과 검색에 사용할 근사 k-NN 라이브러리예요. 유효 값은 faiss, lucene, nmslib(deprecated), jvector(opensearch-jvector 플러그인 필요)이에요.
parameters 아니요 null 아니요 최근접 이웃 메서드에 사용되는 파라미터예요. 자세한 내용은 특정 엔진 섹션을 참고하세요.

Lucene 엔진

Lucene 엔진은 Lucene 내부에서 벡터 검색을 네이티브로 구현해요. 효율적인 필터링 기능을 제공하며 소규모 배포에 잘 맞아요.

지원 메서드

Lucene 엔진은 다음 메서드를 지원해요.

메서드 이름 훈련 필요 지원 space
hnsw 아니요 l2, cosinesimil, innerproduct(OpenSearch 2.13 이상에서 지원)
flat 아니요 l2, cosinesimil, innerproduct(OpenSearch 3.6 이상에서 지원)

HNSW 파라미터

HNSW 메서드는 다음 파라미터를 지원해요.

파라미터 이름 필수 기본값 인덱스 생성 후 업데이트 설명
ef_construction 아니요 100 아니요 k-NN 그래프 생성 중에 사용되는 동적 목록의 크기예요. 값이 클수록 그래프는 더 정확하지만 색인 속도는 느려져요. 참고: Lucene은 내부적으로 beam_width라는 용어를 사용하지만, 일관성을 위해 OpenSearch 문서에서는 ef_construction을 사용해요.
m 아니요 16 아니요 각 새 요소에 대해 생성되는 양방향 링크의 수예요. 메모리 사용에 큰 영향을 줘요. 2에서 100 사이로 유지하세요. 참고: Lucene은 내부적으로 max_connections라는 용어를 사용하지만, 일관성을 위해 OpenSearch 문서에서는 m을 사용해요.

Lucene HNSW 구현은 ef_search를 무시하고 검색 요청의 "k" 값으로 동적으로 설정해요. 따라서 Lucene 엔진을 사용할 때 ef_search 설정을 구성할 필요가 없어요.

OpenSearch 2.11 이하 버전에서 만든 인덱스는 여전히 이전 ef_construction 값(512)을 사용해요.

예시 구성

"method": {
    "name": "hnsw",
    "engine": "lucene",
    "parameters": {
        "m": 2048,
        "ef_construction": 245
    }
}

Flat 파라미터

flat 메서드는 파라미터를 지원하지 않아요. 자세한 내용은 스칼라 양자화를 사용한 정확한 검색을 참고하세요.

예시 구성

"method": {
    "name": "flat"
}

Faiss 엔진

Faiss 엔진은 메모리 사용과 검색 성능을 최적화하기 위해 여러 메서드와 인코딩 옵션을 지원하는 고급 벡터 색인 기능을 제공해요.

지원 메서드

Faiss 엔진은 다음 메서드를 지원해요.

메서드 이름 훈련 필요 지원 space
hnsw 아니요 l2, innerproduct(PQ 사용 시 사용 불가), hamming, cosinesimil(OpenSearch 2.19 이상에서 지원)
ivf 예 l2, innerproduct, hamming(OpenSearch 2.16 이상에서 binary 벡터에 지원. 자세한 내용은 Binary k-NN vectors 참고), cosinesimil(OpenSearch 2.19 이상에서 지원)

Faiss 엔진에서 cosinesimil을 사용하면 Faiss가 내부적으로 정규화된 벡터에 내적(inner product)을 사용하기 때문에 색인 중에 벡터가 자동으로 단위 길이로 정규화돼요. 결과적으로 저장된 벡터 값은 입력 값과 달라질 수 있어요.

HNSW 파라미터

hnsw 메서드는 다음 파라미터를 지원해요.

파라미터 이름 필수 기본값 인덱스 생성 후 업데이트 설명
ef_search 아니요 100 아니요 k-NN 검색 중에 사용되는 동적 목록의 크기예요. 값이 클수록 더 정확하지만 더 느린 검색을 만들어요. binary 인덱스의 기본값은 256이에요.
ef_construction 아니요 100 아니요 k-NN 그래프 생성 중에 사용되는 동적 목록의 크기예요. 값이 클수록 그래프는 더 정확하지만 색인 속도는 느려져요. binary 인덱스의 기본값은 256이에요.
m 아니요 16 아니요 플러그인이 각 새 요소에 대해 생성하는 양방향 링크의 수예요. 이 값을 늘리거나 줄이면 메모리 사용에 큰 영향을 줄 수 있어요. 2에서 100 사이로 유지하세요.
encoder 아니요 flat 아니요 벡터를 인코딩하기 위한 인코더 정의예요. 인코더는 검색 정확도를 희생하는 대신 인덱스의 메모리 사용량을 줄일 수 있어요.

OpenSearch 2.11 이하 버전에서 만든 인덱스는 여전히 이전 ef_construction 값(512)을 사용해요.

IVF 파라미터

IVF 메서드는 다음 파라미터를 지원해요.

파라미터 이름 필수 기본값 인덱스 생성 후 업데이트 설명
nlist 아니요 4 아니요 벡터를 분할할 버킷의 수예요. 값이 클수록 정확도는 올라갈 수 있지만 메모리와 훈련 지연 시간도 증가해요.
nprobes 아니요 1 아니요 쿼리 중에 검색할 버킷의 수예요. 값이 클수록 더 정확하지만 더 느린 검색을 만들어요.
encoder 아니요 flat 아니요 벡터를 인코딩하기 위한 인코더 정의예요.

이 파라미터들에 대한 자세한 내용은 Faiss 문서를 참고하세요.

IVF 훈련 요구사항

IVF 알고리즘은 훈련 단계가 필요해요. IVF를 사용하는 인덱스를 만들려면 Train API로 모델을 훈련하고 IVF 메서드 정의를 전달해야 해요. IVF는 최소한 nlist 개의 훈련 데이터 포인트가 필요하지만, 그보다 더 많이 사용하는 것을 권장해요. 훈련 데이터는 색인하려는 데이터와 같을 수도 있고 별도의 데이터셋에서 가져올 수도 있어요.

지원 인코더

인코더를 사용해 검색 정확도를 희생하는 대신 벡터 인덱스의 메모리 사용량을 줄일 수 있어요. OpenSearch는 현재 Faiss 라이브러리에서 다음 인코더를 지원해요.

인코더 이름 훈련 필요 설명
flat (기본값) 아니요 벡터를 부동소수점 배열로 인코딩해요. 이 인코딩은 메모리 사용량을 줄이지 않아요.
pq 예 곱 양자화(product quantization)의 약자로, 클러스터링을 사용해 벡터를 고정된 바이트 크기로 인코딩하는 손실 압축 기법이에요. k-NN 검색 정확도의 하락을 최소화하는 것을 목표로 해요. 높은 수준에서, 벡터는 m개의 하위 벡터로 분리되고, 각 하위 벡터는 훈련 중에 생성된 코드북에서 얻은 code_size 코드로 표현돼요. 곱 양자화에 대한 자세한 내용은 관련 블로그 게시물을 참고하세요.
sq 아니요 스칼라 양자화(scalar quantization)의 약자예요. OpenSearch 2.13 버전부터 sq 인코더를 사용해 32비트 부동소수점 벡터를 16비트 float로 양자화할 수 있어요. 2.13 버전에서 내장 sq 인코더는 SQFP16 Faiss 인코더예요. 이 인코더는 최소한의 정밀도 손실로 메모리 사용량을 줄이고, SIMD 최적화(x86 아키텍처에서 AVX2, ARM64 아키텍처에서 Neon)를 사용해 성능을 개선해요. 자세한 내용은 Faiss scalar quantization을 참고하세요.

PQ 파라미터

pq 인코더는 다음 파라미터를 지원해요.

파라미터 이름 필수 기본값 인덱스 생성 후 업데이트 설명
m 아니요 1 아니요 벡터를 분리할 하위 벡터 수를 결정해요. 하위 벡터는 서로 독립적으로 인코딩돼요. 이 벡터 차원은 m으로 나누어 떨어져야 해요. 최댓값은 1,024예요.
code_size 아니요 8 아니요 하위 벡터를 인코딩할 비트 수를 결정해요. 최댓값은 8이에요. ivf의 경우 이 값은 8보다 작거나 같아야 해요. hnsw의 경우 이 값은 8이어야 해요.

hnsw 메서드는 OpenSearch 2.10 이상 버전에서 pq 인코더를 지원해요. hnsw 메서드가 있는 pq 인코더의 code_size 파라미터는 8이어야 해요.

SQ 파라미터

sq 인코더는 다음 파라미터를 지원해요.

파라미터 이름 필수 기본값 인덱스 생성 후 업데이트 설명
type 아니요 fp16 아니요 32비트 float 벡터를 해당 타입으로 인코딩하는 데 사용되는 스칼라 양자화 타입이에요. 16비트 양자화에만 지원돼요. 현재는 fp16 인코더 타입만 지원돼요. fp16 인코더의 경우 벡터 값은 [-65504.0, 65504.0] 범위에 있어야 해요.
clip 아니요 false 아니요 16비트 양자화에만 지원돼요. true면 지정된 벡터 타입의 지원 범위를 벗어나는 벡터 값들은 범위 안에 들어오도록 반올림돼요. false면 벡터 값 중 하나라도 지원 범위를 벗어나면 요청이 거부돼요. clip을 true로 설정하면 재현율이 감소할 수 있어요.
bits 예 1 아니요 각 32비트 부동소수점 벡터 차원을 양자화하는 데 사용되는 비트 수예요. 유효 값은 1과 16이에요. OpenSearch 3.6부터 필수예요.

자세한 내용과 예시는 Faiss 스칼라 양자화 사용을 참고하세요.

SIMD 최적화

2.13 버전부터 OpenSearch는 기본 하드웨어가 SIMD 명령(AVX2 on x64, Neon on ARM64)을 지원한다면 SIMD(Single Instruction Multiple Data) 처리를 지원해요. SIMD는 Linux 머신에서 Faiss 엔진에 대해 기본적으로만 지원돼요. SIMD 아키텍처는 색인 처리량을 개선하고 검색 지연 시간을 줄여 전반적인 성능을 높이는 데 도움이 돼요. 2.18 버전부터 OpenSearch는 x64 아키텍처에서 AVX-512 SIMD 명령을 지원해요. 2.19 버전부터 OpenSearch는 Intel Sapphire Rapids 또는 그 이상 세대 프로세서의 x64 아키텍처에서 고급 AVX-512 SIMD 명령을 지원하며, Hamming 거리 계산 성능을 개선해요.

SIMD 최적화는 벡터 차원이 8의 배수일 때만 적용돼요.

x64 아키텍처

x64 아키텍처의 경우 다음 버전의 Faiss 라이브러리가 빌드되어 아티팩트에 함께 제공돼요.

  • libopensearchknn_faiss_avx512_spr.so: 새 세대 프로세서용 고급 AVX-512 SIMD 명령을 포함하는 Faiss 라이브러리로, AWS 같은 공개 클라우드의 c/m/r 7i 이상 인스턴스에서 사용할 수 있어요.
  • libopensearchknn_faiss_avx512.so: AVX-512 SIMD 명령을 포함하는 Faiss 라이브러리예요.
  • libopensearchknn_faiss_avx2.so: AVX2 SIMD 명령을 포함하는 Faiss 라이브러리예요.
  • libopensearchknn_faiss.so: SIMD 명령이 없는 비최적화 Faiss 라이브러리예요.

Faiss 라이브러리를 사용할 때 성능 순위는 다음과 같아요: 고급 AVX-512 > AVX-512 > AVX2 > 최적화 없음.

  • 하드웨어가 고급 AVX-512(spr)를 지원하면 OpenSearch는 런타임에 libopensearchknn_faiss_avx512_spr.so 라이브러리를 로드해요.
  • 하드웨어가 AVX-512를 지원하면 OpenSearch는 런타임에 libopensearchknn_faiss_avx512.so 라이브러리를 로드해요.
  • 하드웨어가 AVX2를 지원하지만 AVX-512를 지원하지 않으면 OpenSearch는 런타임에 libopensearchknn_faiss_avx2.so 라이브러리를 로드해요.

고급 AVX-512(Sapphire Rapids 또는 그 이상 세대 프로세서용), AVX-512, AVX2 SIMD 명령을 비활성화하고 비최적화 Faiss 라이브러리(libopensearchknn_faiss.so)를 로드하려면 opensearch.yml에서 knn.faiss.avx512_spr.disabled, knn.faiss.avx512.disabled, knn.faiss.avx2.disabled 정적 설정을 true로 지정해요(기본적으로 모두 false로 설정돼요).

정적 설정을 업데이트하려면 클러스터를 중지하고 설정을 변경한 다음 클러스터를 다시 시작해야 해요. 자세한 내용은 Static settings 문서를 참고하세요.

ARM64 아키텍처

ARM64 아키텍처의 경우 하나의 성능 향상 Faiss 라이브러리(libopensearchknn_faiss.so)만 빌드되어 제공돼요. 이 라이브러리는 Neon SIMD 명령을 포함하며 비활성화할 수 없어요.

예시 구성

다음 예시는 인코더를 지정하지 않고 ivf 메서드를 사용해요(기본적으로 OpenSearch는 flat 인코더를 사용해요).

"method": {
  "name":"ivf",
  "engine":"faiss",
  "parameters":{
    "nlist": 4,
    "nprobes": 2
  }
}

다음 예시는 pq 인코더와 함께 ivf 메서드를 사용해요.

"method": {
  "name":"ivf",
  "engine":"faiss",
  "parameters":{
    "encoder":{
      "name":"pq",
      "parameters":{
        "code_size": 8,
        "m": 8
      }
    }
  }
}

다음 예시는 인코더를 지정하지 않고 hnsw 메서드를 사용해요(기본적으로 OpenSearch는 flat 인코더를 사용해요).

"method": {
  "name":"hnsw",
  "engine":"faiss",
  "parameters":{
    "ef_construction": 256,
    "m": 8
  }
}

다음 예시는 클리핑이 비활성화된 16비트 양자화를 사용하는 sq 인코더로 ivf 메서드를 구성하는 방법을 보여줘요.

"method": {
  "name":"ivf",
  "engine":"faiss",
  "parameters":{
    "encoder": {
      "name": "sq",
      "parameters": {
        "bits": 16,
        "clip": false
      }
    },
    "nprobes": 2
  }
}

다음 예시는 1비트 양자화를 사용하는 sq 인코더로 hnsw 메서드를 구성하는 방법을 보여줘요.

"method": {
  "name":"hnsw",
  "engine":"faiss",
  "parameters":{
    "encoder": {
      "name": "sq",
      "parameters": {
        "bits": 1
      }
    },
    "ef_construction": 512,
    "m": 16
  }
}

다음 예시는 클리핑이 활성화된 16비트 양자화를 사용하는 sq 인코더로 hnsw 메서드를 구성하는 방법을 보여줘요.

"method": {
  "name":"hnsw",
  "engine":"faiss",
  "parameters":{
    "encoder": {
      "name": "sq",
      "parameters": {
        "bits": 16,
        "clip": true
      }  
    },    
    "ef_construction": 256,
    "m": 8
  }
}

NMSLIB 엔진 (deprecated)

NMSLIB(Non-Metric Space Library) 엔진은 OpenSearch에서 최초의 벡터 검색 구현 중 하나였어요. 여전히 지원되지만, Faiss와 Lucene 엔진을 위해 deprecated 되었어요.

지원 메서드

NMSLIB 엔진은 다음 메서드를 지원해요.

메서드 이름 훈련 필요 지원 space
hnsw 아니요 l2, innerproduct, cosinesimil, l1, linf

HNSW 파라미터

HNSW 메서드는 다음 파라미터를 지원해요.

파라미터 이름 필수 기본값 인덱스 생성 후 업데이트 설명
ef_construction 아니요 100 아니요 k-NN 그래프 생성 중에 사용되는 동적 목록의 크기예요. 값이 클수록 그래프는 더 정확하지만 색인 속도는 느려져요.
m 아니요 16 아니요 각 새 요소에 대해 생성되는 양방향 링크의 수예요. 메모리 사용에 큰 영향을 줘요. 2에서 100 사이로 유지하세요.

NMSLIB(deprecated)의 경우 ef_search는 인덱스 설정에서 설정돼요.

OpenSearch 2.11 이하 버전에서 만든 인덱스는 여전히 이전 ef_construction 값(512)을 사용해요.

예시 구성

"method": {
    "name": "hnsw",
    "engine": "nmslib",
    "space_type": "l2",
    "parameters": {
        "ef_construction": 100,
        "m": 16
    }
}

JVector 엔진

jvector 엔진은 DiskANN 스타일의 근사 최근접 이웃 검색을 JNI(Java Native Interface) 의존성 없이 순수 Java로 구현해요. 이 엔진은 어떤 OpenSearch 배포에도 포함되지 않으며, opensearch-jvector 플러그인으로 제공돼요. 이 플러그인은 opensearch-knn과 같은 클러스터에는 설치할 수 없어요. 설치 방법은 OpenSearch JVector plugin 문서를 참고하세요.

지원 메서드

jvector 엔진은 다음 메서드를 지원해요.

메서드 이름 훈련 필요 지원 space
disk_ann 아니요 l2, cosinesimil, innerproduct

DiskANN 파라미터

disk_ann 메서드는 다음 파라미터를 지원해요.

파라미터 이름 필수 기본값 인덱스 생성 후 업데이트 설명
m 아니요 16 아니요 노드당 양방향 링크 수예요. 값이 클수록 재현율이 개선되지만 인덱스 크기가 커져요.
ef_construction 아니요 100 아니요 그래프 구성 중에 사용되는 후보 목록의 크기예요. 값이 클수록 재현율이 개선되지만 수집이 느려져요.
advanced.alpha 아니요 1.2 아니요 이웃 선택의 다양성 요인이에요.
advanced.neighbor_overflow 아니요 1.2 아니요 이웃 목록의 오버플로 요인이에요.
advanced.hierarchy_enabled 아니요 false 아니요 계층적 그래프 구조를 활성화할지 여부예요.
advanced.num_pq_subspaces 아니요 벡터 차원에 따라 결정(다음 표 참고) 아니요 PQ 하위 공간의 수예요. 벡터 차원 수를 초과해서는 안 되며, 차원의 약수일 때 가장 잘 작동해요. 값이 클수록 압축은 줄어들지만 재현율이 개선돼요.
advanced.min_batch_size_for_quantization 아니요 1024 아니요 양자화가 훈련되기 전에 필요한 문서 수예요.
advanced.leading_segment_merge_disabled 아니요 false 예 force merge 중에 리딩 세그먼트가 재구성되는 것을 방지할지 여부예요.

각 벡터 차원에 대한 advanced.num_pq_subspaces의 기본값은 다음 표와 같아요.

벡터 차원 기본 PQ 하위 공간 수
384 96
768 192
1536 192
3072 384

Space 타입

space_type 파라미터는 벡터를 비교하는 데 사용되는 거리 메트릭을 결정해요. jvector 엔진이 지원하는 space 타입은 다음 표와 같아요. 자세한 내용은 Spaces 문서를 참고하세요.

Space 타입 거리 메트릭 사용 사례
l2 (기본값) 유클리드 거리 (L2 norm) 원시 좌표에 대한 범용 검색
cosinesimil 코사인 유사도 크기보다 방향이 더 중요한 텍스트 임베딩
innerproduct 내적 (inner product) bi-encoder 모델이 생성한 것처럼 크기가 의미를 갖는 임베딩

예시 구성

"method": {
  "name": "disk_ann",
  "engine": "jvector",
  "space_type": "l2",
  "parameters": {
    "m": 16,
    "ef_construction": 100
  }
}

올바른 메서드와 엔진 선택

knn_vector 필드를 만들 때 선택할 수 있는 옵션이 여러 가지 있어요. 올바른 메서드와 파라미터를 선택하려면 먼저 워크로드의 요구사항과 어떤 트레이드오프를 감수할 의향이 있는지 이해해야 해요. 고려할 요소는 (1) 쿼리 지연 시간, (2) 쿼리 품질, (3) 메모리 제한, (4) 색인 지연 시간이에요.

  • 메모리가 문제가 되지 않는다면 HNSW는 강력한 쿼리 지연 시간/쿼리 품질 트레이드오프를 제공해요.
  • HNSW보다 메모리를 덜 사용하고 색인 속도를 높이면서 비슷한 쿼리 품질을 유지하고 싶다면 IVF를 평가해 보세요.
  • 메모리가 문제라면 HNSW 또는 IVF 인덱스에 PQ 인코더를 추가하는 것을 고려해 보세요. PQ는 손실 인코딩이므로 쿼리 품질이 떨어지게 돼요.
  • 데이터셋이 계속 커지거나 사용 가능한 메모리를 초과한다면 opensearch-jvector 플러그인으로 제공되는 JVector 엔진을 고려해 보세요. 이 엔진은 동시 삽입, 전체 그래프 재구성 없는 증분 병합, 더 높은 압축 비율에서 더 나은 재현율을 가진 네이티브 PQ를 지원해요.
  • fp_16 인코더를 사용하면 검색 품질 손실을 최소화하면서 메모리 사용량을 2배로 줄일 수 있어요. 벡터 차원이 [-128, 127] byte 범위 안에 있다면 byte 양자화기를 사용해 메모리 사용량을 4배로 줄이는 것을 권장해요. 벡터 양자화 옵션에 대해 자세히 알아보려면 k-NN vector quantization을 참고하세요.

엔진 권장사항

일반적으로 대규모 사용 사례에는 Faiss를 선택하세요. Lucene은 소규모 배포에 좋은 선택이며, 상황에 따라 최적의 필터링 전략(사전 필터링, 사후 필터링, 정확한 k-NN)을 자동으로 적용하는 스마트 필터링 같은 이점을 제공해요. 높은 업데이트 워크로드나 메모리 제약이 있는 대규모 배포에는 JVector를 고려하세요. 다음 표는 각 옵션 사이의 차이를 요약해요.

Faiss/HNSW Faiss/IVF Lucene/HNSW JVector/DiskANN
최대 차원 16,000 16,000 16,000 16,000
필터 사후 필터 사후 필터 검색 중 필터 검색 중 필터
훈련 필요 아니요 (PQ는 예) 예 아니요 아니요
유사도 메트릭 l2, innerproduct, cosinesimil l2, innerproduct, cosinesimil l2, cosinesimil l2, cosinesimil, innerproduct
벡터 수 수백억 개 수백억 개 1천만 개 미만 수십억 개
색인 지연 시간 낮음 가장 낮음 낮음 낮음 (동시 삽입)
쿼리 지연 시간과 품질 낮은 지연·높은 품질 낮은 지연·낮은 품질 높은 지연·높은 품질 낮은 지연·높은 품질
벡터 압축 Flat, PQ Flat, PQ Flat Flat, PQ (네이티브, 훈련 불필요)
메모리 사용 높음, PQ로 낮음 중간, PQ로 낮음 높음 낮음 (DiskANN), PQ로 매우 낮음
플러그인 필요 아니요 아니요 아니요 예 (opensearch-jvector)

메모리 추정 (Memory estimation)

일반적인 OpenSearch 클러스터에서는 RAM의 일정 부분이 JVM 힙에 예약돼요. OpenSearch는 네이티브 라이브러리 인덱스를 나머지 RAM의 일부에 할당해요. 이 부분의 크기는 circuit_breaker_limit 클러스터 설정에 의해 결정돼요. 기본적으로 제한은 50%로 설정돼요.

  • 복제본(replica)을 사용하면 총 벡터 수가 두 배가 돼요.
  • 벡터 양자화와 함께 메모리 추정을 사용하는 방법은 Vector quantization 문서를 참고하세요.

HNSW 메모리 추정

HNSW에 필요한 메모리는 1.1 * (4 * dimension + 8 * m) bytes/vector로 추정돼요.

예를 들어 차원이 256이고 m이 16인 벡터 100만 개가 있다고 가정해요. 메모리 요구량은 다음과 같이 추정할 수 있어요.

1.1 * (4 * 256 + 8 * 16) * 1,000,000 ~= 1.267 GB

IVF 메모리 추정

IVF에 필요한 메모리는 1.1 * (((4 * dimension) * num_vectors) + (4 * nlist * d)) bytes로 추정돼요.

예를 들어 차원이 256이고 nlist가 128인 벡터 100만 개가 있다고 가정해요. 메모리 요구량은 다음과 같이 추정할 수 있어요.

1.1 * (((4 * 256) * 1,000,000) + (4 * 128 * 256))  ~= 1.126 GB

다음 단계 (Next steps)

  • 성능 튜닝
  • 벡터 저장소 최적화
  • 벡터 양자화

더 알아보기 (Learn more)