Chunking in RAG: why your splitter matters more than your embedding model
개요
Retrieval-Augmented Generation (RAG) 파이프라인에서 임베딩 모델보다 분할(chunking) 전략이 검색 성능에 더 큰 영향을 미치며, 최적의 분할 전략을 찾기 위해 실험하는 것이 중요합니다.
주요 내용
* 분할 전략의 중요성: RAG의 검색 문제는 종종 임베딩 모델이나 랭커(reranker) 변경보다 분할 방식 자체에 기인합니다. 분할기가 임베딩 모델이 접근할 수 있는 정보를 결정하며, 잘못된 분할은 좋은 임베딩으로도 검색 실패를 야기합니다.
* 일반적인 분할 전략:
* 고정 크기 분할 (Fixed-size Split): 지정된 토큰 또는 문자 수로 텍스트를 분할하며, 일부 겹침(overlap)을 포함합니다. 빠르고 재현 가능하지만 문장 중간을 자를 수 있습니다.
* 재귀적 문자 분할 (Recursive character splitting): LangChain의 기본값으로, 문단, 문장, 단어 순으로 자연스러운 구분자를 우선 사용하고, 이를 충족하지 못하면 문자 단위로 재귀적으로 분할합니다. 산문 텍스트에 실용적입니다.
* 문서 구조 인식 분할 (Document-structure-aware): Markdown 헤더, HTML 태그, 코드 AST 노드 등 문서의 구조를 분할 기준으로 사용합니다. 청크에 섹션 경로를 메타데이터로 포함시켜 필터링에 유용합니다.
* 의미론적 분할 (Semantic chunking): 각 문장을 임베딩하고, 인접한 문장 간의 코사인 거리 임계값을 기준으로 청크를 나눕니다. 직관적으로는 매력적이나, 실제 벤치마크에서는 일관성 없는 결과를 보이거나 성능이 저하되는 경우가 많으며, 인덱싱 시 추가 비용이 발생합니다.
* 의미론적 분할의 한계: 연구 결과에 따르면, 의미론적 분할 전략은 단순한 재귀적 분할이나 고정 크기 분할보다 일관되게 우수한 성능을 보이지 않으며, 인덱싱 시 임베딩 및 LLM 호출 비용이 훨씬 더 많이 듭니다. 실험에서 일관되게 중요한 변수는 청크 크기와 겹침이며, 분할 전략 자체가 아닙니다.
* 실제 성능 향상 방법: 맥락 제공 (Contextual Retrieval): 분할기를 단순하게 유지하면서 각 청크에 분할로 인해 손실된 맥락을 추가하는 것이 효과적입니다. Anthropic의 방식은 저렴한 LLM을 사용하여 전체 문서와 해당 청크를 기반으로 50-100 토큰의 맥락을 생성하고, 이를 청크 앞에 붙여 임베딩하는 방식입니다. 프롬프트 캐싱을 사용하면 비용을 크게 절감할 수 있습니다.
* 맥락 제공의 효과: Anthropic의 보고에 따르면, 맥락 제공은 검색 실패율을 크게 감소시켰으며, BM25와 랭커와 함께 사용할 때 더 큰 시너지 효과를 보였습니다.
* 최적의 청크 크기 및 겹침: Anthropic의 테스트에서 800 토큰 크기와 100 토큰 겹침이 최적의 성능을 보였습니다. 이는 단순히 프레임워크의 기본값이나 컨텍스트 창 크기에 기반한 것이 아니라, 실제 데이터셋에서 측정된 결과입니다.
* 맥락 제공의 적용 시점: 색인(indexing) 비용은 증가하지만 쿼리 시간 비용은 동일하므로, 재색인 빈도와 검색 실패의 비용을 고려하여 적용 여부를 결정합니다. 일반적으로 대부분의 프로덕션 시스템에 적용할 가치가 있습니다.
* 권장 초기 레시피: 재귀적 문자 분할기(800 토큰, 100 겹침), 구조적 메타데이터 활용, LLM 기반 맥락 추가, 벡터 인덱스와 BM25의 하이브리드 사용, 랭커 활용. 실제 환경에서 청크 크기 스윕 실험을 통해 최적값을 찾는 것이 중요합니다.
시사점
RAG 파이프라인의 성공은 임베딩 모델 자체보다 분할 전략의 최적화에 달려 있으며, 단순하지만 맥락을 제공하는 분할 기법이 복잡한 의미론적 분할 기법보다 더 나은 성능과 비용 효율성을 제공할 수 있습니다. 실제 프로덕션 환경에서는 단순히 프레임워크의 기본값을 사용하기보다는, 자체 데이터셋에 대한 벤치마킹을 통해 최적의 분할 전략을 수립하고 적용해야 합니다.
댓글
GitHub Discussions