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

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

2026.07.12 갱신 신고 통화 전사 파이프라인을 운영 수준으로 끌어올리려는 실무자·연구자
#음성전사#화자분리#품질관리#WhisperX
검토 상태: 전문 검토 전 위험도 미분류

이 안내서는 공식 절차·법령·현장 판단을 대체하지 않으며, 적용 전 소속 기관 기준과 담당자 검토를 확인하세요.

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

🎯 이 장의 목표
  • 합성·익명화 음성을 사용해 화자 라벨이 붙은 전사 품질을 검증할 수 있습니다.
  • 용어 교정 전후를 동일한 골든 전사와 비교할 수 있습니다.
  • 전체 평균과 잡음·겹침말 조건별 오류를 나눠 읽을 수 있습니다.
  • 신뢰도가 낮은 통화를 자동 분류에서 빼고 사람 재청취로 연결할 수 있습니다.

심화 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()}')

예를 들어 결합된 스크립트는 이런 모양이 됩니다(가상·합성 예시).

TEXT
[SPEAKER_00] 네 119입니다 어디십니까
[SPEAKER_01] 여기 상가 2층인데 탄내가 심하게 나요

이제 분류 프롬프트에 신고자 발화만 골라 넣는 후보를 만들 수 있습니다. 다만 SPEAKER_00/01은 접수자·신고자 역할이 아니라 화자 묶음 번호입니다. 첫 발화의 "119입니다…" 같은 표현은 초기 추정 단서일 뿐이고, 신고자가 먼저 말하거나 두 사람의 말이 겹치면 역할을 뒤집을 수 있습니다. 자동 분류에 넘기기 전 합성 조건별 표본을 사람이 확인하고, 역할이 모호하면 통화 전체를 재청취 대상으로 남겨야 합니다.

2. 용어 교정 — 두 겹

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

  • 전사 전 — 용어 힌트: 전사 시작 프롬프트에 도메인 용어를 심어 모델이 그 표기를 선호하게 합니다(initial_prompt 계열 옵션 — 전편의 faster-whisper transcribe에도 있습니다).
  • 전사 후 — 교정표: 자주 틀리는 표기를 팀이 관리하는 교정표로 치환합니다. 교정표 자체가 자산입니다.
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단(품질 측정)에서 오류를 발견할 때마다 자랍니다. "측정 → 교정표 추가 → 오류율 하락"이 이 파이프라인의 개선 루프입니다.
⚠️ 흔한 실수
교정표는 자산이자 위험입니다. re.sub 치환은 문맥을 가리지 않아, 좁게 겨눈 규칙도 뜻하지 않은 자리에서 발화됩니다 — 이름·지명에 우연히 같은 글자열이 끼면 멀쩡한 표현을 바꿔 버립니다. 그래서 교정표를 한 줄 늘릴 때마다 3단의 골든셋 CER로 "교정 후가 정말 더 나아졌는지"를 확인합니다. 측정 없이 규칙만 쌓으면 오류를 없애는 대신 다른 곳으로 옮길 뿐입니다.

3. 품질 측정 — 골든셋 CER

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

💡 팁
CER의 원리는 채점과 같습니다. 정답지(골든 전사)와 답안(파이프라인 전사)을 나란히 두고 몇 글자를 고쳐야 정답이 되는지 세어, 정답 글자 수로 나눕니다 — 작을수록 정확합니다. 글자 단위로 세는 까닭은 한국어의 들쭉날쭉한 띄어쓰기 때문입니다. 단어 단위(WER)로 재면 요구조자 발견요구조자발견처럼 글자는 똑같고 띄어쓰기만 다른 답도 통째로 틀린 것으로 셈하지만, 글자 단위는 실제로 잘못 받아쓴 글자에만 집중합니다. 예컨대 골든이 요구조자인데 요구소자로 나왔다면 네 글자 중 하나가 어긋나 CER는 0.25입니다.
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 리포트취약 조건이 개선 추세
상시화자 결합 스크립트 점검접수자/신고자 뒤바뀜 사례 기록
▸ 소방 활용 포인트
동시다발 신고 상황에서 "믿어도 되는 전사"와 "사람이 다시 들어야 하는 통화"를 기계가 먼저 갈라 주면, 접수 요원의 재청취 시간이 위험한 통화에 집중됩니다. 화자 결합 스크립트는 사후 검토·교육 자료 정리에도 그대로 쓰입니다 — 단 출동 지령 판단은 언제나 원음성과 사람이 우선입니다.

설계 판단

전사 품질 설계의 핵심은 자동화를 넓히는 것이 아니라 어디서 자동 처리를 멈출지 정하는 것입니다. 신뢰 신호가 부족하면 더 진행하지 않고 원음성과 사람 재청취로 돌아갑니다.

방식맞는 상황트레이드오프사람이 확인할 것
전사 텍스트만 생성검색·교육용 초안처럼 화자 구분이 불필요한 때구조가 단순하지만 누가 말했는지 알 수 없음민감한 원음성의 사용 범위
화자 결합 + 용어 교정대화 흐름을 검토하되 화자 뒤바꾸기를 표본 점검할 수 있을 때정렬·분리·교정의 오류가 연쇄될 수 있음화자 라벨과 교정 전 원문
신뢰도 라우팅 + 재청취자동 분류에 보내기 전 불확실한 통화를 걸러야 할 때사람 큐의 용량과 대기 시간을 관리해야 함재청취 대상과 최종 판단

운영 시나리오

아래는 실제 신고 내용을 사용하지 않은 합성 통화 기반의 가상 연습입니다. 전사 문장이 그럴듯해도 화자·용어·신뢰 신호 중 하나가 깨지면 다음 단계를 멈춥니다.

본문의 CER 코드는 골든셋을 한 번 집계하는 오프라인 예제이고, route()"재청취""자동분류" 문자열만 돌려줍니다. 이 두 예제는 큐에 실제로 넣거나 대기 건수·처리 시간·조건별 추세를 저장하지 않습니다. 아래와 같은 운영 탐지를 하려면 합성 조건 태그, 라우팅 결과, 큐 등록·처리 시각을 별도로 기록하고 사람 검토 결과와 연결해야 합니다.

가상 시나리오 1: 첫 발화 규칙이 접수자와 신고자를 뒤집은 경우

  • 탐지: 신고자가 먼저 말하거나 첫 두 발화가 겹친 합성 통화를 사람이 표본 확인했더니, 첫 발화 표현으로 붙인 역할이 뒤집혀 있었습니다. 위의 코드는 이 역할 오류를 자동 탐지하지 않습니다.
  • 원인 가설: SPEAKER_00/01을 역할로 오해하고 '접수자가 항상 먼저 말한다'는 규칙을 고정했지만, 실제 발화 순서·겹침말은 그 가정을 깨뜨렸다고 봅니다.
  • 대응: 역할이 모호한 통화는 신고자 발화만 자동 추출하지 않고 재청취로 보냅니다. 첫 발화 외의 질문·응답 흐름을 추가 단서로 쓰되, 사용 전 합성 조건별 표본을 사람이 확인합니다.
  • 재발 확인: 접수자 선행·신고자 선행·겹침 시작 합성 픽스처에서 역할 추정과 모호 판정을 사람이 대조하고, 모호한 통화가 자동 분류로 넘지 않는지 확인합니다.

가상 시나리오 2: 잡음 구간의 재청취 큐가 쌓인 경우

  • 탐지: 별도로 추가한 운영 로그에서 신뢰도 낮은 통화의 큐 등록·대기 건수가 함께 늘었고, 오프라인 골든셋에 조건 태그를 더해 비교하니 잡음·겹침말 표본이 악화됐습니다. 이 계측은 본문 최소 예제에 포함돼 있지 않습니다.
  • 원인 가설: 모델 전체의 퇴화보다 특정 음향 조건이 약점을 드러냈고, 사람 큐의 처리 여력도 같이 부족해졌다고 봅니다.
  • 대응: 자동 분류로 보내기 위해 신뢰 기준을 임의로 낮추지 않습니다. 해당 조건의 재청취를 우선하고, 합성 잡음 표본으로 골든셋과 전처리 후보를 보강합니다.
  • 재발 확인: 같은 합성 잡음 픽스처에서 조건별 CER과 재청취 분기가 기준에 맞는지 비교하고, 정상 통화가 과도하게 큐로 빠지지 않는지도 확인합니다.

한계와 리스크

리스크발생 조건영향완화·사람 승인
화자 역할 뒤바꾸기화자 묶음 번호를 역할로 쓰거나 첫 발화 순서만으로 접수자를 고정함신고자·접수자 발화가 틀린 역할에 속함선행 화자·겹침말 합성 픽스처로 역할을 점검하고 사용 전 사람이 표본 승인
용어 과잉 교정교정표가 문맥을 보지 않고 일반 단어까지 바꿈원문의 의미가 달라지고 사후 검토가 흐려짐교정 전·후를 함께 보존하고 골든 전사 비교 후 담당자가 규칙 승인
신뢰도 오용사람 큐를 줄이기 위해 임계를 낮춤자신 없는 전사가 자동 분류로 새어 나감조건별 CER·큐 용량을 함께 보고 출동 판단은 원음성과 사람에게만 두기

자주 묻는 질문

Q. CER가 낮으면 화자 라벨도 맞나요?

아닙니다. CER는 글자 오류를 재며 누가 말했는지는 별도 문제입니다. 화자 뒤바꾸기 테스트와 대화 순서 표본 검토를 따로 둡니다.

Q. 오전사는 모두 교정표로 바꾸면 되나요?

고정 치환은 문맥이 달라지면 정상 단어를 틀리게 바꿀 수 있습니다. 교정 전·후 텍스트를 남기고, 골든 전사에서 오류가 줄어드는 규칙만 사람이 승인합니다.

Q. 신뢰도 낮은 구간만 제거하면 분류에 쓸 수 있나요?

긴급한 내용이 바로 그 구간에 있을 수 있으므로 임의 삭제하지 않습니다. 통화 전체를 재청취 큐로 보내고 최종 판단은 사람이 원음성으로 합니다.

Q. 실제 통화로 골든셋을 만들어도 되나요?

이 안내서의 연습·검증은 합성·익명화 음성으로만 합니다. 실제 통화의 재청취·보관·활용은 소속 기관의 권한·보안·보존 절차 없이 임의로 확대하지 않습니다.

핵심 정리

  • 글자 오류, 화자 오류, 신뢰도 라우팅은 각각 다른 검증 문제입니다.
  • 잡음·겹침말 조건별 오류와 사람 큐 추세를 보려면 본문 최소 예제 밖에 조건 태그·라우팅·큐 계측을 추가해야 합니다.
  • 신뢰도가 낮으면 내용을 버리지 말고 통화 전체를 재청취로 보냅니다.
  • 자동 전사·교정·라우팅은 출동 판단을 대체하지 않으며 원음성과 사람이 우선입니다.

다음 단계

사람 검토 체크리스트

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