YYYEJI

[MAC] 재순위화(Re-rank) 기법 Cross-Encoder 모델과 LLMListwise 모델 비교하기 본문

인공지능 챗봇

[MAC] 재순위화(Re-rank) 기법 Cross-Encoder 모델과 LLMListwise 모델 비교하기

YEJI ⍢ 2025. 8. 7. 11:02
728x90

재순위화(Re-rank)란 무엇인가 ,,, ?

검색 결과를 다시 평가해 최적 순서로 재정렬하는 기술이라네요!!

 

 

* 재순위화는 검색 결과를 재분석하여 최적의 순서로 정렬하는 고도화된 기술이며,

* 이중 단계 프로세스로 기본 검색 후 정교한 기준으로 재평가를 진행하며,

1. 기본 검색 알고리즘으로 관련 문서 찾고,

2. 더 정교한 기준으로 이들을 재평가하여 최종 순위를 결정

* 사용자의 검색 의도에 맞는 정확한 향상을 통해 검색 품질을 개선하고,

* 검색 결과의 품질을 높이기 위한 체계적인 최적화 방법론이라고 볼 수 있습니다!!

 

 

재순위화 방식에는 3가지가 존재합니다.

1) Pointwise

* 문서 하나씩 독립적으로 점수 계산을 하고 점수 높은 순서대로 정렬합니다 

* 단점: 문서 간 상대 비교가 약함

Ex) 각 문서의 "관련도 점수"만 매기기

 

2) Pairwise

* 문서 두 개씩 비교해서 "A가 B보다 관련이 높은가?"를 판단합니다

* 단점: 비교 횟수가 많아짐

Ex) 토너먼트처럼 계속 비교해서 최종 순위 결정

 

3) Listwise

* 전체 후보 문서 리스트를 한 번에 보고 순서를 결정합니다.

* 장점: 문맥과 전체 흐름을 같이 고려 가능

Ex) "이 5개 문서를 관련도 높은 순서대로 나열해라"

 


 

Cross Encoder Reranker

Cross-Encoder 모델을 활용해서 rerank를 해보겠습니다!

데이터 쌍(pair) 단위로 처리하여 문서와 쿼리 간의 관계를 분석하게 됩니다

(Ex. 두 개의 문장 또는 문서)

통합 인코딩 방식으로 검색 쿼리와 검색된 문서 간 유사도를 더 정확하게 계산합니다!

# 검색 결과를 압축 또는 재순위화하는 기능의 retriever (기본 검색 결과 → 필요 없는 것 제거 & 순위 조정 → 최종 출력)
from langchain.retrievers import ContextualCompressionRetriever
# 문서 압축기(Compressor) → CrossEncoderReranker (검색된 문서와 쿼리를 함께 입력받아 관련도 점수 계산 후 점수 기반으로 문서 순위 재매김))
from langchain.retrievers.document_compressors import CrossEncoderReranker
# HuggingFace 모델을 사용하는 CrossEncoder 래퍼(wrappe)
from langchain_community.cross_encoders import HuggingFaceCrossEncoder

코드를 보기 전 필요한 라이브러리들을 불러와줬습니다!

 

 

코드 고고고 ↗↗↗

# CrossEncoderReranker 모델 초기화
# https://huggingface.co/BAAI/bge-reranker-v2-m3
model = HuggingFaceCrossEncoder(model_name = "BAAI/bge-reranker-v2-m3")  # google cloud에서 다운받아서 다운속도 빠름

HuggingFace에서 재순위화 전용인 "BAAI/bge-reranker-v2-m3" 모델을 로드하고,

(입력: (쿼리, 문서) pair → 출력: 관련도 점수)

 

 

# CrossEncoderReranker 모델을 사용한 re-ranker 초기화 (top_n: 3)
re_ranker = CrossEncoderReranker(model = model, top_n = 3)  # 상위 3개

위에서 만든 모델을 CrossEncoderReranker에 연결 후 

가장 관련도 높은 문서 3개만 남깁니다. (top_n=3)

 

 

# CrossEncoderReranker를 사용한 retriever 초기화
cross_encoder_rerank_retriever = ContextualCompressionRetriever(    # 검색기 생성
    base_compressor=re_ranker,          # reranker 지정, 출력되는 순위가 조정되어 출력
    base_retriever=chroma_k_retriever,  # 기본 검색기는 Vector
) # reranker가 포함된 검색기(cross_encoder_rerank_retriever) 생성됨

최종적으로 재순위화 기능이 포함된 검색기를 만드는 코드입니다.

base_retriever=chroma_k_retriever → 벡터 기반 검색기로 먼저 문서를 가져옵니다.

base_compressor=re_ranker → 그 결과를 CrossEncoder로 재평가하고 순위를 조정합니다.

 

 

최종 결과는 재순위화된 문서 3개만 반환합니다!!

 

 

chroma_k_retriever로 빠른 1차 검색,

CrossEncoderReranker → 관련도 점수 계산 + 순위 재조정

top_n=3 → 상위 3개만 남김

cross_encoder_rerank_retriever → 결과 반환

이러한 흐름으로 흘러갑니다 

 

 

방금 만든 재순위화된 검색기로 코드를 돌려보겠습니다!!

# CrossEncoderReranker를 사용한 retriever를 사용하여 검색
query = "테슬라 트럭 모델이 있나요?"

retrieved_docs = cross_encoder_rerank_retriever.invoke(query)

for doc in retrieved_docs:
    print(f"{doc.page_content} [출처: {doc.metadata['source']}]")
    print("="*200)

결과 출력은 이렇게 되었습니다!!

 

 

다음은 LLM 모델을 살펴보겠습니다!!


LLM Reranker

* 대규모 언어 모델을 활용해서 검색 결과의 재순위화를 수행하게 됩니다.

* 쿼리와 문서 간의 관련성 분석을 통해 최적의 순서를 도출합니다!!

# 검색 결과를 압축하거나 재정렬하는 retriever
from langchain.retrievers import ContextualCompressionRetriever
# LLM이 여러 문서를 한 번에 보고 순위를 매김.
from langchain.retrievers.document_compressors import LLMListwiseRerank
# Azure OpenAI에서 GPT 모델을 불러올 수 있게 해주는 래퍼(wrapper)
from langchain_openai import AzureChatOpenAI

필요한 라이브러리를 불러왔습니다!!

 

 

# ChatOpenAI 모델 초기화
llm = AzureChatOpenAI(model="gpt-4o-mini", temperature=0)   # 냉정한

LLM모델은 "gpt-4o-mini"를 사용했고

temperature = 0으로 설정해 최대한 객관적이로 일관된 결과를 위해 창의성을 억제했습니다!

 

 

LLM이 실제 재순위화를 담당하게 됩니다!!

# LLMListwiseRerank 모델 초기화 (top_n: 3)
re_ranker = LLMListwiseRerank.from_llm(
    llm = llm,
    top_n = 3,
    verbose=True,
)

LLM을 활용하여 Listwise 재순위화기를 초기화했습니다!!

top_n=3 로 가장 관련도 높은 문서 3개만 남기고,

verbose=True로 실행 과정에서 어떤 프롬프트와 결과가 오갔는지 로그도 확인 가능하게 했습니다.

# LLMListwiseRerank 모델을 사용한 re-ranker 초기화
llm_rerank_retriever = ContextualCompressionRetriever(
    base_compressor=re_ranker,
    base_retriever=chroma_k_retriever,
)

최종 재순위화 검색기를 만들었습니다!

chroma_k_retriever → 기본 검색기로 빠른 후보 검색

LLMListwiseRerank → 재순위화기(+압축기)로 LLM이 전체 후보를 보고 최종 순위 매김

LLM이 판단한 상위 3개 문서 반환을 하면서 결과가 나옵니다.

 

 

LLMListwiseRerank가 후보 문서 전체를 LLM에 한 번에 넣어서 관련도 높은 순서대로 나열하게 시킵니다!

# LLMListwiseRerank 모델을 사용한 retriever를 사용하여 검색

query = "테슬라 트럭 모델이 있나요?"
retrieved_docs = llm_rerank_retriever.invoke(query)

for doc in retrieved_docs:
    print(f"{doc.page_content} [출처: {doc.metadata['source']}]")
    print("="*200)

결과는 이렇게 나왔습니다

 

그럼 이제 두 재순화기의 차이점을 살펴볼까요??

CrossEncoder vs LLMListwiseRerank

특징 CrossEncoderReranker LLMListwiseRerank
모델 사전학습된 re-rank 전용 모델 LLM(GPT 등)
비교 방식 주로 pairwise 또는 점수 계산 listwise( 한 번에 전체 비교)
장점 빠르고 경량, 일관성 높음 LLM 지식을 활용, 문맥 이해력 강함
단점 사전학습 범위 한정 느리고 비용 큼
  • CrossEncoderReranker → 문서 쌍(pairwise) 또는 개별 점수(pointwise)로 비교 → 여러 번 비교
  • LLMListwiseRerank → 문서 전체를 한 번에 보고 순서 정함 → 비교 과정 한 번
728x90