본문 바로가기
C.W.K.
Stream
Lesson 03 of 05 · published

cross-encoder로 다시 순위 매기기

~22 min · hybrid, reranking

Level 0Scout
0 XP0/41 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

2단계 검색

벡터 검색과 BM25는 쿼리와 각 문서를 따로 표현한 뒤 비교하는 bi-encoder 방식이야. 빠르지만 모델이 쿼리와 문서를 함께 읽지는 않아.

cross-encoder는 쿼리와 후보 문서를 한 쌍으로 transformer에 넣어 둘의 문맥을 함께 반영한 관련성 점수 하나를 만들어. 훨씬 정확하지만 미리 계산할 수 없어 훨씬 느리지. 그래서 표준 구조는 다음과 같아.

  1. 1단계 — 벡터 검색과 BM25 같은 빠른 검색기가 후보 50개를 반환해.
  2. 2단계 — cross-encoder가 그 50개의 순위를 다시 매겨 최종 상위 5개를 찾아.

알아둘 만한 오픈소스 cross-encoder

  • BGE-reranker-v2-m3 — 다국어를 지원하며 2026년 초 오픈소스 가운데 성능이 뛰어나.
  • cross-encoder/ms-marco-MiniLM-L-6-v2 — 영어용 소형 모델로 CPU에서도 작동해.
  • jina-reranker-v2-base-multilingual — 빠르고 작으며 여러 언어를 지원해.

Code

sentence-transformers CrossEncoder로 상위 50개 다시 정렬하기·python
from sentence_transformers import CrossEncoder

reranker = CrossEncoder('BAAI/bge-reranker-v2-m3', max_length=512)

def rerank(query: str, candidates: list[dict], top_k: int = 5) -> list[dict]:
    pairs = [(query, c['text']) for c in candidates]
    scores = reranker.predict(pairs, batch_size=16)
    for c, s in zip(candidates, scores):
        c['rerank_score'] = float(s)
    candidates.sort(key=lambda c: -c['rerank_score'])
    return candidates[:top_k]

stage1 = vector_then_bm25(query, k=50)
final  = rerank(query, stage1, top_k=5)
호스팅형 재순위화 모델(Cohere)·python
import cohere
co = cohere.Client()

resp = co.rerank(
    model='rerank-english-v3.0',
    query=query,
    documents=[c['text'] for c in stage1],
    top_n=5,
)
for r in resp.results:
    print(r.relevance_score, stage1[r.index]['text'][:80])

External links

Exercise

상위 세 정답을 직접 표시한 쿼리 30개를 준비해. 벡터만 사용한 경우, 벡터와 BM25를 RRF로 결합한 경우, 거기에 cross-encoder 재순위화까지 더한 경우의 nDCG@5를 비교해. 보통 마지막 단계에서 가장 크게 좋아지는데, 실제 차이를 측정해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.