Greenfield setup for luke_scribe (local STT transcription API). No source
code yet; this captures the completed design phase so teammates can ramp
through oh-my-claudecode.
Includes:
- .omc/plans/consensus-luke-scribe-stt-api.md — consensus impl plan v2.2
- .omc/specs/deep-interview-luke-scribe-stt-api.md — deep-interview spec
- .omc/artifacts/ask/{codex,gemini}-*.md — external review (CCG)
- .omc/project-memory.json — omc project memory
- opencode.json, .claude/settings.json — shared tooling config
- .gitignore — excludes ephemeral omc state/session logs and local settings
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
31 KiB
Deep Interview Spec: luke_scribe — 로컬 STT 전사 API 시스템
내부용(비공개) 음성/영상 → 텍스트 전사 API. 로컬 모델 실행, GPU/CPU 자동·수동 선택, 실시간(WebSocket) + 배치(파일/영상), 작업 큐·진행률, 혼용어 대응, 후처리, Colab 자동 노출.
Metadata
- Interview ID:
di-luke-scribe-stt-20260602 - Rounds: 3 (스코어링) + 추가 아이디어 1 + 열린 결정 확정 1
- Final Ambiguity Score: ~10% (threshold 20%; 열린 결정 6건 확정 후)
- Type: greenfield (빈 저장소
luke_scribe) - Generated: 2026-06-02
- Threshold: 0.2 / Threshold Source:
default - Initial Context Summarized: no
- Status: PASSED · 결정 확정 완료 · CCG 외부리뷰 반영(v2.2)
Clarity Breakdown
| Dimension | Score | Weight | Weighted |
|---|---|---|---|
| Goal Clarity | 0.94 | 0.40 | 0.376 |
| Constraint Clarity | 0.90 | 0.30 | 0.270 |
| Success Criteria | 0.86 | 0.30 | 0.258 |
| Total Clarity | 0.904 | ||
| Ambiguity | 0.096 (~10%) |
Topology (확정 컴포넌트)
| # | Component | Status | 설명 | 커버리지 |
|---|---|---|---|---|
| 1 | Ingestion API | active | 실시간 스트림(WebSocket) + 파일/영상 업로드 수집 | AC-1, AC-7, AC-9 |
| 2 | Transcription Engine | active | 로컬 STT(faster-whisper), 하이브리드: 실시간=turbo / 배치=large-v3 | AC-4 |
| 3 | Realtime Pipeline | active | VAD·청크·부분/최종 결과 스트리밍 | AC-8 |
| 4 | Output / Results | active | 요청별 출력옵션(txt/ts/word/diarize/SRT/VTT), 결과 보관(7일) | AC-9, AC-11 |
| 5 | Job Queue / Concurrency (1급) | active | Job 추상화, Redis 영속 큐, 워커풀, 우선순위 레인, queue_position·진행률 | AC-5, AC-6 |
| 6 | Device Manager (횡단) | active | GPU/CPU 자동감지 → 정밀도·워커수·동시성 자동 산정, 강제 플래그 | AC-2, AC-3 |
| 7 | Post-processing | active | glossary/rules + (옵션)LLM 보정(백엔드 설정화) + confidence 플래그 | AC-10 |
| 8 | Connectivity / Tunnel | active | Colab 등 공인 IP 없는 환경 자동 외부 노출(cloudflared 등) | AC-13 |
Goal
내부 서비스가 호출하는 비공개 API로, 실시간 음성·녹음 파일·mp3·mp4(및 기타 영상)를 입력받아 로컬에서 실행되는 STT 모델로 텍스트로 전사한다. 실시간 입력은 준실시간(3~5초 내 부분 결과)으로 전사한다. 모델은 감지된 하드웨어(GPU/CPU)에 맞춰 정밀도·동시성을 자동 결정하되 auto | cpu | cuda 강제 선택도 가능하다. 다수 작업을 동시/대기열로 처리하고, 호출자는 대기열 위치와 진행률을 조회할 수 있다. 한국어 중심이되 한·영 혼용 기술용어(예: "API", "vLLM")를 음차로 망가뜨리지 않고 정확히 전사한다. 정확도가 중요한 배치는 large-v3, 저지연이 중요한 실시간은 turbo로 분리한다(하이브리드).
Constraints (제약)
- 로컬 실행(STT). 외부 STT API(구글/AWS 등) 의존 금지 — Whisper를 우리 하드웨어에서 직접 실행. 모델 가중치는 미존재 시 HuggingFace에서 자동 다운로드(인터넷 OK), 손상 시 재다운로드. 에어갭/오프라인 강제는 요구사항 아님.
- 하드웨어 폭이 매우 넓음: 개발=GTX 1050(Pascal, 2~4GB), 테스트=Colab/T4/L4/A100/H100. → 고정 수치 설정 불가, 자동 산정 필수.
- 정밀도 자동 선택: compute capability ≥ 7.0 → fp16, Pascal(6.x) → int8, VRAM 부족 → CPU 폴백, CPU → int8.
- 동시성/워커 수는 감지된 VRAM·코어로 자동 산정(오버라이드만 허용).
- 모델 하이브리드: 실시간=turbo, 배치=large-v3 (둘 다 설치,
model오버라이드 가능). - 언어: 한국어 우선 + 자동 감지, 한·영 혼용(code-switching) 정확도가 하드 요구.
- 실시간 전송: WebSocket. 목표 지연 3~5초(관대) → 정확도 우선 청킹 가능.
- 인증: API Key 헤더(내부용).
- 큐: Redis 영속 큐(RQ, no-fork) — 재시작 내성·다중 워커. Colab/개발은 in-process 폴백(Redis 불필요).
- 보관: 결과/메타만 7일 보관(설정화·자동삭제), 업로드 원본 오디오는 처리 후 즉시 삭제.
- 파일 상한: 모든 입력 비동기 Job 기본, 절대 상한 4시간 / 2GB(초과
413, 설정화). - 배포 이원화: CLI(셸 스크립트)=개발·테스트·Colab / Docker(FastAPI/Python)=프로덕션(내부).
- CPU 폴백은 항상 지원.
Non-Goals (명시적 비범위)
- 외부 공개(public) API·과금·멀티테넌시 SaaS 기능.
- 자체 STT 모델 학습/파인튜닝(기성 Whisper 계열 사용).
- 번역(translation) — 1차 범위 외.
- 프런트엔드 UI(API/CLI만 제공).
- 영구 원본 오디오 아카이빙(원본은 삭제가 기본).
Acceptance Criteria (검증 가능 기준)
- AC-1 동일 시스템으로 파일(오디오/영상)·실시간(WebSocket) 입력을 모두 전사한다.
- AC-2
device=auto가 GTX 1050에서 int8/CPU로, T4/L4/A100/H100에서 fp16로 자동 동작하고,cpu/cuda[:n]강제 플래그가 동작한다. - AC-3 정밀도·워커 수가 감지된 VRAM/compute capability로 자동 산정되며
--workers/--compute-type오버라이드가 가능하다. - AC-4 혼용어 검증: "그 API 서빙할 때 vLLM 쓰면 성능 대박이야" 입력 시 "API", "vLLM"이 영문 그대로(핫워드 적용 시) 전사된다. 배치 경로(large-v3)에서 정확도가 더 높음을 확인한다.
- AC-5 동시 다중 작업을 받아 Redis 큐에 적재/동시 처리하며, 작업 중에도 신규 입력을 계속 수신한다.
- AC-6 호출자가
queue_position(앞 N건)과progress(처리된 길이/전체, %)를 조회할 수 있다. - AC-7 장시간/대용량 파일이 VAD 세그먼트로 분할되어 진행률을 제공하고 메모리 사용이 일정하다. 4h/2GB 초과는
413. - AC-8 실시간 부분 결과가 3~5초 내 스트리밍되고 최종 결과로 안정화된다(turbo 경로).
- AC-9 영상 파일이 ffmpeg로 오디오 추출 후 전사되고, 출력 옵션(timestamps/word/diarize/formats)이 요청별로 동작한다.
- AC-10 후처리: glossary/rules가 동작하고, LLM 보정(백엔드
local/external설정화, 기본 off·신뢰도 게이팅)과 저신뢰 구간 플래그가 동작한다. - AC-11 API Key 인증이 적용되고, 전사 완료 후 원본 오디오가 삭제되며 결과만 7일 보관된다.
- AC-12 CLI(
serve/transcribe/bench/detect)와 Docker(GPU/CPU 이미지 + Redis)로 각각 실행된다. - AC-13 Colab에서
--tunnel cloudflare로 공개 URL이 자동 발급되어 외부에서 호출된다.
Architecture (상세 설계)
시스템 개요도
┌───────────────────────────────────────────────┐
내부 호출자 │ luke_scribe API │
(서비스/CLI) │ │
│ │ ┌──────────────┐ ┌────────────────────┐ │
REST ├──── 파일/영상 ─▶│ │ Ingestion API│────▶│ Job Queue (Redis) │ │
(HTTP)│ │ │ (FastAPI) │ │ - priority lanes │ │
│ │ │ - upload │ │ (realtime/batch) │ │
WS ├── 실시간 오디오▶│ │ - WS stream │ │ - queue_position │ │
│ │ │ - auth(API │ │ - progress │ │
│ │ │ Key) │ │ - durable/재시작내성 │ │
│ │ └──────┬───────┘ └─────────┬──────────┘ │
│ │ │ ffmpeg(영상→오디오) │ dispatch │
│ │ ▼ ▼ │
│ │ ┌──────────────┐ ┌────────────────────┐ │
│ │ │ Realtime │ │ Worker Pool │ │
│ │ │ Pipeline │ │ (N = 자동산정) │ │
│ │ │ VAD→chunk→ │◀───▶│ ┌───────────────┐ │ │
│ │ │ partial/final│ │ │ Engine │ │ │
│ │ │ (turbo) │ │ │ faster-whisper│ │ │
│ │ └──────┬───────┘ │ │ rt=turbo │ │ │
│ │ │ │ │ batch=large-v3│ │ │
│ │ ▼ │ └──────┬────────┘ │ │
│ │ ┌──────────────┐ │ │ │ │
│ │ │Post-processing│◀───┤ │ uses │ │
│ │ │glossary/rules │ └─────────┼───────────┘ │
│ │ │+LLM(opt,plug) │ │ │
│ │ │+conf flag │ ┌─────────▼──────────┐ │
│ │ └──────┬───────┘ │ Device Manager │ │
│ │ ▼ │ GPU/CPU 감지 → │ │
│◀── 결과/진행률 ─┤ ┌──────────────┐ │ fp16·int8·CPU / │ │
│ (txt/srt/ │ │Output/Results│ │ worker수·동시성 │ │
│ vtt/json) │ │store(7일,결과)│ └────────────────────┘ │
│ │ └──────────────┘ │
│ │ Connectivity/Tunnel (Colab→cloudflared 자동) │
│ └───────────────────────────────────────────────┘
1) Ingestion API (입력/수집)
REST (배치/파일):
| Method | Path | 설명 |
|---|---|---|
POST |
/v1/jobs |
multipart: file(오디오/영상) + options(JSON). → {job_id, status:"queued", queue_position} |
GET |
/v1/jobs/{id} |
상태 조회: queued(queue_position, jobs_ahead) / processing(progress %, processed_sec/total_sec, eta) / completed / failed(error) |
GET |
/v1/jobs/{id}/result?format=txt|srt|vtt|json |
결과 조회(포맷 변환) |
DELETE |
/v1/jobs/{id} |
작업 취소 |
GET |
/v1/jobs |
작업 목록/필터 |
WebSocket (실시간): WS /v1/stream
-
- init 프레임(첫 메시지=인증):
{type:"init", api_key, audio:{codec,sample_rate,channels}, options:{language:"ko", ...}}— 2초 내 유효 init 없으면 close. 브라우저는 WS 핸드셰이크에 헤더를 못 넣으므로 인증은 이 첫 메시지로.
- init 프레임(첫 메시지=인증):
-
- 클라이언트 → 오디오 청크(PCM16/opus 등) 연속 전송
-
- 서버 →
{type:"partial", text, t0,t1}(가설) /{type:"final", segment, start, end, words[]}(확정) /{type:"status", ...}
- 서버 →
Admin/관측: GET /health, GET /v1/system(device 프로파일·워커수·큐 깊이), GET /v1/models.
인증: REST = X-API-Key 헤더. WS = 첫 init 메시지의 api_key(헤더 못 쓰는 브라우저 대응; 키가 URL/로그에 안 남음). 키별 스코프/사용량 확장 여지.
요청 옵션 스키마(options):
{
"language": "ko", // 기본 ko(한국어 우선). "auto"|"en"|"ja"... 요청별 override
"model": null, // null=경로별 기본(rt=turbo, batch=large-v3). 오버라이드 가능
"device": "auto", // "auto" | "cpu" | "cuda" | "cuda:0"
"compute_type": null, // null=자동. "float16"|"int8"|"int8_float16"
"timestamps": true, // 세그먼트 타임스탬프
"word_timestamps": false, // 단어 단위
"diarize": false, // 화자 분리(pyannote, opt, HF 토큰)
"formats": ["json"], // ["txt","srt","vtt","json"]
"hotwords": [], // (선택) 반복되는 고정 도메인 용어만 1회 등록. 미예측 — 비우면 ko+모델+후처리로 대응
"glossary_id": null, // 저장된 도메인 사전 참조
"vad": true, // 무음 제거
"post_correction": { // 단계 제어
"mode": "rules", // "none"|"glossary"|"rules"|"llm"
"backend": "local", // llm 모드 시: "local"|"openai"|"external"
"corrector_model": null // 백엔드별 모델/엔드포인트
}
}
2) Transcription Engine (전사 엔진)
- 런타임: faster-whisper (CTranslate2) — openai-whisper 대비 ~4배 빠르고 메모리 적음, GPU/CPU·fp16/int8 지원, Silero VAD 내장, 배치 추론 지원.
- 모델 전략(확정): 하이브리드
- 실시간 경로 = large-v3-turbo (저지연; 디코더 4층 경량화).
- 배치 경로 = large-v3 (혼용어/다국어 정확도 우위).
- 두 모델 모두 설치, 경로별 기본값 적용.
model옵션/환경변수로 런타임 오버라이드.
- 혼용어 대응(핵심):
hotwords/initial_prompt에 도메인 용어 주입 → 기술용어 음차화 방지.- 저장 가능한 Glossary(도메인 사전) →
glossary_id로 재사용. - (옵션) 후처리 LLM 보정으로 잔여 오류 교정.
- 제외: distil-whisper, NVIDIA Parakeet/Canary(영어 중심 → 한국어 혼용 부적합).
✅ 결정 근거: 다국어/혼용어 정확도는 large-v3가 turbo보다 우위(turbo는 일부 언어 정확도 하락). 따라서 정확도 중요한 배치는 large-v3, 저지연 중요한 실시간은 turbo로 분리(하이브리드 확정). 추후 도메인 샘플 WER 벤치로 실시간 경로의 v3 승격 여부 재평가 가능.
3) Realtime Pipeline (실시간)
- WebSocket 오디오 프레임 → 링버퍼 → Silero VAD로 발화 구간 검출 → 청크 구성 → 전사 → 부분/최종 방출.
- 안정화 정책: LocalAgreement(연속 가설 일치분 확정) 또는 AlignAtt(2025 SOTA). 지연이 3~5초로 관대하므로 큰 청크 + LocalAgreement-2로 정확도 우선. 실시간 경로 기본 모델은 turbo.
- 참고 구현: WhisperLive(faster-whisper 백엔드, WS, VAD), WhisperLiveKit(AlignAtt), whisper_streaming(→ SimulStreaming 대체 추세). 정책 채택/재구현 모두 가능.
4) Output / Results (출력·보관)
- 텍스트 기본 + 요청 옵션별 타임스탬프/단어/화자/자막.
- 포맷 변환:
json(원천) →txt/srt/vtt/structured-json. - 보관(확정): 결과/메타만 7일 보관(설정화·만료 자동삭제), 원본 오디오는 전사 직후 삭제.
- 저장소: 기본 로컬 파일/SQLite, 확장 시 S3/DB 가능.
5) Job Queue / Concurrency (큐·동시성)
- Job 추상화: 파일·실시간·영상 모두 Job으로 통일. 작업 중에도 신규 Job 계속 수신.
- 우선순위 레인: 실시간 세션=저지연 우선 / 배치=처리량 레인.
- 워커풀: 워커 수 = Device Manager 자동 산정. 각 워커가 디바이스 바인딩된 모델 인스턴스 보유.
- 큐 백엔드(확정): Redis + RQ(no-fork) 영속 큐를 처음부터 사용 → 재시작 내성·다중 워커 프로세스 지원. Celery 기본 prefork는 CUDA와 충돌하므로 no-fork 워커 사용. (Colab/개발용 in-process 폴백.)
- 진행률: 장시간 파일은 VAD 세그먼트 분할 →
progress = 완료 세그먼트 / 전체(또는 처리 오디오초/전체초).queue_position= 큐 인덱스. - 백프레셔: 최대 큐 길이 초과 시
429.
6) Device Manager (능력 등급 자동판정 — 설계 중심축)
감지: GPU 유무·device name·compute capability·VRAM(총/여유), 시스템 RAM, 디스크 여유(모델 다운로드 공간).
능력 등급(Capability Tier) 자동판정: 부팅 시 실측으로 어떤 모델을 어디서 어떻게 제공할지 결정 — 무음 모델 강등이 아니라, 등급이 "제공 가능 모델"을 정함.
| 등급 | 하드웨어가 감당하는 것 | 동작 |
|---|---|---|
| T0 · CPU | GPU로 turbo도 무리(또는 GPU 없음) | turbo를 CPU로 실행 |
| T1 · turbo-GPU | turbo는 GPU OK, large-v3는 무리 | turbo만 GPU. large-v3 미제공(배치도 turbo) |
| T2 · 스왑 | large-v3는 되지만 turbo와 동시 상주는 무리 | 호출에 따라 모델 로드/언로드(한 번에 하나 상주, MRU 유지로 스왑 최소화) |
| T3 · 동시상주 | turbo + large-v3 동시 적재 가능 | 둘 다 상주 → 실시간(turbo)+배치(large-v3) 동시 처리 |
| 모델 여러 벌 병렬 적재 | 제외(복잡도 과다) |
- 정밀도: cc≥7.0 → fp16/int8_float16, Pascal(6.x, 예 1050) → int8, CPU → int8. (부팅 VRAM 실측으로 확정.)
- 모델 적재 가능성은 부팅 실측으로 판정(정적 상수 비의존): turbo 미적재→CPU(T0), large-v3 미적재→미제공(T1), 동시 미적재→스왑(T2), 동시 적재 가능→동시상주(T3).
- 디스크 가드: turbo ~1.6GB / large-v3 ~3GB 다운로드 전 여유 공간 점검, 부족 시 명확 오류.
- 투명성:
/v1/system·/v1/models로 현재 등급·제공 가능 모델, 결과엔model_used/compute_type_used항상 표시 → 몰래 강등 없음. - 오버라이드:
--device auto|cpu|cuda:N,--compute-type,--model,--workers. - **CLI
detect**로 등급·제공모델·권장설정 출력. 1050: 보통 T1(turbo-int8)/T0. T4~H100: T3 하이브리드 풀가동.
7) Post-processing (전사 오류 후처리)
순차 파이프라인(요청별 post_correction.mode로 단계 제어):
- Glossary/Hotwords (선택): 반복되는 고정 도메인 용어를 1회 등록해 디코드 바이어스. 매 전사 예측이 아님 — 안 쓰면 ko 앵커+모델+규칙으로 대응.
- Rule/Dictionary 정규화(deterministic): 알려진 오인식 → 표준 용어 치환, 정규식, 약어 대소문자 보정.
- LLM 보정(확정: 백엔드 설정화, 기본 off·confidence-gated): 저신뢰/고WER 구간만 교정(Judge-Editor: 고신뢰 스팬 유지, 불확실 스팬만 재작성). 백엔드 플러그형 —
local(소형 LLM, 오프라인·프라이버시) 또는openai/external(OpenAI 호환 엔드포인트),corrector_model설정 가능. 기본 비활성(약 HW 보호·과교정 방지). - Confidence 플래깅: 세그먼트별 신뢰도 부여, 저신뢰 구간 표시 → 선택적 휴먼 리뷰.
⚠️ 리서치 근거: LLM 후처리는 입력 WER이 높을 때(>10%) WER을 크게 낮추지만, 이미 정확한 전사에는 paraphrastic drift(과교정) 위험 → 신뢰도 게이팅 필수. 도메인 고유명사/기술용어 손상이 핵심 위험(R-WER/EWER로 측정). 🔒 프라이버시:
external/openai백엔드는 전사 텍스트를 외부로 전송하므로 내부 전용 정책과 상충 가능 → 기본은local, 외부 백엔드는 명시적 opt-in.
8) Connectivity / Tunnel (Colab 자동 외부 노출)
- 환경 자동 감지(Colab/Kaggle/dev) → 옵션 시 터널 기동.
- 기본: cloudflared Quick Tunnel —
https://<random>.trycloudflare.com, 계정/도메인 불필요, 임시 URL, 제로 설정. (--tunnel cloudflare) - 대안: ngrok — authtoken 필요, 무료는 재시작 시 URL 변경, 요청 인스펙션 제공. (
--tunnel ngrok --ngrok-token ...) - 안정 도메인: named Cloudflare Tunnel(CF 계정+도메인 필요).
- 프로덕션/실IP:
--tunnel none, host IP 바인딩. - 기동 시 공개 URL + API Key 출력.
배포 (Deployment) — 코드는 하나, 실행 프로파일 둘
| Colab / 개발 | 프로덕션(내부) | |
|---|---|---|
| 실행 | 순수 Python / run.sh로 python 직접 (Docker ❌) |
Docker + docker-compose |
| 큐 | in-proc(Redis 불필요) | Redis + 별도 worker |
| 저장 | 로컬 디스크 1개(공유 이슈 없음) | 공유 볼륨/오브젝트 스토어(api↔worker) |
| 가중치 | 받아서 캐시(예: Drive) | 받아서 캐시(미존재 시 다운로드) |
| 외부노출 | cloudflared 바이너리 실행 | 실제 IP |
- CLI (
run.sh+cli.py):serve(API+옵션 터널) /transcribe <file>/bench(모델·등급 벤치) /detect(등급·프로파일). Colab은 Docker 불가 → 반드시 이 경로. - Docker(프로덕션): GPU 이미지(
nvidia/cuda) + CPU(slim). compose: API + Redis + worker(+옵션 LLM). 입력 원본·파생 wav·결과는 공유 스토어(컨테이너 경계에서 안 깨지게). - 모델 프로비저닝(공통): 시작 시 존재 확인 → 없으면 다운로드 → 손상(로드 실패/체크섬) 시 재다운로드 → 준비 전엔
status:"loading". - 설정: env+
.env/yaml — model(rt/batch), device, workers, api_keys+scopes, retention_days, tunnel, redis_url(프로덕션), corrector+allowlist.
기술 스택 (제안)
Python 3.11+, FastAPI + uvicorn, faster-whisper(CTranslate2) (turbo + large-v3), ffmpeg(영상→16kHz mono), Silero VAD(faster-whisper 내장), Redis + RQ(no-fork)(영속 큐), pydantic v2, LLM 보정 백엔드(local: llama.cpp/transformers · external: OpenAI 호환 client), (옵션) pyannote.audio(diarization, HF 토큰), cloudflared/pyngrok(터널), loguru/structlog(로깅), prometheus-client(메트릭, 옵션).
Assumptions Exposed & Resolved (가정 노출·해소)
| Assumption | Challenge | Resolution |
|---|---|---|
| "한 번에 한 작업이면 충분" | 동시/대기 다작업·중간 추가 입력은? | 큐를 1급 승격, Redis 영속, 우선순위 레인 + queue_position/progress |
| "엔진은 정하면 끝" | 혼용어 vs 속도 충돌 | 하이브리드(실시간 turbo / 배치 large-v3) + 핫워드/후처리 |
| "동시성 수치를 정해야 함" | 1050~H100 폭이 너무 큼 | Device Manager가 VRAM/CC로 정밀도·워커수 자동 산정 |
| "출력 형식을 시스템이 고정" | 호출마다 다를 수 있음 | 요청 options로 출력 옵션 전달(요청별) |
| "실시간은 최저 지연 필수" | 3~5초도 허용 | 큰 청크 + 안정화 정책으로 정확도 우선 |
| "Colab도 IP로 호출" | Colab은 공인 IP 없음 | cloudflared Quick Tunnel 자동 노출 |
| "전사 결과만 보면 됨" | 오인식/오타 교정은? | 후처리 파이프라인(glossary→rules→LLM(opt, 백엔드 설정화)→flag) |
| "후처리는 로컬만" | 외부 LLM 허용? | local/external 백엔드 설정화, external은 프라이버시 opt-in |
Ontology (Key Entities)
| Entity | Type | Fields | Relationships |
|---|---|---|---|
| Job | core | id, type(file/stream/video), status, queue_position, progress, options, created_at | has many Segment, produces TranscriptResult |
| AudioInput | core | source(stream/file/video), codec, duration, size | belongs to Job |
| Engine | core | runtime(faster-whisper), model(turbo/large-v3), compute_type | used by Worker |
| Device | core | kind(gpu/cpu), name, vram_total/free, compute_capability | profiled by DeviceManager |
| DeviceProfile | supporting | precision, max_workers, fallback | derived from Device |
| Worker | core | id, device, model_instance, busy | consumes Queue(Redis), runs Engine |
| Queue | core | lane(realtime/batch), depth, backend(redis) | holds Job |
| Segment | supporting | index, start, end, text, words[], confidence | belongs to Job |
| TranscriptResult | core | text, segments[], formats, language | belongs to Job |
| RequestOptions | supporting | language, model, device, formats, hotwords, post_correction | configures Job |
| Glossary | supporting | id, terms[] | applied to Engine/Post-processing |
| PostProcessor | supporting | mode, backend(local/external), corrector_model, stages | transforms TranscriptResult |
| Session(realtime) | core | ws_conn, buffer, options | produces partial/final Segment |
| ApiKey | supporting | key, scopes, usage | authorizes Job |
| RetentionPolicy | supporting | result_ttl=7d, delete_source=true | governs Output |
| Tunnel | supporting | provider(cloudflare/ngrok/none), public_url | exposes API |
Ontology Convergence
| Round | Entity Count | New | Changed | Stable | Stability Ratio |
|---|---|---|---|---|---|
| 1 | 10 | 10 | - | - | N/A |
| 2 | 13 | 3 | 0 | 10 | ~77% |
| 3 | 14 | 1 | 0 | 13 | ~92% |
| 추가반영 | 16 | 2 (PostProcessor, Tunnel) | 0 | 14 | ~88% |
| 결정확정 | 16 | 0 | 1 (Queue→Redis) | 16 | ~100% (수렴) |
확정된 결정 (Resolved Decisions)
| # | 결정 | 확정 내용 |
|---|---|---|
| 1 | 모델 전략 | 하이브리드 — 실시간=turbo(저지연), 배치=large-v3(혼용어 정확도). 모델 설정 오버라이드 가능. |
| 2 | 큐 영속성 | Redis 영속 큐(RQ, no-fork) 처음부터 — 재시작 내성·다중 워커. Colab/개발 in-process 폴백. |
| 3 | LLM 후처리 | 포함, 백엔드 설정화(local 소형 LLM / OpenAI 호환 external), 기본 off·confidence-gated. external은 프라이버시 opt-in. |
| 4 | 결과 보관 | 7일(설정화·자동삭제). 원본 오디오는 전사 직후 삭제. |
| 5 | 파일 상한 | 모든 입력 비동기 Job 기본, 절대 상한 4시간 / 2GB(초과 413, 설정화). |
| 6 | 화자 분리 | 옵션 포함(pyannote, HF 토큰), 기본 off, 요청 시 diarize=true. |
CCG 외부 리뷰 반영 (v2.2)
외부 advisor(Codex/Gemini) 리뷰 + 사용자 확정으로 갱신:
- 모델 프로비저닝: 인터넷 다운로드 OK(에어갭 아님). 미존재→다운로드, 손상→재다운로드, 로딩 중
status:"loading". (구 "오프라인 동작" 문구 폐기.) - 능력 등급 자동판정(§6): GPU VRAM·RAM·디스크로 T0(CPU)~T3(turbo+large-v3 동시상주) 자동 결정, T4(다중복제) 제외. 결과에
model_used항상 표시(무음 강등 없음). - 기본 언어
ko+ 요청별 override. hotwords는 선택(매 전사 예측 아님). - WS 인증 = 첫
init메시지(api_key+오디오포맷+옵션). - 배포 2프로파일: Colab/개발=순수 Python·in-proc·바이너리 cloudflared / 프로덕션=Docker+Redis+공유 스토어.
- (미채택·추후 검토: webhook 콜백, Idempotency-Key, 목록 페이지네이션, 만료 결과
410.)
구현 로드맵 (제안 Phase)
| Phase | 범위 | 산출 |
|---|---|---|
| P1 Core | faster-whisper 통합(turbo+large-v3), Device Manager 자동감지, CLI transcribe/detect, 파일 동기 전사, ffmpeg 영상 추출 |
단발 전사 동작(1050/CPU 포함) |
| P2 API+Queue | FastAPI, Redis 영속 큐·워커풀, 상태/진행률 API, API Key, 결과 보관(7일)·원본 삭제, Docker(GPU/CPU/Redis) | 비동기 배치 API |
| P3 Realtime | WebSocket 스트리밍, VAD 청크, LocalAgreement 부분/최종(turbo) | 실시간 전사 |
| P4 Output+Post | timestamps/word/SRT/VTT, glossary/rules 후처리, confidence flags | 풍부한 출력 + 1차 후처리 |
| P5 Advanced | LLM 후처리 백엔드(local/external, 옵션), diarization(pyannote, 옵션), Colab cloudflared 자동, 메트릭/모니터링, bench |
운영·고급 기능 |
리스크
- 약 GPU(1050) 실시간 한계: turbo도 Pascal/2GB에선 버거움 → int8/CPU 폴백, 실시간은 사실상 T4+ 권장(문서화).
- turbo 혼용어 정확도: 핫워드/후처리로 보완하되 도메인 벤치로 검증, 필요 시 실시간도 v3 승격.
- LLM 후처리 과교정: 신뢰도 게이팅 필수.
- 외부 LLM 후처리 프라이버시:
external/openai백엔드 사용 시 전사 텍스트 외부 전송 → 내부 전용 정책 검토 필요(기본 local). - Redis 의존성: 영속 큐가 Redis에 의존 → 단일 장애점. HA/단발용 in-process 폴백으로 완화.
- GPU 메모리 동시성: 워커당 VRAM 추정 오차 → 보수적 산정 + OOM 재시도/강등.
- Quick Tunnel 임시 URL: trycloudflare는 비영구 → 안정 필요 시 named tunnel/ngrok.
Interview Transcript (요약)
Q&A (3 라운드 + 추가 아이디어 + 결정 확정)
Round 0 — Topology: 4개 컴포넌트 + 큐/동시성·중간 추가입력·대기열 위치·진행률·대용량 처리 요구 → 큐 1급 승격.
Round 1 (100%→~40%)
- 엔진: 혼용어 대응 + 속도 중요, 후보 large-v3, 추천 요청.
- 언어: 한국어+자동감지, 혼용어("vLLM 쓰면 성능 대박") 정확 전사 필수.
- 실시간 전송: WebSocket.
Round 2 (~40%→~26%)
- 엔진: turbo 단일(속도) → 이후 하이브리드로 확정.
- 하드웨어: GTX 1050·Colab·T4/L4/A100/H100 → 자동 감지·자동 용량 산정.
- 동시성: 하드웨어 기반 자동 조절.
- 출력: 요청별 옵션.
Round 3 (~26%→~14%, PASSED)
- 배포: CLI + Docker/FastAPI. 인증: API Key. 보관: 결과만·원본 삭제. 실시간 지연: 3~5초 관대.
추가 아이디어 (반영)
- 전사 오류 후처리 → Post-processing(glossary→rules→LLM(opt)→flag).
- Colab 등 공인 IP 부재 환경 자동 외부 노출 → cloudflared Quick Tunnel 기본.
열린 결정 확정 (~14%→~10%)
- 모델=하이브리드, 큐=Redis 영속, LLM 후처리=백엔드 설정화(local/external), 보관 7일, 상한 4h/2GB, 화자분리 옵션(off).
Generated by deep-interview · threshold 20% (default) · ambiguity ~10% (열린 결정 6건 확정) · PASSED