RAG 답변이 자꾸 빗나가서 리랭커(re-ranker)를 붙이려고 하면 고를 게 여럿 나와요. Cohere·Voyage 같은 API 를 쓸지, 허깅페이스의 크로스 인코더를 직접 띄울지, 아예 LLM 에게 순서를 매기게 할지요. 결론부터 말하면 처음에는 API 크로스 인코더에 후보 20~50개로 시작하고, 비용은 모델 단가보다 후보 수로 조절해요. LLM 리랭킹은 같은 후보 수에서 수 배~수십 배 비싸서 질의가 적고 판정이 까다로운 곳에만 써요.
이 글은 내부 구조보다 고를 때 필요한 숫자를 다뤄요. 단가는 Voyage AI 가격표, Cohere 가격표, OpenAI API 가격표를 2026년 10월 31일에 열어 확인한 값만 썼고, 품질 숫자는 논문과 모델 카드 값만 옮겼어요. 비용·시간 계산은 직접 했고 가정은 그때그때 밝혀요.
비용과 지연은 결국 후보 수 k, 청크 길이, 월 질의 수 세 숫자로 정해져요. 1차 검색 쪽 비용(임베딩 단가·벡터 메모리)은 임베딩 모델 고르기에서 따로 계산했으니, 여기서는 리랭킹 단계만 봐요.
리랭커 품질은 얼마나 차이 나나 — 같은 조건에서 잰 숫자
품질 숫자는 실험 조건이 같을 때만 나란히 놓을 수 있어요. LLM 리랭킹을 다룬 RankGPT 논문(Sun 외, EMNLP 2023)의 표 1은 모든 방법이 같은 BM25 상위 100개를 다시 매기게 해서 비교했어요. 그중 TREC DL19(질문 43개)의 nDCG@10 을 옮기면 이래요.
리랭킹을 붙이는 효과가 모델 간 차이보다 훨씬 커요. 50.58에서 어떤 리랭커든 붙이면 65~75점대예요. 지도 학습한 크로스 인코더끼리는 2~3점 차이로 촘촘하고, LLM 이라고 다 낫지도 않아요. gpt-3.5-turbo 는 340M 짜리 monoBERT 보다 낮았고 gpt-4 가 가장 높았어요.
작은 오픈소스 모델 쪽은 ms-marco-MiniLM-L6-v2 모델 카드에 크기별 표가 있어요. 위 표와 실험 조건이 달라서 같은 차트에 섞지 않고 따로 봐요.
| 모델 (모델 카드 기준) | nDCG@10 (TREC DL19) | MRR@10 (MS MARCO dev) | 초당 문서 수 (V100) |
|---|---|---|---|
| ms-marco-TinyBERT-L2-v2 | 69.84 | 32.56 | 9,000 |
| ms-marco-MiniLM-L2-v2 | 71.01 | 34.85 | 4,100 |
| ms-marco-MiniLM-L4-v2 | 73.04 | 37.70 | 2,500 |
| ms-marco-MiniLM-L6-v2 | 74.30 | 39.01 | 1,800 |
| ms-marco-MiniLM-L12-v2 | 74.31 | 39.02 | 960 |
L6 과 L12 는 점수가 0.01점 차이인데 처리량은 1,800 대 960이에요. 다만 영어 MS MARCO 로만 학습한 2,270만 파라미터 모델이라, 한국어 문서라면 층 수와 속도의 관계만 참고해요.
리랭커 API 가격 비교 — Voyage·Cohere, 후보 수별 월 비용
2026년 10월 31일 기준 두 회사의 리랭커 단가예요.
| 모델 | 100만 토큰당 | 한 번에 볼 수 있는 길이 | 비고 |
|---|---|---|---|
| Voyage rerank-3 | 0.05달러 | 32,000토큰 | 계정당 2억 토큰 무료 |
| Voyage rerank-3-lite | 0.02달러 | 32,000토큰 | 지연 우선 모델 |
| Cohere Rerank 5 Pro | 0.05달러 | 32,768토큰 | 100개 넘는 언어 |
| Cohere Rerank 5 Fast | 0.02달러 | 32,768토큰 | 처리량 우선 모델 |
길이 한도는 Voyage 리랭커 문서와 Cohere Rerank 모델 문서 기준이에요. Voyage 는 과금 토큰을 질문 토큰 × 문서 수 + 문서 토큰 합 으로 센다고 가격표에 공식을 적어 두었어요. 질문이 문서마다 한 번씩 다시 붙는 크로스 인코더 구조를 그대로 반영한 셈이에요. Cohere 는 같은 단가를 쓰지만 세는 공식은 가격표에 없어서, 응답의 meta.billed_units.input_tokens 로 실제 청구 토큰을 확인해야 해요.
Voyage 공식으로 질문 30토큰·청크 400토큰을 넣으면 질문 하나당 과금 토큰은 k × 430 이에요. 월 100만 질의로 곱하면 이래요.
| 후보 수 k | 질문당 토큰 | 월 토큰 | 0.02달러 모델 | 0.05달러 모델 |
|---|---|---|---|---|
| 20 | 8,600 | 86억 | 172달러 | 430달러 |
| 50 | 21,500 | 215억 | 430달러 | 1,075달러 |
| 100 | 43,000 | 430억 | 860달러 | 2,150달러 |
모델을 올리면 2.5배, k 를 20에서 100으로 늘리면 5배라 k 가 더 큰 손잡이예요. 무료 2억 토큰은 k=50 이면 약 9,300질의라 평가 단계용이에요.
문서 길이 한도도 봐요. Cohere 리랭킹 모범 사례 문서에 따르면 v5 의 max_tokens_per_doc 기본값이 4,096이라 더 긴 문서는 잘리고, 질문은 최대 2,048토큰이에요. 긴 문서를 통째로 넘기면 청구 토큰만 늘고 뒷부분은 점수에 안 들어갈 수 있으니 청크 단위로 넘겨요.
LLM 리랭킹 비용 — 순서 생성 방식은 몇 배 비싼가
LLM 리랭킹은 후보 여러 개를 한 프롬프트에 넣고 "관련 있는 순서대로 번호를 나열하라"고 시키는 방식이에요. RankGPT 논문은 모델이 100개를 한 번에 다루지 못해서 창 크기 20, 보폭 10 으로 뒤에서부터 밀어 올리는 슬라이딩 창을 썼어요. 후보 100개면 창이 (100 − 20) ÷ 10 + 1 = 9개이고, 앞 창의 결과가 다음 창에 들어가야 해서 9번을 순서대로 호출해야 해요.
OpenAI 가격표의 표준 요금(100만 토큰당 입력/출력)은 gpt-5.4-nano 0.20/1.25달러, gpt-5.4-mini 0.75/4.50달러예요. 창 하나에 지시문 200토큰 + 문서 20개 × 400토큰 = 입력 8,200토큰, 출력은 번호 나열 100토큰으로 잡고 계산했어요.
후보 20개만 놓고 봐도 nano 가 rerank-3-lite 의 약 10배, mini 는 약 38배예요. 후보 100개에서는 mini 가 월 5만 9,400달러로 rerank-3 의 약 28배가 돼요. 사고 토큰이 붙는 추론 모델이라면 effort 설정에 따라 출력이 크게 늘 수 있어서, 추론 모델 effort 고르는 법에서 정리한 대로 리랭킹 용도에는 가장 낮은 설정부터 재 보는 게 안전해요.
그래도 "2025년 이후 개정된 조항만" 처럼 판정 기준이 질문마다 바뀌는 경우에는 지시문으로 기준을 바꿀 수 있는 LLM 이 맞아요. 질의가 하루 수백 건인 사내 도구라면 월 몇 달러라 부담도 없어요. 크로스 인코더로 50개를 10~20개로 줄인 뒤 LLM 을 한 번만 돌리면 창이 하나라 호출도 한 번이에요.
크로스 인코더 직접 서빙 — 지연과 손익분기 계산
직접 띄우면 토큰 요금은 없고 서버 시간만 들어요. 모델 카드의 초당 문서 수로 후보 k 개를 처리하는 데 걸리는 순수 계산 시간을 어림하면 이래요.
자릿수만 잡는 값이고, 실제 지연은 청크 길이·배치·GPU 에 따라 달라요. 다국어 모델인 bge-reranker-v2-m3는 0.6B 파라미터로 MiniLM-L6(2,270만)보다 훨씬 커서 같은 GPU 에서 몇 배 느릴 수 있고, 예제 코드는 max_length=512 로 잘라요.
비용은 가동률이 정해요. 월 100만 질의 × 후보 50개 = 5,000만 쌍인데, MiniLM-L6 의 초당 1,800개로 나누면 한 달에 GPU 약 7.7시간 분량이에요. 서버를 상시 띄우면 나머지 시간은 놀아요. 시간당 1달러 서버(월 730달러)를 가정하고 API 와 손익분기를 계산하면 이래요.
| 비교 대상 (후보 50개) | 질의당 API 비용 | 월 730달러로 살 수 있는 질의 수 |
|---|---|---|
| 0.02달러 모델 (rerank-3-lite·Rerank 5 Fast 단가) | 0.00043달러 | 약 170만 건 |
| 0.05달러 모델 (rerank-3·Rerank 5 Pro 단가) | 0.001075달러 | 약 68만 건 |
월 질의가 이 선을 꾸준히 넘어야 직접 서빙이 싸지고, 운영 인건비는 빠져 있어요. 다만 문서를 외부로 보낼 수 없다면 비용과 상관없이 직접 서빙이고, 그때는 지연과 품질로 모델을 골라요.
내 환경에서 지연 재기
남의 처리량 숫자보다 내 청크로 잰 숫자가 정확해요. 아래는 실제 청크 길이와 후보 수로 p50·p95 를 재는 최소 코드예요.
import time, statistics
from sentence_transformers import CrossEncoder
model = CrossEncoder("BAAI/bge-reranker-v2-m3", max_length=512)
question = "연차를 다음 해로 넘길 수 있나요?"
chunks = [open(p, encoding="utf-8").read() for p in sample_paths[:50]] # 실제 청크 50개
model.predict([(question, c) for c in chunks[:5]]) # 첫 호출 워밍업
times = []
for _ in range(30):
t0 = time.perf_counter()
model.predict([(question, c) for c in chunks], batch_size=50)
times.append((time.perf_counter() - t0) * 1000)
times.sort()
print(f"p50 {statistics.median(times):.0f} ms / p95 {times[int(len(times) * 0.95) - 1]:.0f} ms")
API 도 같은 질문·청크로 재서 나란히 놓으면 외부 왕복을 없애는 값어치를 숫자로 볼 수 있어요. batch_size 를 후보 수와 같게 두면 한 번에 계산이 끝나요.
후보 수 k 정하는 법 — 평가 세트로 끊는 지점 찾기
k 를 감으로 정하면 비용이 몇 배로 흔들려요. 실제 질문 100~200개와 정답 청크를 짝지은 평가 세트로 두 숫자를 같이 재면 돼요.
- 1차 검색 재현율: 상위 k 안에 정답이 들어온 비율(Recall@k)을 k = 10, 20, 50, 100 으로 재요. 리랭커가 올릴 수 있는 천장이에요.
- 리랭킹 뒤 상위 n 적중률: LLM 에 실제로 넣는 n 개(보통 3~5개) 안에 정답이 있는 비율을 k 별로 재요.
def hit_at(ranked_ids, gold_ids, n):
return any(i in gold_ids for i in ranked_ids[:n])
for k in (10, 20, 50, 100):
recall, top5 = 0, 0
for q in eval_set: # {"text":..., "gold": {...}}
cand = first_stage(q["text"], k) # [(chunk_id, text), ...]
recall += hit_at([c[0] for c in cand], q["gold"], k)
scores = reranker.predict([(q["text"], t) for _, t in cand])
order = [cand[i][0] for i in sorted(range(len(cand)), key=lambda i: -scores[i])]
top5 += hit_at(order, q["gold"], 5)
print(k, f"Recall@k {recall/len(eval_set):.2%}", f"리랭킹 후 Hit@5 {top5/len(eval_set):.2%}")
Hit@5 가 더 오르지 않는 k 가 답이에요. 그 지점이 30이면 k=100 은 비용만 3배 넘게 내는 셈이에요. Recall@100 자체가 낮다면 1차 검색(하이브리드 검색·청크 크기·임베딩 모델)을 고칠 차례이고, 인덱스 탐색 폭이 좁아 재현율이 깎이는 경우도 있으니 벡터 인덱스 고르기의 ef_search 설명도 함께 보세요.
상황별 리랭커 추천
| 상황 | 추천 | 이유 |
|---|---|---|
| 처음 리랭커를 붙여 볼 때 | API 크로스 인코더(저가 모델), k=20~50 | 무료 토큰으로 평가까지 끝나요 |
| 한국어·영어가 섞인 문서 | 다국어 명시 모델 2~3개를 같은 평가 세트로 비교 | 영어 전용 모델은 한국어 품질 보장 없음 |
| 사내 문서를 외부로 못 보낼 때 | 다국어 크로스 인코더 직접 서빙 | 규정이 먼저, 입력 길이 한도 확인 |
| 월 질의 수백만 건 이상, 꾸준함 | 직접 서빙 손익 계산 후 결정 | 0.05달러 단가면 약 68만 건부터 |
| 질의가 적고 기준이 자주 바뀌는 도구 | 크로스 인코더로 10~20개로 줄인 뒤 LLM 한 번 | 창 하나라 호출도 한 번 |
리랭커 도입 체크리스트
- 평가 세트: 실제 질문 100~200개 + 정답 청크. 없으면 고를 근거가 없어요.
- Recall@k 먼저: 낮으면 리랭커보다 1차 검색을 먼저 고쳐요.
- k 결정: k 별 리랭킹 뒤 Hit@n 이 더 오르지 않는 지점에서 끊어요.
- 길이 한도와 학습 언어: 질문 + 청크가 모델 한도를 넘으면 뒷부분이 조용히 잘려요. 다국어 지원도 모델 카드에서 확인해요.
- 점수 해석: ms-marco 계열은 logit, Cohere v5 는 0~1 보정 점수를 내요. 버리는 기준점은 어느 쪽이든 내 평가 세트로 정해요.
- 청구 토큰 확인: 첫 주에는 Cohere
billed_units·Voyage 사용량을 계산과 맞춰 봐요. - 지연 예산과 대체 경로: 단계별 p95 를 재서 리랭킹 몫을 정하고, 그 시간을 넘거나 실패하면 1차 검색 순서 그대로 넘겨요.
- ID 매핑: 위치 번호를 원래 문서 ID 로 바꾸는 코드를 테스트로 고정해요.
자주 묻는 질문
리랭커는 꼭 붙여야 하나요?
필수는 아니에요. RankGPT 논문에서는 BM25 에 붙이면 nDCG@10 이 50점대에서 65~75점대로 올랐지만, 1차 검색이 이미 좋으면 개선 폭이 작아요. 리랭커 없이 상위 5개 정답률을 먼저 재 보세요.
리랭킹 API 비용을 가장 쉽게 줄이는 방법은 뭔가요?
후보 수 k 를 줄이는 거예요. 과금 토큰이 k 에 거의 정비례해서 100에서 50으로 줄이면 비용도 절반이에요. 평가 세트로 정답률이 더 오르지 않는 k 를 찾고, 청크를 필요 이상 길게 넘기지 마세요.
LLM 으로 리랭킹하면 크로스 인코더보다 더 정확한가요?
모델에 따라 달라요. RankGPT 논문에서 gpt-4 는 75.59점으로 가장 높았지만 gpt-3.5-turbo 는 65.80점으로 340M 크로스 인코더(70.50점)보다 낮았어요. 비용은 수 배~수십 배라 질의가 적은 곳에 한정하는 게 좋아요.
영어 크로스 인코더를 한국어 문서에 써도 되나요?
점수는 나오지만 품질은 보장되지 않아요. ms-marco 계열은 영어 데이터로만 학습했어요. 다국어 지원이 명시된 모델(Rerank 5, rerank-3, bge-reranker-v2-m3 등)을 한국어 평가 세트로 비교해 고르세요.
직접 띄운 리랭커가 API 보다 싸지는 기준은 뭔가요?
월 서버비를 질의당 API 비용으로 나눠요. 후보 50개·청크 400토큰이면 질의당 0.00043달러(0.02달러 모델)·0.001075달러(0.05달러 모델)라, 월 730달러 서버는 각각 약 170만·68만 건을 넘어야 본전이에요. 운영 인건비는 별도예요.
정리
평가 세트로 Recall@k 를 재서 천장을 확인하고, 리랭커 없이도 충분한지 본 다음, 붙인다면 API 크로스 인코더에 k=20~50 으로 시작해요. 비용은 단가보다 후보 수와 청크 길이가 정하고, 직접 서빙은 외부 전송이 막혔거나 질의가 많을 때 따져요. LLM 리랭킹은 후보를 줄인 뒤 마지막 한 번에만 써요.
1차 검색 비용은 임베딩 모델 고르기, 재현율은 벡터 인덱스 고르기, 사고 토큰 비용은 추론 모델 effort 고르는 법을 함께 보세요. 단가는 2026년 10월 31일 기준이니 도입 직전에 다시 확인하세요.
더 깊이 읽기
이 글은 실무에서 판단할 때 필요한 것 위주로 정리했어요. 같은 주제의 내부 동작 원리는 devboi 기술 블로그의 RAG 리랭커 원리 — 바이 인코더 vs 크로스 인코더에서 도식과 코드로 단계별로 풀었어요.