feat(web): speaker diarization via pyannote (parity with whisper_stt)

- Add app/diarize.py: local snapshot, A/B labels, disclaimer text
- transcribe_file and async jobs support diarize flag; Form diarize on API
- UI checkbox (default on); requirements: pyannote.audio, huggingface_hub
- README: env vars and model notes

Made-with: Cursor
This commit is contained in:
dosangyoon
2026-03-23 15:23:49 +09:00
parent 2caa74ac05
commit 26ff9b59c2
6 changed files with 280 additions and 3 deletions

View File

@@ -305,6 +305,11 @@
VAD 필터 (무음 구간 감소)
</label>
<label>
<input id="diarize" type="checkbox" checked />
화자 분리 (pyannote, whisper_stt.py와 동일 방식 — 서버에 로컬 모델·HF 토큰 필요)
</label>
<div class="row" style="margin-top: 12px">
<button class="btn primary" id="go" disabled>전사(STT) 실행</button>
<button class="btn" id="cancel" disabled>취소</button>
@@ -314,7 +319,8 @@
<div class="hint">
- 허용: mp3, m4a, wav, mp4, aac, ogg, flac, webm<br />
- 첫 실행 시 Whisper 모델 다운로드로 시간이 걸릴 수 있습니다.
- 첫 실행 시 Whisper 모델 다운로드로 시간이 걸릴 수 있습니다.<br />
- 화자 분리 켜짐: <span class="mono">./models/pyannote-diarization-3.1</span> 및 gated HF 모델 동의(README 참고).
</div>
<div class="progress">
@@ -420,6 +426,7 @@
const progTextEl = $("progText");
const downloadEl = $("download");
const clearEl = $("clear");
const diarizeEl = $("diarize");
const healthEl = $("health");
const metaEl = $("meta");
const timingEl = $("timing");
@@ -677,6 +684,7 @@
const author = (authorEl?.value || "").trim();
if (author) fd.append("author_id", author);
fd.append("vad_filter", $("vad").checked ? "true" : "false");
fd.append("diarize", !diarizeEl || diarizeEl.checked ? "true" : "false");
fd.append("beam_size", $("beam").value);
uploadController = new AbortController();