1-8. 아키텍처: U-Net에서 DiT로
디노이저의 몸통은 U-Net에서 트랜스포머로 바뀌었다. 이번 수업은 그 변화를 따라가고, 1단계에서 배운 부품을 전부 이어 붙여 이미지 생성기 전체를 한 장으로 본다.
U-Net 시대
SD 1.5와 SDXL의 디노이저는 0-4의 U-Net이다. 합성곱 블록 사이에 0-5의 어텐션이 끼어 있다.
[합성곱 블록] → [셀프 어텐션] → [크로스 어텐션(프롬프트)] → 다음 단계
- 합성곱: 가까운 것끼리의 관계. 질감과 디테일
- 셀프 어텐션: 그림 안의 먼 곳끼리의 관계
- 크로스 어텐션: 프롬프트 주입
| 모델 | 파라미터 | 기본 해상도 |
|---|---|---|
| SD 1.5 | 약 8.6억 | 512 |
| SDXL | 약 26억 | 1024 |
SDXL이 커진 부분은 대부분 어텐션이다. 이미 트랜스포머 쪽으로 기울고 있었다.
DiT: 트랜스포머만으로
2022년 말에 DiT(Diffusion Transformer)가 나왔다. 합성곱을 전부 걷어 내고 트랜스포머 블록만 쌓았다.
잠재 → [조각으로 자른다] → 토큰 줄 → [트랜스포머 블록 × N] → [다시 잠재로 편다]
- 잠재를 2×2 조각으로 자른다. 조각 하나가 토큰 하나다.
- 각 토큰에 위치 정보를 붙인다.
- 트랜스포머 블록을 수십 번 통과시킨다.
- 토큰을 다시 잠재의 모양으로 편다.
U-Net과 달리 줄였다 키우는 구조가 없다. 처음부터 끝까지 같은 수의 토큰이 같은 크기로 흐른다.
왜 넘어갔나
- 크기를 키우면 그대로 좋아진다. 트랜스포머는 블록을 더 쌓고 폭을 넓히면 품질이 꾸준히 오른다. 언어 모델에서 이미 확인된 성질이다.
- 멀리 보는 것이 기본이다. 모든 토큰이 모든 토큰을 본다. 전체 구도의 일관성이 좋다.
- 텍스트와 섞기 쉽다. 그림도 토큰, 글도 토큰이다. 한 줄에 넣으면 된다.
- 영상으로 넓히기 쉽다. 시간 방향으로 토큰을 더 늘어놓으면 된다. 6단계에서 다룬다.
텍스트와 그림을 한 줄로: MMDiT
1-5의 "한 줄로 이어 붙이기"를 쓰는 구조다. SD3가 내놓았고 Flux가 이어받았다.
[ 텍스트 토큰들 | 그림 토큰들 ] → 함께 어텐션
Flux는 블록이 두 종류다.
- 앞쪽 블록: 텍스트와 그림이 어텐션은 함께 하되, 나머지 계산은 각자의 가중치로 한다. 성질이 다른 두 정보를 따로 다듬는다.
- 뒤쪽 블록: 텍스트와 그림을 구분 없이 한 줄로 다룬다.
시간과 요약 정보를 넣는 법
노이즈 비율 t와 프롬프트 요약 벡터는 어떻게 넣을까. 0-6에서는 블록마다 더해 줬다. DiT에서는 블록 안의 "정규화" 단계를 조절하는 데 쓴다. 정규화는 숫자들의 크기를 맞춰 주는 단계인데, 얼마나 키우고 옮길지를 t와 요약 벡터가 정한다. 블록 전체의 동작이 t에 따라 달라지게 하는 효율적인 방법이다.
크기와 메모리
| 모델 | 구조 | 파라미터 |
|---|---|---|
| SD 1.5 | U-Net | 약 8.6억 |
| SDXL | U-Net | 약 26억 |
| SD3 Medium | MMDiT | 약 20억 |
| Flux.1 | MMDiT | 약 120억 |
| Qwen-Image | MMDiT | 약 200억 |
메모리는 이렇게 어림한다.
필요한 메모리 ≈ 파라미터 수 × 파라미터 하나의 바이트 수
120억 개를 16비트(2바이트)로 저장하면 24GB다. 8비트면 12GB다. 여기에 텍스트 인코더와 VAE, 계산 중간값이 더해진다. 그래서 큰 모델은 숫자의 정밀도를 낮춘 판(양자화)을 쓴다. 2단계에서 다룬다.
이미지 생성기 전체
1단계의 부품을 전부 이어 붙이면 이렇다.
프롬프트 ──→ [텍스트 인코더] ──→ 토큰 벡터 ─────────┐
↓
시드 ──→ 노이즈(잠재 크기) ──→ [디노이저] ←── 걸음마다 반복 (샘플러, 스케줄러)
│ ↑ CFG면 두 번씩 부른다
└────┘
↓
완성된 잠재 ──→ [VAE 디코더] ──→ 그림
| 부품 | 하는 일 | 배운 곳 |
|---|---|---|
| 텍스트 인코더 | 프롬프트를 토큰 벡터로 | 1-5 |
| 시드와 노이즈 | 출발점을 정한다 | 0-1 |
| 디노이저 | 그림 쪽 방향(속도 또는 노이즈)을 예측 | 1-2, 1-4, 이번 수업 |
| 샘플러, 스케줄러 | 그 방향을 따라 걷는 방법과 걸음 배치 | 1-3 |
| CFG | 프롬프트 방향을 과장 | 1-6 |
| VAE 디코더 | 잠재를 그림으로 | 1-1 |
모델 파일을 받으면 보통 세 덩어리가 들어 있거나 따로 받는다. 디노이저, 텍스트 인코더, VAE. 이 셋이 위 그림의 세 상자다.
1단계에서 얻은 것
이제 이미지 생성 도구의 설정을 보면 각각이 무엇인지 말할 수 있다.
- 모델을 고른다 = 디노이저(와 짝이 맞는 텍스트 인코더, VAE)를 고른다.
- 프롬프트를 쓴다 = 텍스트 인코더에 넣을 글을 쓴다.
- 해상도를 정한다 = 잠재의 크기를 정한다.
- 시드를 정한다 = 출발 노이즈를 정한다.
- 샘플러, 스케줄러, 스텝을 정한다 = 걷는 방법을 정한다.
- CFG를 정한다 = 프롬프트를 얼마나 과장할지 정한다.
2단계에서는 실제 도구를 열어 이 대응을 하나씩 확인한다.
확인 문제
- DiT에서 1024×1024 그림 한 장은 토큰 몇 개가 되나? (VAE 8배 압축, 2×2 조각)
- 파라미터 200억 개인 모델을 16비트로 저장하면 몇 GB인가?
- 이미지 생성기의 세 덩어리는 무엇인가?
풀이
- 4,096개다. 잠재가 128×128이고, 2×2로 자르면 64×64다.
- 40GB다. 200억 × 2바이트.
- 디노이저, 텍스트 인코더, VAE다.