문서 분석 및 처리는 자연어 처리(NLP)에서 중요한 요소 중 하나입니다. 특히, 문서가 너무 길어 LLM (Large Language Model)이 한 번에 처리할 수 없을 때, 적절한 크기로 문서를 분할하는 것은 필수적입니다. LangChain에서는 이러한 문서 분할 작업을 돕기 위해 여러 가지 TextSplitter를 제공합니다. 이 블로그에서는 왜 문서를 분할해야 하는지, 그리고 LangChain에서 제공하는 주요 TextSplitter와 그 사용법을 소개하겠습니다.
TextSplitter란 무엇인가요?
TextSplitter는 문서를 작은 단위로 나누는 도구입니다. 모델이 처리할 수 있는 최대 토큰 수를 넘지 않도록 문서를 나누는 것이 주 역할입니다. 이러한 분할 작업이 없다면, LLM은 긴 문서를 적절히 분석하거나 처리하는 데 어려움을 겪을 수 있습니다. 또한, 정보 검색, 요약 및 의미 기반 작업을 수행할 때, 짧은 문서 조각이 더 나은 결과를 제공합니다.
TextSplitter가 필요한 이유
- 처리 한계: LLM이 한 번에 처리할 수 있는 텍스트 길이에 제한이 있습니다.
- 효율성: 짧은 텍스트는 처리 및 분석에 더 효율적이며, 성능이 향상됩니다.
- 정보 검색: 의미 기반 검색 또는 벡터 스토어를 이용한 검색에서 작은 단위의 텍스트가 더 정확한 결과를 제공합니다.
LangChain의 주요 TextSplitter
LangChain에서는 다양한 종류의 TextSplitter를 제공하여 다양한 분할 방식에 맞춰 문서를 처리할 수 있습니다. 각 Splitter는 고유한 방식으로 문서를 분할하며, 사용하는 시나리오에 맞춰 선택할 수 있습니다.
1. CharacterTextSplitter
가장 기본적인 형태의 Splitter로, 지정된 문자 수에 맞춰 문서를 분할합니다. 사용자는 문서의 최대 길이를 설정하고, 문서가 이 길이를 초과하면 잘라냅니다.
from langchain.text_splitter import CharacterTextSplitter
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
chunks = text_splitter.split_text(text)
- chunk_size: 각 분할된 텍스트 조각의 최대 길이
- chunk_overlap: 분할된 텍스트 간 겹치는 부분의 길이
2. RecursiveCharacterTextSplitter
이 Splitter는 단순히 문자 기준으로 자르는 대신, 더 자연스러운 문장 분할을 위해 여러 기준을 순차적으로 적용합니다. 우선적으로 단락, 그다음 문장, 마지막으로 단어 단위로 분할하여 문서의 구조를 최대한 유지하려고 합니다.
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
chunks = text_splitter.split_text(text)
이 방식은 문서의 문맥과 의미를 최대한 유지하면서도 처리 가능한 크기로 문서를 나누는 데 효과적입니다.
3. TokenTextSplitter
LLM은 텍스트를 처리할 때 '토큰' 단위로 나누어 처리합니다. 따라서, 토큰 기반으로 문서를 나누는 것은 매우 중요합니다. 특히, 한국어처럼 어절 구분이 명확하지 않은 언어에서는 Konlpy와 같은 한국어 전용 토크나이저를 사용하는 것이 좋습니다. 다만, Konlpy는 처리 속도가 상대적으로 느리기 때문에 빠른 응답보다는 분석적 심도가 필요한 작업에 적합합니다.
from langchain.text_splitter import TokenTextSplitter
from konlpy.tag import Okt
class KonlpyTextSplitter(TokenTextSplitter):
def __init__(self, chunk_size, chunk_overlap, tokenizer=None):
self.tokenizer = Okt().morphs if tokenizer is None else tokenizer
super().__init__(chunk_size, chunk_overlap)
text_splitter = KonlpyTextSplitter(chunk_size=1000, chunk_overlap=200)
chunks = text_splitter.split_text(text)
Konlpy를 사용한 토크나이저는 한국어 자연어 처리에서 매우 강력하지만, 처리 속도가 느릴 수 있습니다. 따라서 실시간 응답보다는 심도 있는 텍스트 분석이 요구되는 곳에 적합합니다.
4. HuggingFace Tokenizer
HuggingFace Tokenizer는 다양한 토크나이저 모델을 제공하며, Subword Tokenizer, BPE(Byte-Pair Encoding), WordPiece, SentencePiece, spaCy, Moses 등 다양한 방법을 지원합니다. 각 토크나이저는 다른 방식으로 텍스트를 분할하며, 그중 BPE는 가장 널리 사용되는 방법 중 하나입니다.
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("gpt2")
tokens = tokenizer.tokenize("LangChain은 매우 유용한 프레임워크입니다.")
print(tokens)
HuggingFace의 BPE는 텍스트를 서브워드 단위로 분할해 LLM에 더 적합한 입력을 제공합니다. 다양한 토크나이저를 사용할 수 있어 유연성이 뛰어납니다.
5. SemanticChunker
SemanticChunker는 텍스트의 의미적 유사성에 따라 문서를 분할합니다. 단순히 문자나 토큰 수에 기반한 분할이 아니라, 각 텍스트 조각이 독립적인 의미를 가질 수 있도록 분할하는 것이 특징입니다. 이를 통해 정보 검색이나 텍스트 요약 등 의미 기반의 작업에서 더 나은 성능을 제공합니다.
from langchain.text_splitter import SemanticChunker
semantic_chunker = SemanticChunker()
chunks = semantic_chunker.split_text(text)
SemanticChunker는 의미 기반으로 문서를 나누기 때문에, 의미 상실 없이 정보를 처리하고자 할 때 유용합니다.
문서를 분할하는 것은 LLM을 효율적으로 사용하는 데 필수적인 과정입니다. LangChain의 다양한 TextSplitter를 통해 문서의 특성에 맞는 최적의 분할 방식을 선택할 수 있으며, 이를 통해 더 나은 정보 처리 및 검색 성능을 기대할 수 있습니다. 상황에 맞게 적절한 Splitter를 선택하고 활용해 보세요!
'인공지능' 카테고리의 다른 글
LangChain에서 효율적인 검색을 위한 다중 Retriever전략 (0) | 2024.09.26 |
---|---|
텍스트를 벡터로 변환하는 비밀: LangChain Embedding의 세계 (0) | 2024.09.25 |
AI 혁신의 새로운 기준, LLMOps와 Dify의 강력한 솔루션 살펴보기 (0) | 2024.09.24 |
LangChain에서 PDF 파일을 불러오는 최고의 방법: Loader 소개와 사용법 (0) | 2024.09.24 |
노트북을 넘어, AI와 함께하는 새로운 메모 혁명: NotebookLM의 모든 것 (0) | 2024.09.24 |