File size: 3,728 Bytes
c857b85 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | #!/usr/bin/env python3
"""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
# ํ๋ก์ ํธ ๋ฃจํธ๋ฅผ sys.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:
# Stage 2๋ง ์คํ
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:
# Stage 1 โ Stage 2 ์ ์ฒด ์คํ
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()
|