블로그의 파일들은 깃허브 내에서 다운 가능합니다.
깃허브 주소
text_splitter는 LangChain에서 제공하는 도구로, 긴 텍스트 문서를 더 작고 관리하기 쉬운 청크(chunks)로 나누는 기능을 한다.
text_splitter의 주요 기능
- 텍스트 분할: 긴 문서를 더 작은 단위로 나눈다.
- 의미 유지: 가능한 한 문장이나 단락의 의미를 유지하면서 분할한다.
- 다양한 분할 전략: 문장, 토큰, 문자 기반 등 여러 전략을 지원한다.
- 메타데이터 추가: 각 청크에 원본 문서 내 위치 등의 메타데이터를 추가할 수 있다.
주요 text_splitter 유형
- RecursiveCharacterTextSplitter: 가장 일반적으로 사용되며, 문자를 기반으로 재귀적으로 텍스트를 분할한다.
- CharacterTextSplitter: 사용자 정의 구분자를 사용하여 텍스트를 분할한다.
- TokenTextSplitter: 토큰을 기반으로 텍스트를 분할한다.
- LanguageRecursiveTextSplitter: 특정 프로그래밍 언어에 최적화된 분할을 수행한다.
pdf 로더를 통해 파일을 읽어왔으면 이제 나눠주는 단계가 필요하다.
그 때 사용 할 수 있는게 텍스트 분할기(Text Splitter)다.
RecursiveCharacterTextSplitter는 가장 일반적으로 사용된다.
일반적으로 사용되는데에는 다 이유가 있다.
필자는 다른거 안써봄
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=200
)
pages = text_splitter.split_documents(documents)
여기서 이제 중요한거 설명 들어간다.
청크 사이즈랑 한 청크 내에 얼마나 담을 거냐는 소리다.
현재는 청크 사이즈를 500으로 설정해줬다
이 뜻은 한 청크 내의 500개의 토큰을 담갰다는 거다.
해당 사이즈를 얼마나 설정 하냐에 따라 하나의 공간안에 많은 정보를 닮을 수도 있고, 적은 정보를 닮을 수도 있다.
그러면 많으면 많을 수록 좋은거 아니야? 하겠지만 꼭 그렇지 많은 않다.
청크 사이즈의 중요성
- 정보 검색 효율성: 적절한 청크 사이즈는 관련 정보를 더 정확하게 검색할 수 있게 한다.
- 컨텍스트 유지: 너무 작은 청크는 맥락을 잃을 수 있고, 너무 큰 청크는 관련 없는 정보를 포함할 수 있다.
- 모델 성능 영향: 청크 사이즈는 LLM의 입력 크기와 관련이 있어 모델의 성능에 직접적인 영향을 미친다.
청크 사이즈 설정 고려사항
- 문서 특성: 문서의 길이, 구조, 내용의 복잡성에 따라 적절한 청크 사이즈가 달라진다.
- 질문의 성격: 짧은 쿼리와 긴 쿼리에 따라 최적의 청크 사이즈가 다를 수 있다.
- 모델 제한: 사용하는 LLM의 컨텍스트 윈도우 크기를 고려해야 한다.
최적화 방법
- 실험적 접근: 다양한 청크 사이즈를 테스트하여 최적의 값을 찾는다.
- 고급 기법: Recursive chunking, Overlapping, Parent-Child chunking 등의 기법을 활용할 수 있다.
문서 마다 다르지만 대부분 청크 사이즈는 크면 클 수록 안좋은 경향이 많다.
다른 문서들로 해봤을 때 chunk_size는 256 정도가 가장 괜찮았던거 같다.
오버랩이란 몇 개의 토큰 만큼 겹칠 거냐는 거다.
chunk_size 별로 나눈뒤 chunk_overlap 만큼 서로 겹치게 저장을 하는거다.
그로 인해 각 청크 마다 서로 겹치는 부분이 있어 어느 정도 연결점을 생성하게 해준다.
print(pages[0].page_content)
print("-" * 100)
print(pages[1].page_content)
### 출력 결과
법제처 1 국가법령정보센터
도로교통법
도로교통법
[시행 2024. 10. 25.] [법률 제19745호, 2023. 10. 24., 일부개정]
경찰청 (교통기획계(법제총괄, 안전표지, 보호구역)) 02-3150-2251
경찰청 (교통안전계(안전, 단속, 어린이통학버스)) 02-3150-2252
경찰청 (운전면허계(운전면허)) 02-3150-2253
경찰청 (첨단교통계(신호, 무인단속장비)) 02-3150-2851
경찰청 (교통조사계(교통사고조사)) 02-3150-2552
제1장 총칙
제1조(목적) 이 법은 도로에서 일어나는 교통상의 모든 위험과 장해를 방지하고 제거하여 안전하고 원활한 교통을 확보
함을 목적으로 한다.
----------------------------------------------------------------------------------------------------
경찰청 (운전면허계(운전면허)) 02-3150-2253
경찰청 (첨단교통계(신호, 무인단속장비)) 02-3150-2851
경찰청 (교통조사계(교통사고조사)) 02-3150-2552
제1장 총칙
제1조(목적) 이 법은 도로에서 일어나는 교통상의 모든 위험과 장해를 방지하고 제거하여 안전하고 원활한 교통을 확보
함을 목적으로 한다.
제2조(정의) 이 법에서 사용하는 용어의 뜻은 다음과 같다. <개정 2012. 3. 21., 2013. 3. 23., 2014. 1. 28., 2014. 11. 19.,
2017. 3. 21., 2017. 7. 26., 2017. 10. 24., 2018. 3. 27., 2020. 5. 26., 2020. 6. 9., 2020. 12. 22., 2021. 10. 19., 2022. 1.
11., 2023. 4. 18., 2023. 10. 24.>
1. “도로”란 다음 각 목에 해당하는 곳을 말한다.
가. 「도로법」에 따른 도로
text_splitter의 length_function은 문서를 분할할 때 각 조각의 길이를 계산하는 데 사용된다.
보통 text_splitter는 긴 텍스트 문서를 작은 부분으로 나누는 역할을 하며, 이때 각 부분의 길이를 어떻게 측정할지를 결정하는 함수가 length_function이다.
이 함수는 기본적으로 토큰의 수, 글자의 수, 또는 단어의 수 등을 기준으로 텍스트의 길이를 계산할 수 있다.
예를 들어, 길이를 토큰 기준으로 계산하고 싶다면, length_function에 토큰화 함수(tokenizer)를 사용하여 각 조각이 몇 개의 토큰을 포함하는지를 계산할 수 있다.
반면에, 글자 수를 기준으로 분할하고 싶다면 len() 함수로 길이를 계산할 수 있다.
따라서, length_function을 적절히 정의하면 텍스트 분할 과정에서 조각의 크기나 기준을 세밀하게 조정할 수 있다.
현행 법령을 RAG 시스템으로 구현 할려다 보니, 제 몇 조 이런식으로 나누는게 좋을거 같다.
이 부분도 더 실험해봐야 할 것 같다.