Chuking 파헤치기: RAG을 위한 필수 기술

  • 카카오톡 공유하기
  • 네이버 블로그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 트위터 공유하기
  • 링크 복사하기

LLM(대규모 언어 모델) 관련 애플리케이션을 구축할 때, 특히 콘텐츠를 임베드하여 벡터 데이터베이스에 저장하고 검색하는 과정에서 ‘청킹(Chunking)’은 핵심적인 기술입니다. 큰 텍스트 덩어리를 더 작고 관리 가능한 세그먼트로 나누는 이 과정은 벡터 데이터베이스에서 반환되는 콘텐츠의 관련성을 최적화하는 데 필수적입니다.

VectorDB과 같은 시스템에서 콘텐츠를 인덱싱하려면 먼저 임베드해야 하며, 청킹을 하는 주된 이유는 의미적으로 관련성이 있으면서도 노이즈가 최소화된 콘텐츠를 임베드하기 위해서입니다. 예를 들어, 의미론적 검색에서 효과적인 청킹 전략은 사용자 질의의 핵심을 정확히 포착하는 검색 결과를 얻는 데 도움을 줄 수 있습니다. 청크 크기가 너무 작거나 크면 검색 결과가 부정확해지거나 관련 콘텐츠를 찾을 기회를 놓칠 수 있습니다.

대화형 에이전트의 경우, 내장된 청크는 에이전트가 신뢰할 수 있는 정보 기반 위에 컨텍스트를 구축하는 데 사용됩니다. 여기서 청킹 전략을 올바르게 선택하는 것은 두 가지 이유로 중요합니다: 첫째, 컨텍스트가 프롬프트와 실제로 관련 있는지 여부를 판단하고, 둘째, 외부 모델 제공자(예: OpenAI)로 전송할 토큰 제한 내에서 검색된 텍스트를 맞출 수 있는지 여부를 판단합니다.

콘텐츠를 임베드할 때, 짧은 콘텐츠(문장)와 긴 콘텐츠(단락, 문서)는 다르게 작동합니다.

  • 짧은 콘텐츠 임베딩은 문장의 구체적인 의미에 초점을 맞춥니다. 이는 더 넓은 맥락 정보를 놓칠 수 있음을 의미합니다.
  • 긴 콘텐츠 임베딩은 텍스트 내 문장과 구문 간의 관계 및 전체적인 맥락을 고려하여 더 포괄적인 표현을 얻습니다. 하지만 입력 텍스트가 커지면 노이즈가 발생하거나 개별 문장의 중요성이 약화되어 정확한 일치를 찾기 어려워질 수 있습니다.

쿼리의 길이 또한 임베딩 간의 관계에 영향을 미칩니다. 짧은 쿼리는 구체적인 내용에 집중하므로 문장 단위 임베딩과 더 적합할 수 있고, 긴 쿼리는 더 넓은 맥락을 탐색하므로 단락이나 문서 단위 임베딩과 더 잘 어울릴 수 있습니다.

인덱스는 다양한 크기의 청크 임베딩을 포함하여 비균질적일 수 있습니다. 이는 결과 관련성에 어려움을 줄 수 있지만, 서로 다른 세분성 수준의 텍스트를 나타내므로 더 광범위한 맥락과 정보를 포착하고 다양한 유형의 쿼리를 유연하게 처리할 수 있는 잠재력도 가집니다.

최적의 청킹 전략을 결정하는 데는 여러 변수가 영향을 미치며, 이는 사용 사례에 따라 달라집니다. 고려해야 할 주요 사항으로는 인덱싱되는 콘텐츠의 특성, 사용하는 임베딩 모델 및 해당 최적 성능 청크 크기 (예: 문장 변환 모델은 문장 단위, text-embedding-ada-002는 256 또는 512 토큰), 사용자 쿼리의 길이와 복잡성, 그리고 검색된 결과가 특정 애플리케이션에서 어떻게 활용될 예정인지 (예: 의미 검색, 질의응답, 요약, LLM 토큰 제한 고려) 등이 있습니다. 이러한 질문에 답하면 성능과 정확성의 균형을 이루는 전략을 개발하는 데 도움이 됩니다.

이제 다양한 청킹 방법을 살펴보겠습니다. 각 방법에는 장단점이 있으며, 이를 이해하는 것이 중요합니다.

다양한 Chunking 방법

고정 크기 청킹 (Fixed-size Chunking)

가장 일반적이고 간단한 접근 방식입니다.

청크에 포함될 토큰 개수를 결정하고, 선택적으로 청크 간 중복(overlap) 여부를 결정합니다. 의미적 맥락 손실을 방지하기 위해 어느 정도 중복을 유지하는 것이 일반적입니다.

대부분의 경우 가장 좋은 방법일 수 있습니다. 자연어 처리(NLP) 라이브러리를 사용할 필요가 없어 계산 비용이 저렴하고 사용하기 쉽습니다.

LangChain을 사용한 예시는 CharacterTextSplitter를 사용하는 것입니다. chunk_sizechunk_overlap을 설정할 수 있습니다.

콘텐츠 인식 청킹 (Content-aware Chunking)

청킹하는 콘텐츠의 특성을 활용하는 보다 정교한 방법들의 집합입니다.

문장 분할 (Sentence Splitting): 많은 모델이 문장 단위 콘텐츠 임베딩에 최적화되어 있어 사용됩니다.

순진한 분할 (Naive Splitting): 마침표(“.”)와 줄 바꿈을 사용하여 간단히 분할하는 방법입니다. 빠르지만 모든 예외를 고려하지는 않습니다.

NLTK: Python 라이브러리 NLTK의 문장 토크나이저를 사용하여 의미 있는 덩어리를 생성합니다. LangChain에서 NLTKTextSplitter를 사용할 수 있습니다.

spaCy: NLP 작업을 위한 또 다른 강력한 Python 라이브러리로, 정교한 문장 분할 기능을 제공하여 맥락을 더 잘 보존합니다. LangChain에서 SpaCyTextSplitter를 사용할 수 있습니다.

재귀적 청킹 (Recursive Chunking): 구분 기호 집합을 사용하여 입력 텍스트를 계층적이고 반복적으로 나눕니다. 원하는 크기나 구조에 도달할 때까지 다른 구분 기호나 기준을 사용하여 재귀적으로 호출하며, 청크 크기가 정확히 같지는 않아도 비슷한 크기가 되도록 노력합니다. LangChain에서는 RecursiveCharacterTextSplitter를 사용하여 구현할 수 있습니다.

특수화된 청킹 (Specialized Chunking): Markdown이나 LaTeX처럼 구조화된 콘텐츠의 경우, 원래 구조를 유지하기 위해 사용됩니다.

마크다운 (Markdown): 마크다운 구문을 인식하여 콘텐츠의 구조와 계층에 기반하여 분할하여 의미적으로 일관된 덩어리를 만듭니다. LangChain에서는 MarkdownTextSplitter를 사용합니다.

LaTeX: LaTeX 명령과 환경을 파싱하여 콘텐츠의 논리적 구성을 고려한 청크를 생성합니다. LangChain에서는 LatexTextSplitter를 사용합니다.

의미적 청킹 (Semantic Chunking)

Greg Kamradt에 의해 처음 소개된 새로운 실험적 기법입니다.

고정 청킹 크기는 문서 내 세그먼트의 의미를 충분히 고려하지 못할 수 있다는 문제 의식에서 출발합니다. 이 방법은 서로 의미적으로 관련 있는 세그먼트를 결합할 수 있게 해줍니다.

LLM 애플리케이션 개발 시 임베딩 생성 기능을 활용합니다. 임베딩을 사용하여 데이터의 의미론적 의미를 추출하고, 동일한 주제를 다루는 문장들로 청크를 생성할 수 있습니다.

작동 단계: 문서를 문장으로 나누고, 각 문장을 “앵커”로 하여 앞뒤 문장을 포함하는 문장 그룹을 만듭니다. 각 문장 그룹에 대한 임베딩을 생성하고 “앵커” 문장과 연결합니다. 각 그룹 간의 거리를 순차적으로 비교하여 의미적 거리가 짧으면 주제가 같고, 길면 주제가 변경되었음을 나타냅니다. 이를 통해 문장을 효과적으로 구분합니다.

LangChain은 Kamradt의 연구 기반 의미론적 청킹 분할기를 개발했습니다.

애플리케이션에 가장 적합한 청크 크기 파악

어떤 청킹 방식(예: 고정 청킹)이 사용 사례에 쉽게 적용되지 않는다면, 최적의 청크 크기를 찾는 데 도움이 되는 몇 가지 지침이 있습니다.

  1. 데이터 전처리: 데이터 품질을 보장하기 위해 먼저 전처리를 수행해야 합니다 (예: HTML 태그 또는 노이즈 제거).
  2. 청크 크기 범위 선택: 전처리 후, 테스트할 다양한 청크 크기를 선택합니다. 콘텐츠 특성, 사용할 임베딩 모델, 해당 기능(토큰 제한) 등을 고려해야 합니다. 목표는 맥락 보존과 정확성 유지 사이의 균형을 찾는 것입니다. 128 또는 256 토큰과 같은 작은 청크와 512 또는 1024 토큰과 같은 큰 청크 등 다양한 크기를 탐색해 보세요.
  3. 각 청크 크기의 성능 평가: 다양한 청크 크기를 테스트하기 위해 여러 인덱스를 사용하거나 여러 네임스페이스를 가진 단일 인덱스를 사용할 수 있습니다. 대표 데이터 세트를 사용하여 임베딩을 생성하고 인덱스에 저장합니다. 품질을 평가할 수 있는 일련의 쿼리를 실행하고 다양한 청크 크기의 성능을 비교합니다. 이는 콘텐츠 및 예상 쿼리에 가장 적합한 청크 크기를 결정할 때까지 반복하는 과정입니다.

결론

콘텐츠 청킹은 대부분의 경우 간단하지만, 특정 사용 사례에 맞는 최적의 방법을 찾는 것은 어려울 수 있습니다. 청킹에는 만능 해결책이 없으므로, 특정 애플리케이션에 효과적인 방법이 다른 사용 사례에는 적합하지 않을 수 있습니다. 여러분의 애플리케이션에 맞는 청킹 전략을 이해하고 접근하는 데 이 글이 도움이 되기를 바랍니다.


게시됨

카테고리

작성자

댓글

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다