AI Engineering Academy · 강의

Cohere와 BGE를 활용한 교차 인코더 재순위 지정

Cohere의 재순위 지정 엔드포인트와 BGE-reranker 모델을 통합해 질의-문서 쌍의 점수를 계산하고, 상위 k개 청크를 실제 관련성에 따라 다시 정렬합니다.

레슨 2/413개 단계

Cohere와 BGE를 활용한 교차 인코더 재순위 지정은(는) CoddyKit의 무료 AI Engineering Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Engineering Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Engineering Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

교차 인코더란 무엇인가요?

교차 인코더는 질의와 문서를 하나로 연결한 입력으로 받아 관련성 점수를 출력하는 신경망 모델입니다. 질의와 문서를 별도로 임베딩하는 바이 인코더와 달리, 교차 인코더의 어텐션 계층은 두 텍스트를 동시에 확인하므로 바이 인코더가 포착하지 못하는 세밀한 관련성 신호를 모델링할 수 있습니다. 이러한 공동 처리가 교차 인코더가 순위 지정에서 훨씬 더 정확한 이유입니다.

# Bi-encoder: separate encoding
query_vec = encoder.encode(query)          # [768] vector
doc_vec = encoder.encode(document)         # [768] vector
score = cosine_similarity(query_vec, doc_vec)  # compare independently

# Cross-encoder: joint encoding
combined_input = '[CLS] ' + query + ' [SEP] ' + document + ' [SEP]'
logits = cross_encoder.forward(combined_input)  # score from joint attention
# The model attends from every query token to every document token

Cohere Rerank API

Cohere Rerank는 클라우드에서 호스팅되는 교차 인코더 재순위 지정 API로, 질의와 최대 1,000개의 문서 텍스트 목록을 받아 관련성 점수를 반환합니다. 고품질 순위 지정 데이터 세트로 학습한 대규모 교차 인코더 모델을 사용하며, 대부분의 벤치마크에서 직접 호스팅하는 소형 교차 인코더보다 일관되게 뛰어난 성능을 보입니다. API 요금은 재순위 지정한 문서 1,000개 단위로 부과됩니다.

import cohere

co = cohere.Client('YOUR_COHERE_API_KEY')

candidates = [
    'How to configure pgvector in PostgreSQL for vector search',
    'BM25 scoring formula and hyperparameters explained',
    'Installing and using the pgvector extension for embeddings',
    'Hybrid search combining BM25 and dense retrieval',
]

result = co.rerank(
    model='rerank-english-v3.0',
    query='pgvector setup guide',
    documents=candidates,
    top_n=3,
    return_documents=True,
)

for item in result.results:
    print(f'Score {item.relevance_score:.4f}: {item.document.text[:60]}')

RAG 파이프라인에서 Cohere Rerank 사용하기

Cohere Rerank를 RAG 파이프라인에 통합하는 방법은 간단합니다. 벡터 저장소에서 후보 20~50개를 검색하고, 해당 텍스트를 추출한 뒤, Cohere Rerank API를 호출하고, 상위 K개 결과를 가져와 LLM에 전달합니다. 지연 시간은 일반적으로 100~300ms 추가되며, 정밀도가 향상되어 최종 답변이 더 좋아진다면 충분히 감수할 수 있는 수준입니다.

import cohere
from openai import OpenAI

co = cohere.Client('COHERE_KEY')
client = OpenAI()

def rag_with_rerank(question: str, retriever, top_k: int = 5) -> str:
    # Stage 1: coarse retrieval
    candidates = retriever.invoke(question)  # returns 30 docs
    texts = [doc.page_content for doc in candidates]

    # Stage 2: Cohere re-ranking
    rerank_result = co.rerank(
        model='rerank-english-v3.0',
        query=question,
        documents=texts,
        top_n=top_k,
    )
    top_texts = [texts[r.index] for r in rerank_result.results]
    context = '\n\n'.join(top_texts)

    # Stage 3: generation
    response = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[
            {'role': 'system', 'content': 'Answer using only the provided context.'},
            {'role': 'user', 'content': f'Context:\n{context}\n\nQuestion: {question}'},
        ],
    )
    return response.choices[0].message.content

BGE Reranker: 오픈 소스 대안

BGE Reranker(BAAI General Embedding)는 Beijing Academy of AI에서 개발한 오픈 소스 교차 인코더 모델 제품군입니다. BAAI/bge-reranker-v2-m3 모델은 다국어 재순위 지정을 지원하며, 로컬에서 실행하면서도 영어 벤치마크에서 Cohere Rerank에 가까운 점수를 냅니다. sentence-transformers 라이브러리와 함께 사용하면 API 비용 없이 완전히 직접 호스팅하는 방식으로 재순위 지정을 수행할 수 있습니다.

from sentence_transformers import CrossEncoder

# Load BGE reranker model
reranker = CrossEncoder(
    'BAAI/bge-reranker-v2-m3',
    max_length=512,
    device='cpu',  # use 'cuda' if GPU is available
)

def bge_rerank(query: str, documents: list[str], top_k: int = 5) -> list[dict]:
    pairs = [[query, doc] for doc in documents]
    scores = reranker.predict(pairs, show_progress_bar=False)
    ranked = sorted(
        zip(documents, scores.tolist()),
        key=lambda x: x[1],
        reverse=True,
    )
    return [{'text': doc, 'score': score} for doc, score in ranked[:top_k]]

BGE Reranker 모델 변형

BGE reranker 제품군은 크기와 품질 사이의 다양한 절충안을 제공합니다. bge-reranker-base(2억 7,800만 개 매개변수)는 가장 빠르고 작습니다. bge-reranker-large(5억 6,000만 개 매개변수)는 더 정확합니다. bge-reranker-v2-m3는 여러 언어를 지원하며 운영 환경에 권장되는 기본 모델입니다. 최대 정확도가 필요하다면 bge-reranker-v2-gemma를 사용해 보세요. 이 모델은 Gemma 백본을 사용하며 오픈 소스 모델 중 대부분의 영어 벤치마크에서 가장 뛰어난 성능을 냅니다.

# Model size vs accuracy trade-offs
models = [
    ('BAAI/bge-reranker-base',   '278M params', 'fast,   English-focused'),
    ('BAAI/bge-reranker-large',  '560M params', 'better, English-focused'),
    ('BAAI/bge-reranker-v2-m3',  '570M params', 'best for multilingual use'),
    ('BAAI/bge-reranker-v2-gemma', '2B params', 'SOTA open-source accuracy'),
]

# For most RAG applications, bge-reranker-v2-m3 offers the best
# balance of accuracy, multilingual support, and inference speed on CPU

교차 인코더 예측 일괄 처리

교차 인코더는 기본적으로 (질의, 문서) 쌍을 하나씩 처리하지만, 일괄 예측을 사용하면 여러 쌍을 모델에 동시에 전달하여 처리량을 크게 높일 수 있습니다. batch_size 매개변수는 한 번에 처리할 쌍의 수를 제어합니다. GPU에서는 일반적으로 32~128의 일괄 크기를 사용합니다. CPU에서는 4~16의 더 작은 일괄 크기를 사용하면 메모리 부담을 줄이면서도 순차 처리보다 처리량을 높일 수 있습니다.

def batch_rerank(reranker, query: str, documents: list[str],
                 top_k: int = 5, batch_size: int = 32) -> list[dict]:
    pairs = [[query, doc] for doc in documents]

    # Batch prediction
    all_scores = reranker.predict(
        pairs,
        batch_size=batch_size,
        show_progress_bar=len(pairs) > 100,
    )

    ranked = sorted(
        zip(documents, all_scores.tolist()),
        key=lambda x: x[1],
        reverse=True,
    )
    return [{'text': doc, 'score': score} for doc, score in ranked[:top_k]]

LangChain CrossEncoderReranker 통합

LangChain은 CrossEncoderReranker를 문서 압축기로 제공하며, 교차 인코더 재순위 지정을 ContextualCompressionRetriever 패턴에 통합합니다. 이를 사용하면 몇 줄의 코드만으로 기존 검색기에 재순위 지정 단계를 추가하고, 검색기 인터페이스를 허용하는 모든 LCEL 체인에 연결할 수 있습니다.

from langchain.retrievers.document_compressors import CrossEncoderReranker
from langchain_community.cross_encoders import HuggingFaceCrossEncoder
from langchain.retrievers import ContextualCompressionRetriever
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings

# Base retriever (coarse stage)
base_retriever = FAISS.from_documents(
    documents, OpenAIEmbeddings()
).as_retriever(search_kwargs={'k': 30})

# Re-ranker (fine stage)
model = HuggingFaceCrossEncoder(model_name='BAAI/bge-reranker-v2-m3')
compressor = CrossEncoderReranker(model=model, top_n=5)

# Combined two-stage retriever
two_stage_retriever = ContextualCompressionRetriever(
    base_compressor=compressor,
    base_retriever=base_retriever,
)

docs = two_stage_retriever.invoke('how does hybrid search work?')

점수 해석 및 임계값 설정

교차 인코더 점수에는 보편적인 척도가 없습니다. BGE reranker는 원시 로짓을 출력하며(대개 -10~+10 범위), Cohere는 0~1 사이로 정규화된 관련성 점수를 반환합니다. 최소 점수 임계값을 적용하여 LLM에 전달할 문맥에서 관련성이 매우 낮은 문서를 제외하면 잡음을 더욱 줄일 수 있습니다. 먼저 점수의 25번째 백분위수에 임계값을 설정한 다음 조정해 보세요.

def rerank_with_threshold(reranker, query, documents, top_k=5, min_score=-2.0):
    pairs = [[query, doc] for doc in documents]
    scores = reranker.predict(pairs)

    scored_docs = [
        {'text': doc, 'score': float(score)}
        for doc, score in zip(documents, scores)
        if float(score) >= min_score  # filter low-relevance docs
    ]

    scored_docs.sort(key=lambda x: x['score'], reverse=True)

    if not scored_docs:
        return []  # nothing passed the threshold
    return scored_docs[:top_k]

Cohere와 BGE: 무엇을 선택해야 하나요?

관리형 API를 원하고, 영어 기업 데이터에서 가장 높은 정확도가 필요하며, GPU 인프라를 피하고 싶다면 Cohere Rerank를 사용하세요. 데이터 개인정보 보호를 위해 직접 호스팅해야 하거나, 요청당 API 비용을 없애고 싶거나, 다국어 지원이 필요하거나, 오프라인으로 실행하려면 BGE Reranker를 사용하세요. 두 모델은 대부분의 벤치마크에서 비슷한 NDCG 점수를 내므로, 선택은 주로 인프라 선호도와 비용 구조에 따라 결정됩니다.

다국어 콘텐츠 재순위 지정

말뭉치나 사용자가 여러 언어에 걸쳐 있다면 다국어 교차 인코더를 선택하세요. bge-reranker-v2-m3는 100개가 넘는 언어를 처리하며, Cohere Rerank에도 다국어 모델 변형이 있습니다. 영어 질의를 프랑스어 또는 스페인어 문서와 비교해 점수를 매기는 언어 간 재순위 지정도 지원됩니다. 이는 지식 기반이 여러 언어로 구성된 글로벌 기업 환경에서 유용합니다.

from sentence_transformers import CrossEncoder

# Multilingual BGE reranker
ml_reranker = CrossEncoder('BAAI/bge-reranker-v2-m3')

# Cross-lingual example: English query, French document
query_en = 'How to configure vector search?'
doc_fr = 'La configuration de la recherche vectorielle dans PostgreSQL'

score = ml_reranker.predict([[query_en, doc_fr]])
print(f'Cross-lingual relevance score: {float(score):.3f}')
# Positive score indicates the document is relevant to the query
# despite being in a different language

재순위 지정 결과 캐싱

교차 인코더 추론은 2단계 파이프라인에서 가장 느린 부분입니다. 동일한 (질의, 문서) 쌍이 자주 반복되는 애플리케이션에서는 재순위 지정 결과를 캐싱하여 중복 추론을 없앨 수 있습니다. (질의, document_id) 쌍을 해시하여 캐시 키로 사용하고, Redis에 TTL과 함께 점수를 저장하세요. 사용자가 비슷한 질문을 자주 하는 고객 지원 애플리케이션에서는 캐시 적중률이 30~50%에 이르는 경우가 많습니다.

import redis
import hashlib
import json

r = redis.Redis(host='localhost', port=6379)

def cached_rerank_score(reranker, query: str, doc_text: str, doc_id: str) -> float:
    cache_key = 'rerank:' + hashlib.md5((query + doc_id).encode()).hexdigest()
    cached = r.get(cache_key)
    if cached:
        return float(cached)

    score = float(reranker.predict([[query, doc_text]]))
    r.setex(cache_key, 3600, str(score))  # cache 1 hour
    return score

빠른 확인

이 레슨에서 배운 교차 인코더 재순위 지정을 제대로 이해했는지 확인해 보세요.

레슨 요약

이 레슨에서는 다음을 배웠습니다. Cohere Rerank는 최첨단 정확도를 제공하는 클라우드 호스팅 교차 인코더 API이고, BGE Reranker는 다국어 콘텐츠를 포함한 직접 호스팅 배포를 위한 오픈 소스 대안입니다. 또한 일괄 처리를 사용하면 많은 (질의, 문서) 쌍에 점수를 매길 때 처리량이 크게 향상됩니다. LangChain의 CrossEncoderReranker는 이 두 모델을 ContextualCompressionRetriever 패턴에 통합합니다. 다음으로 검색된 청크의 잡음을 줄이기 위한 문맥 압축을 구현합니다.

무료로 시작

AI 튜터와 함께 Python을(를) 배우세요 — 무료

브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.

코스
30
레슨
120

자주 묻는 질문

“Cohere와 BGE를 활용한 교차 인코더 재순위 지정” 강의는 무료인가요?

네 — “Cohere와 BGE를 활용한 교차 인코더 재순위 지정” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Engineering Academy 강의 전체를 잠금 해제할 수 있습니다. AI Engineering Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“Cohere와 BGE를 활용한 교차 인코더 재순위 지정”에서 뭘 배우나요?

Cohere의 재순위 지정 엔드포인트와 BGE-reranker 모델을 통합해 질의-문서 쌍의 점수를 계산하고, 상위 k개 청크를 실제 관련성에 따라 다시 정렬합니다. 브라우저에서 직접 실행하는 실습 코드로 AI Engineering Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

AI Engineering Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 AI Engineering Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“Cohere와 BGE를 활용한 교차 인코더 재순위 지정” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 AI Engineering Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 AI Engineering Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 2단계 검색이 작동하는 이유
  2. Cohere와 BGE를 활용한 교차 인코더 재순위 지정
  3. 문맥 압축과 관련성 필터링
  4. 재순위 지정의 영향 측정
← AI Engineering Academy(으)로 돌아가기