AI 이미지/SD Video

AnimateDiff for AUTOMATIC1111

하늘이푸른오늘 2024. 2. 13. 22:07

요즘 Stable Diffusion 커뮤니티의 핫한 주제는 Video-to-Video입니다. 그 가운데에는 AnimateDiff 가 있죠. 저도 몇번 생성해봤지만, 아직도 잘 모르는 게 많아, 천천히 알아보려는 중입니다. 이 글은 그중에서 첫 시도로,  https://github.com/continue-revolution/sd-webui-animatediff 을 번역한 글입니다.

===

이 확장은 AnimateDiffCLI(프롬프트 트래블)AUTOMATIC1111 Stable Diffusion WebUIControlNet에 통합하는 것이 목표이다. 이 확장을 사용하면, txt2img로 이미지를 생성하는 것과 똑같은 방식으로 GIF를 생성할 수 있다. 

이 확장은 AnimateDiff를 다른 방식으로 구현한다. 전체 SD.15 저장소를 복제(clone)할 필요 없다. 또한 ldm에 최소한도로 수정했기 때문에, 원치 않을 경우 모델 가중치를 다시 불러올 필요는 없다.

사용방법

  1. AUTOMATIC1111을 v1.6.0 으로, ControlNet을 v1.1.410으로 업데이트한 후, 이 확장을 설치하라. 나는 예전 버전을 지원할 계획이 없다.
  2. 모션 모듈을  stable-diffusion-webui/extensions/sd-webui-animatediff/model 폴더에 다울로드 받는다. 모델 가중치를 다른 폴더에 넣고 싶다면 Settings/AnimateDiff 를 방문하라. 사용가능한 모델은 Model zoo 에 있다.
  3. Settings/Optimization에서 "Pad prompt/negative prompt to be same length"를 활성화시키고 [Apply settings]를 클릭하라. 이렇게 해야만 관련없는 두개의 별도의 GIF 생성을 막을 수 있다. "Batch cond/uncod"의 체크 여부는 선택으로, 선택하면 속도가 빨라지지만 VRAM 사용량이 늘어난다. 
  4. hash 계산을 비활성화시키지 말라. 아니면 모션 모듈을 바꿀 때 AnimateDiff 가 파악하는데 문제가 말생한다.????

WebUI

  1. txt2gif 를 원한다면 txt2img 페이지로, img2gif를 원한다면 img2img로 들어간다.
  2. SD1.5 체크포인트 모델을 선택하고, 프롬프트를 작성하고 이미지 크기 등을 설정한다. 여러장의 GIF를 한꺼번에 생성할 경우, batch size가 아닌 batch number를 증가시켜야 한다.
  3. AnimateDiff 확장을 활성화시킨 후 매개변수를 설정하고 [Generate] 버튼을 누른다.
  4. 생성 결과는 output 폴더 내에 있는 ../AnimateDiff/{yy-mm-dd}에 생성된다. 생성되는 각각의 프레임을 어디에 저장할지는 Settings/AnimateDiff에서 설정할 수 있다.

WebUI 매개변수

  1. Save Format - 결과물 포맷. "GIF|MP4|WebP|WebM|PNG"중의 하나로 선택한다. "TXT"를 선택하면 infotext가 output 폴에 저장된다. infotext는 stable-diffusion-webui/params.txt를 통해서도 접근가능하며, 모든 포맷으로 출력된다.
    1. gifsicle(apt install gifsicle이 필요함. #91을 읽어볼 것) 및/또는 palette(#104를 읽어볼 것)를 이용하면 GIF를 최적화 시킬 수 있다. 이들을 설치한 후, Settings/AnimateDiff에서 활성화시켜야 한다.
    2. Settings/AnimateDiff에서 WebP 의 품질 및 무손실여부를 설정할 수 있다. #233을 읽어보라.
    3. API를 사용할 경우, "format"에 "PNG"을 추가하면, 모든 프레임을 반환하는 대신 자신의 컴퓨터에 모든 프레임을 저장할 수 있다. API가 모든 프레임을 반환하도록 하려면, "format" 리스트에 "Frame"을 추가하라.
  2. Number of frames - 원하는 대로 입력 가능
    • 0 을 입력할경우(기본값)
      • "Video Source"를 통해 비디오를 넣거나, "Video path"를 통해 비디오를 지정하거나, batch ControlNet을 활성화시켰을 경우, 프레임의 수는 해당 비디오의 프레임수로 자동 설정된다.(여러 비디오가 제출된 경우 제일 짧은 것)
      • 그렇지 않다면 아래에서 설명하는 "Context batch size"와 동일한 값으로 설정된다.
    • 0이 아니고 "Context batch size"보다 작은 값을 입력했을 경우,  해당 값 만큼 프레임이 생성된다. 나머지 프레임은 생성된 GIF에는 들어가지 않지만, 평상시처럼 PNG로 저장된다. "Context batch size"보다 작은 값으로는 설정하지 말라(#213 참조)
  3. FPS - 초당 프레임수. "Number of frames"=16이고 "FPS"=8이면 2초짜리  GIF가 생성된다. 비디오 소스 제공하였을 경우, FPS는 비디오 소스와 동일해 진다.
  4. Display loop number - GIF가 반복되는 횟수. 0으로 설정하면 무한 반복된다.
  5. Context batch size - 한번에 모션 모듈을 통과하는 프레임의 수. SD1.5 모션 모듈은 16 프레임으로 학습되었기 때문에 프레임 수가 15일때 가장 최고의 결과를 얻을 수 있다. SDXL HotShotXL 모션 모듈은 8 프레임으로 학습되었다. V1 / HotShotXL 모션 모듈은 [1,24]로 선택하고, V2 /AnimateDiffXL 모션 모듈의 경우 [1,32]로 선택하라.
  6. Closed loop - 이 확장은 첫 프레임과 마지막 프레임을 동일하게 만들려고 시도한다.
    1. 일반론 
      • "Number of frames" 가 "Context batch size"보다 큰 경우, 또한 ControlNet이 활성화되고 소스 비디오 프레임수가 "Context batch size"보다 크고 "Number of frames" = 0 인 경우, closed loop는 AnimateDiff의 infinite context generator가 수행한다.
      • "Number of frames" 가 "Context batch size"보다 작은 경우, AnimateDiff의 infinate context generator 는 효과적이지 않다. "A"를 선택할 경우에만 AnimateDiff가 생성된 프레임을 뒤집어 붙이는 방법으로 closed loop를 형성한다.
    2. 각각의 선택은 아래와 같다.
      • "N"은 절대로 closed loop를 형성하지 않는다. 이는 "Number of frames" 가 "Context batch size" 보다 작고 0이 아닌 때에만 적용가능한 옵션이다.
      • "R-P"는 이 확장이 closed loop context의 수를 줄이려고 시도한다는 뜻이다. 프롬프트 트래블의 경우, 내삽으로 closed loop를 형성하지는 않는다.
      • "R+P"는 이 확장이 closed loop context의 수를 줄이려고 시도한다는 뜻이다. 프롬프트 트래블의 경우, 내삽으로 closed loop를 형성한다.
      • "A"는 이 확장이 공격적으로 마지막 프레임을 첫 프레임과 같게 만들려고 시도한다는 뜻이다. 프롬프트 트래블의 경우, 내삽으로 closed loop를 형성한다.
  7. Stride - 최대 모션 폭?? (2의 배수. 기본 값은 1)
    1. infinate context generator의 한계로 인해, 이 매개변수는 "Number of frames"가 "Context batch size"보다 클 때만, 그리고 ControlNet이 활성되고 소스 비디오의 프레임 수가 "Context batch size"보다 크고 "Number of frames"가 0일 경우에만 효과가 있다. 
    2. "Stride" = 1일 경우에만 "Closed loop"의 "No closed loop"가 가능하다.
    3. "Stride" >= 2**i  >= 1 에 대하여, infinate context generator 는 2**i개의 프레임을 분할하여 시간적 일관성을 유지하려 시도한다. 예를 들어 "Stride"=4 이고 "Number of frames"=8이라면,  다음 프레임들을 시간적으로 일관성있게 만든다.
      • "Stride"==1 -> [0, 1, 2, 3, 4, 5, 6, 7]
      • "Stride"==2 -> [0, 2, 4, 6], [1, 3, 5, 7]
      • "Stride"==4 -> [0, 4], [1,5], [2,6], [3,7]
  8. Overlap - 콘텍스트상에서 중첩되는 프레임의 수."overlap" == -1 (기본 값)일 경우, "Context batch size" // 4가 된다.
    1. infinate context generator의 한계로 인해, 이 매개변수는 "Number of frames"가 "Context batch size"보다 클 때만, 그리고 ControlNet이 활성되고 소스 비디오의 프레임 수가 "Context batch size"보다 크고 "Number of frames"가 0일 경우에만 효과가 있다. 
  9. Frame Interpolation - Deforum의 FILM 내삽법으로 프레임 사이를 내삽한다. Deforum 확장이 필요하다. #128 참조
  10. Interp X - 각 입력 프레임을 X 내삽된 출력 프레임으로 대체한다. #128 참조
  11. Video source (선택) - ControlNet v2v를 위한 소스 비디오 파일. 사용하려면 반드시 ControlNet을 활성화해야 한다. ControlNet 영역에 별도로 콘트롤넷 이미지나 경로를 넣지 않아도, 모든 ControlNet 단위가 이를 소스로 사용하게 된다. 만일 "Single Image" 탭에 하나의 이미지를 넣거나, "Batch"탭에 폴더를 지정할 경우, 이 비디오 소스는 무시되고 평상시처럼 작동하게 된다.
  12. Video path(선택) - ControlNet v2v를 위한 소스 프레임이 포함된 폴더. "Video Source"보다 우선순위가 낮다. 사용하려면 반드시 ControlNet을 활성화해야 한다. ControlNet 영역에 별도로 콘트롤넷 이미지나 경로를 넣지 않아도, 모든 ControlNet 단위가 이를 소스로 사용하게 된다. 만일 "Single Image" 탭에 하나의 이미지를 넣거나, "Batch"탭에 폴더를 지정할 경우, 이 비디오 소스는 무시되고 평상시처럼 작동하게 된다.
    • 비디오를 인페인트하고자 하는 경우: 지정하는 폴더 내에 "image" 및 "mask" 하위폴더가 있어야 한다. 이 두개의 폴더는 동일한 갯수의 이미지가 들어 있어야 한다. 이 확장은 이들 이미지를 동일한 순서로 매칭하여 사용한다. 좀더 편하게 사용하려면 Segment Anything 확장을 사용하라. 

더 읽어볼 글

Img2GIF

img2img 페이지에 들어가 첫 프레임을 제출해야 한다. 필요하다면 마지막 프레임을 extension 패널에 제출한다. 

기본으로, init_latent 는 다음과 같이 변경된다.

init_alpha = (1 - frame_number ^ latent_power / latent_scale)
init_latent = init_latent * init_alpha + random_tensor * (1 - init_alpha)

마지막 프레임을 업로드 했을 경우, init_latent도 비슷하게 변경된다. 어떻게 작동되는지는 이 코드를 읽어보라.

프롬프트 트래블(Prompt Travel)

아래 예제를 참고로 긍정적 프롬프트를 작성하라.

첫번째 줄은 head 프롬프트로서(선택), 없어도 되고 여러줄로 작성해도 된다.

두번째와 세번째 줄은 프롬프트 내삽을 위한 줄로서, "frame number : number" 포맷을 따라야 한다. "frame number"는 오름차순이어야 하며, 총 "Number of frames보다 작아야 한다. 첫번째 프레임의 번호는 0이다.

마지막 줄은 tail 프롬프트로서(선택) , 없어도 되고 여러줄로 작성해도 된다. 

1girl, yoimiya (genshin impact), origen, line, comet, wink, Masterpiece, BestQuality. UltraDetailed, <lora:LineLine2D:0.7>,  <lora:yoimiya:0.8>, 
0: closed mouth
8: open mouth
smile

ControlNet V2V

txt2img / img2img-batch로 가서 비디오 소스나 프레임이 포함된 폴더를 지정해야 한다. 각각의 콘트롤넷이 Contorl 이미지를 찾는 우선순위는 아래와 같다.

  1. ControlNet "Single image" 탭 또는 "Batch" 탭. 
  2. Img2img 의 Batch 탭에서 "Input directory" 로 지정
  3. AnimateDiff의 "Video Source"
  4. AnimateDiff의 "Video Path"

"Number of frames"는 제공된 모든 폴더들에 있는이미지중 최소 이미지수가 된다. 각각의 폴더에 있는 각 제어 이미지가 하나의 프레임에 적용된다. ControlNet 영역에 하나의 이미지를 업로드 하면, 해당 이미지가 모든 프레임을 제어한다.

비디오를 인페인트하고자 하는 경우: 지정하는 폴더 내에 "image" 및 "mask" 하위폴더가 있어야 한다. 이 두개의 폴더는 동일한 갯수의 이미지가 들어 있어야 한다. 이 확장은 이들 이미지를 동일한 순서로 매칭하여 사용한다. 좀더 편하게 사용하려면 Segment Anything 확장을 사용하라. 

img2img batch에 대한 AnimateDiff는 v1.10.0에 사용하게 될 것이다.

모델 사양

모션 LoRA

모션 LoRA 는 여기에서 다운받을 수 있으며, 일반적인 LoRA와 동일한 방법으로 사용할 수 있다. (예: 모션 LoRA를 stable-diffusion-webui/models/lora에 다운로드 받은후, 프롬프트에 <lora:mm_sd15_v2_lora_PanLeft:0.8>을 추가한다) 모션 LoRA는 v2 모션 모듈만 지원한다.

V3

V3는 V1과 동일한 상태 dict 키를 가지지만, 추론 논리는 약간 다르다(V3 는 GroupNorm 는 을 해킹하지 않음??) V3의 경우 선택적으로 LoRA와 동일한 방식으로 adapter 를 사용할 수 있다. 반드시 공식 링크 대신 이 링크를 사용해야 한다. 공식 어댑터는 상태 dict 키가 호환되지 않아 A1111에서 작동하지 않기 때문이다.

SDXL

AnimateDiffXLHotShot-XL 은 AnimateDiff SD1.5와 아키텍처가 동일하다. 다만 아래의 2가지 차이가 있다.

  • HotShot-XL는 16프레임이 아닌 8 프레임으로 학습되었다. HotShot-XL 의 경우 "Context batch size"를 8로 설정하는 것을 추천한다.
  • AnimateDiffXL은 16 프레임으로 학습되었다. 따라서 "Context batch size"를 변경할 필요가 없다.
  • AnimateDiffXL 과 HotShot-XL 은 AnimateDiff SD1.5에 비해 레어어가 작다. 이는 SDXL 때문이다.
  • AnimateDiffXL 은 HotShot-XL 에 비해 높은 해상도로 학습되었다.

AnimateDiffXL 과 HotShot-XL 이 AnimateDiff SD1.5와 아키텍처가 동일하더라도, SDXL에 AnimateDiff SD1.5를 사용하거나, AnimateDiffXL 과 HotShot-XL 을 SD1.5에 사용하는 것은 추천하지 않는다. 심한 결함이 발생할 것이다. 이는 어렵지는 않더라도 지원할 계획이 없다.

기술적으로 AnimateDiff + SD1.5 의 기능은 모두 (AnimateDiff / HotShot) + SDXL 에도 사용가능하다. 하지만, 모두 시험해 보지는 않았다. infinite context generation과 프롬프트 트래블에 대해선 시험해 보았으나, ControlNet은 시험하지 않았다. 버그를 발견하면 알려달라.

최적화

속도를 올리고 VRAM 사용량을 줄이려면, 최적화가 매우 도움이 될 수 있다. 교차인지 최적화, FP8 을 적용하고, AUTOMATIC1111 의 Settings/Optimization에서 Batch cond/uncod의 체크를 꺼버리면, 18GB VRAM 기기로, 4 x ControlNet + AnimateDiff + Stable Diffusion으로 1024*1024 이미지 36프레임을 생성할 수 있었다.

교차인지(Attention)

시작 명령줄에 "--xformers / --opt-sdp-attention"을 추가하면 VRAM 사용량이 상당히 줄고 속도가 향상된다. 하지만 xformer에 버그가 있어서 CURA에러를 만날 가능성이 있다. 따라서 명령줄에서 --xformers를 삭제할 것을 추천한다. 또는 남기려면 Settings/AnimateDiff 에서 "Optimize attention layers wid sdp (torch >= 2.0.0 required)"를 선택하라.

FP8

FP8은 torch >= 2.1.0 이 필요하며, @KohakuBlueleaf님의 test-fp8 branch를 사용해야 한다. 아래 단계를 따라하면 FP8을 적용할 수 있다.

  • stable-diffusion-webui 폴더에서 "get check test-fp8" 을 실행시키면 "test-fp8"  branch 로 바꿀 수 있다.
  • 명령줄에 단 한번만 --reinstall-torch 를 추가하여 torch를 다시 설치한다.
  • Settings 페이지에 들어가 Optimization-> FP8 가중치를 "Enable"로 바꾼다.

LCM

Latent Consistency Model은 최근 Stable Diffusion 분야의 획기적인 발전이다. 나는 이 확장을 v1.12.1이상으로 갱신하는 모든 분들께 선물을 드린다.. 이제 WebUI에서 샘플러를 선택하는 곳에서 LCM 샘플러가 추가되어 있을 것이다. 또한 다음 조건하에서 이미지나 비디오를 6-8 단계만에 생성할 수 있다.

  • "Euler A / Euler / LCM" 샘플러를 선택하라(다른 샘플러도 작동할 수 있지만, 시험이 필요하다).
  • LCM LoRA 를 사용하라.
  • 잡음 제거 강도(denoising strength)를 낮게(1~2)로 설정하라.

참고로 LCM 샘플러는 아직 실험중이며, @luosiallen의 바램에 따라 변경될 수 있다.

sd-webui-lcm 대신 이 확장을 사용하는 장점은 아래와 같다.

  • diffuser를 설치할 필요가 없다.
  • ControlNet이나 AnimateDiff 같은 다른 확장에도 LCM 샘플러를 사용할 수 있다. 

기타

  • --no-half와 같이 VRAM을 무겁게하는 인수는 제거하라. 이 인수를 사용하면 VRAM 사용이 상당히 늘어나고 속도가 줄어든다.
  • "Settings/Optimization"에서 "Batch cond/uncond"를 체크하면 속도가 향상된다. 체크를 끄면 VRAM 사용량이 줄어든다.

Model Zoo

나는 fp16 및 safetensor 포맷으로 모든 공식 모델을 제공하기 위해 huggingface repo를 유지중이다. 이 링크를 사용하기를 적극적으로 추천핟나. 특히 V3를 위한 어댑터는 이 링크를 이용해야 한다. 원한다면 V3 어댑터를 제외하고 예전 링크를 사용해도 된다.

VRAM

실제 VRAM 사용량은 이미지 크기와 context batch size에 의존한다. VRMA 사용량을 줄이려면 이미지 크기와 context batch size를 줄이도록 시도하라.

아래의 데이터는 Ubuntu 22.04, NVIDIA 4090, torch 2.0.1+cu117  인 기기에서 , 이미지크기 512x512, 16 프레임(기본 값)으로  SD1.5 + AnimateDiff 를 시험한 것이다. w/ w/o 은 Settings/Optimization에서 "Batch cond/uncond"를 체크/언체크 함을 의미한다. 

Optimization VRAM w/ VRAM w/0
No Optimization 12.13 GB  
xformers/sdp 5.60 GB 4.21 GB
sub-quadratic 10.39 GB  

SDXL + HotShot + SDP의 경우, 같은 환경으로 테스트했을 때 8.66 GB의 VRAM이 필요하였다.

SDXL + AnimateDiff + SDP의 경우, 동일한 환경으로 테스트했을 때 13.97 GB의 VRAM이 필요하였다.

Batch Size

WebUI에서 Batch size는 내부적으로 GIF 프레임 수로 대체되었다. 1 batch에 하나의 완전한 GIF가 생성된다. 여러개의 GIF를 한꺼번에 생성하고 싶다면 Batch size 대신 Batch number를 사용하라. 이 확장을 사용할 때에는 batch size를 변경시킬 필요가 없다. 

 

이상입니다. 이 글은 https://github.com/continue-revolution/sd-webui-animatediff 을 번역한 글입니다.

민, 푸른하늘

====