재정렬(Reranking)과 문맥 선택과 압축
앞서 살펴본 도메인 특화 AI 기술 RAG의 성능을 높이는 방법에서 우리는 검색 소스의 구성과 인덱싱, 질의 최적화 전략을 알아보았습니다. 검색이 될 데이터를 어떻게 쪼개고, 어떤 기준으로 정리해 LLM에게 전달하느냐가 핵심이었죠. 그런데 검색(Retrieval)만 잘했다고 해서, 반드시 좋은 답변이 나오는 것은 아닙니다. 이번에는 RAG의 또 다른 축인 “생성(Generation)” 단계의 성능 향상 전략에 대해 알아보겠습니다.
“검색된 지식을 관련 있는 순서로 정렬하라”
우선 RAG로 연결한 사내 문서와 같은 전문 지식에 대해 검색이 잘 완료되었다고 가정해 봅시다. 하지만 아무리 훌륭한 LLM이라도 검색된 결과의 정리가 엉성하면, 잘못된 맥락을 따라가며 엉뚱한 답을 내놓을 수 있습니다. 예를 들어 우리 사람도 작성된 회의록에서 핵심이 중간에 묻혀 있으면 내용을 파악하기 어렵듯이, AI도 같은 실수를 합니다. 그래서 검색 이후에는 가장 중요한 문서가 앞에 오도록 순서를 다시 정하는 과정이 필요합니다. 우리는 이 과정을 재정렬(Reranking)이라고 합니다.
재정렬은 단순히 보기 좋게 정리하는 것이 아니라, LLM이 더 정확한 답을 내도록 돕는 핵심 단계입니다. 마치 검색 엔진에서 수백 개의 검색 결과 중, 상위 몇 개만 봐도 내용을 파악할 수 있는 것처럼, RAG에서도 검색된 문서 중 제대로 된 몇 개만 참고하면 충분히 답변 성능이 우수한 경우가 많습니다. 즉, 재정렬은 LLM이 참고할 자료의 '우선순위'를 정해주는 역할을 합니다.
문서 재정렬 기법에는 여러 가지 접근이 있는데요. Cross Encoder는 질문과 문서를 한 쌍으로 입력해 정밀하게 관련성을 점수화하고, RankGPT는 대규모 언어모델의 추론 능력을 활용해 여러 문서를 한 번에 비교하며 순위를 매깁니다.
Cohere Rerank는 API 기반 상용 서비스로서 빠르게 적용할 수 있고, Jina Rerank는 텍스트뿐 아니라 이미지 같은 멀티모달 데이터까지 처리할 수 있어 범용성이 높습니다. 마지막으로 FlashRank는 경량화와 최적화를 통해 많은 문서를 빠르게 재정렬하면서도 효율성을 유지하는 것이 특징이죠.
우리는 이 5가지 재정렬(Reranking) 방식에 대해 좀 더 깊게 알아보겠습니다.
일반적인 RAG 환경에서는 바이 인코더(Bi Encoder)라는 방식이 많이 쓰이는데요. 바이 인코더는 질문과 문서를 각각 따로 임베딩 벡터로 만들고, 이후에 코사인 유사도 계산을 통해 빠르게 비교하는 구조입니다. 하지만 크로스 인코더 방식은 질의(Query, Sentence A)와 문서(Document, Sentence B)를 각각 따로 임베딩하는 것이 아니라, 두 텍스트를 한 문장으로 붙여서 함께 모델에 넣고, 두 텍스트가 얼마나 잘 점수(0~1)를 계산하는지에 차이점이 있습니다.
즉, 사전 문서 임베딩을 따로 만들지 않고, 매번 두 텍스트 쌍을 함께 처리하는 방식입니다. 정확도는 높지만, 연산 비용이 크기 때문에 대량의 문서를 한 번에 처리하기는 어렵습니다. 왜냐하면 모든 문장 쌍을 하나하나 직접 계산해야 하기 때문입니다. 따라서 문제의 문장이 사전에 정의되어 있을 때만 사용할 수 있고, 수많은 문장을 다뤄야 하는 검색 시스템 같은 곳에서는 비현실적일 수 있습니다. 반대로 바이 인코더는 임베딩을 사전에 한 번만 만들어두면, 이후에는 코사인 유사도 계산으로 빠르게 비교할 수 있어 실용적이기 때문에 일반적으로 많이 쓰이는 것이죠.
그래서 크로스 인코더 재정렬 방식은 바이 인코더와 크로스 인코더의 장점을 모두 취하는 구조로 발전했습니다. 먼저 바이 인코더를 통해 질문과 유사한 후보 문서를 뽑아내고, 크로스 인코더로 이 문서와 질문을 함께 입력하여 점수를 계산하는 방식이죠. 예를 들어, 질문이 "파이썬에서 리스트와 튜플의 차이점은 무엇인가?"라면, 바이 인코더로 관련 후보 문서 몇 개를 검색하고, 크로스 인코더로 후보 문서 하나씩과 질문을 연결해 모델에 입력하고, 두 텍스트가 얼마나 잘 맞는지 관련성을 수치로 뽑아내게 됩니다.
① 실제로 RAG 시스템에서 임베딩 모델을 사용하여 관련 문서 50개를 검색하고 나면, 크로스 인코더 모델로 각각의 문서를 질문과 함께 입력받아 점수를 매깁니다.
② 그 결과 질문에 직접 답변할 수 있는 문서(예: "리스트는 변경 가능하지만 튜플은 불변이다"라는 설명)가 더 높은 점수를 받고, 덜 관련 있는 문서(예: "파이썬 설치 방법")는 낮은 점수를 받게 됩니다.
③ 이렇게 하면 상위 50개 문서에 대한 재순위를 결정하고, 상위 3개 만을 사용해 생성 모델이 더 정확한 맥락을 참고해 답을 내놓게 되고, 불필요한 잡음을 줄일 수 있습니다.
대표적으로 BAAI의 bge-reranker 같은 특화 모델이 공개되어, 다국어 지원이나 긴 문서 처리까지 가능해졌습니다. 이런 모델들은 허깅페이스에 오픈소스로 제공되어 연구와 실무 모두에서 널리 쓰이고 있습니다. 또
LangChain 같은 프레임워크에서도 바로 적용할 수 있는 예제가 있어, 개발자가 직접 복잡한 학습을 거치지 않고도 손쉽게 재정렬 기능을 붙일 수 있으니 참고해 주시면 좋겠습니다.
원 글은 5가지 재정렬(Reranking) 방법뿐만 아니라, 컨텍스트의 선택과 압축 전략인 LLMLingua - LongLLMLingua - LLMLingua-2 프레임워크를 담고 있습니다. 보다 자세한 내용과 코드, 관련논문 링크 모음은 프로그래머스 공식 블로그에서 무료로 확인하실 수 있습니다. 감사합니다.
https://community.programmers.co.kr/post/12739