
드디어 내가 가장 배우고 싶은 랭체인과 RAG 주차가 찾아왔다.
5주차부터 프로젝트 제작을 위한 실무 지식들을 배운다.
나는 랭체인과 RAG를 사용해서 도메인에 특화된 프로젝트를 진행하고 싶었다.
그래서 논문 pdf를 주면 해당 논문에 대해 질의응답을 해주는 챗봇을 만들어보려고 한다.
그리고 드디어 퍼플 배지를 받게 되었다.
아직까지는 한 번도 빼먹지 않고 과제를 제출했다.
과제 100% 통과하면 블랙 배지를 받을 수 있는데 반드시 얻고 말테다ㅎㅎ
깃헙 코드 보기
플로우는 대략적으로
논문 pdf 파일을 받으면 pdf 내의 텍스트를 추출하여, 임베딩한 후 RAG의 벡터 DB에 담아두고 해당 논문의 요약본을 생성하는 서비스다.
from langchain.document_loaders import UnstructuredPDFLoader
loader = UnstructuredPDFLoader("./example.pdf")
docs = loader.load()
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1500,
chunk_overlap=200
)
splits = text_splitter.split_documents(docs)
vectorstore = Chroma.from_documents(
documents=splits,
embedding=OpenAIEmbeddings(api_key=api_key)
)
나는 UnstructuredPDFLoader를 사용하여 pdf에서 텍스트를 추출하여 청크 사이즈를 1500, 오버랩을 200으로 맞추어 텍스트를 청킹했다. 그 다음엔 Chroma에 이를 임베딩하여 집어넣어줬는데.. 사실 여기까진 별 거 없었다.
테스트로 사용한 논문은 https://arxiv.org/pdf/2005.11401 RAG에 관한 논문이고
내 파이프라인이 만들어낸 요약본은 아래와 같았다. (gpt-4o-mini)
### 1. 논문의 목적
이 논문의 목적은 RAG( retrieval-augmented generation) 모델을 통해 사실 추출 및 검증을 수행하는 새로운 접근 방식을 제시하는 것이다. 이를 통해 기존의 복잡한 파이프라인 시스템과 비교하여 단순성과 효율성을 강조한다. 특히, RAG는 도메인 특정 아키텍처나 중간 검색 감독 없이도 성능을 발휘할 수 있음을 보여준다.
### 2. 주요 기여
- **성능:** RAG 모델은 3-way 분류에서 최첨단 모델과 비교했을 때 4.3% 내외의 성과를 보였다(§4.4, p.14).
- **단순성:** RAG는 복잡한 시스템 없이도 유효한 결과를 도출할 수 있는 능력을 지닌다.
- **응용 가능성:** 다양한 언어 모델의 기능을 접목하여 사실 기반의 대화형 응용 프로그램 개발에 기여할 수 있다.
### 3. 사용된 방법론
- **데이터셋:** FEVER 데이터셋을 사용하여 모델 성능을 검증한다.
- **모델 검증:** RAG 모델의 성능을 3-way 분류로 평가하며, 복잡한 파이프라인 대비 단순한 구조를 강조한다(§4.4, p.14).
- **정량적 결과:** RAG 모델이 생성한 응답의 사실 정확성은 높은 비율로 유지되며, 특정 입력에 대해 더 정교한 응답을 낸다.
### 4. 주요 결과
- RAG 모델은 3-way 분류에서 정확도가 4.3% 떨어지는 성과를 보였으며, 이는 기존 방법론에 비해 우수한 수치를 나타낸다(§4.4, p.14).
- 생성된 응답의 구체성과 사실 기반 정확성을 높여, 더 나은 대화형 AI의 기반을 마련한다.
### 5. 한계 및 미래 연구 방향
- **한계:** RAG 모델의 데이터 기반이 외부 지식원(예: 위키피디아)의 완전한 사실성을 담보하지 않음으로 인해 생성된 콘텐츠의 신뢰성에 문제가 있을 수 있다(§4.4, p.14).
- **미래 연구 방향:** 다루기 어려운 또는 편향된 내용을 자동으로 생성하지 않도록 개선할 수 있는 AI 시스템의 개발 필요성; 다양한 언어의 지원 범위를 확대하여 모델의 효용성을 높이는 연구가 제안된다.
나는 내 서비스가 생성한 요약본을 ROUGE와 BertScore를 기준으로 평가했다.
사용 모델 : gpt-4o-mini
정답용 모델 : gpt-4o
| 지표 | 점수 | 설명 |
|---|---|---|
| ROUGE-1 | 0.2543 | 단어 수준 유사도 |
| ROUGE-2 | 0.0702 | 2-gram 연속성 유사도 (문장 구성 구조) |
| ROUGE-L | 0.2197 | 문장 뼈대의 유사성 |
| ROUGE-Lsum | 0.2428 | 전체 요약 구조 유사성 |
| 지표 | 점수 | 설명 |
|---|---|---|
| Precision | 0.7095 | 정답 요약 의미 중 포함된 비율 |
| Recall | 0.6887 | 내가 쓴 요약이 정답을 얼마나 커버했는지 |
| F1 | 0.6990 | 의미 유사성 종합 점수 (사람 기준으로 매우 양호함) |
의미적으로는 핵심 내용을 잘 전달한 것 같으나,
문장 구성 방식이나 표현 스타일은 논문 요약 스타일과 차이가 있어보인다.
그리고, 출처를 적어달라했는데 얘가 출처를 제대로 못적는거 보면.. 아직 개선의 여지가 더 필요해 보인다.
다음 과제를 위한 액션 아이템 3가지를 잡아보았다.
프롬프트 수정
→ "논문 스타일로 학술적인 요약을 해줘" 같은 지시 문구 사용
예시 문장 추가
→ 학습 시 논문 스타일 예시 문장을 함께 제시
문단 단위 요약 후 통합
→ Recall + Precision 균형 잡기
이 과제는 5주차 BP로 선정되었다ㅎㅎ
코치님의 피드백 :
RAG를 적절히 구현하신 후 논문 요약을 잘해주셨습니다
ROUGE와 BERT score 등을 통해 정량적 분석을 시도하신 것도 잘하셨습니다.
채점도 GPT api를 통해 "둘 중에 뭐가 더 잘 요약했어?" 또는 "reference 대비 100점 만점에 몇점이라고 생각해" 이런식으로 evaluation해보는 것도 좋을 것 같습니다.
BP 선정 사유: 여러 메트릭을 통한 정량적 평가
심화 과제를 진행하면서, 궁금했던 점들을 과제 QnA 섹션과 멘토링 시간 때 코치님들께 여쭤보았다.
아래는 내가 한 질문들과 다른 분들이 질문해준 것 중에 나도 궁금했던 것들, 그리고 그 답변을 정리한 내용이다!
나처럼 실무에 LLM을 적용해야하는 사람들에게 도움이 됐으면 좋겠다.
Q1. 요약 텍스트 생성 평가 지표 : ROUGE vs BertScore 어느 쪽이 더 좋을까요?
A.
ROUGE
=> 보통은 ROUGE, BertScore, GPT4 평가(LLM-as-a-Judge) 결과를 결합하여 최종 점수를 산출하는 방식으로 진행한다.
Q2. 한국어 텍스트를 평가할 때 중간에 영어로 번역 후 평가를 하는 것이 좋을까요?
A.
번역 품질이 낮으면 평가가 왜곡될 위험성이 많다.
Q3. OpenAI API 서버 불안정 시 대응 전략
A.
인하우스 LLM 대체 (오픈소스 LLM 파인튜닝)
Multi-LLM
LLM 라우터
질문 외 추가 팁
Q1. RecursiveCharacterTextSplitter에서 텍스트를 청크로 분할할 때 overlap하는 이유에 대해 궁금합니다.
A1.
일론 머스크 테슬라 최고경영자(CEO)가 자사 휴머노이드 로봇 '옵
티머스'의 생산이 중국의 희토류 수출 규제로 타격을 입었다고 밝혔다. 테슬라는 중 국 정부와 협의를 진행 중이며, 관련 자원 접근을 위한 승인 절차를 밟고 있다고 덧붙였다.
Q2. open ai의 서버 상태가 불안정해져서 gpt를 사용할 수 없을 때엔 어떻게 하는 것이 좋을까요?(QnA 섹션 때와 같은 질문을 했다.)
A2.
Q3. RAG의 동작방식에 대해: 유저의 입력 → 모든 벡터 DB의 문서들의 임베딩 유사도를 체크 → 가장 유사도가 높은 문서를 가져와서 프롬프트에 얹는다. 이 방식이 맞을까요? 맞다면 문서의 양이 많아질 수록 검색속도가 느려지지 않을까요?
A3.
ㅇㅇ 더 자세하게 말씀드리자면 아래와 같다.
1. 유저 질문을 입력
2. 입력을 임베딩하여 쿼리 벡터 생성
3. 벡터 DB (예: FAISS, Chroma, Weaviate 등)에서 유사도가 높은 문서 top-k를 검색 -> 검색된 문서들을 프롬프트에 넣어 LLM에게 전달
4. LLM이 응답 생성
문서의 수가 많아지면 느려지는 게 맞다.
Q4. 사내에 있는 문서들을 미리 임베딩 후 벡터 DB에 넣어서 검색 속도를 높이고 싶습니다. 이럴 경우에는 벡터 DB를 띄워야할 것 같은데 실무에서는 어떻게 하고 있나요?
RecursiveCharacterTextSplitter로 문서 분할나는 이번 AI 코스를 통해 이런 것들을 가져가고 싶다.
예시)
| 모델 | 적용사항 | 성능 | 비용 | 성능/비용 | 모델 크기 |
|---|---|---|---|---|---|
| chatGPT | x | 0.80 | ~~ | ~~ | - |
| chatGPT | 프롬프팅 | 0.82 | ~~~ | ~~ | |
| chatGPT | 프롬프팅+RAG | 0.85 | |||
| openLLM | x | 0.40 | |||
| openLLM | 프롬프팅+RAG | 0.58 | |||
| openLLM | 프롬프팅+RAG+tune | 0.65 | ~~~ | ~~~ | 2B |
| openLLM | ...+tune+LoRA | 0.71 | ~~~ | ~~~ | 10B |
태스크별 평가 지표
주제의 참신함과 여러가지 기능 추가보다는 여러가지 프롬프팅 기법과 RAG로 다양한 경우의 수를 만들어내고, 성능을 비교하는 것에 초점을 맞출 것이다!
남은 3주 동안 화이팅!