에필로그

처음부터 돌아보기

마지막 시간. 화면에는 ComfyUI 의 KSampler 마디가 떠 있다. 시드, 걸음 수, cfg, 샘플러 이름, 걸음 일정 이름, positive, negative, latent_image.

선생님 T01
선생님

마디를 짚기 전에 처음으로 돌아가 볼게요. 첫 시간에 무엇을 물었는지 기억나요? 손글씨 숫자를 97% 넘게 맞히는 MLP 에게 「3을 하나 그려 봐」라고 했죠.

김민준 M04
김민준

기억나요. 제곱 오차로 배우니까 3들의 평균이 나왔잖아요. 흐린 회색 3이요. 정답들의 평균은 아무도 그린 적 없는 3이었고요.

이서연 S01
이서연

그래서 그림 자신을 정답으로 삼는 오토인코더를 만들었는데, 가운데 칸이 어디에 놓일지 아무도 정하지 않아서 새 그림을 뽑을 자리가 없었어. VAE 는 그 칸을 구름으로 바꾸고 N(0, I) 쪽으로 당겨서 뽑을 자리를 만들었고.

선생님 T01
선생님

그 VAE 가 그린 그림은 어땠어요?

김민준 M01
김민준

여전히 흐릿했어요. 잠재 변수가 다 정하지 못한 것을 디코더가 칸마다 따로 동전을 던져서 메우는 수밖에 없었으니까요.

이서연 S02
이서연

그다음 생각이 재밌었어요. 인코더를 배우지 말고 잡음 섞기로 고정하자. 망가뜨리는 길은 우리가 정했으니 거꾸로 걷는 법만 배우면 된다. 그런데 퍼진 분포를 열 방정식 그대로 거꾸로 풀면 촘촘한 무늬가 e^(+Dk²t)배로 커져서 터졌죠.

선생님 T01
선생님

분포를 통째로 되돌리는 길이 막혔을 때, 무엇을 대신 알면 됐어요?

이서연 S01
이서연

레이더 바늘이요. 로그 밀도의 기울기, 스코어. 모든 잡음 수준의 바늘을 알면 점 하나하나를 바늘 쪽으로 옮겨서 돌아올 수 있었어요. 정규화 상수를 몰라도 읽히고요.

김민준 M01
김민준

문제는 그 바늘을 모른다는 거였는데, 그림에 잡음을 섞어 본 기록으로 배웠죠. 기록마다 떠나온 점 쪽 바늘을 정답으로 주면 제곱 오차의 답이 그 자리에 선 사람들의 평균이 되고, 그 평균이 진짜 바늘이었어요. 결국 섞은 잡음을 맞히는 것과 같은 일이고요.

선생님 T13
선생님

처음에 배운 ELBO 는 그 뒤로 어디서 다시 나왔죠?

이서연 S07
이서연

DDPM 의 손실이요. 잡음을 천 걸음에 나눠 섞는 사슬을 VAE 로 보면, 그림이 데이터고 나머지 사슬이 잠재 변수고, 인코더는 고정된 잡음 섞기예요. 그 ELBO 가 걸음마다의 잡음 맞히기 오차에 가중치를 붙인 합이 됐어요. 흐릿하다고 넘어간 모델의 바닥이 거기서 그대로 손실이 될 줄은 몰랐어요.

선생님 T01
선생님

신경망 쪽은요?

김민준 M01
김민준

그림 크기의 MLP 는 층 하나에 가중치가 수천억 개라서 이웃만 보는 합성곱으로 갔고, 이웃만 보니까 멀리 못 봐서 U-Net 으로 해상도를 낮췄고, 그래도 몫이 가운데에 몰려서 멀리 읽는 어텐션을 끼웠어요. Stable Diffusion 1.x 에서는 어텐션 블록이 매개변수의 31.1%였는데 SDXL 에서는 86.0%였죠. 계산이 너무 커서 잠재 공간으로 내려갔고, 끝에는 합성곱 단계를 다 걷어 내고 트랜스포머 블록만 쌓았어요.

선생님 T01
선생님

그동안 이론 쪽에서는 길을 어떻게 걸었어요?

이서연 S01
이서연

바늘을 따라 걸으며 바람을 맞는 길, 곧 걸음마다 잡음을 다시 넣는 역방향 SDE 와, 바람 없이 흐르는 확률 흐름 ODE 가 같은 분포를 지났어요. 그런데 그 길이 휘어 있어서, 처음부터 곧은 짝의 길로 속도를 통째로 배우는 플로우 매칭으로 넘어갔고요. 몇 걸음에 어떻게 걸을지는 그다음에 샘플러로 따로 정했어요.

선생님 T01
선생님

그럼 마디를 볼까요. 민준 학생이 칸을 하나씩 짚어 봐요.

김민준 M11
김민준

steps, sampler_name, scheduler 는 같은 길을 몇 걸음에, 어떤 걸음법으로, 어느 잡음 크기에 디디며 걸을지예요. cfg 가 1이 아니면 걸음마다 신경망을 두 번 불러요. 조건을 넣은 예측과 빈 조건의 예측을 읽어서 그 차이를 cfg 배로 키우는 거죠. 그리고 seed 는 출발점의 잡음이니까, seed 만 고정해 두면 걸음 수를 바꿔도 같은 그림이 나와요.

선생님 T14
선생님

sampler_name 이 euler_ancestral 이라면요? 시드는 그대로 두고 steps 만 20에서 30으로 바꾸면?

김민준 M04
김민준

앤세스트럴은 걸음마다 읽은 잡음을 덜어 내고 새 잡음으로 채우니까… 걸음 수가 바뀌면 새로 넣는 잡음도 달라지네요. 같은 시드에서도 다른 그림이 나와요. 출발점이 도착점을 정하는 건 잡음을 다시 넣지 않는 euler 같은 걸음일 때고요.

이서연 S01
이서연

그러니까 시드는 뽑을 잡음을 정할 뿐이고, 그 잡음을 몇 번 어디에 쓸지는 샘플러와 걸음 수가 정하는 거야.

김민준 M01
김민준

조교가 문제 은행 순서를 고정해 줘도, 몇 문제짜리 시험이냐에 따라 받는 문제가 달라지는 거랑 같네.

선생님 T01
선생님

서연 학생은 negative 칸을 볼까요.

이서연 S01
이서연

빈 조건 자리에 피할 글을 넣는 칸이에요. 그래서 cfg 가 1이면 아무 일도 하지 않아요. 그때는 빈 조건 쪽 예측을 아예 계산하지 않으니까요. positive 칸의 글은 글 인코더가 토큰마다의 벡터 줄로 바꿔서 크로스 어텐션이나 합동 어텐션으로 넣고요. 예전에는 CLIP 의 마지막 층이나 끝에서 둘째 층을 받았고, 요즘 모델은 언어모델의 여러 층을 쌓아 넘겨요.

선생님 T01
선생님

마지막으로 부록에서 한 일을 떠올려 봐요. 사람이 고른 그림 쌍으로 모델을 다듬으려면 그림의 로그확률이 있어야 했죠.

이서연 S06
이서연

그림의 로그확률은 잴 수 없으니까 ELBO 바닥으로 바꿨어요. 바닥은 언제나 천장 아래에 있으니까, 바닥끼리 견주면 어느 두 모델이든 괜찮은 거 아닌가요?

선생님 T01
선생님

바닥과 천장 사이의 틈은 그림마다 같았나요?

이서연 S08
이서연

아니요, 그림마다 크게 달랐어요. 그 틈이 지워진 건 마진의 「차이의 차이」에서였고, 같은 그림에서 두 모델의 틈이 비슷할 때만이에요. 같은 계열의, 너무 멀지 않은 두 모델이라는 단서가 있었어요. 적분 상수랑 같네요. 같은 함수의 원시함수끼리 빼야 상수가 지워지지, 다른 함수의 원시함수끼리 빼면 남잖아요.

선생님 T13
선생님

흐린 회색 3 한 장에서 시작해서 여기까지 왔네요. 그런데 이 마디의 칸을 다 짚을 수 있게 됐다고 해서 물음이 다 끝난 건 아니에요.