DDIM: 빠른 Diffusion 샘플링
Read time: 1 minute
📘 이 글은 실습용 Jupyter 노트북을 기반으로 작성되었습니다.
DDPM의 한계¶
DDPM은 훌륭한 품질의 이미지를 생성하지만, 치명적인 단점이 있습니다: 너무 느립니다.
# DDPM Sampling
T = 1000 # 1000 스텝 필요!
for t in reversed(range(T)):
x = denoise_step(x, t)
# → 이미지 1장 생성에 수십 초DDIM의 핵심 아이디어¶
DDIM은 두 가지 혁신을 도입합니다:
- 1. Non-Markovian Process: 모든 스텝을 거치지 않아도 됨
- 2. Deterministic Sampling: η=0으로 설정 시 같은 결과 보장
# DDIM Sampling
timesteps = [1000, 800, 600, 400, 200, 100, 50, 0] # 8 스텝만!
for t in timesteps:
x = ddim_step(x, t)
# → 100배 이상 빠름!Non-Markovian Forward Process¶
DDPM은 Markovian (x_t는 오직 x_{t-1}에만 의존). DDIM은 Non-Markovian (x_t는 x_0에 직접 의존).
# DDPM (Markovian)
q(x_t | x_{t-1}, x_0) = q(x_t | x_{t-1}) # x_0 무시!
# DDIM (Non-Markovian)
q(x_t | x_{t-1}, x_0) = N(x_t; √ᾱ_t · x_0 + √(1-ᾱ_t-σ_t²) · ε_{t-1}, σ_t² · I)
# 여기서 σ_t는 자유 파라미터:
# - σ_t = 0: Deterministic (DDIM)
# - σ_t = √β_t: Stochastic (DDPM)DDIM Sampling Formula¶
# DDIM Reverse Process
x_{t-1} = √ᾱ_{t-1} · (x_t - √(1-ᾱ_t) · ε_θ(x_t, t)) / √ᾱ_t
+ √(1-ᾱ_{t-1}-σ_t²) · ε_θ(x_t, t)
+ σ_t · ε_t
# Deterministic (σ_t = 0):
x_{t-1} = √ᾱ_{t-1} · predicted_x_0 + √(1-ᾱ_{t-1}) · ε_θ(x_t, t)
# 여기서:
# predicted_x_0 = (x_t - √(1-ᾱ_t) · ε_θ(x_t, t)) / √ᾱ_t구현¶
from diffusers import DDIMScheduler
# DDIM Scheduler 생성
scheduler = DDIMScheduler(
num_train_timesteps=1000,
beta_schedule="linear"
)
@torch.no_grad()
def ddim_sample(model, shape, num_steps=50, eta=0.0):
"""
DDIM Sampling
Args:
model: Trained diffusion model
shape: Output shape
num_steps: Number of sampling steps (10-50)
eta: Stochasticity parameter (0=deterministic)
"""
# 1. Start from noise
x = torch.randn(shape)
# 2. Set timesteps (uniformly spaced)
scheduler.set_timesteps(num_steps)
# 3. Denoising loop
for t in scheduler.timesteps:
# Predict noise
noise_pred = model(x, t).sample
# DDIM step
x = scheduler.step(
noise_pred,
t,
x,
eta=eta # 0 for deterministic
).prev_sample
return x
# 사용 예시
image = ddim_sample(model, (1, 1, 28, 28), num_steps=50)
# DDPM 1000 스텝과 동일한 품질, 20배 빠름!Timestep Scheduling¶
DDIM은 임의의 timestep subsequence를 사용할 수 있습니다:
# Uniform spacing
def uniform_schedule(total_steps=1000, num_steps=50):
return torch.linspace(0, total_steps-1, num_steps).long()
# Quadratic spacing (더 많은 스텝을 초반에)
def quadratic_schedule(total_steps=1000, num_steps=50):
steps = torch.linspace(0, total_steps**0.5, num_steps) ** 2
return steps.long()
# Custom scheduling
timesteps = [1000, 900, 750, 500, 250, 100, 50, 10, 0]
# 예시:
# 10 steps → 100배 빠름, 품질 약간 하락
# 50 steps → 20배 빠름, 품질 동일
# 100 steps → 10배 빠름, 품질 향상Deterministic vs Stochastic¶
# η (eta) 파라미터 조절
# η = 0: Deterministic (완전히 결정적)
# - 같은 noise seed → 항상 같은 이미지
# - 빠른 샘플링에 적합
image1 = ddim_sample(model, shape, eta=0.0)
image2 = ddim_sample(model, shape, eta=0.0)
# image1 == image2 (seed 동일 시)
# η = 1: Stochastic (DDPM과 동일)
# - 매번 다른 이미지
# - 더 다양한 샘플
image3 = ddim_sample(model, shape, eta=1.0)
image4 = ddim_sample(model, shape, eta=1.0)
# image3 != image4
# η = 0.5: Balanced
# - 약간의 랜덤성
# - 품질과 다양성의 균형성능 비교¶
| Method | Steps | Time | FID | Deterministic |
|--------|-------|------|-----|---------------|
| DDPM | 1000 | 100s | 3.2 | ❌ |
| DDIM | 100 | 10s | 3.2 | ✅ |
| DDIM | 50 | 5s | 3.3 | ✅ |
| DDIM | 10 | 1s | 4.5 | ✅ |
결론: DDIM은 10-50 스텝으로 DDPM과 동일한 품질!📦 실습 코드¶
전체 구현 코드와 Jupyter 노트북을 다운로드할 수 있습니다.
- 💡 더 깊이 공부하고 싶다면?
DDPM부터 Stable Diffusion, SANA까지 체계적으로 배우는 Diffusion Models 완전정복 강의를 확인해보세요! 👉 강의 바로가기
다운로드
파일 다운로드는 로그인이 필요합니다