/ 학습 / 안내서 / 상황대응
L2 중급 · 4분 읽기

119 신고 통화, 전사부터 유형 분류까지 안전하게

상황대응팀 2026.06.29 갱신 신고 통화·관제 데이터를 다루는 실무자·연구자
#음성전사#Whisper#분류#비식별

동시다발 신고 상황에서 통화 내용을 빠르게 유형·긴급도로 가르면 접수 부담이 줄어듭니다. 하지만 신고 음성과 그 전사 텍스트는 119 데이터 중 가장 민감합니다 — 신고자 목소리·이름·전화·위치·환자 상태가 그대로 담깁니다. 이 안내서는 음성을 전 과정 로컬에서 전사·비식별·분류하는 파이프라인이며, 분류 결과는 자동 확정이 아니라 사람 배정용 후보입니다.

이 안내서를 끝내면 음성을 로컬에서 전사하고, 화자를 나누고, 전사에서 개인정보를 뺀 뒤, 유형·긴급도 분류를 검산해 사람 배정용 후보로 만들 수 있습니다.

왜 전 과정을 로컬에서 하나

신고 음성을 외부 전사 API나 클라우드에 올리는 순간, 가장 민감한 데이터의 통제권을 잃습니다. 그래서 전사는 외부 전송 없이 로컬에서 돌리고, 외부 LLM을 쓰는 분류 단계조차 비식별을 거친 텍스트만 넣습니다.

파이프라인 4단

단계무엇을도구데이터 위치
1 전사음성 → 텍스트faster-whisper로컬
2 화자 분리(선택)신고자/접수자 구분pyannote로컬
3 비식별전사에서 개인정보 제거PII 가드로컬
4 분류유형·긴급도 후보프롬프트 + 검산비식별 후에만 외부 가능

1. 로컬 전사 — faster-whisper

한국어 음성을 로컬 CPU에서 전사합니다. 외부로 나가는 요청이 없습니다.

PYTHON
from faster_whisper import WhisperModel

# CPU + INT8 양자화 (메모리 적게, 외부 전송 없음)
model = WhisperModel("large-v3", device="cpu", compute_type="int8")

# language="ko"로 한국어 고정, 타임스탬프 포함
segments, info = model.transcribe("call_001.wav", language="ko", beam_size=5)

lines = [f"[{s.start:.1f}-{s.end:.1f}] {s.text.strip()}" for s in segments]
transcript = "\n".join(lines)   # 전사는 여기서부터 '민감 데이터'로 취급

2. 화자 분리 (선택) — 신고자 발화만 추리기

접수자·신고자가 섞인 통화를 화자별로 나누면, 분류에 신고자 발화만 써서 노이즈를 줄일 수 있습니다. pyannote는 모델 사용 약관 동의 후 받은 토큰이 필요하지만 추론은 로컬에서 돕니다.

PYTHON
from pyannote.audio import Pipeline

pipeline = Pipeline.from_pretrained("pyannote/speaker-diarization-3.1",
                                    use_auth_token="hf_...")  # 로컬 추론
diarization = pipeline("call_001.wav")
for turn, _, speaker in diarization.itertracks(yield_label=True):
    print(f"{turn.start:.1f}-{turn.end:.1f} {speaker}")

3. 전사 비식별 — 분류에 넣기 전

전사 텍스트에는 이름·전화·상세주소가 평문으로 남습니다. 외부 LLM 분류에 넣기 전 반드시 비식별합니다.

개인정보, AI에 넣기 전에 점검하기의 3단 점검(정규식 → 문맥 → 사람)을 전사 텍스트에 그대로 적용하세요. 자동 마스킹 뒤에도 이름·상세주소는 사람이 최종 확인합니다.

4. 유형·긴급도 분류 — 후보를 만들되 단정하지 않기

분류는 고정 라벨셋 안에서만 고르고, 모호하면 "확인필요"로 빼고, 각 분류에 근거 문장을 강제합니다.

TEXT
아래는 비식별된 신고 전사입니다.
유형은 [화재, 구조, 구급, 기타] 중에서만 고르세요.
긴급도는 [높음, 보통, 낮음] 중에서만 고르세요.
판단 근거가 된 전사 문장을 그대로 인용해 함께 적으세요.
근거가 약하면 유형/긴급도를 "확인필요"로 두세요. 추측해서 채우지 마세요.

분류가 끝나면 결과 수가 입력과 맞는지, 라벨이 허용집합 안인지 검산합니다.

PYTHON
ALLOWED = {"화재", "구조", "구급", "기타", "확인필요"}
assert len(results) == len(transcripts), "검산 실패: 분류 수 ≠ 입력 수"
assert all(r["type"] in ALLOWED for r in results), "허용 라벨 밖의 값이 있습니다"
▸ 소방 활용 포인트
동시다발 신고 접수 부담을 줄이는 분류 초안을 만듭니다. 단 자동 유형·긴급도는 후보일 뿐, 출동 자원 배정과 우선순위 판단은 사람이 합니다. 분류가 틀리면 사람이 즉시 바꿀 수 있어야 합니다.

사람 검토 체크리스트

TEXT
- [ ] 음성·전사를 외부 전사 서비스/클라우드에 올리지 않았습니다.
- [ ] 분류에 넣기 전 전사에서 개인정보를 비식별했습니다.
- [ ] 분류 수가 입력 수와 일치하고, 라벨이 허용집합 안입니다.
- [ ] "확인필요"로 빠진 건은 사람이 직접 분류했습니다.
- [ ] 연습은 익명화/합성 통화로만 했습니다.
⚠️ 흔한 실수
실제 신고 음성·전사로 연습하지 마세요 — 익명화하거나 합성한 데이터만 씁니다. 자동 분류는 접수 보조이지 출동 지령이 아니며, 긴급 신고를 자동으로 후순위로 미루지 않도록 "확인필요"는 항상 사람에게 올립니다.