자동 음성 인식(Automatic Speech Recognition, ASR) 또는 음성-텍스트 변환(Speech-to-Text, STT)은 음성 신호를 텍스트로 변환하는 기술이다. 딥러닝의 발전으로 Whisper, Wav2Vec 2.0 같은 모델이 인간 수준의 인식률을 달성했다.
ASR vs STT — 차이점
흔히 혼용되지만, 실제로는 처리 수준이 다르다.
| 항목 | ASR | STT |
|---|
| 출력 형태 | 원시 전사 텍스트 | 형식화된 가독성 텍스트 |
| 구두점 | 없음 | 포함 |
| 대소문자 | 없음 | 적용 |
| 화자 구분 | 없음 | 화자 분리(Diarization) 포함 |
| 최적화 목표 | 속도·기계 처리 | 가독성·검색 가능성 |
| 예시 | can you send me the document tomorrow | Can you send me the document tomorrow? |
처리 파이프라인
음성 파형 (오디오 입력)
│
├── 1단계: 전처리 — 배경 소음 제거, 정규화
│
├── 2단계: 특성 추출 — MFCC / 멜 스펙트로그램 변환
│
├── 3단계: 음향 모델 — 음성 → 음소/서브워드 확률 매핑
│ (RNN-T, CTC, Attention Encoder-Decoder)
│
├── 4단계: 언어 모델 — 단어 시퀀스 확률 보정
│
└── 5단계: STT 후처리 — 구두점, 대소문자, 화자 분리 적용
핵심 구성 요소
| 구성 요소 | 역할 |
|---|
| 음향 모델 | 음파를 음소(phoneme)로 매핑 |
| 언어 모델 | 단어 시퀀스 예측·확률 보정 |
| 디코딩 알고리즘 | 두 모델 출력을 최종 텍스트로 결합 |
| 구두점 모델 | 쉼표·마침표·물음표 삽입 (STT 전용) |
| True Casing | 적절한 대소문자 적용 (STT 전용) |
| 화자 분리 | 여러 화자를 구분·레이블링 (STT 전용) |
Whisper (OpenAI)
python
import whisper # pip install openai-whisper
model = whisper.load_model("base") # tiny/base/small/medium/large
# 음성 파일 → 텍스트
result = model.transcribe("audio.mp3")
print(result["text"])
# 다국어 인식
result = model.transcribe("audio.mp3", language="ko")
print(result["text"])
# 로그멜 스펙트로그램 직접 처리
import torch
audio = whisper.load_audio("audio.mp3")
audio = whisper.pad_or_trim(audio)
mel = whisper.log_mel_spectrogram(audio).to(model.device)
options = whisper.DecodingOptions(language="ko", without_timestamps=True)
result = whisper.decode(model, mel, options)
print(result.text)
스트리밍 vs 배치 처리
| 방식 | 특징 | 지연 시간 | 사용 사례 |
|---|
| 스트리밍 ASR | 발화 중 실시간 부분 결과 전달 | 300ms 이하 | 음성 에이전트, 실시간 자막 |
| 배치 ASR | 녹음 완료 후 오프라인 처리 | 비실시간 | 회의 녹취, 콜 센터 분석 |
python
# 스트리밍 STT 예시 (Whisper + pyaudio)
import pyaudio
import numpy as np
import whisper
model = whisper.load_model("base")
CHUNK = 16000 * 3 # 3초 청크
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paFloat32, channels=1, rate=16000, input=True)
while True:
data = stream.read(CHUNK)
audio = np.frombuffer(data, dtype=np.float32)
result = model.transcribe(audio, language="ko")
print(result["text"], end=" ", flush=True)
CTC 손실 함수
입력 시퀀스 길이와 레이블 길이가 달라도 학습할 수 있는 핵심 알고리즘.
python
import torch
import torch.nn as nn
ctc_loss = nn.CTCLoss(blank=0, reduction='mean', zero_infinity=True)
# log_probs: (T, N, C) — 시간, 배치, 클래스
T, N, C = 50, 4, 28
log_probs = torch.randn(T, N, C).log_softmax(2).detach()
targets = torch.randint(1, C, (N, 10))
input_lengths = torch.full((N,), T, dtype=torch.long)
target_lengths = torch.randint(5, 10, (N,))
loss = ctc_loss(log_probs, targets, input_lengths, target_lengths)
print("CTC Loss:", loss.item())
모델 비교
| 모델 | 방식 | WER (LibriSpeech) | 파라미터 |
|---|
| DeepSpeech 2 | RNN + CTC | ~5% | 100M |
| Wav2Vec 2.0 | 자기지도 + CTC | ~1.8% | 317M |
| HuBERT | 자기지도 학습 | ~1.5% | 317M |
| Whisper Large-v3 | Encoder-Decoder | ~2.7% | 1.5B |
| Deepgram Nova-3 | 배치 | 5.26% | — |
| Deepgram Nova-3 | 스트리밍 | 6.84% | — |
평가 지표 — WER (Word Error Rate)
WER = (S + D + I) / N
S: 치환(Substitution) 오류 수
D: 삭제(Deletion) 오류 수
I: 삽입(Insertion) 오류 수
N: 정답 단어 수
목표: WER 5% 이하 (상용 서비스 기준)
python
def word_error_rate(reference, hypothesis):
ref_words = reference.split()
hyp_words = hypothesis.split()
r, h = len(ref_words), len(hyp_words)
dp = [[0] * (h+1) for _ in range(r+1)]
for i in range(r+1): dp[i][0] = i
for j in range(h+1): dp[0][j] = j
for i in range(1, r+1):
for j in range(1, h+1):
if ref_words[i-1] == hyp_words[j-1]:
dp[i][j] = dp[i-1][j-1]
else:
dp[i][j] = 1 + min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1])
return dp[r][h] / r
ref = "the cat sat on the mat"
hyp = "the cat set on mat"
print(f"WER: {word_error_rate(ref, hyp):.2%}") # 33.33%
화자 분리 (Speaker Diarization)
"누가 언제 말했는가"를 식별하는 기술. 회의록 자동 작성, 콜 센터 분석 등에 활용.
python
# pyannote.audio로 화자 분리
from pyannote.audio import Pipeline
pipeline = Pipeline.from_pretrained("pyannote/speaker-diarization-3.1")
diarization = pipeline("meeting.wav")
for turn, _, speaker in diarization.itertracks(yield_label=True):
print(f"[{turn.start:.1f}s - {turn.end:.1f}s] {speaker}")
# [0.0s - 3.2s] SPEAKER_00
# [3.5s - 7.1s] SPEAKER_01
클라우드 API vs 온프레미스
| 항목 | 클라우드 API | 온프레미스 |
|---|
| 초기 비용 | 낮음 (사용량 기반) | 높음 (GPU 인프라) |
| 확장성 | 즉시 (10만+ 동시 처리) | 하드웨어 추가 필요 |
| 지연 시간 | 네트워크 의존 | 매우 낮음 |
| 데이터 프라이버시 | 외부 전송 | 내부 보관 |
| 경제적 손익분기 | 연간 ~8,500시간 이하 | 연간 800만 시간 이상 |
주요 클라우드 STT 서비스: Google Speech-to-Text, AWS Transcribe, Azure Speech, Deepgram, OpenAI Whisper API
ASR 선택 기준
ASR(원시)을 선택해야 할 때:
- •음성 명령 의도 인식 (IoT, 스마트 스피커)
- •실시간 콜 라우팅 (300ms 이하 필요)
- •다운스트림 NLU 처리가 별도로 존재할 때
STT(형식화)를 선택해야 할 때:
- •법적 검토·준수 기록 보관
- •접근성 자막 (청각장애인 지원)
- •회의록·의료 기록 자동 작성
- •사람이 직접 읽는 문서 생성
산업별 활용 사례
| 분야 | 기술 | 목적 |
|---|
| 의료 | STT (의료 특화 모델) | 진료 기록 자동 작성, EHR 통합 |
| 자동차 | ASR | 핸즈프리 내비게이션·엔터테인먼트 제어 |
| 콜 센터 | ASR + STT 병행 | 즉시 라우팅(ASR) + 감사 기록(STT) |
| 접근성 | STT | 실시간 자막, 청각장애인 지원 |
| 미디어 | ASR | 인터뷰 하이라이트, 검색 가능 아카이브 |
| 보안 | 음성 인식 | 화자 생체인식, 사기 방지 |
관련 개념 구분
| 개념 | 설명 |
|---|
| ASR | 음성 → 원시 텍스트 (기계 처리용) |
| STT | 음성 → 형식화 텍스트 (사람 가독성) |
| TTS | 텍스트 → 음성 합성 (STT의 역방향) |
| NLU | 전사된 텍스트의 의미·의도 파악 |
| 받아쓰기 | 의도적·완전 문장 전사 (의료 기록 등) |
| 필사(Transcription) | 자연 대화 처리 (더 복잡) |
관련 개념
- •자연어 처리 — STT 결과를 처리하는 NLP
- •Transformer — 현대 STT 모델의 기반 아키텍처
- •RNN — 초기 STT 모델에서 활용
- •딥러닝 — STT 정확도 혁신의 기반
- •LLM — STT와 결합하는 음성 에이전트
- •임베딩 — 음성 특성 벡터 표현
참고문헌
- •Ultralytics. What is Speech-to-Text? (ultralytics.com/glossary)
- •Deepgram. ASR vs Speech-to-Text (deepgram.com/learn)
- •OpenAI. Whisper: Robust Speech Recognition via Large-Scale Weak Supervision (2022)
- •Baevski et al. Wav2Vec 2.0: A Framework for Self-Supervised Learning of Speech Representations (2020)