빠른 속도 대 정확도: 양자화된 벡터 검색의 리콜 측정하기

최소한의 설정으로 Elasticsearch에서 벡터 검색의 리콜을 측정하는 방법을 설명합니다.

모두가 벡터 검색이 즉각적으로 이루어지기를 원합니다. 하지만 고차원 벡터는 무겁습니다. 단일 1,024차원 float-32 벡터는 상당한 메모리를 차지하며, 이를 수백만 개의 다른 벡터와 비교하는 것은 계산상 비용이 많이 듭니다.

이를 해결하기 위해 Elasticsearch와 같은 검색 엔진은 두 가지 주요 최적화 전략을 사용합니다.

  1. 근사 검색(계층적 탐색 가능 스몰 월드 [HNSW]): 모든 문서를 스캔하는 대신, 답이 있을 가능성이 높은 근처로 빠르게 이동할 수 있는 탐색 그래프를 구축합니다.
  2. 양자화: 메모리 사용량을 줄이고 계산 속도를 높이기 위해 벡터를 압축합니다(예: 32비트 부동소수점에서 8비트 정수 또는 1비트 이진 값으로).

하지만 최적화에는 정확성이라는 대가가 따르는 경우가 많습니다.

"만약 데이터를 압축하고 검색 중에 지름길을 택한다면 최상의 결과를 놓치게 될까요?" 혹은 "이러한 최적화가 검색 엔진의 관련성을 저하시킬까요?"라는 두려움이 당연히 생길 수 있습니다.

Elastic의 정량화가 결과를 저하시키지 않는다는 것을 증명하기 위해, DBPedia-14 데이터 세트를 사용해 반복 가능한 테스트 하네스를 구축하여 Elasticsearch에서 기본 최적화를 사용할 때 속도와 얼마나 많은 정확도(특히, 리콜)를 교환하는지 정확히 계산했습니다.

tldr: 생각보다 훨씬 적을 가능성이 높습니다. 여기에서 노트북을 확인하고 직접 사용해 보세요.

정의(비전문가를 위한)

코드를 살펴보기 전에 먼저 몇 가지 용어를 정리해 보겠습니다.

  • 정확도 대 리콜: 정확도는 주관적입니다(좋은 것을 찾았는가?). 리콜은 수학적입니다. 데이터베이스에 검색어와 수학적으로 완벽하게 일치하는 문서가 10개 있고 검색 엔진이 그 중 9개를 찾았다면 리콜 확률은 90%(또는 0.9)입니다.
  • 정확한 검색(평면 검색): 때때로 "무차별 대입" 방법이라고도 합니다. 검색 엔진은 색인에 있는 모든 문서를 스캔하여 거리를 계산합니다.
    • 장점: 리콜이 100% 완벽합니다.
    • 단점: 계산 비용이 높고 규모가 커질수록 느려집니다.
  • 근사 검색(HNSW): "지름길" 방식입니다. 검색 엔진이 HNSW 그래프를 구축합니다. 그래프를 탐색하여 최근접 이웃을 찾습니다.
    • 장점: 매우 빠르고 확장 가능합니다.
    • 단점: 그래프 탐색이 너무 일찍 중단되면 이웃을 놓칠 가능성이 있습니다.

실험: 정확한 값과 근사치 비교

리콜을 테스트하기 위해 텍스트 분류 모델을 학습하고 평가하는 데 일반적으로 사용되는 14개 온톨로지 클래스에 걸친 제목과 초록으로 구성된 대규모 데이터 세트인 DBPedia-14 데이터 세트를 사용했습니다. 특히 "영화" 카테고리에 초점을 맞출 것입니다. 최적화된 프로덕션 설정을 수학적으로 완벽한 기준 데이터와 비교하고 싶었습니다.

이 실험에서는 jina-embeddings-v5-text-small 모델을 사용하고 있습니다. 이 모델은 텍스트 표현에 대한 업계 벤치마크를 선도하는 최첨단 다국어 모델입니다. 이 모델이 고성능 임베딩의 현재 표준을 정의하기 때문에 이 모델을 선택했습니다. Jina v5의 탁월한 정확도와 Elasticsearch의 네이티브 양자화 기능을 결합함으로써, 계산 효율성이 뛰어나면서도 검색 품질을 저하시키지 않는 검색 아키텍처를 구현할 수 있음을 보여줍니다.

이중 매핑으로 색인을 설정했습니다. 동일한 텍스트를 두 개의 서로 다른 필드에 동시에 수집했습니다.

  1. content.raw 유형: flat. 이로 인해 Elasticsearch는 전체 Float32 벡터에 대해 무차별 대입 스캔을 수행하게 됩니다. 이렇게 하면 정확한 일치 결과가 반환되며 기준선으로 사용됩니다.
  2. content 유형 semantic_text. 기본값으로 HNSW + 더 나은 이진 양자화(BBQ)를 사용합니다. 이것이 근사 일치를 위한 표준적이고 최적화된 생산 설정입니다.

Recall@10 테스트

메트릭으로는 Recall@10을 사용했습니다.

무작위로 영화 50편을 골라 두 필드에 대해 동일한 쿼리를 실행했습니다.

  • 정확한 (평면) 검색에서 상위 10개 이웃의 ID가 [1, 2, 3... 10]인 경우.
  • 그리고 대략적인 (HNSW) 검색은 ID [1, 2, 3... 9, 99]를 반환합니다.
  • 상위 10개 중 9개를 정확히 찾아냈습니다. 점수는 0.9점입니다.

다음은 사용한 매핑입니다.

결과: 성공의 "플랫 라인"

전체 데이터 세트를 다시 로드하고 1,000~40,000개의 문서 색인 크기에 대해 테스트하는 확장성 테스트를 실행했습니다.

리콜 점수에 대한 자세한 내용은 다음과 같습니다.

문서Recall@10 점수
1,0001.000(100%)
5,0000.998 (100%)
10,0000.992 (99.4%)
20,0000.999 (99.0%)
40,0000.992 (98.8%)

결과는 놀라울 정도로 안정적이었습니다. 규모를 확장했음에도 불구하고, 근사 검색은 무차별 대입 방식의 정확한 검색과 99%를 넘는 일치율을 보였습니다.

왜 그렇게 잘 작동했을까요?

벡터를 이진 값으로 압축하면 정확도가 더 많이 저하될 것으로 예상할 수 있습니다. 그렇게 되지 않는 이유는 Elasticsearch가 데이터 검색을 처리하는 방식에 있습니다.

오늘날 대부분의 임베딩 모델은 크기가 큰 Float32 벡터를 출력합니다. 검색 효율성을 높이기 위해 Elasticsearch는 고차원 벡터에 양자화를 사용합니다. 특히, 9.2 이후로는 기본적으로 BBQ를 사용합니다.

BBQ는 리스코어 메커니즘을 사용합니다.

  1. 트래버설: 검색 엔진은 압축(양자화된) 벡터를 사용하여 HNSW 그래프를 빠르게 탐색합니다. 벡터가 작기 때문에 성능 저하 없이 효율적으로 오버샘플링하여 더 많은 후보 목록(예: 거의 비슷한 상위 100개 문서)을 수집할 수 있습니다.
  2. 리스코어: 후보 문서가 있으면 해당 문서에 대한 전체 정밀도 값을 검색하여 최종적이고 정확한 순위를 계산합니다.

이는 무거운 작업을 위한 양자화의 속도와 최종 정렬을 위한 부동 소수점의 정밀도, 이 두 가지 장점을 모두 제공합니다.

더 나은 성과를 낼 수 있을까요?

여기에 표시된 결과는 기본 설정과 무작위 데이터 샘플링을 사용한 결과라는 점에 주목할 필요가 있습니다. 이걸 고성능 출발점이라고 생각해 보세요. Jina v5는 강력한 성능을 자랑하지만, 이러한 리콜 점수가 모든 데이터 세트에 대해 "만능 해결책"을 보장하는 것은 아닙니다. 모든 데이터 수집에는 고유한 특성이 있으며, 더 많은 성능을 끌어내기 위해 더 조정할 수는 있지만, 항상 자신의 특정 데이터와 벤치마킹하여 한계가 어디인지 확인해야 합니다.

결론

이것은 매우 작은 규모의 테스트입니다. 하지만 이 연습의 요점은 임베딩 모델이나 BBQ를 구체적으로 측정하는 것이 아니라, 최소한의 설정으로 데이터 세트의 리콜을 쉽게 측정하는 방법을 보여주기 위한 것입니다.

자신의 데이터로 이 테스트를 실행하려면 여기에서 노트북을 확인하여 직접 시도해 보세요.

이 콘텐츠가 얼마나 도움이 되었습니까?

도움이 되지 않음

어느 정도 도움이 됩니다

매우 도움이 됨

관련 콘텐츠

최첨단 검색 환경을 구축할 준비가 되셨나요?

충분히 고급화된 검색은 한 사람의 노력만으로는 달성할 수 없습니다. Elasticsearch는 여러분과 마찬가지로 검색에 대한 열정을 가진 데이터 과학자, ML 운영팀, 엔지니어 등 많은 사람들이 지원합니다. 서로 연결하고 협력하여 원하는 결과를 얻을 수 있는 마법 같은 검색 환경을 구축해 보세요.

직접 사용해 보세요