Elasticsearch 8.0의 근사 최근접 이웃 검색 소개

벡터 검색에 대한 관심이 급증하고 있는데, 이는 텍스트, 이미지, 이벤트 등을 포함한 모든 종류의 콘텐츠를 벡터로 표현할 수 있는 차세대 Machine Learning 모델 덕분입니다. 종종 “임베딩 모델”이라고 불리는 이러한 강력한 표현은 표면적인 특성을 넘어 두 콘텐츠 간의 유사성을 포착 할 수 있습니다.

k-최근접 이웃(kNN) 검색 알고리즘은 데이터 세트에서 쿼리 벡터와 가장 유사한 벡터를 찾습니다. 이러한 벡터 표현과 결합된 kNN 검색은 검색을 위한 흥미로운 가능성을 열어줍니다:

  • 질문에 대한 답변이 포함되어 있을 가능성이 높은 단락 찾기
  • 대규모 데이터 세트에서 거의 중복되는 이미지 탐지
  • 특정 노래와 유사하게 들리는 노래 찾기

벡터 검색은 용어 기반 점수 산정과 같은 기존 기술과 함께 검색 툴박스의 중요한 구성 요소가 될 준비를 마쳤습니다.

Elasticsearch는 현재 dense_vector 필드 유형 을 통해 벡터를 저장하고 이를 사용하여 문서 점수를 계산하는 기능을 지원합니다. 이를 통해 사용자는 모든 문서를 스캔하여 정확한 kNN 검색을 수행할 수 있습니다. Elasticsearch 8.0은 이러한 기능을 기반으로 빠르고 근사한 최인접 이웃 검색(ANN)을 지원합니다. 이는 훨씬 더 확장 가능한 접근 방식을 나타내며, 대규모 데이터 세트에서 벡터 검색을 효율적으로 실행할 수 있게 합니다.

Elasticsearch의 ANN

근사 최근접 이웃 검색이란 무엇입니까?

KD 트리와 같이 저차원 벡터에서의 kNN을 위해 잘 확립된 데이터 구조가 있습니다. 사실, Elasticsearch는 지리적 위치 및 수치 데이터에 대한 검색을 지원하기 위해 KD 트리를 통합 합니다. 그러나 텍스트 및 이미지용 최신 임베딩 모델은 일반적으로 100~1000개 요소, 또는 그 이상의 고차원 벡터를 생성합니다. 이러한 벡터 표현은 고차원에서 최근접 이웃을 효율적으로 찾는 것이 매우 어렵기 때문에 독특한 과제를 제시합니다.

이러한 어려움에 직면했을 때, 최인접 이웃 알고리즘은 일반적으로 속도를 향상하기 위해 완벽한 정확도를 희생합니다. 이러한 근사 최인접 이웃(ANN) 알고리즘이 항상 실제 k 개의 최인접 벡터를 반환하지는 않을 수 있습니다. 하지만 이 알고리즘들은 효율적으로 실행되며, 우수한 성능을 유지하면서 대규모 데이터 세트로 확장됩니다.

ANN 알고리즘 선택

ANN 알고리즘 설계는 활발한 학술 연구 분야이며, 선택할 수 있는 유망한 알고리즘이 많이 있습니다. 이들은 종종 검색 속도, 구현 복잡성 및 색인 비용 측면에서 서로 다른 장단점을 제시합니다. 다행히도 주요 알고리즘을 여러 데이터 세트에 대해 테스트하고 비교 결과를 게시하는 ann-benchmarks 라는 훌륭한 오픈 소스 프로젝트가 있습니다.

Elasticsearch 8.0은 계층적으로 탐색 가능한 작은 세계(Hierarchical Navigable Small World, HNSW) 그래프라는 ANN 알고리즘을 사용하며, 이는 벡터를 서로의 유사성에 따라 그래프로 구성합니다. HNSW는 다양한 ann-benchmarks 데이터 세트 전반에서 강력한 검색 성능을 보여주며, 자체 테스트에서도 우수한 결과를 보였습니다. HNSW의 또 다른 이점은 여러 다른 시스템에 구현되어 업계에서 널리 사용된다는 점입니다. 원본 학술 논문 외에도 알고리즘의 세부 정보를 학습하는 데 도움이 되는 많은 리소스가 있습니다. 현재 Elasticsearch ANN은 HNSW를 기반으로 하지만, 이 기능은 향후 다양한 접근 방식을 통합할 수 있도록 유연하게 설계되었습니다.

코드를 보여 주십시오!

ANN 검색하기 위해 벡터를 색인하려면 index: true로 설정하고 비교에 사용할 유사성 메트릭을 지정해야 합니다:

PUT index
{
 "mappings": {
   "properties": {
     "image-vector": {
       "type": "dense_vector",
       "dims": 128,
       "index": true,
       "similarity": "l2_norm"
     }
   }
 }
}

PUT index/_doc
{
 "image-vector": [0.12, 1.34, ...]
}
그런 다음 벡터를 추가한 후 쿼리 벡터에 대한 k 최근접 이웃을 검색할 수 있습니다:
GET index/_knn_search
{
 "knn": {
   "field": "image-vector",
   "query_vector": [-0.5, 9.4, ...],
   "k": 10,
   "num_candidates": 100
 }
}
새로운 _knn_search 엔드포인트는 HNSW 그래프를 사용하여 유사한 벡터를 효율적으로 검색합니다. 데이터 전체를 스캔하는 정확한 kNN과 달리, 대규모 데이터 세트로도 잘 확장됩니다. 다음은 128차원의 이미지 벡터 100만 개로 구성된 데이터 세트에서 10,000개 이상의 다양한 쿼리를 평균하여 _knn_search 와 script_score 쿼리에 기반한 정확한 방식을 비교한 예시입니다:
Approach         Queries Per Second    Recall (k=10)
script_score           5.257               1.000
_knn_search          849.286               0.945

이 예에서 ANN 검색은 정확한 방식보다 수십 배 더 빠릅니다. 재현율은 약 95%이므로, 평균적으로 10개의 실제 최근접 이웃 중 9개 이상을 찾습니다.

Elasticsearch 나이틀리 벤치마크에서 kNN 검색의 성능을 확인할 수 있습니다. 이 벤치마크는 Elasticsearch 벤치마킹 도구인 es-rally, 특히 새로운 dense_vector Rally 트랙을 기반으로 합니다. 알고리즘의 정확도를 추적하는 것 또한 중요하므로, 지연 시간 외에 재현율도 보고할 수 있도록 Rally를 확장할 계획입니다. 현재 이 벤치마크는 수백만 개의 벡터로 구성된 데이터 세트를 테스트하지만, ANN 검색은 더 긴 인덱싱 시간이나 하드웨어 리소스를 추가하여 확실히 그 이상으로 확장할 수 있습니다.

근사 알고리즘이므로 다른 유형의 검색과 비교하여 ANN을 실행할 때 특별히 고려해야 할 사항이 있습니다. ANN에는 검색 지연 시간, 결과 정확도, 색인 비용 간의 균형을 제어하기 위한 검색 시점 및 색인 시점 매개변수가 모두 있습니다. 구성이 제대로 작동하는지 확인하려면 데이터 세트에서 ANN 검색의 재현율을 측정하는 것이 중요합니다. kNN 검색을 시작할 때 참조 가이드 가 도움이 될 수 있습니다.

Apache Lucene 기반

Elasticsearch의 핵심 검색 기능 중 상당수는 Apache Software Foundation에서 관리하는 오픈 소스 프로젝트인 Lucene 라이브러리를 기반으로 합니다. Elasticsearch ANN도 예외는 아니며, 숫자 벡터를 저장하고 검색하기 위한 흥미로운 새로운 Lucene 기능을 기반으로 구축되었습니다. 이 기능은 여러 조직의 개발자들이 참여한 훌륭한 협업의 결과물입니다. 대담한 제안으로 시작된 이 프로젝트는 빠르게 작동하는(그리고 빠른) 구현으로 발전했습니다. 그다음에는 API를 설계 하고 기능을 완성해야 하는 과제가 있었습니다.

그 이후로 Lucene 커뮤니티는 해당 기능을 발전시키기 위해 지속적으로 협력해 왔습니다. 여러 개발자가 관심을 갖고 이름 재설계부터 알고리즘 업데이트, 성능 개선 등에 이르기까지 다양한 기여를 했습니다. Lucene의 벡터 검색 기능은 모두의 노력 덕분에 빠르게 확장되고 있습니다.

성공적인 협업 외에도 Lucene에서 ANN을 개발함으로써 다른 주요 이점을 얻을 수 있습니다. Lucene의 구현은 기존 기능과 올바르게 통합되도록 저수준에서 설계되었으며, 이를 통해 ANN 검색이 다른 Elasticsearch 기능과 원활하게 상호 작용할 수 있습니다. 외부 ANN 라이브러리에 의존했다면 이와 같은 심층적인 통합은 사실상 불가능했을 것입니다. 예를 들어, Lucene ANN은 그래프 검색 중에 'tombstone'을 건너뜀으로써 삭제된 문서를 투명하게 처리합니다. 또한 Lucene의 모든 데이터 호환성 보장을 준수하므로 업그레이드 후에도 벡터 데이터가 정상적으로 작동함을 확신할 수 있습니다. 마지막으로, Elasticsearch와 마찬가지로 Java로 작성된 구현을 통해 보안을 보장하고 메모리 관리를 단순화할 수 있습니다.

다음 단계

8.0 버전에서는 효율적인 ANN 검색을 위한 _knn_search 엔드포인트가 “기술 미리보기”로 출시될 예정입니다. ANN 검색은 Elastic뿐만 아니라 업계 전반에서도 비교적 새로운 주제이며, 어떻게 동작해야 하는지에 대해 중요한 미해결 질문들이 남아 있습니다. 벡터 유사성 점수를 전통적인 BM25 점수와 결합하는 가장 좋은 방법은 무엇인가요? kNN 검색하는 것이 페이지네이션을 지원해야 할까요? ANN을 자체적인 실험용 엔드포인트로 개발하면 그 동작을 빠르게 반복하고 테스트할 수 있을 것입니다. 이 질문들에 대한 확실한 답변이 마련되면 궁극적으로 ANN을 _search API에 통합할 계획입니다. (_knn_search는 아직 정식 버전(GA)이 아니지만, dense_vector 필드 유형은 7.6에서 정식 버전으로 출시되었으며 안정적인 API를 유지하고 있습니다.)

지원할 예정인 주요 기능으로는 필터가 포함된 ANN과 ANN 결과를 기존 쿼리 결과와 결합하는 “하이브리드” 검색이 있습니다. 또한 HNSW 그래프 구축은 많은 리소스를 소모하는 작업이므로 색인 속도를 개선하기 위해 노력하고 있습니다. 이번 릴리즈는 시작에 불과하며, 향후 릴리즈를 통해 ANN 검색을 지속적으로 개선해 나갈 예정입니다. 사용자의 피드백은 매우 소중하며, 기능의 방향을 구체화하는 데 도움이 됩니다. GitHub 및 Discuss 포럼 (그리고 Lucene)을 통해 여러분의 의견을 들려주십시오!

Elastic Cloud 콘솔 에 로그인하거나 14일 무료 체험판에 등록하여 Elastic Cloud에서 ANN 검색을 사용해 보세요.