9장 — 샘플러: 같은 길을 걷는 여러 걸음법

DDIM: 새 잡음의 몫을 다이얼 하나로

오일러 걸음은 읽은 잡음을 모두 물려주고, 앤세스트럴은 그 일부를 새 잡음으로 바꾼다. 둘은 같은 분포를 지나는 두 길의 양 끝이다. 그렇다면 그 사이 어디쯤에서 걸을 수도 있지 않을까? 그리고 DDPM처럼 학습 때 1000걸음으로 정한 모델을, 다시 학습하지 않고 50걸음이나 20걸음으로 걸을 수는 없을까? 이 두 물음에 한꺼번에 답한 것이 DDIM이다.

역사: 같은 학습, 다른 생성

송(Jiaming Song), 멍(Chenlin Meng), 에르몬(Stefano Ermon)은 2020년 10월 「잡음 제거 디퓨전 암묵 모델(Denoising Diffusion Implicit Models)」을 내놓았다. 출발점은 DDPM의 손실이 걸음 사이의 관계가 아니라 원래 그림에서 각 잡음 수준으로 바로 가는 분포 q(xt ∣ x₀)에만 기댄다는 관찰이었다. 그렇다면 이 분포들은 그대로 두고 걸음 사이의 관계만 다르게 정한 과정들이 모두 같은 학습 목표를 가진다. 논문은 그런 과정의 가족을 만들고, 그 가운데 생성이 잡음을 하나도 넣지 않는 쪽을 「암묵 모델」이라 불렀다. 논문 요약은 DDIM이 DDPM보다 벽시계 시간으로 10배에서 50배 빠르게 좋은 표본을 만든다고 적었다. 신경망은 다시 학습하지 않는다.

뒤에 카라스와 동료들은 DDIM이 앞에서 본 잡음 크기 눈금(잡음 크기를 시간처럼 쓰고 그림을 줄이지 않는 꼴)을 쓰고 있었다는 것을 짚었다. 그 눈금에서 DDIM의 결정적인 걸음은 오일러 걸음이다.

다이얼 η

앞의 앤세스트럴 걸음에서 새 잡음의 크기에 다이얼 η(에타)를 곱한다.

x′=x^0+σdown ε^+σup εnew,σup=η σ′σ2−σ′2σ,σdown=σ′2−σup2\textcolor{#1b9e77}{x'} = \textcolor{#1b9e77}{\hat x_0} + \textcolor{#4c5d80}{\sigma_{\mathrm{down}}}\,\textcolor{#1f6066}{\hat\varepsilon} + \textcolor{#4c5d80}{\sigma_{\mathrm{up}}}\,\textcolor{#1f6066}{\varepsilon_{\mathrm{new}}}, \qquad \textcolor{#4c5d80}{\sigma_{\mathrm{up}}} = \textcolor{#87965a}{\eta}\,\frac{\textcolor{#4c5d80}{\sigma'}\sqrt{\textcolor{#4c5d80}{\sigma}^2 - \textcolor{#4c5d80}{\sigma'}^2}}{\textcolor{#4c5d80}{\sigma}}, \qquad \textcolor{#4c5d80}{\sigma_{\mathrm{down}}} = \sqrt{\textcolor{#4c5d80}{\sigma'}^2 - \textcolor{#4c5d80}{\sigma_{\mathrm{up}}}^2}
η새 잡음의 몫을 정하는 다이얼 (0 이상 1 이하)σ, σ′걸음 전과 뒤의 잡음 크기σup, σdown새로 섞는 잡음의 크기, 읽은 잡음을 남기는 크기x^0, ε^, εnew읽은 원래 그림, 읽은 잡음, 새로 뽑은 잡음\begin{array}{ll} \textcolor{#87965a}{\eta} & \text{새 잡음의 몫을 정하는 다이얼 (0 이상 1 이하)} \\ \textcolor{#4c5d80}{\sigma},\ \textcolor{#4c5d80}{\sigma'} & \text{걸음 전과 뒤의 잡음 크기} \\ \textcolor{#4c5d80}{\sigma_{\mathrm{up}}},\ \textcolor{#4c5d80}{\sigma_{\mathrm{down}}} & \text{새로 섞는 잡음의 크기, 읽은 잡음을 남기는 크기} \\ \textcolor{#1b9e77}{\hat x_0},\ \textcolor{#1f6066}{\hat\varepsilon},\ \textcolor{#1f6066}{\varepsilon_{\mathrm{new}}} & \text{읽은 원래 그림, 읽은 잡음, 새로 뽑은 잡음} \end{array}

η = 0이면 σup = 0, σdown = σ′이라 x′ = x̂₀ + σ′ε̂, 곧 오일러 걸음이다. η = 1이면 앤세스트럴 걸음이다. 그 사이의 값은 읽은 잡음과 새 잡음을 섞는 비율을 정한다. 어느 η든 걸음 뒤의 잡음 크기는 σ′로 같다. 이 가족을 DDIM (같은 학습으로 새 잡음의 몫만 바꿔 걷는 샘플러 가족 / denoising diffusion implicit models)이라 하고, 흔히 η = 0인 결정적 걸음을 가리켜 DDIM이라고 한다.

같은 두 봉우리 데이터에서 η를 돌려 보자. 8걸음이면 골짜기 비율이 η = 0에서 5.9%, 0.5에서 5.7%, 1에서 3.9%이고, 봉우리 폭은 0.349, 0.342, 0.292다. 200걸음이면 골짜기 비율이 0.8%, 0.6%, 0.7%, 폭이 0.300, 0.298, 0.295로 셋 다 데이터(0.8%, 0.302)에 붙는다. 걸음이 넉넉하면 다이얼은 결과의 분포를 거의 바꾸지 않고, 걸음이 적을 때만 차이가 드러난다.

직접 움직여 보기η 다이얼새 창에서 열기 ↗

ML에서: ComfyUI 의 「ddim」은 오일러다

ComfyUI 의 샘플러 메뉴에서 ddim 을 고르면 코드(comfy/samplers.py 의 sampler_object)는 euler 샘플러를 돌려준다. 잡음 크기 눈금에서 DDIM의 결정적 걸음과 오일러 걸음이 같은 식이기 때문이다. 또 euler_ancestral 과 dpm_2_ancestral 같은 앤세스트럴 샘플러들은 eta 라는 손잡이를 가지는데, 기본값 1이 앤세스트럴이고 0으로 내리면 새 잡음을 넣지 않는다. 잡음을 덜 넣는 쪽은 같은 출발 잡음이 같은 그림을 주므로, 두 출발 잡음 사이를 조금씩 옮겨 가며 그림이 매끄럽게 바뀌는 것을 볼 수 있다. DDIM 논문이 「잠재 공간에서 의미 있는 그림 보간」을 내세운 까닭이다.

문제 6. 물려받은 흔들림과 새 흔들림

출근 시간이 날마다 흔들린다. 오늘 흔들림의 표준편차가 10분인데, 내일은 6분으로 맞추고 싶다. 내일의 흔들림은 오늘 흔들림을 a배로 물려받은 몫과, 오늘과 상관없이 새로 생기는 흔들림 c분을 더한 것이다(서로 상관없는 흔들림은 분산이 더해진다). (가) 새 흔들림이 없다면 a는 얼마인가? (나) a = 0.36이면 c는 얼마여야 하는가? (다) 두 경우 모두 내일의 흔들림은 6분인데, 무엇이 다른가?

김민준 M01
김민준

(가)는 10a = 6이니까 a = 0.6이요. (나)는 3.6분 물려받으니까 6 − 3.6 = 2.4분이요.

이서연 S06
이서연

잠깐, 그러면 3.6 + 2.4로 6이 되는데, 서로 상관없는 흔들림이면 그렇게 더하면 안 되잖아.

선생님 T01
선생님

분산으로 적어 봐요.

김민준 M04
김민준

아, 3.6² + c² = 36이어야 하니까 c² = 36 − 12.96 = 23.04, c = 4.8분이에요.

이서연 S01
이서연

(다)는 내일의 흔들림 크기는 같은데, 오늘 늦은 사람이 내일도 늦을지가 달라. (가)는 오늘 10분 늦은 사람이 내일 정확히 6분 늦고, (나)는 3.6분만 물려받고 나머지는 새로 굴린 운이야.

선생님 T13
선생님

잡음 크기 10에서 6으로 가는 디퓨전 한 걸음도 같은 계산이에요. (가)는 η = 0, (나)는 η = 1이에요. σdown = 36/10 = 3.6, σup = 4.8이죠.

김민준 M01
김민준

분산 다이얼이네요. 반 평균 점수 퍼짐을 맞추면서 지난 시험 성적을 얼마나 반영할지 고르는 것처럼요.

문제 7. DDPM 의 눈금에서 본 DDIM

DDPM의 일정(β 10⁻⁴ → 0.02, 1000걸음)에서 걸음 500은 원래 그림이 남는 비율 α = 0.2803, 잡음 크기 σ = 0.9599이고, 걸음 250은 α = 0.7239, σ = 0.6899다. 이 일정은 그림을 줄이며 잡음을 섞는다(xt = αtx₀ + σtε). 걸음 500의 자리 xt = 0.5에서 신경망이 x̂₀ = 0.8을 읽었다. (가) 읽은 잡음 ε̂과, 걸음 250으로 가는 DDIM(η = 0) 걸음 x′ = α′x̂₀ + σ′ε̂을 구하라. (나) 양변을 α로 나눈 눈금(y = x/α, 잡음 크기 σ/α)에서 오일러 한 걸음을 가고 다시 α′를 곱하면 같은 값이 나오는가?

이서연 S01
이서연

(가)는 ε̂ = (0.5 − 0.2803 × 0.8)/0.9599 = 0.2873이고, x′ = 0.7239 × 0.8 + 0.6899 × 0.2873 = 0.7773이에요.

김민준 M01
김민준

(나)는 y = 0.5/0.2803 = 1.7836, 잡음 크기는 3.4241에서 0.9529로 가요. 오일러 걸음은 y + (0.9529 − 3.4241)(y − 0.8)/3.4241 = 1.0737이고, 0.7239를 곱하면… 0.7773이에요. 똑같네요.

선생님 T01
선생님

우연일까요?

이서연 S08
이서연

아니에요. 나눈 눈금에서 오일러 걸음은 x̂₀ + (다음 잡음 크기)·ε̂였잖아요. 거기에 α′를 곱하면 α′x̂₀ + α′(σ′/α′)ε̂ = α′x̂₀ + σ′ε̂, 바로 DDIM 식이에요. 원래 그림과 잡음을 읽고 다음 수준의 비율로 다시 섞는다는 건 눈금을 어떻게 잡든 같은 일이에요.

선생님 T13
선생님

그래서 그림 생성 도구는 모든 모델을 σ/α 눈금 하나로 바꿔 두고 같은 샘플러를 써요.

이서연 S01
이서연

선형대수에서 좌표를 바꿔도 같은 일차변환은 같은 일을 한다는 것과 같네요.

문제 8. 다이얼은 언제 중요한가

데이터가 ±2에 봉우리를 둔 두 봉우리(표준편차 0.5, 반반)다. 골짜기를 |x| < 1로 잡으면 데이터의 골짜기 비율은 2.2%, 봉우리 폭(|x|의 표준편차)은 0.499다. (가) 6걸음으로 η = 0, 0.5, 1을 걸으면 골짜기 비율과 봉우리 폭은 어떻게 되는가? (나) 100걸음이면? (다) 결과를 보고 「어느 η가 가장 좋다」고 말할 수 있는가? (위젯 2의 「문제 8 불러오기」로 시작해 걸음 수를 바꿔 보자.)

김민준 M01
김민준

6걸음은 골짜기 15.0%, 14.5%, 12.9%, 폭 0.576, 0.566, 0.513이에요. η = 1이 골짜기도 제일 비고 폭도 데이터에 제일 가까워요. 앤세스트럴이 이기네요.

이서연 S01
이서연

100걸음은 골짜기 2.8%, 2.5%, 2.3%, 폭 0.507, 0.498, 0.489야. 차이가 확 줄었어.

선생님 T01
선생님

그럼 걸음이 아주 많으면요?

이서연 S08
이서연

셋 다 같은 분포로 가야 해요. 다이얼은 같은 분포를 지나는 길 가운데 하나를 고르는 거니까요. 걸음이 적을 때 생기는 어긋남의 모양만 다이얼마다 달라요. η = 0은 넓게 퍼지는 쪽으로, η = 1은 봉우리로 뭉치는 쪽으로 어긋나요.

선생님 T14
선생님

이 데이터에서는 6걸음에 η = 1이 나아 보였지만, 앞의 두 봉우리 ±1.5에서는 η = 1이 봉우리를 데이터보다 좁게 뭉쳤어요. 어느 쪽 어긋남이 덜 나쁜지는 데이터와 걸음 수에 따라 달라요.

김민준 M01
김민준

그래서 메뉴에 둘 다 있고, 사람들이 그림을 보고 고르는 거군요. 조교님이 채점 기준은 하나여도 과제마다 감점 방식이 다르다고 하신 게 생각나요.