[LLM] Chunking

CHOI HYUK·2025년 8월 14일
0

AI

목록 보기
2/6
post-thumbnail

Chunking 🔧

이번에는 저번 Prompt Engineering에 이어서 Chunking에 대해서 알아보겠다.

청킹은 자연어를 특정 크기로 나누는 것을 의미한다. 각 나누어진 단위를 청크(chunk)라고 하며, 이러한 기법을 적용하는 도구를 텍스트 분할기(Text splitters)라고 한다. 따라서 텍스트 분할을 어떻게 하느냐에 따라서 청킹이 구성되는 방식이 달라진다. 중요한 점은 이러한 텍스트 분할은 분할을 적용하려는 자연어의 종류에 따라 나뉜다는 것이다.

텍스트 분할기 (Text Splitters) 📑

텍스트 분할은 RAG(Retrieval-Augmented Generation, 검색 증강 생성)에서 사용되는 핵심 기법이다. 긴 문서를 모델이 처리하기 쉬운 작은 단위인 청크로 나누어, 효율적인 검색과 정확한 답변 생성을 가능하게 한다.

문서를 나누는 구체적인 이유는 다음과 같다.

  • 다양한 문서 길이 처리: 실제 문서들은 길이가 제각각이다. 분할을 통해 모든 문서를 일관된 크기로 처리할 수 있다.
  • 모델 한계 극복: 대부분의 임베딩 모델과 언어 모델은 입력 크기 제한이 있다. 분할을 통해 이 제한을 초과하는 문서를 처리할 수 있다.
  • 표현 품질 향상: 긴 문서는 임베딩 품질이 저하될 수 있다. 분할을 통해 각 섹션에 더 집중된, 정확한 표현을 생성할 수 있다.
  • 검색 정확도 향상: 정보 검색 시스템에서 분할은 검색 결과의 세분성을 높여, 질의와 관련된 문서 섹션을 더 정확하게 찾아낼 수 있게 한다.
  • 연산 자원 최적화: 작은 텍스트 청크로 작업하면 메모리 효율이 높아지고, 처리 작업을 병렬화하기 쉬워진다.

텍스트 분할을 구현하는 방법은 여러 가지가 있다.

길이를 기반으로 분할 (Length-based) 📝

가장 직관적인 방법으로, 정해진 길이(문자 또는 토큰 수)를 기준으로 문서를 나눈다.

  • 특징: 구현이 간단하고, 청크 크기가 일관적이며, 모델의 요구사항에 맞추기 쉽다.
  • 유형: 토큰 기반은 언어 모델에 유용하도록 토큰 수를 기준으로 나누고, 문자 기반은 텍스트 유형에 관계없이 일관된 문자를 기준으로 나눈다.

텍스트 구조를 기반으로 분할 (Text-structured based) ✨

문단, 문장, 단어 등 텍스트의 계층적 구조를 활용하여 자연스러운 언어 흐름을 유지하며 분할한다.

  • 특징: 문맥적 일관성을 보존하고, 텍스트의 세분화 수준에 맞게 조절한다.

문서 구조를 기반으로 분할 (Document-structured based) 📚

HTML, Markdown, JSON 등 문서 자체의 내재된 구조를 활용하여 분할한다.

  • 특징: 문서의 논리적 조직을 보존하고, 각 청크 내의 문맥을 유지하며, 검색이나 요약 같은 후속 작업에 더 효과적이다.
  • 유형: Markdown의 헤더(#, ##), HTML의 태그, JSON의 객체나 배열 등을 기준으로 분할한다.

의미적 유사도를 기반으로 분할 (Semantic meaning based) 🤔

텍스트의 내용적 의미를 직접 분석하여 분할한다.

  • 특징: 의미적 변화가 큰 지점을 찾아 분할한다. 이를 통해 의미적으로 더욱 응집된 청크를 만들고, 후속 작업의 품질을 향상시킨다.
  • 예시: 슬라이딩 윈도우(Sliding Window) 방식을 사용하여 문장 그룹의 임베딩을 생성하고, 임베딩 간의 유의미한 차이를 비교하여 분할 지점을 찾는다.

참고로, 슬라이딩 윈도우는 특정 데이터를 어떠한 단위(윈도우)로 나누고, 그 데이터 단위들을 순회(슬라이딩)하며 작업을 진행하는 기법이다. 의미적 유사도 기반 분할의 경우, 특정 단위의 문장(윈도우)의 의미를 분석하여 임베딩을 하고, 다음 문장으로 넘어간 뒤(슬라이딩), 다시 해당 문장을 임베딩하여 임베딩된 문장 사이의 차이점을 알아내 분할 지점을 찾는 방식이다.


청크 (Chunk) 🧩

텍스트 분할을 진행할 때 고려해야 하는 점은 자연어를 청크로 나누는 단위인 청크 크기(Chunk Size)와, 나누어진 청크 사이의 관계인 청크 중첩(Chunk Overlap)을 유지하는 것이다. 인접한 청크 사이에 청크 중첩을 적용하여 문맥적 연속성을 유지시켜주는 작업을 진행한다.

청크 크기와 청크 중첩, 이 두 변수를 적용하여 텍스트 분할을 진행하게 되는데, 해당 변수의 크기에 따라 자연어를 분석하는 정도가 달라진다. 중요한 점은, 해당 자연어가 어떠한 종류의 자연어인지가 중요한데, 각 종류에 따라 문장의 복잡도와 구조가 다르기 때문이다.

청크 크기에 따라 좋은 성능을 보이는 문서들을 표로 정리하면 다음과 같다. 이는 문서의 구조와 내용적 특성을 기반으로 한다.

특징작은 청크 크기(Small Chunk Size)큰 청크 크기(Large Chunk Size)
적합한 문서 종류질문-답변(FAQ) 문서, 기술 문서의 API 설명, 법률 조항, 단순 사실 목록학술 논문, 연구 보고서, 소설, 에세이, 복잡한 기술 매뉴얼, 심층 뉴스 기사
효율성 근거정확한 검색, 노이즈 감소, 컨텍스트 창 효율문맥 보존, 관계 추론 용이, 종합적 답변 가능

청크 크기를 결정할 때는 문서의 내용이 얼마나 독립적인지와 문맥이 얼마나 중요한지를 기준으로 판단하는 것이 중요하다. 정형화되고 독립적인 내용이 많은 문서는 작은 청크가, 문맥적 흐름과 논리적 관계가 중요한 문서는 큰 청크가 더 효율적이다.

또한, 청크 오버랩은 보통 청크 크기의 10~20% 를 사용한다. 문서 구조와 내용에 따라 적절한 청크 크기를 찾아내고 10~20% 비율 안에서 최적의 오버랩 비율을 찾아내는 것이 좋은 텍스트 분할기를 만드는 방법이라 볼 수 있겠다.

다음 시간에는 LangChain 환경에서 간단한 청킹 실습을 진행해 보겠다.

[참고] LangChain Text splitters

0개의 댓글