🎯

input → 사전학습 모델 → output — AI 추론의 본질은 이 한 줄이다

STFT도 마스킹도 잊어라 — 모델이 하는 일은 딱 하나, 입력을 받아 출력을 내는 것

핵심: 신경망이 하는 일은 딱 한 줄이다

음원 분리 파이프라인을 다시 보자:

song.mp3
  ↓ torchaudio.load()        ← 파일 읽기 (수학)
  ↓ torch.stft()             ← 푸리에 변환 (수학)
  ↓ .abs() / .angle()        ← 복소수 분리 (수학)
  ↓ model(magnitude)         ← ★ 여기만 신경망 ★
  ↓ magnitude × mask         ← 행렬 곱셈 (수학)
  ↓ × exp(j × phase)         ← 복소수 복원 (수학)
  ↓ torch.istft()            ← 역 푸리에 변환 (수학)
vocals.wav

model(magnitude) — 이 한 줄이 신경망을 사용하는 유일한 부분이다.

나머지는 전부 결정적인 수학 연산이다. 같은 입력을 넣으면 같은 출력이 나온다. 학습이 필요 없고, 파라미터도 없다.

신경망이 하는 일: "이 주파수×시간 위치가 보컬일 확률"을 출력하는 것. 그게 전부다. 모델이 80MB든 913MB든, 하는 일의 본질은 같다.

패턴: input → model → output

모든 AI 추론은 이 구조다:

output = model(input)

사전 훈련된 모델을 불러오고, 입력을 넣고, 출력을 받는다. 아래 5가지 예제 전부 이 패턴이다.


예제 1: 숫자 이미지 분류 (가장 단순)

input: 손글씨 숫자 이미지 (28×28 픽셀)
model: 사전 훈련된 CNN
output: 0~9 중 어떤 숫자인지

import torch
import torch.nn as nn
from torchvision import datasets, transforms

# 1. 사전 훈련된 모델 정의 + 가중치 로드
class SimpleNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.flatten = nn.Flatten()
        self.fc = nn.Sequential(
            nn.Linear(28*28, 128),
            nn.ReLU(),
            nn.Linear(128, 10)  # 10개 클래스 (0~9)
        )
    def forward(self, x):
        return self.fc(self.flatten(x))

model = SimpleNet()
# 실제로는 torch.load("pretrained.pt")로 가중치를 불러온다
# 여기서는 구조만 보여주기 위해 생략
model.eval()

# 2. input 준비
test_data = datasets.MNIST('.', download=True, train=False,
                            transform=transforms.ToTensor())
image, label = test_data[0]  # 28×28 이미지 1장

# 3. ★ 이 한 줄이 전부 ★
with torch.no_grad():
    output = model(image.unsqueeze(0))  # [1, 10] — 각 숫자의 점수

predicted = output.argmax(dim=1).item()
print(f"input: 28×28 이미지 → model → output: {predicted} (정답: {label})")

output = model(image) — 이게 추론의 전부다.


예제 2: 오디오 분류 — "이게 무슨 소리?"

input: 오디오 파형 (1D 배열)
model: 사전 훈련된 Audio Spectrogram Transformer
output: "Dog", "Rain", "Music" 등 527개 카테고리 중 하나

from transformers import pipeline

# 1. 사전 훈련된 모델 로드 (자동 다운로드 ~350MB)
classifier = pipeline("audio-classification",
                      model="MIT/ast-finetuned-audioset-10-10-0.4593")

# 2. ★ input → model → output ★
result = classifier("dog_bark.wav")

# 3. output
print(result[0])
# → {'label': 'Dog', 'score': 0.9834}

내부에서 일어나는 일:

dog_bark.wav → 멜 스펙트로그램 변환 → model() → 527개 클래스 확률 → 가장 높은 것 = "Dog"

멜 스펙트로그램 변환은 수학이다. model()만 신경망.


예제 3: 음성 인식 — "뭐라고 말했어?"

input: 음성 오디오
model: 사전 훈련된 Whisper
output: 텍스트

import whisper

# 1. 사전 훈련된 모델 로드 (tiny=75MB)
model = whisper.load_model("tiny")

# 2. ★ input → model → output ★
result = model.transcribe("speech.mp3")

# 3. output
print(result["text"])
# → "안녕하세요 오늘 날씨가 좋네요"

내부에서 일어나는 일:

speech.mp3 → 멜 스펙트로그램 → model() → 토큰 시퀀스 → 디코딩 → "안녕하세요..."

model()이 스펙트로그램을 받아서 토큰(단어 조각)을 하나씩 출력한다. 토큰을 텍스트로 바꾸는 건 룩업 테이블(수학).


예제 4: 음원 분리 — "보컬만 빼줘"

input: 음악 스펙트로그램
model: 사전 훈련된 Demucs
output: 마스크 (어디가 보컬인지)

from demucs.pretrained import get_model
from demucs.apply import apply_model
import torchaudio

# 1. 사전 훈련된 모델 로드 (~80MB)
model = get_model("htdemucs")
model.eval()

# 2. input 준비
wav, sr = torchaudio.load("song.mp3")

# 3. ★ input → model → output ★
with torch.no_grad():
    sources = apply_model(model, wav[None], device="cpu")[0]
    # sources: [4, 2, samples] — 4개 스템

# 4. output
vocals = sources[3]  # index 3 = vocals
torchaudio.save("vocals.wav", vocals, sr)
print(f"input: song.mp3 → model → output: vocals.wav")

apply_model(model, wav) 안에서 일어나는 일:

wav → 청크 분할 → STFT → model() → 마스크 → 마스크 적용 → ISTFT → 오버랩-애드

model() 호출만 신경망이고 나머지는 전부 수학.


예제 5: 음성 합성 — "이 텍스트를 읽어줘"

input: 텍스트 문자열
model: 사전 훈련된 TTS
output: 음성 파형

from TTS.api import TTS

# 1. 사전 훈련된 모델 로드 (~1.8GB)
tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2")

# 2. ★ input → model → output ★
tts.tts_to_file(
    text="안녕하세요",
    language="ko",
    file_path="hello.wav"
)
print(f"input: '안녕하세요' → model → output: hello.wav")

내부에서 일어나는 일:

"안녕하세요" → 음소 변환 → model() → 오디오 토큰 생성 → 보코더 → hello.wav

음소 변환은 규칙 기반(수학/룩업), 보코더도 신경망이지만 핵심은 model()이 텍스트에서 오디오 표현을 생성하는 것.


공통 패턴 정리

태스크 input model() output
이미지 분류 28×28 픽셀 CNN 0~9 확률
소리 분류 멜 스펙트로그램 AST Transformer 527개 카테고리 확률
음성 인식 멜 스펙트로그램 Whisper Transformer 토큰 시퀀스 (→텍스트)
음원 분리 스펙트로그램 Demucs/RoFormer 마스크 (→분리된 음원)
음성 합성 텍스트 (음소) XTTS/GPT-SoVITS 오디오 토큰 (→음성)

전부 같은 구조다:

# 1. 모델 로드
model = load_pretrained("model_name")

# 2. 추론
output = model(input)

# 3. 후처리
result = postprocess(output)

model() 앞의 전처리(STFT, 토크나이징, 멜 변환)와 뒤의 후처리(ISTFT, 디코딩, 보코더)는 각 태스크마다 다르지만, 핵심은 항상 model(input) 한 줄이다.

사전 훈련된 모델의 파라미터(가중치)가 "어떻게 변환할지"를 이미 학습해놨기 때문에, 우리는 input만 넣으면 된다.

그래서 모델 크기가 왜 다른가

model(input) → output

이 한 줄에서 model의 크기가 다른 이유:

모델 파라미터 수 파일 크기 왜 이렇게 큰가
MNIST CNN ~60K ~0.2 MB 28×28 흑백 → 10개 숫자. 단순
Whisper tiny 39M 75 MB 오디오 → 텍스트. 다국어
Demucs 26.3M 80 MB 곡 → 4스템. 시간+주파수 처리
AST 87M 350 MB 오디오 → 527개 분류
Whisper large 1.5B 3 GB 99개 언어 지원
UVR RoFormer 84.2M 913 MB 리드/백킹 구분 (더 어려운 태스크)

파라미터가 많을수록 더 복잡한 패턴을 학습할 수 있다. 근데 하는 일의 본질은 동일하다 — input을 받아서 output을 내는 것.

핵심 개념

1

model = load_pretrained("name") — HuggingFace/GitHub에서 사전 훈련된 가중치를 다운로드

2

input = preprocess(raw_data) — STFT, 토크나이징, 멜 변환 등 (전부 수학, 신경망 아님)

3

output = model(input) — ★ 신경망을 사용하는 유일한 부분 ★

4

result = postprocess(output) — ISTFT, 디코딩, 보코더 등 (전부 수학)

사용 사례

AI 추론의 본질 이해 — 복잡한 파이프라인에서 신경망이 하는 일 한 줄을 식별 사전 훈련 모델 활용 — 훈련 없이 model(input)만으로 결과를 얻는 방법 모델 크기와 성능의 관계 — 60K 파라미터(MNIST) vs 84.2M(RoFormer)의 차이