본문 바로가기
ML

효과적으로 문장을 분리하는 방법론

by 혜룐 2024. 3. 23.

Document Loader(pdf) 선택지 고려사항

  • 텍스트를 원형 그대로 잘 가져오는가
    • 한글 인코딩
    • 특수문자
  • 메타데이터의 종류를 잘 추출하는가
    • page_content
    • 페이지번호
    • 표, 차트, 문서의 좌표, 속성(타이틀, 테이블, 이미지, 텍스트)
      • 표나 아미지의 캡션
      • 마크다운형식
  • 문서를 읽는 속도가 얼마나 빠른다
    • 문서의 양이 크다면, 문서 업로드(색인시) 문서를 읽는 속도가 중요

pdfLoader

  • fitz
    • 모든 텍스트를 읽어서 하나의 문자열을 합칠때 유용
    • 페이지 읽는 속도가 가장 빠름
      • 실시간으로 요약본을 받아봐야 할때 = 예를 들면 kbpro웰컴메시지 작성시 유리할듯
    • 페이지 번호 제공
    • 그러나 번호 이외 메타데이터 미지원
    • 이미지만 추출가능
      • 커머스관련 자료에 상품 이미지
      • 그래프나 차트를 이미지로 삽입된 경우
  • pyPDFLoader
    • 한글 인코딩 처리 속도가 빠름 + 메타데이터 지원 (파일명소스, 페이지번호 제공)
  • UnstructuredPDFLoader
    • pdf내 각각의 요소들의 속성, 좌표를 준다.
    • 단 속도가 느리다. 그렇기 때문에 메타데이터 정보가 필요 없다면 고려할 필요 없음
    • 한글 인코딩 능력 우수 + 다양한 메타데이터 정보를 제공
      • 페이지 전체 넘버를 제공해준다.
    • 읽기 속도가 가장 느리다.
    • page.crop
        • table.bbox옵션 사용
        • PDFminer
          • 자동으로 분할된 컬럼에 대한 처리
          • 차트/표안의 텍스트를 인식할 수 있어 표나 그래프를 제거 하고 작업
          • 또는 한줄에 글자수 < N개 이하는 제거
        • 표추출
          • camelot, paddleOCR바운딩 박스를 계산후 박스안의 텍스트를 순서대로 읽는 방식 

TextSplitter

문서를 특정 기준으로 청크 할때 사용 kbpro는 현재 TokenTextSplitter를 사용하고 있음 

  • CharacterTextSplitter
    • 분할 가능한 최소의 단위로 분할을 시도한다. 공백이나 .을 기준으로 분할
    • 중요한 문서의 소제목에서 텍스트가 잘릴수 있다. 이런 경우 청크오버랩으로 해결이 안되는 경우가 많다.
    • 비추
  • TokenTextSplitter
    • 토큰 단위로 분할할대 사용하는데, 한글 처리가 모호해 잘 안될수 있다. 이런 경우 KonlpyTextSplitter를 사용하면 한글 처리 해결이 될수도 있다. (Kkma형태소 분석기를 사용하고 있음)
    • 빠른 텍스트 처리보다, 정확도를 높이고 싶은 경우 사용하는것이 좋다.
  • RecursiveCharacterTextSplitter
    • 범용적으로 많이 사용하는 방식으로 개인프러덕에서는 사용했으나 현재 kbpro에서는 사용하고 있지 않다.
    • 청크가 충분히 작아질때까지 순서대로 분할하려고 시도한다.
    • 단락 → 문장 → 단어순서대로 함께 유지 하려고 시도하는 효과가 있다. 의미관련된 부분을 보존하기 위해서
  • HuggingFace
  • SemanticChunker
    • 랭체인에 신규 추가
    • 텍스트를 의미 유사성에 따라 분할한다. 의미유사성에 따라서 알아서 나눠주는게 장점이라 임베딩 모델을 지정해서 분할해야 한다.
    • 다만 청크의 크기가 균일하지 않다.

Chunking Strategy

  • fixed size chuking
    • 고정된 길이로 단위로 잘라내는 방법
  • content-aware chuking
    • 문맥을 인지 하는 방식으로 청킹하는 방식
    • 문장이나 문단 단위로 문서를 잘라낸다. 문장과 문단을 온전히 보장할 수있지만, 길이가 길경우 청크의 사이즈가 커지는 문제가 있다. 그리고 텍스트에 마침표나 띄어쓰기를 제대로 사용하지 않은 경우, 제대로 문장을 나눠내지 못한다.
  • recursive chunking
    • fixed + contextAware방식 혼하는 것으로, "." 나 줄바꿈 단위로 문장을 추출하고, 그 문장이원하는 고정사이즈 보다 클경우 다시 fixed size로 자른 후, 나머지 문장을 . 이나 줄바꿈으로 재귀적으로 호출하는 방식이다.
    • 해당 방식은 개인코드에서 사용했으나 kbpro에는 현재 반영이 되어있지 않다.

Chunking 테크닉

  • overlapping
    • 앞의 예제 출력 결과를중 일부 청크만큼 윈도윙 하여 청킹하는것으로 일정 길이의 문장을 중첩해서 추출 하는 방식
    • 문장이 강제적으로 잘리더라도 최소한 앞의 문장을 덧 붙여 의미가 훼손되는 것을 방지한다.
  • parent child chunking 
    • 문서들을 작은 청크 단위로 나눠서 벡터임베딩에 넣는 과정까지는 비슷하다. 이때 문서의 인덱스도 같이 저장해 메타를 관리 하는 것으로 현재는 검색을 용이하게 하기위해 es에 해당 필드를 저장하고 있다. 
    • 이렇게 작은 단위의 청킹을 저장해 두면, 문서 검색시 해당 문장과 유사한 것을 찾은 후, 저장된 문서의 인덱스 값을 사용해 앞뒤에 연관성 있는 문서 전체의 내용을 컨텍스트에 주입할때 사용할 수 있다.

  • 청크 서머라이즈
    • 문서를 문단 단위로 잘라낸 후, 일정 크기 이하로 요약하는 방법
    • ContextAware chunking 문단추출 → LLM활용하여 요약 → 요약문 임베딩
    • 해당방식은 중간에 잘리지 않는 장점과, 원본청크 데이터에 가비지성 텍스트를 필터링 할수는 있지만, 정보가 유실 될수 있는 단점이 있다. 원본청크 데이터에 가비지데이터없이 전처리 하는것에 대한 고민이 있어 현재 kbpro에서는 검색과정에서만 서머라이즈를 선택 할수 있게 했다. llm컨텍스트에 요약문을 전달했던 이유는 maru-red 모델 사용시 답변의 품질을 보기위해 컨텍스트 필드로 사용했음을 추가로 남깁니다.
    •