LoGO 해외로고 프로젝트 - RAG 5: RAGAS로 성능 평가하기
- -
https://github.com/khw11044/my_RAGAS
우선 해당 레파지토리 코드를 기반으로 설명하는 게시물임을 알린다.
그리고 해당 코드는 아래 링크를 기반으로 커스텀하였다.
https://www.youtube.com/watch?v=jSd6pdydBNU&t=1257s
https://www.youtube.com/watch?v=rA5SoBXB8R4
평가를 위한 과정 요약
1. 문서에서 text split를 통해 'contents 생성'과 'metadata(문서 소스)' 저장
AutoRAG를 살펴보게 되면 먼저 문서들을 지정한 chunk size로 text split를 한 이후 판다스를 통해 parquet 파일을 만듭니다.
parquet 파일에 대한 설명은 아래 링크를 참고
https://butter-shower.tistory.com/245
2. contents와 metadata로 부터 평가데이터 만들기
AutoRAG등 RAGAS를 통해 평가를 하든 '질문'과 '대답' 그리고 그 대답의 '원천'이 쌍으로 구성되어 있어야 합니다.
따라서 컬럼은 'question'과, 'generation_ground_truth', 'retrieval_ground_truth'등이 있을 수 있겠습니다.
3. 구축한 RAG를 통해 'question'으로 부터 'answer'생성하기
구축한 RAG를 통해 전체 데이터에서 뽑은 평가데이터의 question으로부터 RAG가 '답변'을 생성하고 답변의 근거인 '소스(contexts)'를 가져옵니다.
또는 이 단계에서부터 AutoRAG를 사용할 경우 여러 RAG를 조합하고 평가합니다.
4. RAGAS를 통해 평가하기
최종적으로 RAGAS를 통해 faithfulness, answer relevancy, context recall, context precision, answer correctness, answer similarity를 측정합니다.
그럼 이제 깃허브 레파지토리를 함께 보겠습니다.
01. 준비하기
raw_docs에 pdf파일들을 준비해 둡니다. 또는 구축해 둔 pkl 파일 (실제 서비스를 위해 구축한 VectorDB에 데이터를 넣은 것처럼, 이미 합의한 방식의 contexts들이 들어 있음)을 준비해 둡니다.
00.make_corpus.py
import os
import pandas as pd
import click
from autorag.utils import cast_corpus_dataset
from llama_index.core import SimpleDirectoryReader
from llama_index.core.node_parser import TokenTextSplitter
from autorag.data.corpus import llama_text_node_to_parquet
root_dir = os.path.dirname(os.path.realpath(__file__))
@click.command()
@click.option('--dir_path', type=click.Path(exists=True, dir_okay=True, file_okay=False),
default=os.path.join(root_dir, 'raw_docs'))
@click.option('--save_path', type=click.Path(exists=False, dir_okay=False, file_okay=True),
default=os.path.join(root_dir, 'my_data', 'corpus_india.parquet'))
def main(dir_path: str, save_path: str):
if not save_path.endswith('.parquet'):
raise ValueError('The input save_path did not end with .parquet.')
documents = SimpleDirectoryReader(dir_path, recursive=True).load_data()
nodes = TokenTextSplitter().get_nodes_from_documents(documents=documents, chunk_size=256, chunk_overlap=64)
corpus_df = llama_text_node_to_parquet(nodes)
corpus_df = cast_corpus_dataset(corpus_df)
corpus_df.to_parquet(save_path)
df = pd.read_parquet(save_path)
df_cleaned = df[df['contents'].str.strip() != '']
df_cleaned.to_parquet(save_path)
print('done')
if __name__ == '__main__':
main()
dir_path의 default로 raw_docs 폴더의 파일들을 가져오고
save_path의 default로 my_data 폴더의 corpus_india.parquet 파일로 저장합니다.
코드를 run할때 따로 위치와 이름을 바꿔주어도 됩니다.
- SimpleDirectoryReader를 통해 raw_docs 폴더의 파일들을 모두 읽습니다.
- TokenTextSplitter를 통해 documents에서 chunk_size 별로 자르면서 chunk_overlap 크기만큼 겹치면서 text를 잘라 nodes로 쌓아줍니다.
- llama_documents_to_parquet에서 doc_id, contents, metadata 컬럼으로 pandas의 DataFrame을 만들어 냅니다.
- 다음 cast_corpus_dataset를 통해 autorag에서 정의한 metadata형식과 contents 형식으로 수정해줍니다.
- 이 다음 to_parquest를 통해 해당 위치로 parquet 파일을 저장해줍니다.
그 다음 코드는 생성한 파일의 contents에 아무것도 못들어간 경우가 있을 수 있습니다.
이 부분을 빼주기 위한 코드입니다.
AutoRAG의 make_corpus.py 코드를 사용하여 대중적인 방법을 따름으로써 , 자신의 RAG 성능을 대중적으로 증명하고 보여줄 수 있다는 장점이 있을 수 있습니다.
단점으로는 contents를 가져오는 방법이나 metadata 구성 방법은 서비스에 따라, 자료 및 목적에 따라 다를 수 있습니다.
따라서 저희는 pkl파일에서 parquet파일을 만들어 냅니다. 이를 위해 01.pkl_to_parquet.ipynb 파일에서 이를 수행하였습니다.
02. 질문-대답 정답 데이터 만들기 1
02.01.make_qa.py의 경우 chatbot RAG의 성능 평가를 위해 질문과 대답에 대한 정답 데이터를 만들려고 하는 코드입니다.
- corpus_path에서 my_data폴더의 my_corpus.parquet 파일을 가져오고
- 해당 코드를 통해 생성된 질문-대답 정답 데이터는 save_path에서 default로 my_data폴더의 my_qa.parquet 파일로 저장됩니다.
- qa_size는 만들 정답 데이터의 개수 (행의 개수) 입니다. 저희는 default로 12개의 질문과 대답 쌍을 만들었습니다.
다음 main 함수에서 corpus parquet 파일을 가져오고
주어진 context에서 질문과 대답을 만들어낼 LLM 모델로 OpenAI의 gpt-4o를 가져옵니다.
이때 창의성은 0.1로 하였습니다. 왜냐하면 주어진 context에서 다양한 질문을 만들어 내기 위함입니다.
make_single_content_qa 함수를 통해 corpus_df내용에서 qa_size 만큼 pandas 행 (질문과 대답 쌍)을 만들어 냅니다.
question_num_per_content는 주어진 content당 몇개의 질문-대답 쌍을 만들어 낼 것인지 정합니다.
예를 들어 3일 경우 하나의 내용(content)에 3개의 질문과 대답을 만들어 냅니다.
rando_state를 정해줌으로써, 해당 코드를 다시 실행해도 계속 같은 contents를 뽑아냅니다.
그 다음 '해당 자료와 관련이 없습니다'라고 생성한 질문의 행은 제거해버립니다. 그리고 저장합니다.
03. 질문-대답 정답 데이터 만들기 2
02에서 qid, retrieval_gt, query, generation_gt 컬럼을 생성하였다.
03.00.make_experiment_data_for_RAGAS.ipynb에서 query와 generation_gt는 각각 question과 ground_truth 컬럼으로 다시 표를 만들고 엑셀로 저장한다.
03부터 AutoRAG flow에서 벗어나서 RAGAS를 사용하기 위한 코드인데, AutoRAG는 retrieval_gt를 사용해서 검색기가 검색 소스를 잘 찾아왔는지도 평가하는데 RAGAS에서는 단순히 질문과 대답 정답만 사용한다.
04. 실험 데이터셋의 질문에 대한 RAG 결과 뽑기
04.00.qa_experiment_RAGAS.ipynb에서 지금까지 만든 qa_data.xlsx 파일을 불러온다.
그리고 다양한 RAG 조합과 함께 qa_data의 질문에 대해 결과(대답)를 뽑고 저장한다.
04.01은 단일 파일에 대해 평가를 한번 해 본 코드이다. 테스트를 위해
05. 최종 평가하기
05.00에서 평가를 진행한다.
평가를 위해 임베딩 모델도 필요하고, 잘 대답하였는지 평가하기 위한 LLM이 또 필요하다.
import nest_asyncio
nest_asyncio.apply()
그리고 평가를 할 때마다, 위 코드를 실행해주어야 오류가 나지 않는다.
04에서 다양한 RAG에 대한 결과들이 워낙 많기 때문에 하나하나 결과를 확인하지 않고 모두 불러들여서 결과를 저장한다.
06. 평가 결과 확인하기
저장한 내용을 불러들여서 확인한다.
'Project' 카테고리의 다른 글
Redis (0) | 2024.08.11 |
---|---|
Ollema 이용해서 자기 노트북에 LLM 모델 사용하기 (0) | 2024.08.08 |
Chroma DB 폴더 및 파일 구조 (0) | 2024.08.01 |
LoGO 해외로고 프로젝트 - RAG 4. (0) | 2024.07.31 |
LoGO 해외로고 프로젝트 - RAG 3. (0) | 2024.07.31 |
소중한 공감 감사합니다