배치 전사·요약

배치 · 2026년 8월 31일 기준

  • 테스트
  • Celery
  • SSE
  • 멀티파트 업로드
목차 6
  1. 개요
  2. 왜 이 설계가 필요했는가 (Problem)
  3. 처리 흐름
  4. 핵심 설계 결정
  5. 설계가 만든 결과 (Result)
  6. 배포 환경에서의 자원 예산 (2026-08-30 확인)

개요

업로드된 오디오 파일을 백그라운드(Celery)로 전사·요약하고, 진행 상황을 SSE로 실시간 푸시하는 파이프라인. 파일 업로드(202) → Celery 큐 → STT 세그먼트 스트리밍 → LLM 구조화 요약 → DB 저장 으로 동작하며, 클라이언트는 SSE로 과거 세그먼트 → 실시간 진행 → 최종 요약 을 순서대로 받는다.

비동기 접수 Celery 동시성 4 SSE 3단계 Look-ahead 3단계 에러 후처리
202 즉시 응답 재시도 지원 과거+실시간+요약 메모리 효율 스트리밍 DB 로그·상태·통보

왜 이 설계가 필요했는가 (Problem)


처리 흐름

처리 흐름 다이어그램처리 흐름 다이어그램

핵심 설계 결정

1. Look-ahead 세그먼트 스트리밍

# look-ahead 로 마지막 세그먼트 식별
현재 = next(전사 제너레이터)
while True:
    try:
        다음 = next(전사 제너레이터)  # 다음을 미리 읽음
        저장 후 발행(현재, 상태=처리 중)
        현재 = 다음
    except StopIteration:  # 다음이 없으면 = 마지막
        저장 후 발행(현재, 상태=전사 완료)
        break

2. SSE 3단계 (과거 replay + 실시간 구독)

# SSE 이벤트 생성기
for 세그먼트 in DB 의 과거 세그먼트:  # ① 과거 replay
    yield SSE(세그먼트, 과거=True)
if 작업 상태 == 완료:  # ② 이미 완료 → 즉시 종료
    yield SSE(최종 요약); return
async for 메시지 in Redis 구독(작업 ID):  # ③ 실시간 구독
    yield SSE(메시지)
    if 메시지 종류 in (최종 요약, 오류): break

3. 3단계 에러 후처리 (컨텍스트 매니저)

# 에러 컨텍스트 — 파이프라인 예외를 한 곳에서 처리
로그.error("[단계] 처리 중 오류", 작업 ID, exc_info=True)  # 구조화 로그
await 에러 로그 기록(작업 ID, 단계, 메시지 + 스택)  # ① DB
await 상태 갱신(작업 ID, 실패, 메시지)  # ② 상태
이벤트 발행(작업 ID, {종류: 오류, 메시지})  # ③ 통보

설계가 만든 결과 (Result)

검증 결과

look-ahead 파이프라인 테스트 · 10/10 통과

구분 검증 내용
★ 태깅 세그먼트가 몇 개든 마지막 하나만 ‘전사 완료’, 나머지는 ‘처리 중’ (1~30개 랜덤)
경계 세그먼트가 하나뿐이면 그 하나가 바로 ‘전사 완료’ — off-by-one 이 가장 잘 드러나는 지점
순서 세그먼트 번호 1부터 순차 · 본문과 DB 저장 순서 일치
누락방지 각 세그먼트마다 저장과 발행이 모두 수행
흐름 전사 후 ‘전사 완료’ → LLM 요약 → 최종 요약 발행 → ‘완료’
무음 세그먼트 0개면 LLM 미호출 + ’완료’로 종결, 오류 이벤트 없음
실패 전사 도중 예외 → 오류 이벤트 발행 + DB 로그, 예외는 삼켜 Celery 태스크가 안 죽는다

무음을 실패로 처리하지 않는 것도 계약이다

이 검증이 말하지 않는 것


배포 환경에서의 자원 예산 (2026-08-30 확인)

서비스 역할 스레드 설정 최대 점유
API 서버 실시간 스트리밍 추론 스레드 6 세션 수 × 워커 3 × 6
워커 배치 전사·요약 추론 스레드 2 · Celery 동시성 4 자식 4 × 2스레드 ≈ 8

배치와 실시간은 STT 설정이 갈린다

설정 실시간(API 서버) 배치(워커) 이유
beam 크기 1 (greedy) 5 배치는 지연 제약이 없어 정확도를 택할 수 있다. 주석: 「그리디(1)는 “가정”→“과정” 류 오인식 발생」
연산 정밀도 int8 int8 「int8_float32 는 출력이 문자단위로 동일하고 속도도 같아 무의미」

같은 엔진 추상화 위에서 경로별로 다른 트레이드오프를 고른 사례다 — 실시간은 지연을, 배치는 정확도를 우선한다. 「멀티 엔진 추상화」 카드의 설계가 실제로 값을 하는 지점이기도 하다.