콘텐츠로 이동

Kss + 청크로 문단 나누기

실행 준비

!pip install openai
!pip install gradio
!pip install faiss-cpu sentence-transformers
!pip install pdfplumber
!pip install tiktoken

문장 분리 방법의 비교

항목 kss + 청크 조합 LangChain 분리기
한글 문장 유지 ✅ 매우 좋음 ❌ 보장 안 됨 (문장 중간 자를 수 있음)
설정 유연성 ✅ 높음 (직접 구현) ✅ 간편 설정
성능/속도 빠름 약간 느릴 수 있음
권장 대상 한국어 중심 문서 로컬/다양한 구조 문서

문장 분리 방법

  • 청크당 300토큰 기준
  • 50토큰 겹침(sliding window)

kss + 청크 조합 방식 (직접 구현)

import kss
import pdfplumber
import tiktoken
from typing import List

# ✅ GPT-3.5/4 기준 토크나이저 사용 (tiktoken)
tokenizer = tiktoken.get_encoding("cl100k_base")

def num_tokens_from_string(string: str) -> int:
    return len(tokenizer.encode(string))

# ✅ PDF 텍스트 추출
def extract_text_from_pdf(file_path: str) -> str:
    full_text = ""
    with pdfplumber.open(file_path) as pdf:
        for page in pdf.pages:
            text = page.extract_text()
            if text:
                full_text += text + "\n"
    return full_text

# ✅ 문장 단위로 분리 (kss)
def split_sentences(text: str) -> List[str]:
    return kss.split_sentences(text)

# ✅ 청크 생성 (300토큰 기준, 50토큰 겹침)
def chunk_sentences_by_token(sentences: List[str], chunk_size: int = 300, overlap: int = 50) -> List[str]:
    chunks = []
    current_chunk = []
    current_tokens = 0
    i = 0

    while i < len(sentences):
        sentence = sentences[i]
        token_len = num_tokens_from_string(sentence)

        if current_tokens + token_len > chunk_size:
            chunks.append(" ".join(current_chunk))
            # 겹침 적용
            if overlap > 0:
                overlap_tokens = 0
                overlap_chunk = []
                j = len(current_chunk) - 1
                while j >= 0 and overlap_tokens < overlap:
                    t = num_tokens_from_string(current_chunk[j])
                    overlap_tokens += t
                    overlap_chunk.insert(0, current_chunk[j])
                    j -= 1
                current_chunk = overlap_chunk
                current_tokens = sum(num_tokens_from_string(s) for s in current_chunk)
            else:
                current_chunk = []
                current_tokens = 0
        else:
            current_chunk.append(sentence)
            current_tokens += token_len
            i += 1

    # 마지막 청크 추가
    if current_chunk:
        chunks.append(" ".join(current_chunk))
    return chunks

# ✅ 예제 실행
pdf_path = "/content/sample.pdf"  # 자신의 PDF 파일 경로
text = extract_text_from_pdf(pdf_path)
sentences = split_sentences(text)
chunks = chunk_sentences_by_token(sentences)

# ✅ 출력 확인
print(f"총 {len(chunks)}개의 청크 생성됨 (각 청크는 약 300토큰)")
print("\n🔹 첫 번째 청크 예시:\n", chunks[0])