Stable Diffusion with Python 파이썬으로 배우는 확산 모델
Chapter 09 목차
제3부 · 고급 주제 — 14·15·16장

움직이는 프레임, 말하는 이미지

AnimateDiff의 motion 모듈로 일관된 16프레임을 만들고, BLIP-2와 LLaVA로 이미지에서 설명을 끌어낸다 — 그리고 SDXL이 무엇을 새롭게 했는지 살핀다.

AnimateDiff Motion Module BLIP-2 LLaVA SDXL

Section 01비디오 생성의 난제

정적 이미지에서 동적 콘텐츠 — 비디오로의 진행은 자연스럽다. 하지만 Stable Diffusion의 UNet 아키텍처는 단일 이미지 처리에 효과적인 대신, 여러 이미지를 다룰 때 컨텍스트 인식이 부족하다.

같은 프롬프트·매개변수에 시드만 다르면, 결과 이미지는 색상·형태·스타일에서 크게 달라진다. 비디오 클립을 프레임으로 쪼개 img2img나 ControlNet으로 각각 처리해도, 시퀀스 전체의 일관성은 여전히 도전 — 출력 비디오에는 눈에 띄는 깜박임(flicker)이 남는다.

Key — AnimateDiff의 돌파구 Yuwei Gao 등의 논문 "AnimateDiff: Animating Your Personalized Text-to-Image Diffusion Models without Specific Tuning"이 돌파구를 열었다. 텍스트에서 일관된 이미지 시퀀스를 생성해, 짧은 비디오를 만들 수 있게 했다.

Section 02AnimateDiff의 motion 모듈

AnimateDiff 저자들은 ControlNet과 유사한 별도의 motion 모델 — zero-initialized convolution side 모델 — 을 훈련했다. 이미지를 제어하는 대신, motion 모델은 연속 프레임 시리즈에 적용된다. 기본 SD 모델은 동결한 채, 비디오 데이터셋에서 motion 모듈을 훈련해 motion prior를 추출한다.

motion 모듈 — 16개 latent를 상관된 프레임으로 STEP 01 / 5
space 재생 · → 다음 · R 리셋
AnimateDiff 파이프라인 로드
from diffusers import MotionAdapter, AnimateDiffPipeline

adapter = MotionAdapter.from_pretrained(
    "guoyww/animatediff-motion-adapter-v1-5-2")

pipe = AnimateDiffPipeline.from_pretrained(
    "digiplay/majicMIX_realistic_v6",
    motion_adapter = adapter,
    safety_checker = None)

pipe.enable_vae_slicing()        # 프레임 하나씩 디코딩
pipe.enable_model_cpu_offload()  # 유휴 모델 CPU 오프로드
Intuition — 왜 프레임이 상관되는가 16프레임 비디오를 생성할 때, 파이프라인은 먼저 16개의 무작위 latent를 가우시안 노이즈로 초기화한다. motion 모듈 없이는 UNet이 16개의 독립적인 이미지를 만든다. 하지만 내부에 Transformer attention 헤더를 둔 motion UNet은 16개의 상관된 프레임을 만든다 — 훈련 비디오의 프레임이 서로 상관돼 있었기 때문이다. 핵심 구성 요소는 TransformerTemporalModel이다. 기본 SD가 동결돼 있으니, LoRA·TI·ControlNet 같은 확장 기술도 그대로 쓸 수 있다.

Section 03BLIP-2 이미지 캡셔닝

이미지는 있는데 연관된 프롬프트가 없다고 하자. 한 장이면 직접 쓰면 되지만, 설명 없는 이미지가 수백만 장이라면? AI가 캡션을 자동 생성해야 한다. BLIP-2(Bootstrapping Language-Image Pre-training)는 빠르고 하드웨어 요구가 비교적 낮은 캡셔닝 솔루션이다.

BLIP의 핵심 아이디어는 효과적인 비전·언어 구성 요소를 재사용하고, 둘을 잇는 중간 모델만 훈련하는 것이다. 이 중간 모델이 Q-Former다 — 이미지 인코더에서 귀중한 정보를 추출해, LLM이 시각 콘텐츠 기반의 정확한 응답을 만들게 한다.

BLIP-2 — float16으로 로드
from transformers import AutoProcessor, Blip2ForConditionalGeneration
import torch

processor = AutoProcessor.from_pretrained("Salesforce/blip2-opt-2.7b")

# 기본은 float32 — 메모리 절약을 위해 float16으로
model = Blip2ForConditionalGeneration.from_pretrained(
    "Salesforce/blip2-opt-2.7b",
    torch_dtype = torch.float16)

Section 04LLaVA

LLaVA(Large Language and Vision Assistant)는 책 집필 시점 기준 가장 새롭고 강력한 캡셔닝 모델이다(llava-v1.5-13b 사용). BLIP-2가 빠르고 가벼운 반면, LLaVA는 더 풍부하고 상세한 설명을 생성한다.

Table 15.1 — BLIP-2 대 LLaVA
모델특성적합한 상황
BLIP-2빠르고 하드웨어 요구 낮음대량 이미지 일괄 캡셔닝
LLaVA가장 강력, 풍부한 설명상세하고 정교한 캡션이 필요할 때
Intuition — 캡셔닝의 쓸모 자동 캡셔닝은 단지 편의가 아니다. img2img·업스케일·전이학습 모두 좋은 텍스트 설명을 필요로 한다. 설명 없는 거대한 이미지 데이터셋을 BLIP-2나 LLaVA에 통과시키면, 모델 학습용 캡션을 손 하나 까딱 않고 얻을 수 있다.

Section 05SDXL의 새로운 점

그다지 성공적이지 못했던 SD 2.0·2.1 이후, 2023년 7월 SDXL이 출시됐다. SDXL은 여전히 latent diffusion 모델이고 SD v1.5와 같은 전체 아키텍처를 유지하지만, 모든 구성 요소를 확장했다.

SD v1.5 → SDXL — 구성 요소의 확장 STEP 01 / 4
space 재생 · → 다음 · R 리셋
ConceptSDXL이 바꾼 것들

UNet — 26억 파라미터로 SD v1.5(8억 6천만)의 거의 3배. Transformer 블록 위치도 재배열했다.

두 텍스트 인코더 — CLIP ViT-L(768차원)과 OpenCLIP ViT-bigG(1,280차원)를 함께 쓴다. 두 임베딩을 연결하면 2,048차원 — v1.5의 768차원보다 훨씬 크다.

재훈련된 VAE — 같은 아키텍처지만 배치 크기 256(기존 9), 지수 이동 평균으로 가중치 추적. 모든 메트릭에서 원본을 능가한다.

2단계 설계 — base 모델이 생성하고, 선택적 refiner가 정제한다.

Key — 더 직관적인 프롬프트 SDXL은 거의 모든 면에서 v1.5를 능가한다. 무엇보다 더 직관적인 자연어 프롬프트를 쓸 수 있다 — 의미 있는 프롬프트를 만들려고 "마법 단어"를 잔뜩 조합할 필요가 없고, 더 간결한 프롬프트로 원하는 이미지를 얻는다. 대가는 VRAM이다 — SDXL은 보통 15GB가 필요하다.