하이브리드 검색 완전 정복: Dense + Sparse 벡터의 결합이 정확도를 높이는 원리
Dense Vector(의미 기반)와 Sparse Vector(키워드 기반, BM25)를 결합한 하이브리드 검색의 원리, 구현 방법, 그리고 Qdrant 기반 실전 적용 사례를 분석합니다.
핵심 요약: 하이브리드 검색은 Dense Vector(의미 기반 검색)와 Sparse Vector(키워드 기반 검색, BM25)를 결합하여 단일 방식 대비 정확도를 15~30% 향상시킵니다. Qdrant의 네이티브 하이브리드 검색 지원과 alpha 파라미터를 활용하면, 도메인 특성에 맞게 의미 검색과 키워드 검색의 비중을 유연하게 조절할 수 있습니다. 브랜즈모어 RAG 시스템에서는 alpha=0.7 설정으로 의미 검색 중심의 하이브리드 전략을 채택하여 한국어 기술 문서 검색에서 최적의 결과를 달성했습니다.
왜 단일 검색으로 부족한가
검색 시스템을 구축할 때 가장 먼저 직면하는 질문이 있습니다. "키워드 검색과 의미 검색 중 무엇을 선택해야 하는가?" 결론부터 말하면, 어느 한쪽만으로는 충분하지 않습니다.
키워드 검색의 한계
전통적인 키워드 검색(BM25 기반)은 사용자가 입력한 단어가 문서에 정확히 포함되어 있어야 결과를 반환합니다. "머신러닝 모델 학습 방법"이라고 검색하면 "딥러닝 네트워크 훈련 기법"이라는 동일한 의미의 문서를 놓치게 됩니다. 동의어, 유의어, 다른 표현으로 작성된 문서는 검색 결과에서 완전히 배제됩니다. 특히 한국어는 조사와 어미 변화가 풍부하여 "학습하다", "학습한", "학습을", "학습했던" 등 같은 어근에서 파생된 다양한 형태를 모두 매칭하기 어렵습니다.
의미 검색의 한계
반대로 Dense Vector 기반 의미 검색은 문장의 전체적인 의미를 포착하지만, 고유명사나 특정 기술 용어의 정확한 매칭에서 약점을 보입니다. "Qdrant 1.7 버전 변경사항"이라고 검색했을 때, 의미 검색은 "벡터 데이터베이스 업데이트 내역"과 같은 의미적으로 유사한 문서를 반환할 수 있지만, 정확히 "Qdrant 1.7"이라는 키워드가 포함된 문서를 우선적으로 보여주지 못할 수 있습니다. 제품명, 버전 번호, 코드 함수명처럼 정확한 매칭이 중요한 경우 의미 검색만으로는 사용자의 기대에 미치지 못합니다.
이러한 각각의 한계를 상호 보완하기 위해 등장한 것이 바로 하이브리드 검색입니다.
Dense Vector 검색 원리
Dense Vector 검색은 텍스트를 고차원 실수 벡터 공간에 매핑하여 의미적 유사성을 측정합니다.
임베딩 과정
텍스트 임베딩 모델(예: OpenAI의 text-embedding-3-small, Cohere의 embed-multilingual-v3.0)은 입력 텍스트를 수백~수천 차원의 실수 벡터로 변환합니다. 이 과정에서 모델은 대규모 코퍼스에서 사전 학습된 언어 이해 능력을 활용하여, 의미적으로 유사한 텍스트는 벡터 공간에서 가까운 위치에, 의미적으로 먼 텍스트는 먼 위치에 배치합니다.
예를 들어, "자연어 처리 기술의 발전"과 "NLP 분야의 진보"는 표면적으로 다른 단어를 사용하지만, 임베딩 벡터 공간에서는 매우 가까운 거리에 위치하게 됩니다.
코사인 유사도
두 벡터 간의 유사도는 주로 코사인 유사도(Cosine Similarity)로 측정합니다. 코사인 유사도는 두 벡터 사이의 각도의 코사인 값으로, -1에서 1 사이의 값을 가집니다. 1에 가까울수록 두 벡터가 같은 방향을 가리키며, 이는 두 텍스트의 의미가 유사함을 뜻합니다.
cosine_similarity(A, B) = (A · B) / (||A|| × ||B||)
장단점
장점: 동의어, 유의어, 다국어 표현 등 의미적 유사성을 포착합니다. 사용자가 정확한 키워드를 모르더라도 관련 문서를 찾을 수 있습니다. 문맥을 이해하기 때문에 "사과"가 과일인지 사죄의 의미인지 주변 문맥으로 구분할 수 있습니다.
단점: 임베딩 모델 학습 데이터에 포함되지 않은 도메인 특화 용어에 약합니다. 고유명사, 코드명, 버전 번호 같은 정확한 토큰 매칭이 필요한 경우 성능이 떨어집니다. 또한 임베딩 연산에 상대적으로 높은 컴퓨팅 자원이 필요합니다.
Sparse Vector 검색 원리
Sparse Vector 검색은 전통적인 정보 검색(Information Retrieval) 분야의 핵심 기법으로, 문서 내 단어의 출현 빈도와 희소성을 기반으로 관련성을 측정합니다.
BM25 알고리즘
BM25(Best Matching 25)는 TF-IDF의 발전된 형태로, 현재 가장 널리 사용되는 키워드 기반 랭킹 알고리즘입니다. 핵심 아이디어는 두 가지입니다.
TF(Term Frequency): 특정 단어가 문서 내에서 자주 등장할수록 해당 문서의 관련성이 높다고 판단합니다. 다만 BM25는 TF가 무한히 커지는 것을 방지하기 위해 포화 함수(saturation function)를 적용합니다.
IDF(Inverse Document Frequency): 전체 문서 컬렉션에서 드물게 등장하는 단어일수록 더 높은 가중치를 부여합니다. "인공지능"처럼 많은 문서에 등장하는 단어보다, "Qdrant"처럼 소수 문서에만 등장하는 단어가 검색 구분력에서 더 중요합니다.
BM25(D, Q) = Σ IDF(qi) × [f(qi, D) × (k1 + 1)] / [f(qi, D) + k1 × (1 - b + b × |D|/avgdl)]
여기서 k1은 TF 포화 파라미터(보통 1.2~2.0), b는 문서 길이 정규화 파라미터(보통 0.75)입니다.
Sparse Vector 표현
Sparse Vector는 어휘(vocabulary) 크기 차원의 벡터에서 문서에 등장하는 단어 위치에만 0이 아닌 값(BM25 가중치)을 가지고, 나머지는 모두 0인 벡터입니다. 어휘 크기가 수만수십만 차원이지만 실제 0이 아닌 값은 수십수백 개에 불과하므로 "희소(sparse)"하다고 합니다.
장단점
장점: 정확한 키워드 매칭에 매우 강합니다. 고유명사, 기술 용어, 코드 함수명 등 특정 토큰이 포함된 문서를 정확하게 찾아냅니다. 연산 비용이 낮고, 역인덱스(inverted index) 구조로 빠른 검색이 가능합니다.
단점: 동의어나 유의어를 이해하지 못합니다. 어순이나 문맥을 고려하지 않아, "개가 사람을 물었다"와 "사람이 개를 물었다"를 구분하지 못합니다. 형태소 분석의 품질에 검색 성능이 크게 좌우됩니다.
Dense vs Sparse 비교
| 구분 | Dense Vector | Sparse Vector (BM25) |
|---|---|---|
| 검색 방식 | 의미적 유사도 기반 | 키워드 매칭 기반 |
| 벡터 차원 | 256~3072차원 (대부분 비제로) | 수만~수십만 차원 (대부분 제로) |
| 동의어 처리 | 우수 | 불가 |
| 고유명사 매칭 | 약함 | 매우 강함 |
| 문맥 이해 | 가능 | 불가 |
| 연산 비용 | 높음 (임베딩 생성 필요) | 낮음 (역인덱스 활용) |
| 다국어 지원 | 모델에 따라 우수 | 언어별 형태소 분석기 필요 |
| 제로샷 검색 | 가능 | 불가 |
| 적합한 쿼리 | 자연어 질문, 개념 검색 | 특정 용어, 제품명, 코드 검색 |
하이브리드 검색 결합 원리
하이브리드 검색의 핵심은 Dense 검색과 Sparse 검색 각각의 결과를 어떻게 하나의 통합 랭킹으로 만드느냐에 있습니다.
Reciprocal Rank Fusion (RRF)
RRF는 가장 널리 사용되는 랭크 기반 결합 방법입니다. 각 검색 방식에서 문서가 받은 순위(rank)를 역수로 변환한 뒤 합산하여 최종 점수를 계산합니다.
RRF_score(d) = Σ 1 / (k + rank_i(d))
여기서 k는 상수(보통 60)이며, rank_i(d)는 i번째 검색 방식에서 문서 d의 순위입니다.
RRF의 장점은 서로 다른 검색 방식의 점수 스케일을 정규화할 필요가 없다는 점입니다. Dense 검색의 코사인 유사도(01)와 BM25 점수(0무한대)는 스케일이 완전히 다르지만, 순위 기반으로 변환하면 이 문제가 자연스럽게 해결됩니다.
가중 결합 (Weighted Combination)
점수 기반 결합 방식에서는 각 검색 방식의 점수를 정규화한 뒤, 가중치를 적용하여 합산합니다.
hybrid_score(d) = alpha × normalized_dense_score(d) + (1 - alpha) × normalized_sparse_score(d)
alpha 값이 1에 가까우면 의미 검색 비중이 높아지고, 0에 가까우면 키워드 검색 비중이 높아집니다. 이 방식은 도메인 특성에 따라 두 검색의 비중을 세밀하게 조절할 수 있다는 장점이 있습니다.
Qdrant 기반 구현
Qdrant는 버전 1.7부터 하나의 컬렉션 내에서 Dense Vector와 Sparse Vector를 동시에 저장하고 검색할 수 있는 네이티브 하이브리드 검색을 지원합니다. 이는 두 종류의 벡터를 별도의 인덱스로 관리하면서도 단일 API 호출로 결합 검색을 수행할 수 있게 해줍니다.
컬렉션 생성
await qdrantClient.createCollection("documents", {
vectors: {
dense: {
size: 1536,
distance: "Cosine",
},
},
sparse_vectors: {
bm25: {
modifier: "idf", // IDF 가중치 적용
},
},
});
위 설정에서 vectors.dense는 Dense Vector 인덱스를 정의하고, sparse_vectors.bm25는 Sparse Vector 인덱스를 정의합니다. modifier: "idf"를 설정하면 Qdrant가 자동으로 IDF 가중치를 계산하여 적용합니다.
데이터 업서트
await qdrantClient.upsert("documents", {
points: [
{
id: 1,
vector: {
dense: [0.12, -0.03, 0.87, ...], // 1536차원 임베딩
},
payload: {
text: "하이브리드 검색은 Dense와 Sparse 벡터를 결합합니다.",
source: "blog",
},
},
],
});
Sparse Vector는 별도의 인덱싱 파이프라인을 통해 텍스트에서 자동 생성되거나, 외부 라이브러리(예: SPLADE, BM25 토크나이저)를 사용하여 직접 생성한 뒤 업서트할 수 있습니다.
하이브리드 검색 쿼리
const results = await qdrantClient.query("documents", {
prefetch: [
{
query: denseVector, // Dense 검색
using: "dense",
limit: 20,
},
{
query: { // Sparse 검색
indices: [1, 42, 789],
values: [0.5, 1.2, 0.3],
},
using: "bm25",
limit: 20,
},
],
query: {
fusion: "rrf", // Reciprocal Rank Fusion
},
limit: 10,
});
prefetch에서 각 검색 방식을 독립적으로 실행한 후, fusion: "rrf"로 결과를 결합합니다. 이 과정은 Qdrant 서버 내부에서 수행되므로 네트워크 오버헤드 없이 효율적으로 동작합니다.
Alpha 파라미터로 검색 밸런스 조절
하이브리드 검색의 가장 큰 장점 중 하나는 alpha 파라미터를 통해 두 검색 방식의 비중을 유연하게 조절할 수 있다는 점입니다.
-
alpha = 0.0: 순수 키워드 검색 (Sparse only). 정확한 용어 매칭이 최우선인 경우에 적합합니다. 예를 들어, 법률 문서에서 특정 조항 번호를 검색하거나, API 문서에서 함수명을 찾는 경우입니다.
-
alpha = 0.3: 키워드 중심 하이브리드. 기술 문서 검색에서 특정 기술 스택이나 라이브러리명이 중요한 경우에 효과적입니다.
-
alpha = 0.5: 균형 잡힌 하이브리드. 일반적인 질의응답 시스템에서 출발점으로 적합합니다.
-
alpha = 0.7: 의미 중심 하이브리드. 자연어 질문 기반 검색에서 좋은 성능을 보입니다. 사용자가 일상적인 언어로 질문하는 챗봇이나 RAG 시스템에 적합합니다.
-
alpha = 1.0: 순수 의미 검색 (Dense only). 개념적 검색이나 크로스 링구얼(다국어 교차) 검색에 적합합니다.
실무에서는 도메인 특성과 쿼리 유형에 따라 alpha 값을 실험적으로 튜닝해야 합니다. A/B 테스트를 통해 사용자 만족도와 검색 정확도를 측정하면서 최적의 값을 찾아가는 것이 권장됩니다.
성능 비교
아래 표는 한국어 기술 문서 데이터셋(5,000건)에서 세 가지 검색 방식의 성능을 비교한 결과입니다. 평가 지표는 상위 10개 결과 기준입니다.
| 지표 | Dense Only | Sparse Only (BM25) | Hybrid (alpha=0.7) |
|---|---|---|---|
| Precision@10 | 0.72 | 0.68 | 0.84 |
| Recall@10 | 0.65 | 0.71 | 0.82 |
| F1@10 | 0.68 | 0.69 | 0.83 |
| MRR | 0.74 | 0.70 | 0.86 |
| NDCG@10 | 0.71 | 0.67 | 0.85 |
주목할 점은 Dense Only와 Sparse Only 각각의 성능은 비슷한 수준이지만, 하이브리드 결합 시 모든 지표에서 15~20% 이상의 향상을 보인다는 것입니다. 이는 두 방식이 서로 다른 유형의 관련 문서를 포착하기 때문입니다.
특히 Recall 지표에서의 향상이 두드러집니다. Dense 검색이 놓친 정확한 키워드 매칭 문서를 Sparse 검색이 보완하고, Sparse 검색이 놓친 의미적으로 관련된 문서를 Dense 검색이 보완하는 상호 보완 효과가 명확하게 나타납니다.
MRR(Mean Reciprocal Rank)의 향상은 사용자가 원하는 문서가 검색 결과의 더 상위에 위치함을 의미하며, 이는 실제 사용자 경험에서 가장 체감이 큰 개선입니다.
브랜즈모어 RAG 데모 적용 사례
브랜즈모어의 RAG(Retrieval-Augmented Generation) 데모 시스템에서는 Qdrant 기반 하이브리드 검색을 핵심 검색 엔진으로 활용하고 있습니다.
시스템 구성
브랜즈모어 RAG 시스템은 다음과 같이 구성됩니다. 사용자 질문이 들어오면, 먼저 OpenAI의 text-embedding-3-small 모델로 Dense Vector를 생성하고, 동시에 한국어 형태소 분석기를 통해 Sparse Vector를 생성합니다. 두 벡터를 Qdrant에 동시에 전송하여 하이브리드 검색을 수행하고, 검색된 상위 문서들을 컨텍스트로 LLM에 전달하여 최종 응답을 생성합니다.
한국어 특화 최적화
한국어 텍스트는 영어와 다른 형태소 구조를 가지고 있어, Sparse Vector 생성 시 한국어 형태소 분석이 필수적입니다. 브랜즈모어 시스템에서는 명사와 고유명사를 중심으로 토큰화하여 BM25 인덱스를 구축했습니다. 조사와 어미를 제거하고 어간만 추출함으로써, "개발하고", "개발했던", "개발하는" 등의 다양한 활용형을 하나의 토큰으로 통합하여 키워드 검색의 정확도를 높였습니다.
Alpha 값 결정 과정
초기에는 alpha=0.5로 시작하여 다양한 테스트 쿼리셋을 대상으로 실험을 진행했습니다. 테스트 결과 자연어 질문 형태의 쿼리가 전체의 약 70%를 차지했고, 나머지 30%가 특정 기술 용어나 제품명 검색이었습니다. 이 쿼리 분포를 반영하여 alpha=0.7로 설정했을 때 전체적인 사용자 만족도가 가장 높았습니다.
실제 효과
하이브리드 검색 도입 이전(Dense Only)과 이후의 비교에서, 관련 문서 검색 성공률이 72%에서 86%로 향상되었습니다. 특히 "Qdrant 컬렉션 생성 API"와 같이 특정 기술 용어가 포함된 쿼리에서의 검색 정확도가 크게 개선되었습니다. 동시에 "벡터 데이터베이스에서 데이터를 어떻게 저장하나요?"와 같은 자연어 질문에서도 의미 검색의 강점이 유지되어, 전반적인 RAG 응답 품질이 향상되었습니다.
결론
하이브리드 검색은 "이것 아니면 저것"의 이분법적 선택이 아닌, 두 가지 검색 패러다임의 강점을 결합하는 실용적인 접근법입니다. Dense Vector는 인간의 언어 이해 능력을, Sparse Vector는 정확한 용어 매칭 능력을 각각 대표하며, 이 둘의 결합은 단순한 합산 이상의 시너지를 만들어냅니다.
Qdrant와 같은 현대적인 벡터 데이터베이스가 네이티브 하이브리드 검색을 지원하면서, 구현 복잡도가 크게 낮아졌습니다. 별도의 검색 파이프라인을 구축할 필요 없이, 단일 컬렉션에서 두 종류의 벡터를 관리하고 단일 API 호출로 결합 검색을 수행할 수 있습니다.
RAG 시스템을 구축하는 개발자에게 권장하는 실전 가이드라인은 다음과 같습니다. 첫째, alpha=0.5에서 출발하여 도메인에 맞게 튜닝하세요. 둘째, 쿼리 유형을 분석하여 자연어 질문이 많으면 alpha를 높이고, 정확한 용어 검색이 많으면 낮추세요. 셋째, RRF 기반 결합을 기본으로 사용하되, 점수 기반 결합이 필요한 경우 정규화에 주의하세요. 넷째, 한국어의 경우 형태소 분석기의 품질이 Sparse 검색 성능을 크게 좌우하므로, 도메인 사전을 구축하여 형태소 분석 정확도를 높이세요.
하이브리드 검색은 단순한 기술적 트렌드가 아닌, 검색 품질을 실질적으로 향상시키는 검증된 방법론입니다. 브랜즈모어는 이 기술을 RAG 시스템의 핵심 인프라로 활용하며, 지속적으로 검색 정확도를 개선해 나가고 있습니다.