RAG에 cross-encoder 리랭커를 붙인 전후를 한국어 문서로 직접 측정했다
서동현
@bigdata_seo
RAG 답변이 자꾸 질문과 살짝 동떨어진다는 체감이 있어서, 감으로 두지 않고 cross-encoder 리랭커를 붙인 전후를 숫자로 재봤다. 결론부터: 정답 포함률은 분명히 올랐고, 대신 검색 지연이 거의 두 배가 됐다. 둘 다 적은 폭이 아니라 워크로드에 따라 채택 여부가 갈린다.
구성 변경
원래 파이프라인은 embedding으로 바로 top-5를 뽑아 LLM에 던지는 단순 구조였다. 이걸 두 단계로 쪼갰다.
- 1단계: embedding으로 top-30 retrieval (recall 우선, 넓게 건짐)
- 2단계: cross-encoder 리랭커로 30개를 다시 점수내 top-5만 LLM에 전달
리랭커는 처음에 Cohere rerank API로 붙였다가, 비용과 데이터 외부 전송 문제로 bge-reranker-v2-m3 셀프호스팅으로 갈아탔다.
측정 환경
- 한국어 문서 위주, 청크 약 1.8만 개
- 질의 120개를 수동 라벨링 (정답 청크가 결과에 포함되는지)
- 지표: top-5 안에 정답 청크가 들어오는 비율
정답 top-5 포함 검색 지연
리랭커 없음 120건 중 79 ~800ms
리랭커 추가 120건 중 101 ~1.4초
79→101이면 무시할 차이가 아니다. LLM 최종 답변도 눈에 띄게 정돈됐는데, 동떨어진 청크가 컨텍스트에 덜 섞이니 모델이 헷갈릴 여지가 줄어든 것으로 보인다.
대가는 지연
800ms에서 1.4초로 늘었다. retrieval 자체는 그대로고, 30개를 cross-encoder로 다시 채점하는 비용이 통째로 붙은 것이다. 이 추가 지연이 케이스에 따라 치명적이다.
- 채팅처럼 한 번에 한 응답을 주는 구조: 1.4초는 사용자 체감에 묻힌다. 채택.
- 실시간 자동완성, 타이핑 중 추천: 못 쓴다. 이 워크로드였으면 롤백했을 것이다.
즉 리랭커 도입은 "품질 vs 응답 지연" 트레이드오프이고, UX가 동기 응답을 허용하는지가 선결 조건이다.
한국어에서 주의할 점
bge-m3 계열이 멀티링궐이라고는 하지만, 공개된 영어 벤치 수치를 믿고 한국어 문서에 그대로 박으면 안 된다. 도메인 어휘가 많은 한국어 문서에서는 리랭커가 오히려 무관한 청크를 위로 올리는 케이스도 있었다. bge-reranker-v2-m3와 Cohere rerank 중 무엇이 나은지는 본인 데이터로 직접 A/B를 돌려야 한다. 내 데이터셋에서는 m3가 이겼지만 이건 도메인 의존도가 크다.
정리하면, 답변 품질이 이상할 때 프롬프트부터 만지기 쉬운데 retrieval 품질을 먼저 측정해보길 권한다. 리랭커는 그 retrieval 단계를 보강하는 가장 효과가 큰 한 수였고, 다만 지연 예산이 있는 워크로드에서만 켤 수 있는 카드다.