https://github.com/lllyasviel/ControlNet/blob/main/docs/train.md
ControlNet/docs/train.md at main · lllyasviel/ControlNet
Let us control diffusion models! Contribute to lllyasviel/ControlNet development by creating an account on GitHub.
github.com
ControlNet을 학습시켜보자. 이 문서에 잘 나와있긴하지만, 몇가지 디버깅했던 내용을 포함해서 적어보려한다.
ControlNet은 github, huggingface 모두 다 올라와있는데, github에는 코드 중심으로, huggingface에는 데이터 중심으로 나와있어서 서로 다르다.
하지만 모든 코드는 git이 base이기때문에 git clone을 하고 시작하는 것을 추천한다.
git clone https://github.com/lllyasviel/ControlNet.git
1. Dataset Download하기
데이터셋의 경우 ControlNet Huggingface에 zip 파일이 올라와있다.
terminal 상에서
wget "https://huggingface.co/lllyasviel/ControlNet/resolve/main/training/fill50k.zip"
을 하여 다운받을 수 있다.
그리고 zip파일이므로 압축을 풀어준다.
unzip training/fill50k
그러면 다음과 같이 압축이 풀린 데이터들이 나온다.

2. Dataset Load하기
이제 다운받은 데이터셋을 load해야한다.
https://github.com/lllyasviel/ControlNet/blob/main/tutorial_dataset.py
ControlNet/tutorial_dataset.py at main · lllyasviel/ControlNet
Let us control diffusion models! Contribute to lllyasviel/ControlNet development by creating an account on GitHub.
github.com
이 tutorial_dataset.py는 앞서 다운받은 fill50k 폴더 안에 있는 prompt.json파일에서 데이터 정보를 읽어와서,
각 아이템을 jpg(타겟이미지), txt(프롬프트), hint(소스이미지)를 포함하는 딕셔너리 형태로 반환하는 역할을 한다.
ControlNet은 소스이미지를 입력으로 사용하고 텍스트 프롬프트(txt)를 조건으로 사용하여 타겟이미지(jpg)를 생성하는 것을 목표로 삼아 학습한다. 여기서 왜 타겟이미지가 jpg라고 불리고, 소스이미지가 hint라고 불리는지는 그냥 convention인듯싶다. 아무이유없는 것 같다. (왜냐하면 이 데이터셋에서는 이미지가 png이다.)
아무튼
이 tutorial_dataset.py가 정의된 상황에서
https://github.com/lllyasviel/ControlNet/blob/main/tutorial_dataset_test.py
ControlNet/tutorial_dataset_test.py at main · lllyasviel/ControlNet
Let us control diffusion models! Contribute to lllyasviel/ControlNet development by creating an account on GitHub.
github.com
tutorial_dataset_test.py 코드를 다음과 같이 실행시키면
python tutorial_dataset_test.py
아래와 같은 output을 확인할 수 있다.
50000
burly wood circle with orange background
(512, 512, 3)
(512, 512, 3)
이 결과가 나왔으면 dataset은 잘 로드가 되는 상태가 되었네, 하고 넘어가면 된다.
3. ControlNet을 어떤 StableDiffusion 모델에 연결할지 결정
다들 잘 알다싶이, ControlNet은 Stable Diffusion 모델과 연결하고, 그 Stable Diffusion model의 parameter를 copy한 상태에서 학습을 시작한다. Stable Diffusion Model이 버전이 여러개가 있으니, 어떤 것을 사용할지 정해야한다.
이 Stable Diffusion Model의 가중치는 아래의 HuggingFace에서 가져올 수 있다.
https://huggingface.co/runwayml/stable-diffusion-v1-5/tree/main
runwayml/stable-diffusion-v1-5 at main
stable-diffusion-diffusers
huggingface.co
나의 경우 v1-5-pruned.ckpt를 가지고 왔다.
wget "https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned.ckpt"
꽤 용량이 크다. 내 경우 7.7GB가 필요했다. 아무튼, 이 가중치 파일을 models폴더에 넣어놓고 ControlNet을 Stabld Diffusion model
에 연결하는 스크립트를 실행해야한다.
tool_add_control.py 는 https://github.com/lllyasviel/ControlNet/blob/main/tool_add_control.py 에서 찾을 수 있다.
스크립트 내용은
'cldm_v15.yaml' 설정 파일을 사용하여 ControlNet 모델을 생성하고, 입력 경로에서 사전 학습된 가중치를 로드하고,
새 모델의 구조에 맞게 사전 학습된 가중치를 매핑한다.
'control_'로 시작하는 레이어는 'model.diffusion_'으로 시작하는 가중치와 매핑된다. 매핑되지 않은 새 가중치는 초기화된 상태로 유지되며 출력된다. 매핑된 가중치를 새 모델에 적용한다. 최종 모델의 상태를 지정된 출력 경로에 저장하는 스크립트이다.
python tool_add_control.py ./models/v1-5-pruned.ckpt ./models/control_sd15_ini.ckpt
이를 실행하면, 다음과 같은 에러가 뜰 것이다.
File "/local_data_2/home/ControlNet/ldm/models/diffusion/ddpm.py", line 20, in <module>
from pytorch_lightning.utilities.distributed import rank_zero_only
ModuleNotFoundError: No module named 'pytorch_lightning.utilities.distributed
PyTorch Lightning의 특정 모듈을 찾을 수 없다는 말인데, PyTorch Lightning의 버전 차이때문에 나타나는 오류일듯하다.
이는 https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/11458
[Bug]: ModuleNotFoundError: No module named 'pytorch_lightning.utilities.distributed' · Issue #11458 · AUTOMATIC1111/stable-di
Is there an existing issue for this? I have searched the existing issues and checked the recent builds/commits What happened? Launching Web UI with arguments: --share --disable-safe-unpickle --no-h...
github.com
이 이슈의 도움을 받아 해결할 수 있는데, 간략하게 말하면
'ldm/models/diffusion/ddpm.py' 파일에서 import를 해오는 부분인 20번째 줄에서 'pytorch_lightning.utilities.distributed'를 'pytorch_lightning.utilities.rank_zero'로 변경하면 해결된다. 아래와 같이 20번째 줄이 적혀있으면 그 에러는 생기지 않는다.

그러면 다시, 앞서 설명했던
python tool_add_control.py ./models/v1-5-pruned.ckpt ./models/control_sd15_ini.ckpt
를 실행시키면 되겠다. 정상적으로 실행이 된다.


ControlNet 모델을 초기화하고 가중치를 로드하는 과정을 볼 수 있다. ControlNet의 새로운 구성 요소들로 기존
모델에 없던 새로운 가중치 레이어가 추가되는 모습을 볼 수 있다. 이 추가된 가중치들은 ControlNet의 구성요소인 Control model의 일부이다.
Zero Convolution의 weight와 bias, 그리고 input_hint_block과 middle_block_out의 가중치 레이어가 추가되었음을 알 수 있다.
1) 처음에 추가된 logvar은 variational inference에 사용되는 로그 분산 파라미터로 모델의 불확실성을 조절하는데 사용될 수 있다.
2) Zero Convolution은 처음부터 너무 control에 해당하는 부분이 급격하게 학습되는 것을 막기위한 합성곱 레이어이다.
3) Input_hint_block은 제어입력을 처리하는 초기 블록이다. 여러개의 합성곱 레이어로 구성되어있으며 입력된 hint를 모델이 사용할 수 있는 형태로 변환한다.
4) Middle_block_out은 ControlNet의 중간 처리 단계에서 사용되는 출력 블록으로 처리된 제어신호를 Stable Diffusion의 중간 레이어와 통합하는 역할을 한다.
이를 마치면 앞서 작성했던 ./models/control_sd15_ini.ckpt 으로
Stable Diffusion과 ControlNet이 통합된 전체 모델의 가중치가 포함된 체크포인트 파일이 저장된다.
4. 학습시키기
이제 학습시킬 수 있는 상태가 되었다.
https://github.com/lllyasviel/ControlNet/blob/main/tutorial_train.py
ControlNet/tutorial_train.py at main · lllyasviel/ControlNet
Let us control diffusion models! Contribute to lllyasviel/ControlNet development by creating an account on GitHub.
github.com
이 파일을 실행시키면 된다. 사실 이 파일을 실행시키려면 cldm.model 이나 cldm.logger 파일등이 필요하겠지만 맨 처음에 git clone했을때 잘 복사해왔을거라 가정하고 진행하겠다.
python tutorial_train.py
이렇게 훈련을 시키면 또 다음과 같은 에러가 뜰 것이다.
ModuleNotFoundError: No module named 'pytorch_lightning.utilities.distributed'
그러면 또 저 에러가 난 파일에 들어가서 (내 경우, cldm/logger.py", line 8 였음.)

'pytorch_lightning.utilities.distributed'를 'pytorch_lightning.utilities.rank_zero'로 변경하면 해결이 된다.
그런데 또 에러가 난다.
TypeError: LatentDiffusion.on_train_batch_start() missing 1 required positional argument: 'dataloader_idx'
이 오류는 PyTorch Lightning의 최신 버전과 LatentDiffusion 클래스의 on_train_batch_start 메서드 정의 사이의 불일치로 인해 발생한듯 한데,
https://github.com/lllyasviel/ControlNet/issues/84
colab error, pytorch lighting trainer · Issue #84 · lllyasviel/ControlNet
I tried to do pix2pix training scripts on google colab, but I met the following error and I could not start training... TypeError: on_train_batch_start() missing 1 required positional argument: 'da...
github.com
이 이슈를 참고하면 문제가 해결된다. 이또한 간략하게 말하자면 ldm/models/diffusion/ddpm.py 의 591번째 on_train_batch_start 함수 정의부분에 가서 dataloader_idx부분을 삭제해주고, cldm/logger.py의 74번째 on_train_batch_end 함수 정의 부분에 가서도 dataloader_idx 부분을 삭제해주면 에러는 해결될 것이다.
하지만 마지막 에러가 남았다.
TypeError: Trainer.__init__() got an unexpected keyword argument 'gpus'
코드가 나온 직후에 많은 업데이터가 되었겠거니.. 라는 마음을 가지고
tutorial_train.py의 29번째 줄을 다음과 같이 변경해준다.
Before
trainer = pl.Trainer(gpus=1, precision=32, callbacks=[logger])
After
trainer = pl.Trainer(accelerator="gpu", devices=1,precision=32, callbacks=[logger])
이렇게 바꿔서 실행하면, 학습이 진행된다.

총 1.4B 개의 파라미터 중 1.2B 개가 학습 가능한 것 같다.
+) 마지막 에러
ImportError: cannot import name 'get_full_repo_name' from 'huggingface_hub'
이 에러는
https://github.com/comfyanonymous/ComfyUI/issues/2055
ImportError: cannot import name 'get_full_repo_name' from 'huggingface_hub' · Issue #2055 · comfyanonymous/ComfyUI
Total VRAM 6144 MB, total RAM 32509 MB Traceback (most recent call last): File "F:\ai\ComfyUI-master\comfy\model_management.py", line 218, in import accelerate File "C:\Users\Ryan\AppData\Local\Pro...
github.com
이 깃허브 이슈를 참고해서 conda install chardet 로 해결해줄 수 있었다.
'AI&ML > Lab' 카테고리의 다른 글
Mocking을 통해 Test Code 작성하기 (0) | 2024.10.05 |
---|---|
[Debug] 디버깅하느라 print해놨는데 어디에 해놓았는지 모르는 경우 (0) | 2024.07.21 |
[ML/DL] 소프트맥스 회귀/다항 로지스틱 회귀 (0) | 2023.12.26 |
[ML/DL] Entropy, CrossEntropy, KL divergence 개념 정리 (0) | 2023.09.10 |
[NLP] 라마(LLaMA) 정리 (0) | 2023.09.05 |
댓글