오늘의집 검색 - 모든 언어와 도메인을 아우르는 일반화된 Retrieval 시스템 만들기
검색 품질을 끌어올리는 기술적 도전과 최적화 여정
2026년 1월 14일Jaiden, Yuri

벡터 서치 서비스 화면

▲ 한국 서비스 화면(위) 일본 서비스 화면(아래) // 기존에 검색결과가 없거나 적었던 검색어에서, 관련성 높은 상품들이 노출된다
▲ 한국 서비스 화면(위) 일본 서비스 화면(아래) // 기존에 검색결과가 없거나 적었던 검색어에서, 관련성 높은 상품들이 노출된다


상품을 찾으려 하는데 검색 결과가 없어요 😞

이커머스에서 검색 결과가 없는 상황은 유저의 불만족과 이탈을 유발하며, 장기적으로는 매출에도 악영향을 줄 수 있기 때문에 매우 중요한 문제입니다. 특히 GPT, Gemini 등이 일상화되면서 유저는 언제나 그럴듯하고 만족스러운 답변을 기대하는 환경이 되었고, 그만큼 ‘검색 결과 없음’ 문제는 검색 서비스에서 더욱 비중 있게 다뤄야 하는 과제가 되었습니다.

오늘의집 검색팀은 이러한 문제를 완화하기 위해 연관검색어 노출, 광고 기반 대체 제안, 검색 의도 분석을 활용한 상품 추천 등 다양한 방식으로 유저 이탈을 방지하고 체류 시간을 높이기 위한 노력을 지속해 왔습니다. 또한 유저의 다양한 검색어, 특히 Mid-Tail 쿼리까지 더 적합한 결과를 제공하기 위해 CLIP 기반 멀티모달 검색을 특정 검색어 집합에 리랭킹 방식으로 적용하며 검색 품질 개선을 이어왔습니다.


텍스트를 먼저 이해하고 이미지로 확장

CLIP 기반 모델은 대규모 이미지–텍스트 데이터를 활용한 WSL(Weakly Supervised Learning) 방식으로 학습된 강력한 구조이지만, 이커머스 검색 환경에서는 몇 가지 한계가 존재합니다.

우선 한국어 데이터의 학습량이 부족하며, 특히 이커머스·라이프스타일 상품 도메인에 대한 이해가 충분하지 않다는 점이 크게 작용합니다. 텍스트 인코더의 컨텍스트 길이도 77로 매우 짧아, 텍스트 데이터만으로 학습된 언어 모델과 비교했을 때 문맥 이해력이 제한적이라는 한계가 있습니다. 이미지 측면에서도 상품의 스타일, 색상, 재질 등 검색에 중요한 요소가 담겨 있음에도, 이를 검색 의도에 맞게 정확히 매칭하고 해석하는 것은 쉽지 않은 문제입니다.

반면 이커머스 상품은 판매자, MD, 운영팀 등 다양한 주체가 입력한 구조적 / 비구조적 텍스트 속성이 매우 풍부합니다. 이러한 텍스트 정보만 잘 이해해도 검색 의도에 맞는 상품을 노출할 수 있는 가능성이 크게 열려 있었습니다. 이에 따라 개발 방향을 텍스트에 대한 깊은 Semantic Proximity을 먼저 확보하는 것으로 설정하고, 이후 이를 이미지 영역까지 확장하는 전략을 선택했습니다.


다국어와 여러 도메인을 이해하는 일반화 능력이 뛰어난 임베딩 모델 필요

오늘의집은 국내를 넘어 일본, 미국까지 글로벌 앱을 서비스하고 있으며, 단순히 상품만 다루는 것이 아니라 유저들의 콘텐츠, 스타일링, 집들이, 노하우, 인테리어 시공까지 아우르는 통합 라이프스타일 플랫폼입니다. 따라서 검색 서비스는 언제나 다국어(Multilingual)와 여러 도메인(Multidomain)을 동시에 잘 이해하는 방향으로 설계되어야 합니다. 이를 위해 오늘의집 검색팀은 다음과 같은 목표를 두고 시스템을 고도화했습니다.

  • 기존 키워드 매칭(예 : BM25)의 부족한 문맥 이해 능력(미스매치, 부분 매치, 이중 언어, 동의어, 묘사형 검색어 등)을 Hybrid Search로 보완합니다.
  • 다국어 및 다양한 도메인을 이해할 수 있는 일반화된 텍스트 임베딩 모델을 개발합니다.
  • 빠른 추론 속도와 우수한 검색 성능을 동시에 제공하여 유저 편의성을 유지합니다.
  • 효율적인 인덱스 사이즈 운영을 통해 색인 속도 저하를 최소화합니다.


BGE-M3 모델 파인튜닝

위 요구사항을 충족하기 위해 가장 단순한 SimCSE부터 LLM 기반 인코더까지 폭넓게 실험하며 오늘의집 검색 서비스에 가장 적합한 텍스트 인코더를 탐색했고, 그 결과 BGE-M3(BAAI, 2024) 모델을 선택했습니다.

BGE-M3 모델은 Dense, Sparse, ColBERT 학습을 동시에 수행하는 구조로, 다양한 길이, 언어, 데이터 소스를 활용해 학습된 모델입니다. XLM-RoBERTa를 백본으로 사용하기 때문에 한국어, 영어, 일본어 등 다국어 이해 능력이 우수하지만, 토큰 효율성은 Qwen 계열에 비해 상대적으로 낮은 편입니다.

BGE-M3 모델은 토큰 단위의 Multi-Vector 표현을 함께 학습하기 때문에 Dense Embedding의 한계점(Weller et al. 2025)을 보완할 수 있어서 Retrieval 성능에 특화되어 있습니다. 중간 레이어의 토큰 벡터를 사용하지 않고도 ColBERT 토큰 벡터를 통해 검색어-문서 간 유사도를 시각화할 수 있기 때문에 모델의 설명력이 뛰어나다는 장점도 있습니다.

다만 여러 언어와 다양한 소스로 충분히 학습된 강력한 모델임에도, 오늘의집 도메인 데이터에 대한 사전 학습은 적기 때문에 도메인 적응이 필요했습니다. 이에 검색팀은 유저 인터랙션 데이터를 기반으로 Fine-Tuning을 수행했습니다.

또한 검색 인덱스 사이즈를 최적화하고 추천, 광고 등 여러 서비스에서 재활용할 수 있도록 Matryoshka Representation Learning(Kusupati et al, 2024)를 1024, 768, 512, 256, 128, 64, 32 차원으로 적용했습니다. 그 결과 128차원에서도 1024차원 대비 성능 저하가 매우 적었고, 100만 개의 Float32 벡터 기준 약 512MB 수준으로 인덱스 크기를 줄여 색인 속도와 활용성을 크게 개선할 수 있었습니다.


import torch import torch.nn as nn import torch.nn.functional as F from typing import Dict, Tensor class EmbedderModel(nn.Module): def trunc(self, tensor: Tensor, dim: int) -> Tensor: tensor = tensor[..., :dim] tensor = F.normalize(tensor, p=2, dim=-1) return tensor def forward(self, queries: Dict[str, Tensor], passages: Dict[str, Tensor], **kwargs): scores = [] q_dense_vecs, q_sparse_vecs, q_colbert_vecs = self.encode(queries) p_dense_vecs, p_sparse_vecs, p_colbert_vecs = self.encode(passages) loss = 0.0 for idx in range(len(self.matryoshka_dims)): dim = self.matryoshka_dims[idx] weight = self.matryoshka_weights[idx] _q_dense_vecs, _, _q_colbert_vecs = self.trunc(q_dense_vecs, dim), self.trunc(q_sparse_vecs, dim), self.trunc(q_colbert_vecs, dim) _p_dense_vecs, _, _p_colbert_vecs = self.trunc(p_dense_vecs, dim), self.trunc(p_sparse_vecs, dim), self.trunc(p_colbert_vecs, dim) dense_scores, dense_loss = self._compute_in_batch_neg_loss( _q_dense_vecs, _p_dense_vecs, compute_score_func=self.compute_dense_score, ) # NOTE: bge-m3 use sparse vector cannot be truncated because it is a hard sparse vector consisting of input token weights sparse_scores, sparse_loss = self._compute_in_batch_neg_loss( q_sparse_vecs, p_sparse_vecs, compute_score_func=self.compute_sparse_score, ) colbert_scores, colbert_loss = self._compute_in_batch_neg_loss( _q_colbert_vecs, _p_colbert_vecs, compute_score_func=self.compute_colbert_score, q_mask=self._get_queries_attention_mask(queries), ) _, ensemble_loss = self._compute_in_batch_neg_loss( _q_dense_vecs, _p_dense_vecs, compute_score_func=self.ensemble_score, dense_scores=dense_scores, sparse_scores=sparse_scores, colbert_scores=colbert_scores, ) loss += (dense_loss + ensemble_loss + 0.1 * sparse_loss + colbert_loss) / 4 loss *= weight scores.append(self.get_local_score(q_dense_vecs, p_dense_vecs, dense_scores)) scores = torch.stack(scores, dim=1) return EmbedderOutput( loss=loss, scores=scores, )

Matryoshka Representation Learning 적용 예시 (BGE-M3 소스 출처 : https://github.com/FlagOpen/FlagEmbedding)


벡터들이 임베딩 공간에 골고루 퍼질 수 있도록

임베딩 모델 학습 시 많이 사용되는 Contrastive Learning은 벡터가 과도하게 밀집되거나 군집을 이루는 경우 표현력이 떨어질 수 있는 문제가 있습니다. 따라서 벡터들이 임베딩 공간에서 골고루 퍼지는 것이 좋은 성질 중 하나입니다. 검색팀에서는 EmbeddingGemma(DeepMind, 2025)의 Spread-Out Regularizer를 참고하여 BGE-M3의 Loss를 발전시켰습니다.

Spread-Out Regularizer는 Global Orthogonal Regularizer(GOR) 아이디어에서 출발한 기법입니다. 핵심 개념은 검색어 벡터들끼리와 문서 벡터들끼리의 내적을 최소화해 서로 직교에 가깝게 만드는 것입니다. 이를 통해 벡터들이 특정 방향으로 몰리지 않고, 2차 모먼트를 활용해 전체 임베딩 공간에서 균형 있게 분산(Dispersion) 되도록 유도합니다. 특히 이 방법은 Mini-batch에 포함된 랜덤한 검색어쌍과 문서쌍을 대상으로 정규화를 적용하기 때문에, 전체 데이터셋을 대상으로 하지 않고도 효율적인 학습이 가능하다는 장점이 있습니다.


First-Stage Ranker Pipeline

기존 CLIP 기반 임베딩 모델은 Post-Quantization을 거쳐 벡터를 압축해야 했고, 다국어 지원 및 도메인 적응도 쉽지 않아 전체 학습 파이프라인이 길고 복잡하다는 문제점이 있었습니다.

반면 BGE-M3-Matryoshka 모델은 여러 임베딩 차원을 자연스럽게 지원하기 때문에 별도의 양자화 과정 없이도 원하는 차원으로 바로 임베딩을 활용할 수 있습니다. 그 결과 파이프라인이 훨씬 간결해지고 복잡성도 크게 줄일 수 있었습니다.

▲ ML 온오프라인 파이프라인
▲ ML 온오프라인 파이프라인


또한 모든 검색어에 대응하기 위해 쿼리추론서버가 필요했고, Text Embeddings Inference 를 사용하여 배포한 결과 평균 4~6ms의 빠른 응답속도를 보장하였습니다.


Model-in-the-Loop : LLM 기반 검색어 생성 및 리랭킹과 학습 이터레이션

임베딩 모델이 랭커로서 안정적으로 기능하기 위해서는 지속적인 모델 개선과 더불어, 이를 정량적으로 비교할 수 있는 Recall 평가 체계가 필요합니다. 그러나 실제 서비스 검색에서는 벤치마크 데이터셋처럼 정확한 True Recall을 아는 것이 사실상 불가능합니다. 따라서 이를 최대한 잘 추정할 수 있는 평가 방식이 필수적입니다.

전통적으로는 사람이 직접 레이블링한 평가 데이터를 활용해 모델을 검증해 왔습니다. 하지만 이러한 방식은 서비스 검색 결과를 기반으로 평가되기 때문에 쉬운 Negative 케이스가 많으며, 검색어와 문서의 다양성이 부족한 한계가 존재합니다. 또한 서비스 로그를 그대로 사용할 경우, 자주 검색되는 쿼리에 과도하게 편향되고, Mid-Tail 검색어는 인터랙션 데이터가 부족하다는 문제가 있습니다.

이 문제를 해결하기 위해 검색팀은 Gecko(Deep Mind, 2024) 프레임워크를 참고하여 LLM 기반 학습 및 평가 프로세스를 구축했습니다. Gecko는 대형 언어모델이 가진 폭넓은 지식과 일반화 능력을 활용하여 저차원의 임베딩 모델 성능을 효과적으로 향상시키는 똑똑한 방법을 제시합니다.

  1. 임의의 문서를 선택하고, 이를 기반으로 LLM이 해당 문서와 관련된 검색어를 Task에 적합하게 생성(Generation)합니다.
  2. 생성된 검색어에 대해 임베딩 모델이 후보 문서를 추출합니다.
  3. 후보 문서 리스트를 LLM이 다시 리랭킹(Reranking)하여 점수를 부여합니다. LLM이 재정렬한 결과를 학습 데이터로 활용해 임베딩 모델을 업데이트합니다.


이 방식의 가장 큰 장점은 문서로부터 검색어를 생성하기 때문에 항상 1개 이상의 Positive 문서를 확실히 확보할 수 있습니다. 또한 LLM 리랭킹을 통해 더 적절한 Positive/Negative 샘플을 자동으로 선별할 수 있습니다. 그리고 검색어를 다양하게 생성할 수 있기 때문에 모델의 일반화 능력 향상에도 매우 효과적입니다.

▲ Model-in-the-Loop를 통해 대형언어모델인 LLM이 가진 능력을 작은 임베딩 모델로 Distillation
▲ Model-in-the-Loop를 통해 대형언어모델인 LLM이 가진 능력을 작은 임베딩 모델로 Distillation


검색팀은 이 파이프라인을 활용해 대량의 (Query, Positive, Negative) 데이터셋을 구축하고 있으며, 이를 모델 학습과 평가에 적극 활용하고 있습니다. 이러한 과정은 저차원 임베딩 모델이 대형 언어모델의 지식과 판단력을 효과적으로 전수받는 Knowledge Distillation의 기반이 됩니다. 더불어 LLM을 통해 생성되는 다양한 검색어와 문서들의 데이터셋은 모델의 일반화 성능을 지속적으로 높이는 데 중요한 역할을 합니다.


Embedding Quality : Alignment/Uniformity Loss

학습된 모델의 임베딩 퀄리티가 좋아졌는가를 평가하는 정량적인 지표로 Alignment Loss / Uniformity Loss (Wang et al, 2020)를 사용해 볼 수 있습니다.

  • Alignment Loss : 검색어와 의미적으로 연결된 문서가 얼마나 가깝게 위치하는가?
  • Uniformity Loss : 검색어와 문서 벡터들이 임베딩 공간에서 골고루 펴져있는가?

일반적으로 두 Loss 모두 작을수록 좋은 경향을 보이지만, 항상 낮다고 해서 성능이 좋아지는 것은 아닙니다. 예를 들어 Alignment Loss가 지나치게 작아지면 Positive 문서만 과도하게 강조되어 의미적으로 비슷한 다른 문서들에 대한 표현력이 떨어질 수 있습니다. 또 Uniformity Loss가 너무 줄어들면 임베딩이 지나치게 넓게 퍼져 의미적 유사도가 약해질 수 있기 때문에 두 지표의 균형이 중요합니다.

오늘의집 데이터로 파인튜닝한 BGE-M3 모델의 품질을 확인하기 위해, 학습 과정에서 사용되지 않은 사람이 구성한 별도의 테스트셋을 활용해 외부 모델과 비교 분석을 진행했습니다.

▲ 빨간색 테두리의 점은 전체 best model, 그리고 파란색 테두리의 점은 128 차원에서의 best model을 나타낸다. 파인튜닝 모델의 경우 alignment loss가 크게 감소하여 도메인에 적합한 데이터를 더 선호하도록 학습되었음을 알 수 있다. 또한 GOR 아이디어를 적용하여 NDCG 손실없이 uniform loss도 감소시킬 수 있다.
▲ 빨간색 테두리의 점은 전체 best model, 그리고 파란색 테두리의 점은 128 차원에서의 best model을 나타낸다. 파인튜닝 모델의 경우 alignment loss가 크게 감소하여 도메인에 적합한 데이터를 더 선호하도록 학습되었음을 알 수 있다. 또한 GOR 아이디어를 적용하여 NDCG 손실없이 uniform loss도 감소시킬 수 있다.


위 그림에서 보듯이 Alignment Loss는 파인튜닝의 긍정적인 효과를 잘 보여줍니다. 도메인에 맞는 Positive 문서들이 검색어와 더 가깝게 배치되면서 의미적 유사도가 증가했고, 이는 NDCG 향상으로 이어졌습니다. 또한 임베딩을 더 골고루 분산시키기 위해 Spread-Out Regularizer를 적용했을 때, NDCG 손실 없이도 Uniformity Loss를 효과적으로 낮출 수 있었습니다.

이러한 결과는 Qwen 등 다른 대형 언어모델과 비교했을 때도 더 낮은 수준입니다. NDCG만으로는 명확히 드러나지 않는 부분이 있지만, 벡터들이 임베딩 공간에서 더 잘 퍼짐으로써 모델의 일반화 성능을 높이는 데 도움이 될 수 있음을 보여줍니다.


Matryoshka Representation Learning 학습 효과

Matryoshka 학습의 가장 큰 장점은 저차원에서도 성능 손실이 적다는 것에 있습니다. 특히 오늘의집 도메인에 적합한 데이터셋으로 파인튜닝한 모델의 경우, 그 표현력이 더 뛰어나기 때문에 성능손실이 더 적다고 할 수 있습니다.


검색팀에서는 인덱스 최적화와 표현력의 크기, 그리고 성능을 고려하여 손실이 적으면서도 효율적인 128 차원의 벡터를 서비스에 사용했습니다.


ColBERT Token Alignment를 통한 모델 설명력 향상

BGE-M3 모델은 ColBERT Layer를 함께 학습하기 때문에 토큰 단위의 벡터를 계산할 수 있다는 강점이 있습니다. 물론 Transformer 기반 모델에서도 마지막 Hidden State의 토큰 벡터를 활용할 수 있지만, 검색어-문서 간 토큰 히트맵을 직관적으로 해석하기 어렵다는 한계가 존재합니다.

반면 ColBERT는 각 검색어 토큰과 가장 높은 유사도(MaxSim)를 갖는 문서 토큰을 명확하게 찾아낼 수 있습니다. 이를 통해 검색어의 어느 토큰이 문서의 어떤 토큰과 연결되는지 시각적으로 확인할 수 있어, 모델의 동작 방식을 보다 쉽게 설명할 수 있습니다.

▲ ‘2겹으로된 유리잔’ 검색어에 대한 문서와의 Alignment Map으로 (’2겹 유리잔’, ‘이중유리컵’)에 가장 유사하게 맵핑된 것을 확인해볼 수 있다.
▲ ‘2겹으로된 유리잔’ 검색어에 대한 문서와의 Alignment Map으로 (’2겹 유리잔’, ‘이중유리컵’)에 가장 유사하게 맵핑된 것을 확인해볼 수 있다.


예를 들어, 위 그림의 Alignment Map에서는 모델이 다음과 같은 의미적 매칭을 수행하고 있음을 확인할 수 있습니다.

  • ‘2겹’ ↔ ‘이중’
  • ‘유리잔’ ↔ ‘유리컵’

이처럼 의미적으로 가까운 표현을 정확히 매핑하는 모습은 모델의 언어적 이해 능력이 높다는 점을 뒷받침해 줍니다. 또한 이러한 Token Alignment 기반 설명력을 활용하면, 랭커가 특정 문서를 선택한 이유를 더욱 투명하게 해석할 수 있다는 장점도 있습니다.


시맨틱 검색의 다음 여정 : 더 발전된 문맥이해를 위한 컨텍스트 보강과 모달리티 확장

Retrieval 기반 시맨틱 검색을 도입한 결과, 유저 인터랙션이 2.45% 증가하고 CTR 역시 2.82% 상승하는 긍정적인 성과를 확인했습니다. 또한 더 다양한 검색어에 대해 높은 관련성을 가진 상품들이 매칭되면서, 검색 결과 수도 크게 확대되었습니다.

임베딩 모델은 키워드 매칭 기반 접근의 한계를 보완하는 대표적인 방법입니다. 그러나 BM25 대비 설명 가능성이 낮고, Contrastive Learning 기반 메트릭 학습은 저품질 케이스를 정교하게 다루기 어렵다는 까다로움이 있습니다. 또한 추론 과정에서 어떤 컨텍스트를 주입하느냐에 따라 모델이 풀 수 있는 문제의 폭이 크게 달라진다는 점 역시 중요하게 고려되어야 합니다. 따라서 검색팀은 더 안정적이고 풍부한 시맨틱 검색을 구축하기 위해 현재 다음과 같은 방향을 중점적으로 진행하고 있습니다.

  • 상품 상세 정보, 리뷰 등 다양한 데이터 소스를 활용해 검색 품질을 끌어올릴 수 있는 고품질 학습 및 추론 컨텍스트 확장
  • 다양한 언어, 도메인 데이터셋으로 스케일 확장
  • 이미지–텍스트 연결(예 : Frozen 기반 이미지 백본 결합)을 통한 색상·스타일·형태 등 주요 시각 피처를 반영
  • Model-in-the-Loop 기반의 지속적인 모델 개선 사이클


오늘의집 검색은 상품, 사진, 집들이, 노하우, 아파트, 시공 등 다양한 도메인에서 사용자가 원하는 결과를 정확하게 찾을 수 있는 서비스를 목표로 하고 있습니다. 검색팀은 텍스트뿐 아니라 이미지와 비디오 등 여러 모달리티를 아우르는 검색 경험(오늘의집 렌즈 - 텍스트를 넘어 이미지로 확장되는 검색 경험)을 제공하기 위해 서비스를 확장하고 있습니다. 앞으로의 변화에도 많은 관심 부탁드립니다.

오늘의집에서 당신을 찾고 있습니다!
Senior Backend Engineer, Tech Lead & Manager, CommerceSenior Frontend Engineer, Tech Lead & Manager, CommerceSenior Backend Engineer, AdsSenior Backend Engineer, Core PlatformSenior Machine Learning Engineer, SearchSenior Machine Learning Engineer, Vision/GenAISenior Machine Learning Engineer, Ads & RecommendationSenior Android Engineer, Client FoundationBackend Engineer, Core PlatformBackend Engineer, Interior & LifeBackend Engineer, CommerceBackend Engineer, AdsFrontend Engineer, ContentFrontend Engineer, Interior & LifeFullstack Engineer, Life ServiceFullstack Product Engineer, AI AgentMachine Learning Engineer, ML PlatformMachine Learning Engineer, SearchMachine Learning Engineer, Ads & RecommendationMachine Learning Engineer, Ads & Recommendation (전문연구요원)iOS Engineer, ContentCloud EngineerSenior Data Analytics EngineerData Analytics EngineerAI Solutions EngineerQA EngineerQA Assistant (계약직)[오늘의집페이] Backend Engineer[오늘의집페이] Fullstack Engineer
목록으로 돌아가기