| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- Consistent Video Depth Estimation
- CNN
- Link Prediction
- Stable Diffusion #Image generation #Diffusion #AI #Generative model
- CityJSON
- Road network
- Today
- Total
빙글빙글 돌아가는 바람개비
[Study] Stable Diffusion 동작 원리 본문
Stable Diffusion 이란?
Stable Diffusion 은 2022년 LMU 뮌헨 대학 연구팀과 Stability AI 가 함께 공개한 텍스트-투-이미지 모델이다. 문장을 입력하면 몇 초 안에 그에 맞는 이미지가 나온다. 비슷한 시기에 등장한 DALL·E 2 나 Midjourney 와 달리 모델 가중치와 코드가 전부 공개돼 있어, 개인 GPU 에서도 그대로 돌릴 수 있다는 점이 가장 큰 차이다.
모델은 크게 세 가지 모듈로 구성된다.
- Text Encoder (CLIP) — 프롬프트를 의미 벡터로 변환한다.
- Autoencoder (VAE) — 이미지를 압축된 잠재 공간으로 옮기고, 다시 픽셀로 되돌린다.
- U-Net — 잠재 공간 안에서 노이즈를 단계적으로 걷어내는 실제 생성 엔진.
GAN 처럼 한 번에 이미지를 만들어내는 방식이 아니라, 노이즈를 수십 단계에 걸쳐 조금씩 걷어내는 방식이다. 학습이 더 안정적이고, 비슷한 입력에서도 다양한 결과가 나오는 게 강점이다. 아래에서는 Forward diffusion 부터 U-Net 의 Cross-Attention 까지 동작 방식을 차례로 살펴본다.
1. Diffusion 의 기본 아이디어

깨끗한 이미지에 노이즈를 조금씩 더한다. 처음에는 살짝 흐릿해지지만, 계속 더하다 보면 원본은 사라지고 무작위 잡음만 남는다. 이 과정을 Forward diffusion 이라 부른다. 더할 노이즈의 양과 단계가 미리 정해져 있다는 점만 알아두면 된다.
여기서 한 번 뒤집어 보자. 노이즈로 가득 찬 이미지에서 노이즈를 단계별로 빼나가면 깨끗한 이미지로 돌아온다. 한 발 더 나가서, 매 단계에서 뺄 노이즈를 적절히 골라낼 수만 있다면, 처음부터 무작위 잡음으로 시작해도 의미 있는 이미지를 만들어낼 수 있다. 디퓨전 모델은 여기서 출발한다.
2. Noise Predictor 학습시키기

그러면 매 단계에서 어떤 노이즈를 빼야 할지는 어떻게 알 수 있을까. 이걸 학습하는 신경망이 Noise predictor 다. 학습 절차는 단순하다.
- 학습 데이터에서 깨끗한 이미지를 한 장 가져온다.
- 무작위 양의 노이즈를 만들어 이미지에 더한다.
- 노이즈 예측기에게 이 이미지를 보여주고 "어떤 노이즈가 더해졌는지" 맞히게 한다.
- 정답(실제로 더한 노이즈) 과 예측값을 비교해서 모델을 업데이트한다.
이걸 수백만 장의 이미지로 반복하다 보면, 노이즈 예측기는 어떤 그림을 봐도 그 안에 섞인 노이즈를 잘 짚어내게 된다.
학습을 마친 뒤에는 거꾸로 동작시킨다. 완전히 무작위인 노이즈 이미지를 입력으로 주고, 예측기가 내놓은 노이즈를 조금씩 덜어낸다. 보통 50번 정도 반복하면 그럴듯한 이미지가 나타난다.
3. Latent Space — 픽셀 대신 압축된 공간에서

여기까지의 과정을 픽셀 이미지에 그대로 적용하면 연산량이 너무 많다. 512×512 컬러 이미지 한 장만 해도 다뤄야 할 숫자가 약 78만 개(512 × 512 × 3) 이고, 이걸 50번 처리해야 한다.
Stable Diffusion 은 이걸 우회한다. 이미지를 압축한 작은 표현 위에서 디퓨전을 돌리는 방식인데, 이 압축과 복원을 담당하는 신경망이 Autoencoder 다.
Autoencoder 는 압축했다가 다시 풀었을 때 원본과 거의 같은 이미지가 나오도록 미리 학습돼 있다. 덕분에 디퓨전 연산이 전부 훨씬 작은 64×64×4 공간 안에서 끝난다. 픽셀 해상도 대비 약 48분의 1 크기다.
흥미로운 건 채널 수가 3이 아니라 4라는 점이다. RGB 의 3채널과는 달리, 잠재 공간의 4채널은 Autoencoder 가 학습 과정에서 자체적으로 만들어낸 표현이다. 각 채널이 정확히 무엇을 담당하는지 사람이 해석하기는 어렵지만, 색감 · 윤곽 · 질감 같은 시각 정보가 채널별로 흩어져 들어 있다고 보면 된다.
정리하면 학습 단계에서는 이미지를 Encoder 로 압축해 잠재 텐서를 만들고, 거기에 노이즈를 더해 Noise predictor 를 학습시킨다. 생성 단계에서는 무작위 노이즈 텐서 (4, 64, 64) 에서 시작해 단계별로 노이즈를 제거하고, 마지막에 Decoder 로 픽셀 이미지를 복원한다.
4. Text Encoder — 단어를 의미 벡터로
"푸른 하늘 아래 들판" 같은 문장을 신경망이 다루려면 먼저 숫자로 바꿔야 한다. Stable Diffusion 은 이 단계에서 OpenAI 가 공개한 CLIP 모델의 텍스트 인코더(ClipText) 를 그대로 가져다 쓴다. Transformer 기반 언어 모델이다.
CLIP 은 어떻게 학습되나

CLIP 의 학습 데이터는 인터넷에서 모은 약 4억 장의 (이미지, 캡션) 쌍이다. 보통 웹페이지 이미지의 alt 태그가 캡션으로 쓰인다.
이미지는 이미지 인코더로, 캡션은 텍스트 인코더로 통과시켜 각각 임베딩 벡터를 뽑는다. 학습 목표는 단순하다. 짝지어진 이미지와 텍스트의 임베딩은 서로 가깝게, 짝이 아닌 것들은 멀게 만든다.
이걸 4억 쌍에 대해 반복하고 나면, "강아지 사진" 이미지와 "a picture of a dog" 라는 문장이 거의 같은 위치의 벡터로 매핑된다. 텍스트와 이미지가 같은 의미 공간 위에 놓이는 셈이다.
텍스트 처리 흐름

텍스트 처리 자체는 세 단계로 끝난다. 문장을 작은 단위(Token) 로 쪼개고 (최대 77개), 각 토큰을 768차원 벡터로 변환한 뒤, Transformer 를 통과시켜 문맥이 반영된 최종 벡터를 얻는다. 최종 출력은 (77, 768) 크기의 행렬이고, 프롬프트의 의미가 이 안에 통째로 압축돼 들어 있다.
5. U-Net — 텍스트를 이미지 생성에 주입하기

앞에서 "노이즈 예측기" 라고 불렀던 신경망의 실체가 U-Net 이다. 입력 텐서가 점점 작은 해상도로 압축되다가(인코더), 가장 작은 표현에 도달한 뒤(병목), 다시 원래 해상도로 펼쳐진다(디코더). 같은 해상도의 인코더 층과 디코더 층이 잔차 연결(residual connection) 로 직접 이어지는데, 이 연결이 압축 과정에서 사라졌을 디테일을 디코더 쪽에 그대로 전달한다.
시간 단계 t 는 사인 · 코사인 함수로 만든 임베딩 벡터 형태로 각 층에 주입된다. "지금이 노이즈가 가득한 초반인지, 거의 정리된 후반인지" 를 모델에 알려주는 신호다. 각 층 안쪽에서 합성곱 처리는 주로 ResNet 블록이 맡는다.
텍스트가 없는 버전 vs 있는 버전
텍스트 조건이 없는 버전의 U-Net 은 노이즈 섞인 잠재 텐서 (4, 64, 64) 와 시간 단계 t 만 입력으로 받아 예측 노이즈를 내놓는다. 여기에 텍스트를 더하려면 (77, 768) 임베딩을 추가로 받아야 한다. 방법은 ResNet 블록 사이사이에 Attention 층을 끼워 넣는 것이다.
ResNet 블록은 텍스트를 직접 보지 않는다. 텍스트를 읽는 건 Attention 층뿐이다. Attention 층이 텍스트의 의미를 잠재 표현 안에 녹여 넣고 나면, 그다음 ResNet 블록은 이미 텍스트가 반영된 잠재 표현을 평소처럼 처리하면 된다.
Cross-Attention 메커니즘
이 Attention 층이 작동하는 방식이 Cross-Attention 이다. 이미지의 각 위치가 텍스트의 어떤 단어를 참조할지 결정하는 메커니즘이라고 보면 된다.
"빨간 사과와 파란 컵" 이라는 프롬프트를 떠올려 보자. 이미지에서 사과가 그려지는 영역은 "빨간" 토큰에 강하게 주목하고, 컵이 그려지는 영역은 "파란" 토큰에 주목한다. 구체적으로는, 이미지의 각 위치가 "나는 어떤 정보가 필요해" 라는 Query 를 던지면, 텍스트의 각 토큰이 "나는 이런 걸 갖고 있어" 라는 Key 로 응답한다. 둘의 일치도가 높을수록 그 토큰이 가진 실제 정보(Value) 가 더 많이 전달된다.
Cross-Attention 블록은 U-Net 안에 한 번만 있는 게 아니라 여러 층에 걸쳐 분산돼 있다. 디퓨전 50 스텝을 도는 동안 매 스텝마다, 그것도 U-Net 의 여러 깊이에서 텍스트가 반복적으로 주입되는 셈이다. 프롬프트의 영향이 결과에 깊게 박히는 이유다.
전체 흐름 정리
텍스트에서 이미지가 나오기까지의 전체 흐름을 다시 한 번 짚어 보면 다음과 같다.
- 텍스트 인코딩 — 프롬프트를 ClipText 에 통과시키면 (77, 768) 크기의 텍스트 임베딩 행렬이 나온다.
- 잠재 노이즈 초기화 — (4, 64, 64) 크기의 표준정규분포 노이즈 텐서를 하나 만든다. 같은 시드 값은 항상 같은 노이즈를 만들어내고, 결국 같은 이미지를 재현한다.
- 디퓨전 루프 — 현재 잠재 텐서 · 시간 단계 t · 텍스트 임베딩을 U-Net 에 넣어 노이즈를 예측하고, 잠재 텐서에서 조금 덜어낸다. 정해진 횟수만큼 반복.
- 디코딩 — 루프가 끝나면 깨끗한 (4, 64, 64) 잠재 텐서가 남는다. 이걸 Autoencoder 의 Decoder 에 넣으면 (3, 512, 512) RGB 이미지가 복원된다.
- 출력 — 픽셀 값을 0~255 범위로 맞춰 화면에 띄운다.
'Image Generation > Study' 카테고리의 다른 글
| [Study] ControlNet으로 이미지 제어하기 (0) | 2026.03.20 |
|---|---|
| [Study] Textual Inversion의 원리 (0) | 2026.03.18 |
| [Study] LoRA(Low-Rank Adaptation)를 이용한 스타일 학습 (0) | 2026.03.17 |
| [Study] Diffusion Sampler - DDPM, DDIM, Euler, DPM (0) | 2026.03.16 |
| [Study] Classifier-Free Guidance의 원리 (0) | 2026.03.15 |