본문 바로가기
Study (Data Science)/NLP

Langchain / Splitter

by 콜라찡 2024. 5. 23.

참고: https://velog.io/@dlsrks0631/LangChain-3.-RAG

LangChain - Text Splitters

  • Text Splitter는 토큰 제한이 있는 LLM이 여러 문장을 참고해 답변할 수 있도록 문서를 분할하는 역할이다.
  • 여러개의 문서를 더 작은 단위로 나눈 chunking을 통해 chunk들이 만들어지고 임베딩 벡터로 변환되는 과정을 거치고 사용자 질문을 하나의 임베딩 벡터로 수치화하는 과정을 거친다. 그것과 가장 유사한 수치를 벡터 스토어에서 찾고 이 임베딩 벡터에 해당하는 chunk와 사용자의 질문이 합쳐져서 최종 prompt가 완성되고 이 prompt를 통해 LLM이 답변을 한다. 또한 chunk 하나당 하나의 vector가 매칭이 된다. vector store안에 있는 임베딩 벡터들이 각각의 chunk들이 수치로 변환된거라고 생각하면 된다.

1) CharacterTextSplitter

  • 구분자 1개 기준으로 분할하므로 max_token을 지키는 못하는 경우 발생
with open('/Users/kimjehyeon/study/강의대화1.pdf', 'rb') as f:
    state_of_the_union = f.read()

print(state_of_the_union)

from langchain.text_splitter import CharacterTextSplitter
text_splitter = CharacterTextSplitter(
    separator="\n\n",     # 구분자
    chunk_size = 1000,    # chunk_size
    chunk_overlap = 100,  # chunk 가 문단별로 나눈다고 했을 때 앞부분을 겹치게 왜냐면 문맥 파악이 필요하니
    length_function = len,# chunk size를 측정할 때 무슨 기준으로 1000이냐 -> 글자수를 기준으로 하겠다.
)

2) RecursiveCharacterTextSplitter

  • 줄바꿈, 마침표, 쉼표 순으로 재귀적으로 분할하므로, max_token 지켜 분할
from langchain.text_splitter import RecursiveCharacterTextSplitter

text_splitter2 = RecursiveCharacterTextSplitter(
    chunk_size = 1000,
    chunk_overlap = 200,
    length_function = len,
)

Token 단위 텍스트 분할기

  • 텍스트 분할의 목적은 LLM이 소화할 수 있을 정도의 텍스트만 호출하도록 만드는 것이다. 따라서 LLM이 소화할 수 있는 양으로 청크를 제한하는 것은 LLM 앱을 개발할 때 필수적인 과정이다.
  • LLM은 텍스트를 받아들일 때, 정해진 토큰 이상으로 소화할 수 없게 설계되어 있다. 따라서 글을 토큰 단위로 분할한다면 최대한 많은 글을 포함하도록 청크를 분할할 수 있다.
  • 토큰이라는 것은, 텍스트와 달리 Transformer에서 처리하는 방식에 따라서 그 수가 달라질 수 있다. 따라서, LLM 앱을 개발하고자 한다면 앱에 얹힐 LLM의 토큰 제한을 파악하고, 해당 LLM이 사용하는 Embedder를 기반으로 토큰 수를 계산한다. 예를 들어, OpenAI의 GPT 모델은 tiktoken이라는 토크나이저를 기반으로 텍스트를 토큰화한다. tiktoken encoder를 기반으로 텍스트를 토큰화하고, 토큰 수를 기준으로 텍스트를 분할하는 것은 필수라고 할 수 있다.
import tiktoken
tokenizer = tiktoken.get_encoding("cl100k_base")

def tiktoken_len(text):
    tokens = tokenizer.encode(text)
    return len(tokens)

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000, chunk_overlap=0, length_function=tiktoken_len)
texts = text_splitter.split_documents(pages)
728x90

댓글