← Ascendy EN

ml

벡터검색에서 리랭커를 뺐다 — '아기 사진 다 찾아줘'가 무너뜨린 가정

· Ascendy Engineering


TL;DR

소스 노트. 이 글은 운영자 인터뷰로 썼다. 모델 스펙은 발행 시점에 공식 출처(HF Qwen3-VL-Embedding, arXiv 통합 프레임워크 논문)로 fact-check했고, 내부 컬렉션·인프라 식별자와 정확한 차원 튜닝값은 일반화했다(모델명은 공개 모델이라 유지). 제품 동기는 사진은 저장이 아니라 ‘못 찾는 것’이 문제였다와 이어진다.

두 개의 결정, 다른 이유

사진검색의 검색 스택을 손보면서 두 가지를 결정했는데, 둘은 별개다. 헷갈리기 쉬워 먼저 갈라둔다.

”아기 사진 다 찾아줘”가 무너뜨린 가정

리랭커를 빼야겠다고 깨달은 건 테스트 중이었다. 시나리오 하나가 가정을 무너뜨렸다.

“아기가 나온 사진 다 찾아줘.”

이런 쿼리는 수천 장을 돌려줘야 한다. 그리고 여기서 중요한 구분이 있다 — 이건 precision 문제가 아니라 recall 문제다. “상위 10장이 얼마나 정확한가”가 아니라 “있는 거 다 끌어왔는가”가 성공 기준이다.

리랭커는 이 벌크에 구조적으로 안 맞았다.

한 줄로: 리랭커는 precision@(작은 k) 도구지, “다 찾아줘”라는 recall 도구가 아니다. 우리는 리랭커를 잘못된 일에 쓰고 있었다.

그럼 쿼리 타입으로 나누면 되잖아? — 안 된다

가장 자연스러운 반론이 여기서 나온다. “벌크 쿼리(‘다 찾아줘’)엔 리랭커 끄고, 콕 집는 쿼리(‘내 아들 촛불 부는 그 사진’)엔 켜면 되잖아.” 쿼리 타입별 분기. 고려했고, 포기했다. 두 가지 이유 때문이다.

첫째, 자연어가 조건을 깔끔히 안 가른다. 한 문장에 넣을 조건뺄 조건이 섞일 수 있다 — “강아지 나온 건 빼고 아기 사진은 다 보여줘”처럼. 이걸 LLM이 완벽하게 분해해서 “이 부분은 벌크, 이 부분은 정밀”로 라우팅하는 건 불가능에 가깝다. 한 번이라도 틀리면 사용자는 엉뚱한 결과를 받는다.

둘째, 설령 갈라도 의도를 추론할 수 없다. “다 보여줘”가 누군가에겐 문자 그대로 수천 장 전부이고, 누군가에겐 그냥 많이 보여줘다. 같은 표현 뒤의 의도를 시스템이 함부로 단정하면, 절반의 사용자는 매번 기대와 다른 결과를 본다. 표현은 같은데 의도가 갈리는 걸, 자연어만 보고 안전하게·일관되게 가려내긴 어렵다.

그래서 분기 대신 리랭커를 통째로 뺐다. 이 결정을 뒷받침한 건, 임베딩만으로도 정밀도가 멀쩡했다는 사실이다 — 처음 뺐을 때부터 검색 품질 자체가 나쁘지 않았다.

대체 — MRL로 만든 2단계 (리랭커 없이 정밀도)

리랭커를 빼고 정밀도를 보완할 방법을 고민했는데, 생각보다 쉽게 찾았다. Qwen3-VL-Embedding에는 MRL(Matryoshka Representation Learning)이 적용돼 있다. 하나의 임베딩 벡터를 짧게 잘라(truncate) 써도 의미가 보존되는 성질이다 — 마트료시카 인형처럼, 앞쪽 일부 차원만 떼어내도 그 자체로 쓸 만한 임베딩이 된다. 공식 스펙상 임베딩 차원은 최대 4096(2B 모델은 2048, 8B 모델은 4096)이고, 64~4096 범위에서 사용자가 출력 차원을 자유롭게 정할 수 있다.

이걸로 2단계를 만들었다.

  1. 저차원 1차 필터 — 낮은 차원으로 전체를 빠르고 싸게 훑어 후보를 좁힌다. 차원이 낮으니 비교가 가볍다.
  2. 고차원 2차 정밀화 — 좁혀진 후보만 높은 차원으로 다시 비교해 순위를 정밀하게 만든다.

별도의 cross-encoder 리랭커 모델 없이, 같은 임베딩 한 모델 안에서 리랭커와 비슷한 효과를 낸다. 단, 로직은 다르다 — 이건 차원을 달리한 2단계 dense 검색이지, 쿼리-문서 쌍을 재점수하는 cross-encoder가 아니다. coarse-to-fine으로 정밀도를 끌어올리되, 벌크(저차원 1차 필터)는 막지 않는다.

결과: 정밀도 멀쩡, 벌크 가능, 스택은 모델 하나만큼 단순해졌다.

가져갈 것


저작·인용: 이 글은 Ascendy Engineering이 작성했으며 출처 표기 시 재인용 가능합니다. 잘못된 정보를 발견하면 GitHub 이슈로 알려주세요.


Tags: vector-search, embeddings, reranker, matryoshka, retrieval, rag