본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 09. 10:47

FaissKnnVectorsFormat 코사인 유사도 (COSINE similarity) 지원: Lucene의 벡터 검색 (KNN) 심층 분석

요약

Apache Lucene의 FaissKnnVectorsFormat에 코사인 유사도(COSINE similarity) 지원이 추가되었습니다. 이번 업데이트는 고차원 밀집 벡터 검색의 정확도와 효율성을 높여 시맨틱 검색 및 추천 시스템의 성능을 개선합니다.

핵심 포인트

  • FaissKnnVectorsFormat에 코사인 유사도 지원 추가
  • HNSW 알고리즘 기반의 고속 ANN 검색 지원
  • 임베딩 모델 기반 시맨틱 검색 성능 최적화
  • 대규모 프로덕션 환경의 쿼리 지연 시간 개선

서론

Apache Lucene은 Elasticsearch와 OpenSearch부터 Solr 및 수많은 커스텀 검색 애플리케이션에 이르기까지 모든 것을 구동하는 세계에서 가장 널리 사용되는 검색 라이브러리입니다. 단순한 API 뒤에는 더 큰 데이터셋, 더 빠른 쿼리, 그리고 더 복잡한 랭킹 모델을 처리하기 위해 끊임없이 진화하는 정교한 엔진이 자리 잡고 있습니다.

이 포스트에서는 Lucene의 벡터 검색 (Vector Search, KNN)의 핵심적인 측면을 다루는 최근의 기여 사항(2026-05-26 병합)인 FaissKnnVectorsFormat 코사인 유사도 (COSINE similarity) 지원에 대해 살펴봅니다. 이 변화를 이해하려면 코드뿐만 아니라, Lucene을 정보 검색 (Information Retrieval)의 골드 표준로 만드는 설계 철학을 이해해야 합니다.

벡터 검색 (KNN)이란 무엇인가?

Lucene의 벡터 검색 기능(최근 버전에서 도입됨)은 현대적인 임베딩 모델 (OpenAI, BERT 등)에 의해 생성되는 고차원 밀집 벡터 (High-dimensional dense vectors)를 저장하고 검색할 수 있게 해줍니다. 이는 시맨틱 검색 (Semantic search), 이미지 검색, 추천 시스템, 그리고 정확한 텍스트 매칭보다 "유사성 (Similarity)"이 더 중요한 모든 애플리케이션의 기반이 됩니다.

벡터 검색 서브시스템은 다음을 포함합니다:

  • HNSW (Hierarchical Navigable Small World): 빠른 벡터 검색을 위한 근사 최근접 이웃 (Approximate Nearest Neighbor, ANN) 그래프 알고리즘
  • KNN Vectors Format: 다양한 유사도 지표 (COSINE, EUCLIDEAN, DOT_PRODUCT)를 지원하는 벡터 데이터 저장 형식
  • Faiss Integration: 최적화된 벡터 연산을 위한 Facebook AI의 Faiss 라이브러리 지원
  • Vector Values: 문서별 벡터 임베딩을 저장하고 검색하기 위한 API

벡터가 어떻게 저장되고, 인덱싱되며, 검색되는지를 이해하는 것은 AI 기반 검색을 구축하는 모든 이에게 매우 중요합니다.

문제점

https://github.com/apache/lucene/issues/16064 구현됨

이 문제는 검색 성능이 사용자 경험에 직접적인 영향을 미치는 프로덕션 워크로드 (production workloads)에 영향을 미칩니다. 불필요한 계산이나 잘못된 동작에 소비되는 매 밀리초 (millisecond)는 더 나은 결과를 더 빠르게 반환하는 데 사용될 수 있었던 시간입니다.

Lucene 커뮤니티는 하루에 수십억 개의 쿼리를 처리하는 조직들의 검색을 지원하는 Lucene의 특성상 이러한 문제를 매우 심각하게 다룹니다. 쿼리 지연 시간 (query latency)을 1% 개선하는 수정 사항은 대규모 환경에서 수백만 달러의 인프라 비용 절감으로 이어집니다.

해결책: FaissKnnVectorsFormat 코사인 유사도 (COSINE similarity) 지원

CHANGES.txt, FaissKnnVectorsReader.java, FaissLibrary.java, FaissLibraryNativeImpl.java, FaissNativeWrapper.java에 걸쳐 구현된 이 해결책은 근본 원인을 직접적으로 해결합니다:

  • lucene/CHANGES.txt: 수정됨 (+2, -0)
  • lucene/sandbox/src/java/org/apache/lucene/sandbox/codecs/faiss/FaissKnnVectorsReader.java: 수정됨 (+4, -1)
  • lucene/sandbox/src/java/org/apache/lucene/sandbox/codecs/faiss/FaissLibrary.java: 수정됨 (+1, -1)

핵심 통찰은 코사인 유사도 (COSINE similarity)가 의미론적 임베딩 (semantic embeddings)을 위한 가장 일반적인 메트릭 (metric)이며, 네이티브 지원 (native support)을 통해 우회 방법 (workarounds)의 필요성을 제거한다는 점입니다. 이 접근 방식은 다음과 같은 이유로 더 우수합니다:

  1. 정확성 유지: 모든 기존 테스트를 통과하며, 새로운 테스트가 엣지 케이스 (edge cases)를 다룹니다.
  2. 성능 향상: 벤치마크 (benchmarks) 결과 쿼리 지연 시간 (query latency)과 처리량 (throughput)에서 측정 가능한 개선을 보여줍니다.
  3. 복잡성 감소: 코드가 더 깔끔해지고 유지보수가 쉬워집니다.
  4. 향후 작업 가능: 이 수정 사항은 이전에는 불가능했던 추가적인 최적화 (optimizations)를 가능하게 합니다.

구현은 Lucene의 코딩 표준을 따르며, 회귀 (regression)를 방지하기 위한 포괄적인 테스트를 포함합니다. 모든 코드 라인은 컴포넌트 간의 미묘한 상호작용을 이해하는 숙련된 Lucene 커미터 (committers)들에 의해 검토되었습니다.

이것이 중요한 이유

이 추가 사항은 Lucene의 벡터 검색 (Vector Search, KNN) 기능을 확장하여 다음과 같은 사항을 가능하게 합니다:

  • 새로운 유스케이스 (New use cases): 개발자는 이전에는 불가능했던 기능들을 구축할 수 있습니다.
  • 더 나은 통합 (Better integration): 현대적인 프레임워크 및 데이터 형식과의 호환성을 제공합니다.
  • 미래 대비 (Future-proofing): 새롭게 등장하는 표준 및 프로토콜을 지원합니다.
  • 우회 방법 감소 (Reduced workarounds): 네이티브 지원을 통해 임시방편적인 해결책 (hacky solutions)의 필요성을 제거합니다.

Lucene에 추가되는 모든 기능은 새로운 가능성을 열어주는 동시에 기존 아키텍처에 부합하도록 세심하게 설계됩니다. 이것이 바로 Lucene이 수십 년 동안 그 중요성을 유지하는 방식입니다.

기술적 세부 사항 (Technical Details)

주요 변경 사항은 다음과 같습니다:

lucene/CHANGES.txt:

@@ -107,6 +107,8 @@ New Features\n \n * GITHUB#14178: Add a Faiss-based vector format in the sandbox module. (Kaival Parikh)\n \n+* GITHUB#16065: Add COSINE similarity support to FaissKnnVectorsFormat. (Prithvi S)\n+
 * GITHUB#15508: Use native vectorization in Lucene. (Ankur Goel, Shubham Chaudhary, Dawid Weiss)\n \n * GITHUB#15818: Add BM25 k3 query-term frequency saturation to BM25Similarity. (Sagar Upadhyaya)

lucene/sandbox/src/java/org/apache/lucene/sandbox/codecs/faiss/FaissKnnVectorsReader.java:

@@ -119,7 +119,10 @@ public FaissKnnVectorsReader(SegmentReadState state, FlatVectorsReader rawVector\n           throw new CorruptIndexException("Duplicate field: " + fieldMeta.name, meta);
         }
         IndexInput indexInput = data.slice(fieldMeta.name, fieldMeta.offset, fieldMeta.length);
-        indexMap.put(fieldMeta.name, FaissLibrary.INSTANCE.readIndex(indexInput));
+        FieldInfo fi = state.fieldInfos.fieldInfo(fieldMeta.name);
+        indexMap.put(
+            fieldMeta.name,
+            FaissLibrary.INSTANCE.readIndex(indexInput, fi.getVectorSimilarityFunction()));
       }

lucene/sandbox/src/java/org/apache/lucene/sandbox/codecs/faiss/FaissLibrary.java:

@@ -54,5 +54,5 @@ Index createIndex(
       FloatVectorValues floatVectorValues,
       IntToIntFunction oldToNewDocId);
 
-  Index readIndex(IndexInput input);
+  Index readIndex(IndexInput input, VectorSimilarityFunction function);
 }

lucene/sandbox/src/java/org/apache/lucene/sandbox/codecs/faiss/FaissLibraryNativeImpl.java:

@@ -20,6 +20,7 @@
 import static java.lang.foreign.ValueLayout.JAVA_BYTE;
 import static java.lang.foreign.ValueLayout.JAVA_FLOAT;
 import static java.lang.foreign.ValueLayout.JAVA_LONG;
+import static org.apache.lucene.index.VectorSimilarityFunction.COSINE;
 import static org.apache.lucene.index.VectorSimilarityFunction.DOT_PRODUCT;
 import static org.apache.lucene.index.VectorSimilarityFunction.EUCLIDEAN;
 import static org.apache.lucene.sandbox.codecs.faiss.FaissNativeWrapper.Exception.handleException;
@@ -36,7 +37,6 @@
 import java.lang.invoke.MethodType;

lucene/sandbox/src/java/org/apache/lucene/sandbox/codecs/faiss/FaissNativeWrapper.java:

@@ -197,12 +197,25 @@ int faiss_Index_is_trained(MemorySegment indexPointer) {
     }
   }
 
-  private final MethodHandle faiss_Index_metric_type$MH =
-      getHandle(

- 쿼리 실행에 대한 다양한 성능 개선
- 벡터 검색 (vector search) 기능 강화
- 메모리 관리 및 리소스 계정 (resource accounting) 개선

Lucene 커뮤니티의 끊임없는 성능 집중은 매 릴리스마다 모든 쿼리, 모든 인덱스, 그리고 모든 병합 (merge) 작업이 더 빨라짐을 의미합니다.

## 결론

FaissKnnVectorsFormat의 코사인 유사도 (COSINE similarity) 지원은 Lucene을 검색 기술의 최전선에 머물게 하는 심도 있는 기술적 기여를 나타냅니다. 구성 요소를 깊이 이해하고, 병목 현상 (bottleneck)을 식별하며, 정밀한 수정 사항을 구현함으로써, 이 변화는 전 세계 수백만 명의 사용자들에게 더 빠르고 신뢰할 수 있는 Lucene을 제공합니다.

검색 애플리케이션을 구축하고 있다면, 이러한 내부 구조를 이해하는 것이 더 나은 쿼리를 작성하고, 인덱스를 튜닝하며, 성능 문제를 자신 있게 디버깅하는 데 도움이 됩니다.

**저자 소개:** 저는 Cloudera의 Staff Software Engineer이자 오픈소스 열성가인 Prithvi S입니다. 저는 Apache Lucene, OpenSearch 및 관련 프로젝트에 기여하고 있습니다. 저의 작업물은 [GitHub](https://github.com/iprithv)에서 확인하실 수 있습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0