본문 바로가기
/ 학습 / 안내서 / 상황대응
L3 심화 · 7분 읽기

신고 전사 심화, 화자 결합과 품질 관리

상황대응팀 2026.07.03 갱신 신고 통화 전사 파이프라인을 운영 수준으로 끌어올리려는 실무자·연구자
#음성전사#화자분리#품질관리#WhisperX

전편의 파이프라인은 통화 한 건을 전사해 분류 후보까지 만들었습니다. 운영은 다른 질문을 던집니다 — "이 전사, 얼마나 틀리는가?" 오류율을 모르는 전사 위에 세운 분류는 모래 위의 집입니다. 그리고 전사와 화자 분리를 따로 돌리면 "무슨 말이 있었는지"는 알아도 "누가 한 말인지" 는 모릅니다. 신고자의 "불이 났어요"와 접수자의 "불이 난 게 맞습니까?"가 같은 무게로 분류에 들어갑니다.

이 안내서를 끝내면 화자 라벨이 붙은 전사 스크립트를 만들고, 소방 용어 오전사를 교정하고, 골든셋으로 오류율(CER)을 측정하고, 신뢰도 낮은 통화를 자동으로 사람 재청취로 보낼 수 있습니다. 전 과정 로컬 원칙은 전편 그대로입니다.

심화 4단

단계무엇을전편과의 차이
1 화자 결합발화마다 화자 라벨전사·화자분리를 결합해 한 스크립트로
2 용어 교정소방 용어 오전사 수정전사 전 힌트 + 전사 후 교정표, 두 겹
3 품질 측정골든셋 CER"감"이 아니라 오류율 숫자로
4 신뢰도 라우팅낮은 신뢰 통화 분리전부 자동이 아니라 재청취 큐로

1. 화자 결합 — "누가 말했나"가 붙은 스크립트

전편에서 따로 돌리던 faster-whisper(전사)와 pyannote(화자)를 WhisperX가 한 흐름으로 묶습니다. 정렬(alignment)로 단어 단위 타임스탬프를 정밀하게 만든 뒤, 그 위에 화자 구간을 겹쳐 발화마다 화자를 배정합니다. 추론은 전부 로컬입니다.

PYTHON
import whisperx

device = "cpu"                                   # 전편과 같은 로컬 원칙
audio = whisperx.load_audio("call_001.wav")

# 1) 전사 (내부는 faster-whisper)
model = whisperx.load_model("large-v3", device=device, compute_type="int8", language="ko")
result = model.transcribe(audio, batch_size=4)

# 2) 정렬 — 단어 단위 타임스탬프
model_a, meta = whisperx.load_align_model(language_code="ko", device=device)
result = whisperx.align(result["segments"], model_a, meta, audio, device=device)

# 3) 화자 분리 결합 — 신고 통화는 보통 2인(접수자·신고자)
diarize = whisperx.diarize.DiarizationPipeline(token="hf_...", device=device)
segments = diarize(audio, min_speakers=2, max_speakers=2)
result = whisperx.assign_word_speakers(segments, result)

for s in result["segments"]:
    print(f'[{s.get("speaker", "?")}] {s["text"].strip()}')

이제 분류 프롬프트에 신고자 발화만 골라 넣을 수 있습니다 — 접수자의 확인 질문이 유형 판단을 오염시키지 않습니다. 화자 라벨(SPEAKER_00/01) 중 누가 접수자인지는 첫 발화("119입니다…")로 규칙 판별하면 충분합니다.

2. 용어 교정 — 두 겹

일반 음성 모델은 소방 용어에 약합니다. "선착대"가 "선착 대기"로, "요구조자"가 "요 구조자"로 갈라지는 식입니다. 두 겹으로 잡습니다.

PYTHON
import re

# 팀이 관리하는 교정표 — 재청취에서 발견될 때마다 한 줄씩 자란다
FIX = {
    r"선착\s*대기": "선착대",
    r"요\s*구조자": "요구조자",
    r"공기\s*호흡기": "공기호흡기",
}

def fix_terms(text: str) -> str:
    for pat, to in FIX.items():
        text = re.sub(pat, to, text)
    return text
💡 팁
교정표는 3단(품질 측정)에서 오류를 발견할 때마다 자랍니다. "측정 → 교정표 추가 → 오류율 하락"이 이 파이프라인의 개선 루프입니다.

3. 품질 측정 — 골든셋 CER

전사 품질은 감상이 아니라 숫자로 관리합니다. 합성·익명 통화 20건을 골라 사람이 정확히 받아쓴 골든 전사를 만들고, 파이프라인 출력과 비교해 오류율을 잽니다. 띄어쓰기가 유동적인 한국어는 단어 오류율(WER)보다 글자 오류율(CER) 이 정직합니다.

PYTHON
import pandas as pd
from jiwer import cer   # pip install jiwer

pairs = load_goldenset()   # [{"ref": 사람 전사, "hyp": 파이프라인 전사, "잡음": "높음"}, ...]
for p in pairs:
    p["cer"] = cer(p["ref"], fix_terms(p["hyp"]))

# 전체 평균보다 '조건별' 평균이 운영 정보다
report = pd.DataFrame(pairs).groupby("잡음")["cer"].mean()
보는 법의미
전체 CER 추세모델·설정을 바꿀 때마다 회귀 비교(오르면 되돌린다)
잡음·통화품질별 CER어떤 통화에서 취약한가 — 사이렌·바람·차량 소음 구간
교정표 적용 전후 CER교정표가 실제로 효과 있는지 검증
📌 핵심
골든셋 20건이면 시작으로 충분하지만, 반드시 익명화·합성 통화만 씁니다. 골든 전사를 만드는 재청취 자체가 민감 데이터 접촉이므로 실통화로는 하지 않습니다 — 전편의 원칙이 여기서도 그대로입니다.

4. 신뢰도 라우팅 — 전부 자동이 아니라, 자신 없는 것만 사람에게

전사 모델은 자신 없음을 숫자로 남깁니다. 전편의 faster-whisper 세그먼트에는 평균 로그확률(avg_logprob)과 무음성 확률(no_speech_prob)이 붙어 있습니다. 이 값이 나쁜 통화를 분류로 보내지 말고 사람 재청취 큐로 보냅니다.

PYTHON
def route(segments) -> str:
    """전사 신뢰도 기반 분기 — 임계값은 자기 골든셋 CER과 맞춰 조정한다."""
    bad = [s for s in segments if s.avg_logprob < -1.0 or s.no_speech_prob > 0.6]
    if len(bad) / max(len(segments), 1) > 0.3:
        return "재청취"        # 사람이 듣고 직접 처리
    return "자동분류"          # 비식별 후 전편의 분류 단계로

낮은 신뢰 구간이 많은 통화는 대개 잡음·겹침말·아주 짧은 발화입니다 — 바로 CER가 가장 나쁘게 나오는 조건들이고, 자동 분류가 가장 위험한 통화들입니다. 라우팅은 그 위험을 사람 쪽으로 되돌리는 장치입니다.

운영 루틴 한 장

언제무엇을통과 기준
모델·설정 변경 시골든셋 CER 회귀이전 대비 오르지 않음
매주재청취 큐 처리·원인 태깅큐 비움 + 교정표/골든셋 보강
매월조건별 CER 리포트취약 조건이 개선 추세
상시화자 결합 스크립트 점검접수자/신고자 뒤바뀜 사례 기록
▸ 소방 활용 포인트
동시다발 신고 상황에서 "믿어도 되는 전사"와 "사람이 다시 들어야 하는 통화"를 기계가 먼저 갈라 주면, 접수 요원의 재청취 시간이 위험한 통화에 집중됩니다. 화자 결합 스크립트는 사후 검토·교육 자료 정리에도 그대로 쓰입니다 — 단 출동 지령 판단은 언제나 원음성과 사람이 우선입니다.

사람 검토 체크리스트

TEXT
- [ ] 전사·정렬·화자분리 전 과정이 로컬에서 돌았습니다(외부 전송 없음).
- [ ] 골든셋은 익명화·합성 통화로만 만들었습니다.
- [ ] CER를 조건별(잡음·통화품질)로 나눠 보고 취약 조건을 파악했습니다.
- [ ] 모델·설정 변경 시 골든셋 CER 회귀를 돌려 이전과 비교했습니다.
- [ ] 신뢰도 낮은 통화가 자동분류로 새지 않고 재청취 큐로 갑니다.
- [ ] 화자 라벨(접수자/신고자) 뒤바뀜을 사람이 표본 점검합니다.
⚠️ 흔한 실수
화자 분리는 겹침말(두 사람이 동시에 말함)에서 가장 약하고, 하필 긴박한 신고일수록 겹침말이 많습니다 — 화자 결합 스크립트를 근거로 책임 소재를 가리는 용도로 쓰지 마세요. 전사·분류·라우팅 어디에도 출동 판단을 위임하지 않으며, "재청취" 큐는 지연 없이 사람에게 도달해야 합니다.