| |
| """Stage 1 β Stage 2 E2E νμ΄νλΌμΈ μ€ν μ€ν¬λ¦½νΈ. |
| |
| Usage: |
| python scripts/run_pipeline.py # κΈ°λ³Έ μν μ¬μ© |
| python scripts/run_pipeline.py data/samples/my_call.wav # νΉμ νμΌ μ§μ |
| python scripts/run_pipeline.py --stage2-only # Stage 2λ§ μ€ν (stage1_output.json νμ) |
| """ |
|
|
| from __future__ import annotations |
|
|
| import argparse |
| import json |
| import logging |
| import sys |
| from pathlib import Path |
|
|
| |
| PROJECT_ROOT = Path(__file__).parent.parent |
| sys.path.insert(0, str(PROJECT_ROOT)) |
|
|
| logging.basicConfig( |
| level=logging.INFO, |
| format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", |
| ) |
| logger = logging.getLogger("run_pipeline") |
|
|
|
|
| def run_stage1(audio_path: str) -> dict: |
| """Stage 1 μ€ν: νμλΆλ¦¬ + ASR.""" |
| from src.stage1.process import process as stage1_process |
|
|
| logger.info("=" * 60) |
| logger.info("Stage 1 μμ: %s", audio_path) |
| logger.info("=" * 60) |
|
|
| result = stage1_process(audio_path) |
|
|
| logger.info( |
| "Stage 1 μλ£: %d segments, %.1fs μ²λ¦¬μκ°", |
| len(result.segments), |
| result.processing_info.processing_time_sec, |
| ) |
| return result |
|
|
|
|
| def run_stage2(stage1_output) -> dict: |
| """Stage 2 μ€ν: κ°μ λΆμ.""" |
| from src.stage2.process import process as stage2_process |
|
|
| logger.info("=" * 60) |
| logger.info("Stage 2 μμ: %s (%d segments)", stage1_output.call_id, len(stage1_output.segments)) |
| logger.info("=" * 60) |
|
|
| result = stage2_process(stage1_output) |
|
|
| logger.info( |
| "Stage 2 μλ£: %d emotions, speakers=%s", |
| len(result.emotions), |
| list(result.speaker_summaries.keys()), |
| ) |
|
|
| |
| for speaker_id, summary in result.speaker_summaries.items(): |
| logger.info( |
| " %s: dominant=%s (%.1f%%), avg_confidence=%.2f", |
| speaker_id, |
| summary.dominant_emotion, |
| summary.emotion_distribution.get(summary.dominant_emotion, 0) * 100, |
| summary.avg_confidence, |
| ) |
|
|
| return result |
|
|
|
|
| def main(): |
| parser = argparse.ArgumentParser(description="Stage 1 β Stage 2 νμ΄νλΌμΈ μ€ν") |
| parser.add_argument( |
| "audio_path", |
| nargs="?", |
| default="data/samples/sample_data.wav", |
| help="μ
λ ₯ μ€λμ€ νμΌ κ²½λ‘ (κΈ°λ³Έ: data/samples/sample_data.wav)", |
| ) |
| parser.add_argument( |
| "--stage2-only", |
| action="store_true", |
| help="Stage 2λ§ μ€ν (data/stage1_output.json νμ)", |
| ) |
| args = parser.parse_args() |
|
|
| if args.stage2_only: |
| |
| from src.common.schemas import Stage1Output |
|
|
| stage1_path = PROJECT_ROOT / "data" / "stage1_output.json" |
| if not stage1_path.exists(): |
| logger.error("data/stage1_output.json μμ. Stage 1μ λ¨Όμ μ€ννμΈμ.") |
| sys.exit(1) |
|
|
| stage1_output = Stage1Output.model_validate_json(stage1_path.read_text()) |
| run_stage2(stage1_output) |
| else: |
| |
| audio_path = str(PROJECT_ROOT / args.audio_path) if not Path(args.audio_path).is_absolute() else args.audio_path |
|
|
| if not Path(audio_path).exists(): |
| logger.error("μ€λμ€ νμΌ μμ: %s", audio_path) |
| sys.exit(1) |
|
|
| stage1_output = run_stage1(audio_path) |
| run_stage2(stage1_output) |
|
|
| logger.info("=" * 60) |
| logger.info("νμ΄νλΌμΈ μλ£!") |
| logger.info(" Stage 1 μΆλ ₯: data/stage1_output.json") |
| logger.info(" Stage 2 μΆλ ₯: data/stage2_output.json") |
| logger.info("=" * 60) |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|