Dongjin1203's picture
Initial commit for HF Spaces deployment
4739096
"""
RAG 전체 νŒŒμ΄ν”„λΌμΈ μ‹€ν–‰ 슀크립트
단계:
1. μ „μ²˜λ¦¬ (preprocess): ν…μŠ€νŠΈ μΆ”μΆœ β†’ μ •μ œ β†’ μ²­ν‚Ή
2. μž„λ² λ”© (embed): 청크 벑터화 β†’ ChromaDB μ €μž₯
3. RAG (rag): RAG νŒŒμ΄ν”„λΌμΈ ν…ŒμŠ€νŠΈ (선택)
μ‚¬μš©λ²•:
python main.py --step all # 전체 μ‹€ν–‰
python main.py --step preprocess # μ „μ²˜λ¦¬λ§Œ
python main.py --step embed # μž„λ² λ”©λ§Œ
python main.py --step rag # RAG ν…ŒμŠ€νŠΈλ§Œ
"""
import argparse
import sys
from pathlib import Path
from src.utils.config import PreprocessConfig
from src.loader.preprocess_pipeline import RAGPreprocessPipeline
def parse_arguments():
"""μ»€λ§¨λ“œ 라인 인자 νŒŒμ‹±"""
parser = argparse.ArgumentParser(
description='RAG 전체 νŒŒμ΄ν”„λΌμΈ μ‹€ν–‰',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
μ˜ˆμ‹œ:
python main.py --step all # 전체 νŒŒμ΄ν”„λΌμΈ μ‹€ν–‰
python main.py --step preprocess # μ „μ²˜λ¦¬λ§Œ μ‹€ν–‰
python main.py --step embed # μž„λ² λ”©λ§Œ μ‹€ν–‰
python main.py --step rag --query "질문" # RAG ν…ŒμŠ€νŠΈ
python main.py --step preprocess --chunk-size 500 # 청크 크기 μ‘°μ •
"""
)
# μ‹€ν–‰ 단계 선택
parser.add_argument(
'--step',
type=str,
choices=['all', 'preprocess', 'embed', 'rag'],
default='all',
help='μ‹€ν–‰ν•  단계 (κΈ°λ³Έκ°’: all)'
)
# μ „μ²˜λ¦¬ κ΄€λ ¨ 인자
preprocess_group = parser.add_argument_group('μ „μ²˜λ¦¬ μ˜΅μ…˜')
preprocess_group.add_argument(
'--meta-csv',
type=str,
default='./data/data_list.csv',
help='메타데이터 CSV 파일 경둜'
)
preprocess_group.add_argument(
'--files-dir',
type=str,
default='./data/files/',
help='원본 파일 폴더 경둜'
)
preprocess_group.add_argument(
'--output-chunks',
type=str,
default='./data/rag_chunks_final_small.csv',
help='청크 좜λ ₯ 파일 경둜'
)
preprocess_group.add_argument(
'--chunk-size',
type=int,
default=1000,
help='청크 크기'
)
preprocess_group.add_argument(
'--chunk-overlap',
type=int,
default=200,
help='청크 μ˜€λ²„λž©'
)
# RAG κ΄€λ ¨ 인자
rag_group = parser.add_argument_group('RAG μ˜΅μ…˜')
rag_group.add_argument(
'--query',
type=str,
help='RAG 질의 (rag λ‹¨κ³„μ—μ„œλ§Œ μ‚¬μš©)'
)
return parser.parse_args()
def step_preprocess(args):
"""1단계: μ „μ²˜λ¦¬ μ‹€ν–‰"""
print("\n" + "="*70)
print("πŸ”§ 1단계: 데이터 μ „μ²˜λ¦¬ μ‹œμž‘")
print("="*70)
# μ„€μ • μ΄ˆκΈ°ν™”
config = PreprocessConfig()
config.META_CSV_PATH = args.meta_csv
config.BASE_FOLDER_PATH = args.files_dir
config.OUTPUT_CHUNKS_PATH = args.output_chunks
config.CHUNK_SIZE = args.chunk_size
config.CHUNK_OVERLAP = args.chunk_overlap
# μ „μ²˜λ¦¬ νŒŒμ΄ν”„λΌμΈ μ‹€ν–‰
pipeline = RAGPreprocessPipeline(config)
df_chunks = pipeline.run()
print("\n" + "="*70)
print("βœ… 1단계: μ „μ²˜λ¦¬ μ™„λ£Œ")
print("="*70)
print(f"πŸ“ 좜λ ₯ 파일: {config.OUTPUT_CHUNKS_PATH}")
print(f"πŸ“Š 총 청크 수: {len(df_chunks)}")
return df_chunks
def step_embed(args):
"""2단계: μž„λ² λ”© 및 ChromaDB μ €μž₯"""
print("\n" + "="*70)
print("πŸ”§ 2단계: μž„λ² λ”© 및 벑터DB ꡬ좕 μ‹œμž‘")
print("="*70)
try:
# μž„λ² λ”© λͺ¨λ“ˆ μž„ν¬νŠΈ
from src.embedding.rag_data_processing import RAGVectorDBPipeline
# μž„λ² λ”© μ‹€ν–‰
pipeline = RAGVectorDBPipeline()
vectorstore = pipeline.build()
print("\n" + "="*70)
print("βœ… 2단계: μž„λ² λ”© μ™„λ£Œ")
print("="*70)
except ImportError as e:
print(f"⚠️ μž„λ² λ”© λͺ¨λ“ˆμ„ 찾을 수 μ—†μŠ΅λ‹ˆλ‹€: {e}")
print(" src/embedding/rag_data_processing.py 파일이 μžˆλŠ”μ§€ ν™•μΈν•˜μ„Έμš”.")
sys.exit(1)
except Exception as e:
print(f"❌ μž„λ² λ”© μ‹€ν–‰ 쀑 였λ₯˜ λ°œμƒ: {e}")
import traceback
traceback.print_exc()
sys.exit(1)
def step_rag(args):
"""3단계: RAG νŒŒμ΄ν”„λΌμΈ ν…ŒμŠ€νŠΈ"""
print("\n" + "="*70)
print("πŸ”§ 3단계: RAG νŒŒμ΄ν”„λΌμΈ ν…ŒμŠ€νŠΈ")
print("="*70)
try:
# RAG λͺ¨λ“ˆ μž„ν¬νŠΈ
from src.generator.generator import RAGPipeline
from src.utils.rag_config import RAGConfig
# RAG μ„€μ •
config = RAGConfig()
# RAG νŒŒμ΄ν”„λΌμΈ μ΄ˆκΈ°ν™”
rag = RAGPipeline(config=config)
# ν…ŒμŠ€νŠΈ 질의 μ‹€ν–‰
if args.query:
print(f"\nπŸ“ 질의: {args.query}")
result = rag.generate_answer(args.query)
print(f"\nπŸ’¬ λ‹΅λ³€:")
print(result['answer'])
print(f"\nπŸ“š μ°Έκ³  λ¬Έμ„œ: {len(result.get('sources', []))}개")
print(f"πŸ”’ 토큰 μ‚¬μš©: {result['usage']['total_tokens']}")
else:
print("\n⚠️ --query μΈμžκ°€ μ—†μ–΄ ν…ŒμŠ€νŠΈ 질의λ₯Ό κ±΄λ„ˆλœλ‹ˆλ‹€.")
print(" μ˜ˆμ‹œ: python main.py --step rag --query 'ν•œμ˜λŒ€ν•™κ΅ νŠΉμ„±ν™” 사업은?'")
print("\n" + "="*70)
print("βœ… 3단계: RAG νŒŒμ΄ν”„λΌμΈ μ™„λ£Œ")
print("="*70)
except ImportError as e:
print(f"⚠️ RAG λͺ¨λ“ˆμ„ 찾을 수 μ—†μŠ΅λ‹ˆλ‹€: {e}")
print(" src/generator/rag_pipeline.py 파일이 μžˆλŠ”μ§€ ν™•μΈν•˜μ„Έμš”.")
sys.exit(1)
except Exception as e:
print(f"❌ RAG μ‹€ν–‰ 쀑 였λ₯˜ λ°œμƒ: {e}")
import traceback
traceback.print_exc()
sys.exit(1)
def main():
"""메인 μ‹€ν–‰ ν•¨μˆ˜"""
args = parse_arguments()
print("="*70)
print("πŸš€ RAG 전체 νŒŒμ΄ν”„λΌμΈ")
print("="*70)
print(f"μ‹€ν–‰ 단계: {args.step}")
try:
if args.step == 'all':
# 전체 νŒŒμ΄ν”„λΌμΈ μ‹€ν–‰
step_preprocess(args)
step_embed(args)
# RAG ν…ŒμŠ€νŠΈλŠ” 선택적 (queryκ°€ 있으면 μ‹€ν–‰)
if args.query:
step_rag(args)
elif args.step == 'preprocess':
step_preprocess(args)
elif args.step == 'embed':
step_embed(args)
elif args.step == 'rag':
step_rag(args)
print("\n" + "="*70)
print("πŸŽ‰ λͺ¨λ“  μž‘μ—… μ™„λ£Œ!")
print("="*70)
except KeyboardInterrupt:
print("\n\n⚠️ μ‚¬μš©μžμ— μ˜ν•΄ μ€‘λ‹¨λ˜μ—ˆμŠ΅λ‹ˆλ‹€.")
sys.exit(1)
except Exception as e:
print(f"\n❌ 였λ₯˜ λ°œμƒ: {e}")
import traceback
traceback.print_exc()
sys.exit(1)
if __name__ == "__main__":
main()