Whisper 코드 리뷰: Open AI STT 모델의 내부 구조 완전 해부

screenshot 2025 10 31 at 12.32.24 am

Whisper 코드 리뷰 — Open AI STT 모델의 내부 구조 해부

OpenAI의 Whisper는 오픈소스로 공개된 음성 인식(STT, Speech-to-Text) 모델입니다. 겉으로는 “그냥 음성을 텍스트로 바꿔주는 모델”처럼 보이지만, 실제로 코드를 들여다보면 Transformer 기반 멀티모달 인퍼런스 엔진에 가깝습니다. 이번 글에서는 Whisper의 코드를 직접 뜯어보며 구조를 해부해보겠습니다.

screenshot 2025 10 31 at 12.20.45 am

🎯 1. 전체 구조 개요

Whisper 레포지토리의 핵심은 단 3개의 파일에 있습니다.

  • model.py — 모델 정의 (Transformer encoder-decoder)
  • audio.py — 오디오 전처리 (FFT, mel spectrogram)
  • transcribe.py — 실제 inference 파이프라인

이 단순한 구조 덕분에 Whisper는 PyTorch 모델 중 가장 읽기 쉬운 코드 중 하나입니다.


🎧 2. 오디오 처리 파이프라인 (audio.py)

먼저 오디오를 처리하는 부분을 봅시다.


def load_audio(file: str, sr: int = 16000):
    out = subprocess.run(
        ["ffmpeg", "-i", file, "-f", "s16le", "-ac", "1", "-acodec", "pcm_s16le", "-ar", str(sr), "-"],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        check=True,
    )
    return np.frombuffer(out.stdout, np.int16).astype(np.float32) / 32768.0

핵심 포인트:

  • Whisper는 모든 입력 오디오를 16kHz mono float32로 맞춥니다.
  • ffmpeg를 직접 호출해 다양한 포맷을 호환합니다.
  • 출력은 [-1, 1] 범위의 float32 numpy array입니다.

다음은 멜 스펙트로그램 변환 부분입니다.


def log_mel_spectrogram(audio):
    spec = librosa.feature.melspectrogram(
        y=audio, sr=16000, n_fft=400, hop_length=160, n_mels=80
    )
    return np.log10(np.maximum(spec, 1e-10))

여기서 중요한 건 80채널 Mel spectrogram을 생성한다는 점입니다. 이는 Whisper의 인코더 입력 토큰 역할을 합니다 — 즉, 오디오를 “이미지처럼” 본다는 개념이죠.


🧠 3. 모델 정의 (model.py)

Whisper의 핵심은 Transformer입니다. 코드를 보면 거의 GPT 스타일의 디코더와, BERT 스타일의 인코더가 짝을 이룹니다.


class Whisper(nn.Module):
    def __init__(self, dims):
        super().__init__()
        self.encoder = AudioEncoder(dims)
        self.decoder = TextDecoder(dims)

🎙️ 인코더

AudioEncoder는 Mel spectrogram을 입력받아 latent representation을 만듭니다.


class AudioEncoder(nn.Module):
    def __init__(self, dims):
        super().__init__()
        self.conv1 = Conv1d(80, dims.n_audio_state, kernel_size=3, stride=1, padding=1)
        self.blocks = nn.ModuleList([ResidualAttentionBlock(...) for _ in range(dims.n_audio_layer)])

이 구조는 Conv → Self-Attention 반복으로, 시간축의 특징을 추출하며 “음성 문맥 벡터”를 만듭니다.

✍️ 디코더

TextDecoder는 GPT와 거의 동일합니다. 차이점은 Cross-Attention으로 오디오 인코딩을 참조한다는 점입니다.


class TextDecoder(nn.Module):
    def forward(self, tokens, audio_features):
        for block in self.blocks:
            x = block(x, cross_kv=audio_features)
        return self.ln(x)

즉, Whisper는 “오디오를 보고 문장을 예측하는 GPT”입니다.


⚙️ 4. 추론 파이프라인 (transcribe.py)

전체 파이프라인은 이렇게 단순합니다.


def transcribe(model, audio):
    mel = log_mel_spectrogram(audio)
    mel = torch.from_numpy(mel).to(model.device)
    result = model.decode(mel)
    return decode_tokens(result)

단 세 단계입니다:

  1. 오디오 로드 + Mel 변환
  2. Transformer 인코딩 + 디코딩
  3. 토큰을 텍스트로 디코딩

여기에 beam search, temperature, language detection 등의 옵션이 붙으면 Whisper CLI에서 사용하는 --task translate, --temperature 0.2 같은 기능이 됩니다.


🌍 5. 다국어 지원

Whisper STT의 가장 큰 장점 중 하나는 다국어 인식입니다. 모델은 98개 이상의 언어를 지원하며, 자동 언어 감지 기능도 탑재되어 있습니다. 즉, 입력 오디오 언어를 미리 지정하지 않아도 모델이 판단하여 텍스트로 변환합니다.

코드 레벨에서는 language 파라미터와 --task transcribe 옵션이 이를 가능하게 합니다. 모델이 학습한 멀티링구얼 데이터 덕분에, 영어 외에도 스페인어, 중국어, 한국어 등 다양한 언어에서 높은 정확도를 보여줍니다.


⚡ 6. Whisper.cpp 포팅

Whisper 모델은 PyTorch 기반이지만, C++로 포팅된 Whisper.cpp 프로젝트가 있습니다. 주요 장점:

  • CPU 환경에서도 빠른 추론 가능
  • 모바일 및 임베디드 기기에서도 실행 가능
  • PyTorch 설치 없이 사용 가능

실제로 Whisper.cpp는 quantization, 메모리 최적화 등 다양한 기법을 적용해 속도와 효율을 극대화했습니다. Whisper STT를 서버가 아닌 로컬 장치에서 활용하고자 할 때 훌륭한 대안이 됩니다.


💡 7. Whisper의 설계 철학

코드를 읽다 보면 Whisper 팀의 철학이 느껴집니다:

  • Simple > Clever — 복잡한 트릭보다 일관된 설계
  • 모듈화된 파이프라인 — 오디오 → 멜 → 인코더 → 디코더 → 텍스트
  • End-to-End Differentiable — 전처리까지 포함한 end-to-end 설계

Whisper는 “거대한 모델을 단순한 구조로 구현하는 방법”의 모범 사례입니다. 덕분에 모델 크기에 비해 읽기 쉽고 유지보수가 쉬운 코드베이스가 되었죠.


🏁 8. 마무리

Whisper STT의 코드는 “STT의 표준 교과서”라고 할 수 있습니다. Transformer를 이용해 음성을 텍스트로 변환하는 전체 과정이 간결하고 직관적으로 담겨 있기 때문입니다. 다국어 지원과 Whisper.cpp 포팅 덕분에 활용 범위도 넓습니다.

📚 더 깊이 보고 싶다면:

  • Beam Search가 Whisper에서 어떻게 구현되어 있는가
  • Whisper 모델의 다국어 처리 방식
  • Whisper.cpp나 MLX 포팅 버전의 최적화 비교

참고 자료

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top