참고 : 테디노트, LangChain밋업 발표자료
< RAG >
[ RAG 프로세스 ]
<전처리 작업>과 <서비스 단계에서 이뤄지는 작업>으로 나눌 수있다.
<전처리 작업>에서는 4가지 파트로 나눌 수 있다.
(실제 LLM 서비스를 만들 때 사전에 처리하는 작업이기 때문)
문서 로드(document loader),
다양한 형태의 문서를 로드 →
스플릿 : 긴 문서의 경우 LLM이 한번에 입력을 받을 수 없기 때문에 문서를 작은 조각으로 나누게 된다. 이 작업을 ‘청킹 작업’ 이라고 한다. →
이제 벡터 DB 공간에 저장하기 위해서 임베딩 과정 수행 → 벡터 DB에 저장
<서비스 단계에서 이뤄지는 작업> (실시간으로 유저가 질문을 하고 실시간 처리를 수행)
유저의 입력 →
입력 문장 임베딩 처리 →
Retrieve 검색을 통해 원하는 문서의 내용을 가져옴 →
프롬프트를 통해 LLM에 전달해서 원하는 답변을 출력 → Answer.
langchain에서는 다음과 같은 모듈들을 제공해준다.
- Document loader : 문서의 로드를 도와주는 로더. 약 150개 정도의 로더가 존재. 이렇게나 많다. 그만큼 다양한 기능들을 제공.
- Text Splitter : 문서를 청킹할 때 사용. 이 splitter 알고리즘들이 대표적으로 10가지 정도가 있다.
- Embedding : 문서를 임베딩, 엄청 많은 임베딩 모델들 사용 가능
- Vector Store : 임베딩한 문서들을 저장해주는 역할. 벡터 DB 종류도 랭체인에 인티그레이션 되어 있는 종류만 80가지 정도 된다.
- Retrievers : 벡터DB에서 검색을 해오는 역할. 이 종류도 50개 정도 된다.
⇒ RAG 프로세스를 만들기 위해서는 이 하나하나를 다 선택을 해줘야 한다. 아하~
모든 파이프라인 조합을 다 테스트를 해볼 수 없으니 상황에 맞는 적절한 조합을 선택해야 한다.
→ (이걸 자동적으로 해주겠다고 해서 나온 개념이 ‘AutoRAG’ 인 것이다!)
자 이제 이걸 하나씩 차례대로 살펴보자.
[Document loader]
수많은 문서들을 로드해줌. PDF, 엑셀, 마크다운, json, 파이썬 등 여러 파일들을 문서를 로드할 수 있는 로더를 제공.
langchain의 장점이 langchain은 이 로더를 통합된 인터페이스 형식으로 제공한다!
→ 즉, 로드라는 함수가 있다고하면 pdf 가져오고 싶으면 pdf, 엑셀이면 엑셀 이렇게 앞에 부분만 바꿔주면 된다! (실제로 사용시에 PDF를 다루는 프로젝트가 대부분이었음!)
→ PDF 로드를 하면 글자들을 잘 가져올 수 있을 것 같은데 실제로 구현해보면 그렇지 않은 경우가 많다!
그래서
고려사항 1 : 원형 그대로 잘 가져오는가. 한글 인코딩 처리가 안되어 있으면 한글이 깨져서 나오는 경우가 많다. 특수 문자나 수식이 잘 가져와지는지.
고려사항 2 : 메타데이터 즉, 본문의 내용뿐만 아니라 본문 외적의 내용들도 가져올 수 있는지. 표나 차트들도. 또는 이게 이미지인지 텍스트인지 속성값을 태깅을 다 해서 주는 경우도 있다. 상황에 맞는걸 사용하면 된다.
고려사항 3 : 문서를 읽는 속도. DB에 PDF 문서를 하나만 넣는게 아니다. 여러개 단위로 넣을 텐데 읽는 속도가 너무 느리면 DB를 쌓는데 굉장히 오랜 시간이 거리게 된다. (실시간인 경우에.) 또 다른 경우는, DB에 문서를 미리 저장해두는 것. 미리 문서들을 저장해 두기 때문에 몇 시간, 몇 일이 걸리든 크게 상관이 없다. 태스크에 따라서 속도가 중요할수도, 아닐 수도 있다.
<대표적인 PDF 문서로더>
- fitz : 단순하게 모든 Text를 읽어서 하나의 문자열을 합칠 때 유용하다. (전체 페이지 요약)
- 페이지를 읽는 속도가 가장 빠름
- 페이지 번호 제공
- 페이지 번호를 제외한 metadata 미지원
→ 속도가 빠르기 때문에 사용자가 PDF 문서를 업로드 하고 바로 이거에 대한 요약본을 받아야하는 경우에 사용했다.
- PyPDFLoader : 예제 코드에 가장 많이 출현하는 방식
- 평균적으로 우수함 (한글 인코딩 처리, 속도, metadata)
- 페이지 단위로 데이터를 로드
- 인코딩에서 깨지는 경우가 많이 없음. 무난무난
- metadata (source:파일명, page:페이지 번호 표기)
- UnstructuredPDFLoader : 가장 많은 metadata 정보 제공
- 요소별 Load 가능 (mode = ‘elements’, 페이지 안의 세부 요소에 대한 정보(좌표)가 필요하다면 좋은 Loader)
- 단, 다양한 정보를 포함하고 있기 때문에 속도가 다른 로더대비 느림 (메타데이터 정보 중 페이지번호를 제외한 다른 메타정보가 필요 없다면 과감히 스킵!
- PDFPlumber : 한글 인코딩 처리 능력이 우수하고, 다양한 메타데이터 정보(Author, ModDate)를 제공
- 단, 읽기 속도가 가장 느림. (UnstructuredPDFLoader와 비슷한 수준)
- 따라서, 다량의 페이지를 포함하는 문서는 parsing에 꽤 많은 시간이 소요
[Text Splitter]
→ 문서를 특정 기준으로 분할(Chunk) 할 때 활용
<대표적인 Text Splitter>
- CharacterTextSplitter : 분할 가능한 최소의 단위로 분할을 시도 (공백이나 “.”을 기준으로 분할)
- 중요한 문서의 소제목에서 텍스트가 잘릴 수 있음 (이는 chunk_overlap)이 궁극적인 해결책이 안되는 경우가 많음
- RecursiveCharacterTextSplitter : 범용적으로 많이 사용되는 분할 방식
- 청크가 충분히 작아질 때까지 순서대로 분할하려고 시도
- 기본 목록은 ["\n\n", "\n", " ", ""] • 단락 ➡ 문장 ➡ 단어 순서로 함께 유지하려고 시도하는 효과가 있는데, 이는 일반적으로 텍스트의 가장 강력한 의미 관련 부분으로 보이기 때문
- TokenTextSplitter : 토큰 단위로 분할
- TokenTextSplitter를 바로 사용하면 한글 처리가 모호함
- 따라서, KonlpyTextSplitter를 사용하면 해결책이 될 수 있음 (Kkma는 빠른 텍스트 처리보다 분석적 심도가 우선시되는 애플리케이션에 적합)
- 오픈 소스 : 허깅페이스에 업로드 된 다양한 토크나이저를 쉽게 활용 가능
- 속도와 성능 면에서 개선된 버전이 지속적으로 업데이트되고 있으므로, 최적의 토크나이저를 다양하게 테스트 해 볼 수 있음.
- 신조어, 특정 도메인 용어(의료 용어) 등의 tokenizer.trainer 로 Fine-Tuning 혹은 단순 추가(add) 가능 • 대표적인 Tokenizer • Subword Tokenizer • BPE • WordPiece • SentencePiece • spaCy • Moses
- SemanticChunker : langchain_experimental에 신규 추가된 Chunker
- 텍스트를 의미 유사성에 따라 분할
- 다른 Tokenizer와 달리 chunk_size, chunk_overlap과 같은 파라미터를 initialize에 사용하지 않는 것이 특징
- 단점은 청크 사이즈나 청크 관리가 힘들 수 있다.
[Embedding]
→ 임베딩은 텍스트의 벡터 표현을 만든다.
임베딩 작업을 하는 이유는 나중에 벡터 DB로 문서들을 저장할건데 가장 우수한 텍스트를 찾는 semantic search를 하기 위해서 임베딩 작업을 한다.
문서와 적합한 임베딩 모델을 선택하는 게 중요, 한글까지 처리를 잘 할 수 있는 임베딩 모델을 선택하는게 중요.
@ 중요! 임베딩은 두 군데에서 일어난다!
하나는 문서를 임베딩해서 DB에 넣을 때, 사용자가 질문을 했을 때 그 질문도 임베딩을 해야한다.
그래서 사용자 질문과 문서 임베딩의 유사성을 찾아서 그 결과를 반환하게 되는 것이다.
'NLP > RAG' 카테고리의 다른 글
| [RAG] teddynote (part2. 체인 파이프라인의 기본 요소) Ch 2. 미니프로젝트 (0) | 2024.09.27 |
|---|---|
| [RAG] teddynote (part2. 체인 파이프라인의 기본 요소) Ch 1. 프롬프트 (0) | 2024.09.27 |
| [RAG] teddynote (part1. LangChain 입문) - Ch4. 문법 (0) | 2024.08.27 |
| [RAG] teddynote (part1. LangChain 입문) (0) | 2024.08.09 |
| [concept] Retrieval-Augmented Generation (RAG) (1) | 2024.02.28 |