CoolFace
Apppublic

Dongjin1203/QLoRA_RAG_test

sourceHugging Facemitupdated 10mo agoView on Hugging Face
0likes
create_eval_dataset.py247 linesDownload Raw Back to src
1"""2평가 데이터셋 생성 도구3 4실제 RFP 문서에서 질문-답변 쌍을 만들어5Ground Truth가 있는 평가 데이터셋을 생성합니다.6 7사용법:8    python create_eval_dataset.py --input data/rag_chunks_final.csv --output data/eval_dataset.json9"""10 11import json12import csv13import argparse14from pathlib import Path15from typing import List, Dict, Any16 17 18class EvalDatasetCreator:19    """평가 데이터셋 생성 클래스"""20    21    def __init__(self):22        self.dataset = {23            "metadata": {24                "version": "1.0",25                "description": "RFPilot 평가 데이터셋",26                "created_by": "manual_annotation"27            },28            "in_distribution": [],29            "out_distribution": []30        }31    32    def add_in_distribution_sample(33        self,34        query: str,35        expected_answer: str,36        category: str,37        source_doc: str = None,38        metadata: Dict[str, Any] = None39    ):40        """In-Distribution 샘플 추가"""41        sample = {42            "query": query,43            "expected_answer": expected_answer,44            "category": category,45            "expected_type": "document",46            "source_doc": source_doc,47            "metadata": metadata or {}48        }49        self.dataset["in_distribution"].append(sample)50    51    def add_out_distribution_sample(52        self,53        query: str,54        expected_answer: str,55        category: str,56        metadata: Dict[str, Any] = None57    ):58        """Out-Distribution 샘플 추가"""59        sample = {60            "query": query,61            "expected_answer": expected_answer,62            "category": category,63            "expected_type": "out_of_scope",64            "metadata": metadata or {}65        }66        self.dataset["out_distribution"].append(sample)67    68    def create_template_dataset(self):69        """템플릿 데이터셋 생성 (수동 작성용)"""70        print("📝 템플릿 데이터셋 생성 중...")71        72        # In-Distribution 템플릿73        in_dist_templates = [74            {75                "query": "사업 제안서 제출 마감일은 언제인가요?",76                "expected_answer": "2024년 3월 15일까지입니다.",  # 실제 문서에서 추출77                "category": "deadline",78                "source_doc": "RFP_2024_001.hwp",79                "metadata": {"difficulty": "easy"}80            },81            {82                "query": "제안 요청서의 제출 서류는 무엇인가요?",83                "expected_answer": "기술제안서, 가격제안서, 사업자등록증, 회사소개서가 필요합니다.",84                "category": "requirements",85                "source_doc": "RFP_2024_001.hwp",86                "metadata": {"difficulty": "medium"}87            },88            {89                "query": "사업 예산 규모는 얼마인가요?",90                "expected_answer": "총 5억원입니다.",91                "category": "budget",92                "source_doc": "RFP_2024_002.hwp",93                "metadata": {"difficulty": "easy"}94            },95        ]96        97        # Out-Distribution 템플릿98        out_dist_templates = [99            {100                "query": "한국의 수도는 어디인가요?",101                "expected_answer": "서울입니다.",102                "category": "general_knowledge",103                "metadata": {"difficulty": "easy"}104            },105            {106                "query": "파이썬에서 리스트와 튜플의 차이는 무엇인가요?",107                "expected_answer": "리스트는 가변(mutable)이고, 튜플은 불변(immutable)입니다.",108                "category": "programming",109                "metadata": {"difficulty": "medium"}110            },111        ]112        113        # 데이터셋에 추가114        for sample in in_dist_templates:115            self.add_in_distribution_sample(**sample)116        117        for sample in out_dist_templates:118            self.add_out_distribution_sample(**sample)119        120        print(f"✅ 템플릿 생성 완료")121        print(f"   - In-Distribution: {len(in_dist_templates)}개")122        print(f"   - Out-Distribution: {len(out_dist_templates)}개")123        print(f"\n⚠️ 이 템플릿을 수정하여 실제 데이터를 채워주세요!")124    125    def load_from_csv(self, csv_path: str):126        """CSV에서 데이터셋 로드"""127        print(f"📥 CSV 로드 중: {csv_path}")128        129        with open(csv_path, 'r', encoding='utf-8') as f:130            reader = csv.DictReader(f)131            for row in reader:132                distribution = row.get('distribution', 'in_distribution')133                134                if distribution == 'in_distribution':135                    self.add_in_distribution_sample(136                        query=row['query'],137                        expected_answer=row['expected_answer'],138                        category=row['category'],139                        source_doc=row.get('source_doc'),140                        metadata=json.loads(row.get('metadata', '{}'))141                    )142                else:143                    self.add_out_distribution_sample(144                        query=row['query'],145                        expected_answer=row['expected_answer'],146                        category=row['category'],147                        metadata=json.loads(row.get('metadata', '{}'))148                    )149        150        print(f"✅ CSV 로드 완료")151    152    def save_json(self, output_path: str):153        """JSON 형식으로 저장"""154        output_path = Path(output_path)155        output_path.parent.mkdir(parents=True, exist_ok=True)156        157        with open(output_path, 'w', encoding='utf-8') as f:158            json.dump(self.dataset, f, ensure_ascii=False, indent=2)159        160        print(f"💾 저장 완료: {output_path}")161    162    def save_csv_template(self, output_path: str):163        """수동 작성용 CSV 템플릿 저장"""164        output_path = Path(output_path)165        output_path.parent.mkdir(parents=True, exist_ok=True)166        167        with open(output_path, 'w', encoding='utf-8', newline='') as f:168            writer = csv.DictWriter(f, fieldnames=[169                'distribution', 'query', 'expected_answer', 170                'category', 'source_doc', 'metadata'171            ])172            writer.writeheader()173            174            # In-Distribution 예시175            writer.writerow({176                'distribution': 'in_distribution',177                'query': '사업 제안서 제출 마감일은 언제인가요?',178                'expected_answer': '2024년 3월 15일까지입니다.',179                'category': 'deadline',180                'source_doc': 'RFP_2024_001.hwp',181                'metadata': '{"difficulty": "easy"}'182            })183            184            # Out-Distribution 예시185            writer.writerow({186                'distribution': 'out_distribution',187                'query': '한국의 수도는 어디인가요?',188                'expected_answer': '서울입니다.',189                'category': 'general_knowledge',190                'source_doc': '',191                'metadata': '{"difficulty": "easy"}'192            })193        194        print(f"📄 CSV 템플릿 저장: {output_path}")195        print(f"   → 이 파일을 수정하여 실제 데이터를 채워주세요!")196    197    def print_summary(self):198        """데이터셋 요약 출력"""199        print("\n" + "="*60)200        print("데이터셋 요약")201        print("="*60)202        print(f"In-Distribution: {len(self.dataset['in_distribution'])}개")203        print(f"Out-Distribution: {len(self.dataset['out_distribution'])}개")204        print(f"총 샘플: {len(self.dataset['in_distribution']) + len(self.dataset['out_distribution'])}개")205        print("="*60 + "\n")206 207 208def main():209    parser = argparse.ArgumentParser(description='평가 데이터셋 생성')210    parser.add_argument('--mode', choices=['template', 'csv'], default='template',211                        help='생성 모드: template (템플릿 생성) 또는 csv (CSV에서 로드)')212    parser.add_argument('--input', type=str, help='입력 CSV 파일 경로')213    parser.add_argument('--output', type=str, default='data/eval_dataset.json',214                        help='출력 JSON 파일 경로')215    parser.add_argument('--csv-template', type=str, default='data/eval_template.csv',216                        help='CSV 템플릿 저장 경로')217    218    args = parser.parse_args()219    220    creator = EvalDatasetCreator()221    222    if args.mode == 'template':223        print("📝 템플릿 모드")224        creator.create_template_dataset()225        creator.save_json(args.output)226        creator.save_csv_template(args.csv_template)227    228    elif args.mode == 'csv':229        if not args.input:230            print("❌ CSV 모드에서는 --input 옵션이 필요합니다.")231            return232        233        print("📥 CSV 모드")234        creator.load_from_csv(args.input)235        creator.save_json(args.output)236    237    creator.print_summary()238    239    print("\n✅ 완료!")240    print(f"\n다음 단계:")241    print(f"1. {args.csv_template} 파일을 열어서 실제 데이터 작성")242    print(f"2. python create_eval_dataset.py --mode csv --input {args.csv_template} --output {args.output}")243    print(f"3. 생성된 {args.output}을 실험에 사용")244 245 246if __name__ == "__main__":247    main()