ustwo-api / scripts /run_pipeline.py
asdfasdfqrqwer's picture
Deploy from GitHub 2026-04-23T03:56:31Z
c857b85
Raw
History Blame Contribute Delete
3.73 kB
#!/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()