SD의 체크포인트를 보면 저렇게 EMA 라는 것이 있는 놈이 있는데,

예전부터 좀 궁금했단 말이지.


찾아보던 도중 아래의 영상을 찾있음.

https://youtu.be/lAq96T8FkTw

엔드류 응 교수의 강의를 찾았고 설명이 명쾌해서 이해하기 좋았음.



그런데 드는 의문은 "이 개념을 SD에 적용한다고 했을 때 어떻게 적용이 되는가?"였음.

단적으로 말하자면 지수가중평균은 보다 최근의 데이터에 웨이트를 더 둔 것으로 결과물을 도출한다는 것인데,

실제로 SD에서 Diffusers로 변환하는 스크립트를 보면

In this conversion only the non-EMA weights are extracted. If you want to instead extract the EMA
weights (usually better for inference), please make sure to add the `--extract_ema` flag.

라고 돼있음.

Inference에 더 좋다는 데, 나는 아래와 같이 생각했음.


===

EMA는 최근의 데이터라는 보다 좁은 데이터 간격을 활용해 데이터를 도출하는데,

EMA가 SD에 적용된다면, 다음과 같이 적용 될 것이다.

Model을 학습할 때 1만스텝을 학습했다고 가정하고, 임의의 값을 가지는 β를 적용해 V_theta를 계산하여

최근 N스텝에 웨이트를 더 주게 한다.


최근 N스텝에 대해 가중치를 더 준다면 이전 스텝의 가중치는 지수적으로 감소하게 된다.

따라서 EMA는 모델의 과적합을 일정 부분 억제하며 보다 학습에 충실한 결과를 도출할 수 있게 작용한다.


EMA가 없다는 것은 각 스텝마다 웨이트를 갱신해 온 상태 그대로 있다는 것이고 이는 Fine Tuning에 적합하다.

그렇다면 일반적으로 full이라는 단어가 붙는 체크포인트는 일반 웨이트 및 EMA의 웨이트를 동시에 갖고 있고,

따라서 보다 큰 용량을 가진다.

===


라고 생각해도 되는건가?


다른 의문은

NAI 유출 체크포인트의 경우 일반적인 스크립트로 Diffusers로 변환하기 위해선 코드의 수정이 필요한데,

["state_dict"]를 삭제하는 부분과 

text_model = convert_ldm_clip_checkpoint(checkpoint) 이 부분을

CLIPTextModel.from_pretrained("openai/clip-vit-large-patch14") 이렇게 고치는 부분이었음.


내가 실제로 유출 모델을 EMA와 Non EMA로 따로 뽑아보려고 시도했는데,

뽑힌 두 결과를 바이너리로 비교했음에도 불구 차이가 단 하나도 없었음.

이게 유출 모델이 이미 state_dict여서 그런 것인지,

위의 코드를 수정한 것이 원인 중의 하나라고 봐도 되는 것인지 모르겠음.



난 머신러닝 말고 다른 전공이라 이쪽은 잘 모름.

혹시 전공자가 있다면 답을 주면 정말 고맙겠음...