見出し画像

WSL2でAnimateDiff MotionDirectorを試してみる

「追加のトレーニングを必要とせずに、ほとんどのコミュニティモデルをアニメーションジェネレーターに変換するプラグ&プレイモジュール」らしいAnimateDiff MotionDirector (DiffDirector)を試してみます。


追記 2024/2/11 
scripts/animate.py を使用して動画生成できることが分かったので、4章を追記。追加で必要となるモデルファイルがあるので、「ダウンロード」にもその点を追記。


追記 2024/2/12
この記事では環境構築と学習までを書いています。作成した学習データ(LoRA)を用いて「試して」みた結果は、以下の記事を参照ください。


使用するPCはドスパラさんの「GALLERIA UL9C-R49」。スペックは
・CPU: Intel® Core™ i9-13900HX Processor
・Mem: 64 GB
・GPU: NVIDIA® GeForce RTX™ 4090 Laptop GPU(16GB)
・GPU: NVIDIA® GeForce RTX™ 4090 (24GB)
・OS: Ubuntu22.04 on WSL2(Windows 11)
です。


1. 準備

環境構築

git clone https://github.com/ExponentialML/AnimateDiff-MotionDirector

パッケージのインストール

pip install -r requirements.txt
pip install accelerate

ここでもgradioのRow問題が発生するので、

pip uninstall -y gradio
pip install gradio==3.41.2

としておきます。

ダウンロード

Stable Diffusion v1.5をクローンします。

git lfs install
git clone https://huggingface.co/runwayml/stable-diffusion-v1-5 models/StableDiffusion

ダウンロードが終わったら、symbolic linkを張ります。これは、学習時にカレントディレクトリからの相対位置でファイルを読み込もうとしているためです。

mkdir runwayml 
cd $_
ln -sf ../models/StableDiffusion/stable-diffusion-v1-5 .
cd ..

つづいて、V3 Motion Moduleです。
v3で始まるもの全部ダウンロードしておきます。

git lfs install
wget https://huggingface.co/guoyww/animatediff/resolve/main/v3_sd15_mm.ckpt
#
mkdir models/SparseCtrl
wget -P models/Motion_Module https://huggingface.co/guoyww/animatediff/resolve/main/v3_sd15_adapter.ckpt
wget -P models/SparseCtrl https://huggingface.co/guoyww/animatediff/resolve/main/v3_sd15_sparsectrl_rgb.ckpt
wget -P models/SparseCtrl https://huggingface.co/guoyww/animatediff/resolve/main/v3_sd15_sparsectrl_scribble.ckpt

v3_sd15_mm.ckptだけ、カレントディレクトリに配置します。学習時、ここにないとファイルが見つからないと怒られるためです。

推論向けにsymbolic link張っておきます。

cd models/Motion_Module
ln -sf ../../v3_sd15_mm.ckpt .
cd ../..

なにかいろいろと間違えている気もしますが。
「きちんとディレクトリ設計をして実装してよ」と言いたくなりますが、そんなところに注力する前に本体を動かさないとならぬのだぁ、だと思いますからつべこべ言わない。わたしも極力.pyは直したくないので、lnコマンドですべてお茶を濁しています。

あと、scripts/animate.pyによる動画生成を試す際、その設定ファイルに

dreambooth_path:   "models/DreamBooth_LoRA/realisticVisionV51_v51VAE.safetensors

とあるため、以下のダウンロードスクリプトを実行しておきます。

bash download_bashscripts/5-RealisticVision.sh

なのてすが、ダウンロードされるファイル名はrealisticVisionV51_v51VAE.safetensorsではなく、realisticVisionV60B1_v51VAE.safetensorsのため、後ほど設定ファイルを編集します…。

2. 試してみる - 学習

学習してからでないと推論が試せないので、学習からためします。

設定ファイルの修正

学習の前に設定ファイルの修正です。提供されているconfigs/training/motion_director/my_video.yaml のままだとHFにリポジトリが無い(404)となるため、以下のように修正します。

--- a/configs/training/motion_director/my_video.yaml
+++ b/configs/training/motion_director/my_video.yaml
@@ -1,5 +1,5 @@
 # Model From Huggingface Diffusers
-pretrained_model_path: "diffusers/stable-diffusion-v1-5"
+pretrained_model_path: "runwayml/stable-diffusion-v1-5"

 # Model in CKPT format. This is the CKPT that you download from CivitAI or use in A111 Comfy, etc.
 # In most cases, leave this blank.

そうなんですよ。ここでHugging Faceからダウンロードするならば、git cloneでダウンロードではなくて、そのキャッシュ使えばええやんと思いましたが後の祭りです。(末尾の「おまけ」参照)

学習開始

学習するデータは、examplesディレクトリにあるmp4ファイルです。
別の学習データ(LoRA)を作成したい場合は、動画ファイルを差し替えればよいだけです。

$ ls -al examples/
total 21960
drwxr-xr-x  2 user user     4096 Feb  9 19:47  .
drwxr-xr-x 14 user user     4096 Feb 11 13:20  ..
-rw-r--r--  1 user user 22477729 Feb  9 19:47 'pexels-cottonbro-5319934 (2160p).mp4'
$

では実行。

time python train.py --config ./configs/training/motion_director/my_video.yaml

リソース状況

メモリは10.3GBほど使用しています。

2つGPUがあるので、学習に要した時間を比較します。
・RTX 4090(24GB) : 12分37秒(757秒)
・RTX 4090 Laptop GPU(16GB) : 16分24秒(984秒)
でした。timeコマンドの結果は以下です。

# RTX 4090(24GB)
real    12m37.511s
user    14m10.067s
sys     2m49.928s

# RTX 4090 Laptop GPU(16GB) 
real    16m24.452s
user    16m56.994s
sys     5m16.735s

生成されたファイルの確認

$ find outputs/2024-02-10/man_running_my_video-13-59-57/ -type f -ls | sort -k 11
136577051    388 -rw-r--r--   1 user user    395864 Feb 10 14:00 outputs/2024-02-10/man_running_my_video-13-59-57/cached_latents/cached_0.pt
136577049      4 -rw-r--r--   1 user user      2732 Feb 10 13:59 outputs/2024-02-10/man_running_my_video-13-59-57/config.yaml
136577060  99796 -rw-r--r--   1 user user 102190584 Feb 10 14:03 outputs/2024-02-10/man_running_my_video-13-59-57/lora/spatial/100_man_running_spatial_unet.safetensors
136577069  99796 -rw-r--r--   1 user user 102190584 Feb 10 14:06 outputs/2024-02-10/man_running_my_video-13-59-57/lora/spatial/200_man_running_spatial_unet.safetensors
136577088  99796 -rw-r--r--   1 user user 102190584 Feb 10 14:09 outputs/2024-02-10/man_running_my_video-13-59-57/lora/spatial/300_man_running_spatial_unet.safetensors
136577094  99796 -rw-r--r--   1 user user 102190584 Feb 10 14:12 outputs/2024-02-10/man_running_my_video-13-59-57/lora/spatial/400_man_running_spatial_unet.safetensors
136577101  99796 -rw-r--r--   1 user user 102190584 Feb 10 14:15 outputs/2024-02-10/man_running_my_video-13-59-57/lora/spatial/500_man_running_spatial_unet.safetensors
136577062 132076 -rw-r--r--   1 user user 135244472 Feb 10 14:03 outputs/2024-02-10/man_running_my_video-13-59-57/lora/temporal/100_man_running_temporal_unet.safetensors
136577070 132076 -rw-r--r--   1 user user 135244472 Feb 10 14:06 outputs/2024-02-10/man_running_my_video-13-59-57/lora/temporal/200_man_running_temporal_unet.safetensors
136577089 132076 -rw-r--r--   1 user user 135244472 Feb 10 14:09 outputs/2024-02-10/man_running_my_video-13-59-57/lora/temporal/300_man_running_temporal_unet.safetensors
136577095 132076 -rw-r--r--   1 user user 135244472 Feb 10 14:12 outputs/2024-02-10/man_running_my_video-13-59-57/lora/temporal/400_man_running_temporal_unet.safetensors
136577102 132076 -rw-r--r--   1 user user 135244472 Feb 10 14:15 outputs/2024-02-10/man_running_my_video-13-59-57/lora/temporal/500_man_running_temporal_unet.safetensors
136577065   1856 -rw-r--r--   1 user user   1898841 Feb 10 14:03 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-100.gif
136577064   1856 -rw-r--r--   1 user user   1898841 Feb 10 14:03 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-100/0.gif
136577068   1860 -rw-r--r--   1 user user   1903648 Feb 10 14:05 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-150.gif
136577067   1860 -rw-r--r--   1 user user   1903648 Feb 10 14:05 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-150/0.gif
136577055   1716 -rw-r--r--   1 user user   1755224 Feb 10 14:00 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-2.gif
136577054   1716 -rw-r--r--   1 user user   1755224 Feb 10 14:00 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-2/0.gif
136577073   1864 -rw-r--r--   1 user user   1908106 Feb 10 14:06 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-200.gif
136577072   1864 -rw-r--r--   1 user user   1908106 Feb 10 14:06 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-200/0.gif
136577081   1880 -rw-r--r--   1 user user   1922375 Feb 10 14:08 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-250.gif
136577080   1880 -rw-r--r--   1 user user   1922375 Feb 10 14:08 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-250/0.gif
136577090   2028 -rw-r--r--   1 user user   2074933 Feb 10 14:09 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-300.gif
136708098   2028 -rw-r--r--   1 user user   2074933 Feb 10 14:09 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-300/0.gif
136577092   1880 -rw-r--r--   1 user user   1922975 Feb 10 14:11 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-350.gif
136708106   1880 -rw-r--r--   1 user user   1922975 Feb 10 14:11 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-350/0.gif
136577097   1956 -rw-r--r--   1 user user   2000959 Feb 10 14:13 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-400.gif
136708112   1956 -rw-r--r--   1 user user   2000959 Feb 10 14:13 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-400/0.gif
136577099   1888 -rw-r--r--   1 user user   1930434 Feb 10 14:14 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-450.gif
136708118   1888 -rw-r--r--   1 user user   1930434 Feb 10 14:14 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-450/0.gif
136577058   1948 -rw-r--r--   1 user user   1990779 Feb 10 14:02 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-50.gif
136577057   1948 -rw-r--r--   1 user user   1990779 Feb 10 14:02 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-50/0.gif
136577103   2008 -rw-r--r--   1 user user   2053715 Feb 10 14:16 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-500.gif
136708122   2008 -rw-r--r--   1 user user   2053715 Feb 10 14:16 outputs/2024-02-10/man_running_my_video-13-59-57/samples/sample-500/0.gif
136577052    112 -rw-r--r--   1 user user    111986 Feb 10 14:00 outputs/2024-02-10/man_running_my_video-13-59-57/sanity_check/0_a-man-is-running-on-a-bridge.mp4

sampleの下にある画像を覗いてみましょう。学習を重ねると賢くなっていくのが分かりますね。

sampleフォルダ下にある画像ファイルたち

sample 500はこちら。学習時の評価プロンプトは、

a highly realistic video of batman running in a mystic forest, depth of field, epic lights, high quality, trending on artstation

a highly realistic video of batman running in a mystic forest, depth of field, epic lights, high quality, trending on artstation

バットマン…。腕と足に模様がある所ぐらい?

さて、次の推論(Gradioで)では、ここで生成された2つのLoRA(spatialとtemporal)を使用することになります。

$ ls -Rl outputs/2024-02-10/man_running_my_video-13-59-57/lora/*
outputs/2024-02-10/man_running_my_video-13-59-57/lora/spatial:
total 498980
-rw-r--r-- 1 user user 102190584 Feb 10 14:03 100_man_running_spatial_unet.safetensors
-rw-r--r-- 1 user user 102190584 Feb 10 14:06 200_man_running_spatial_unet.safetensors
-rw-r--r-- 1 user user 102190584 Feb 10 14:09 300_man_running_spatial_unet.safetensors
-rw-r--r-- 1 user user 102190584 Feb 10 14:12 400_man_running_spatial_unet.safetensors
-rw-r--r-- 1 user user 102190584 Feb 10 14:15 500_man_running_spatial_unet.safetensors

outputs/2024-02-10/man_running_my_video-13-59-57/lora/temporal:
total 660380
-rw-r--r-- 1 user user 135244472 Feb 10 14:03 100_man_running_temporal_unet.safetensors
-rw-r--r-- 1 user user 135244472 Feb 10 14:06 200_man_running_temporal_unet.safetensors
-rw-r--r-- 1 user user 135244472 Feb 10 14:09 300_man_running_temporal_unet.safetensors
-rw-r--r-- 1 user user 135244472 Feb 10 14:12 400_man_running_temporal_unet.safetensors
-rw-r--r-- 1 user user 135244472 Feb 10 14:15 500_man_running_temporal_unet.safetensors

3. 推論 - gradio(app.py)

gradioを使って、アレコレ試しましょう。と言いたいところですが、上手く動きませんでした

設定ファイル

app.py内では、configs/inference/inference.yaml が参照されていますが、

$ ls -l configs/inference/
total 16
-rw-r--r-- 1 user user  770 Feb  9 19:47 inference-v1.yaml
-rw-r--r-- 1 user user  806 Feb  9 19:47 inference-v2.yaml
-rw-r--r-- 1 user user  717 Feb  9 19:47 inference-v3.yaml
drwxr-xr-x 2 user user 4096 Feb 10 14:38 sparsectrl

そのようなファイルは存在しないので修正します。v3ですから、v3へ。

--- a/app.py
+++ b/app.py
@@ -66,7 +66,7 @@ class AnimateController:
         self.pipeline              = None
         self.lora_model_state_dict = {}

-        self.inference_config      = OmegaConf.load("configs/inference/inference.yaml")
+        self.inference_config      = OmegaConf.load("configs/inference/inference-v3.yaml")

     def refresh_stable_diffusion(self):
         self.stable_diffusion_list = glob(os.path.join(self.stable_diffusion_dir, "*/"))

LoRAの配置

学習で生成されたLoRAをmodels/DreamBooth_LoRAに配置します。
ディスクがもったいないので、symbolic linkにしています。

cd models/DreamBooth_LoRA
ln -sf ../../outputs/2024-02-10/man_running_my_video-13-59-57/lora/spatial/* .
ln -sf ../../outputs/2024-02-10/man_running_my_video-13-59-57/lora/temporal/* .
cd ..

実行

やっと実行できます。

 python app.py

起動しました。

ベースモデルのロード、モーションモジュールのロードはOK。

だがしかし、LoRAの指定でエラー発生

コンソールに出力されたエラーログはこちら。

Traceback (most recent call last):
  File "/mnt/data/user/venv/animatediff/lib/python3.10/site-packages/gradio/routes.py", line 488, in run_predict
    output = await app.get_blocks().process_api(
  File "/mnt/data/user/venv/animatediff/lib/python3.10/site-packages/gradio/blocks.py", line 1431, in process_api
    result = await self.call_function(
  File "/mnt/data/user/venv/animatediff/lib/python3.10/site-packages/gradio/blocks.py", line 1103, in call_function
    prediction = await anyio.to_thread.run_sync(
  File "/mnt/data/user/venv/animatediff/lib/python3.10/site-packages/anyio/to_thread.py", line 56, in run_sync
    return await get_async_backend().run_sync_in_worker_thread(
  File "/mnt/data/user/venv/animatediff/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 2134, in run_sync_in_worker_thread
    return await future
  File "/mnt/data/user/venv/animatediff/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 851, in run
    result = context.run(func, *args)
  File "/mnt/data/user/venv/animatediff/lib/python3.10/site-packages/gradio/utils.py", line 707, in wrapper
    response = f(*args, **kwargs)
  File "/mnt/data/user/venv/animatediff/AnimateDiff-MotionDirector/app.py", line 111, in update_base_model
    converted_vae_checkpoint = convert_ldm_vae_checkpoint(base_model_state_dict, self.vae.config)
  File "/mnt/data/user/venv/animatediff/AnimateDiff-MotionDirector/animatediff/utils/convert_from_ckpt.py", line 570, in convert_ldm_vae_checkpoint
    new_checkpoint["encoder.conv_in.weight"] = vae_state_dict["encoder.conv_in.weight"]
KeyError: 'encoder.conv_in.weight'

KeyError: 'encoder.conv_in.weight' らしく。学習データがおかしいのかしら。でも手順通りなんですよねぇ。

4. 推論 - scripts/animate.py

animate.pyを読む

READMEに触れられていなかったので気づきませんでしたが、コマンドラインから動画生成できる.pyファイルがありました。

$ python -m scripts.animate
usage: animate.py [-h] [--pretrained-model-path PRETRAINED_MODEL_PATH] [--inference-config INFERENCE_CONFIG] --config
                  CONFIG [--L L] [--W W] [--H H] [--without-xformers]
animate.py: error: the following arguments are required: --config
$

よくわからないので、ソースを読みます。

  • --pretrained-model-path : デフォルトパスは「models/StableDiffusion/stable-diffusion-v1-5」。このままでよい。

  • --inference-config : 推論時の設定。デフォルトは 「configs/inference/inference-v1.yaml」なので、v3と指定する必要あり。

  • --config : 読み解くに config/prompts/v3/ にある設定ファイルらしい。知らんがな。

  • --L : ビデオの長さ。デフォルトは 16

  • --W : 幅。デフォルトは 512

  • --H : 高さ。デフォルトは 512

取り急ぎ、scripts/animate.py内のデフォルト値をv3に変更しておきます。

--- a/scripts/animate.py
+++ b/scripts/animate.py
@@ -182,7 +182,7 @@ def main(args):
 if __name__ == "__main__":
     parser = argparse.ArgumentParser()
     parser.add_argument("--pretrained-model-path", type=str, default="models/StableDiffusion/stable-diffusion-v1-5",)
-    parser.add_argument("--inference-config",      type=str, default="configs/inference/inference-v1.yaml")
+    parser.add_argument("--inference-config",      type=str, default="configs/inference/inference-v3.yaml")
     parser.add_argument("--config",                type=str, required=True)

     parser.add_argument("--L", type=int, default=16 )

configファイルを確認すると、サンプルファイルが3つありました。

$ ls -l configs/promp
ts/v3/
total 12
-rw-r--r-- 1 user user 3456 Feb  9 19:47 v3-1-T2V.yaml
-rw-r--r-- 1 user user 2258 Feb 11 01:17 v3-2-animation-RealisticVision.yaml
-rw-r--r-- 1 user user 1885 Feb 11 01:40 v3-3-sketch-RealisticVision.yaml

こちらダウンロードの節でも説明したとおり、修正が必要です。

--- a/configs/prompts/v3/v3-2-animation-RealisticVision.yaml
+++ b/configs/prompts/v3/v3-2-animation-RealisticVision.yaml
@@ -1,7 +1,7 @@
 # animation-1
 - domain_lora_scale: 1.0
   adapter_lora_path: "models/Motion_Module/v3_sd15_adapter.ckpt"
-  dreambooth_path:   "models/DreamBooth_LoRA/realisticVisionV51_v51VAE.safetensors"
+  dreambooth_path:   "models/DreamBooth_LoRA/realisticVisionV60B1_v51VAE.safetensors"

   inference_config: "configs/inference/inference-v3.yaml"
   motion_module:    "models/Motion_Module/v3_sd15_mm.ckpt"
@@ -27,7 +27,7 @@
 # animation-2
 - domain_lora_scale: 1.0
   adapter_lora_path: "models/Motion_Module/v3_sd15_adapter.ckpt"
-  dreambooth_path:   "models/DreamBooth_LoRA/realisticVisionV51_v51VAE.safetensors"
+  dreambooth_path:   "models/DreamBooth_LoRA/realisticVisionV60B1_v51VAE.safetensors"

   inference_config: "configs/inference/inference-v3.yaml"
   motion_module:    "models/Motion_Module/v3_sd15_mm.ckpt"
diff --git a/configs/prompts/v3/v3-3-sketch-RealisticVision.yaml b/configs/prompts/v3/v3-3-sketch-RealisticVision.yaml
index 5de4d2e..ce12fc4 100644
--- a/configs/prompts/v3/v3-3-sketch-RealisticVision.yaml
+++ b/configs/prompts/v3/v3-3-sketch-RealisticVision.yaml
@@ -1,7 +1,7 @@
 # 1-sketch-to-video
 - domain_lora_scale: 1.0
   adapter_lora_path: "models/Motion_Module/v3_sd15_adapter.ckpt"
-  dreambooth_path:    "models/DreamBooth_LoRA/realisticVisionV51_v51VAE.safetensors"
+  dreambooth_path:    "models/DreamBooth_LoRA/realisticVisionV60B1_v51VAE.safetensors"

   inference_config: "configs/inference/inference-v3.yaml"
   motion_module:    "models/Motion_Module/v3_sd15_mm.ckpt"
@@ -27,7 +27,7 @@
 # 2-storyboarding
 - domain_lora_scale: 1.0
   adapter_lora_path: "models/Motion_Module/v3_sd15_adapter.ckpt"
-  dreambooth_path:    "models/DreamBooth_LoRA/realisticVisionV51_v51VAE.safetensors"
+  dreambooth_path:    "models/DreamBooth_LoRA/realisticVisionV60B1_v51VAE.safetensors"

   inference_config: "configs/inference/inference-v3.yaml"
   motion_module:    "models/Motion_Module/v3_sd15_mm.ckpt"

実行と結果

それぞれ実行しましょう。

python -m scripts.animate --config v3-1-T2V.yaml
#
python -m scripts.animate --config v3-2-animation-RealisticVision.yaml
#
python -m scripts.animate --config v3-3-sketch-RealisticVision.yaml

生成されたファイルは、samplesディレクトリの配下に出力されています。

v3-1-T2V.yaml
v3-2-animation-RealisticVision.yaml
v3-3-sketch-RealisticVision.yaml

うーん、学習させたデータを使いたいのだがしかし。

まとめ

・学習
VRAMは10.3GBほど使用、学習に要した時間は、設定ファイルのデフォルト値のままだと、
・RTX 4090(24GB) : 12分37秒(757秒)
・RTX 4090 Laptop GPU(16GB) : 16分24秒(984秒)
でした。

・推論
Gradioアプリ(app.py)を使用して学習で生成したLoRAを読み込もうとするとエラーになりました。後日改めて試してみます。

おまけ

HF経由でsd15をダウンロードしてそれを流用する場合は、pythonを起動して以下を流し込み、

from huggingface_hub import snapshot_download

REPO_ID = "runwayml/stable-diffusion-v1-5"
snapshot_download(repo_id=REPO_ID, revision="main")

推論向け(Gradio向け)に、

cd models/StableDiffusion
ln -s ~/.cache/huggingface/hub/models--runwayml--stable-diffusion-v1-5/snapshots/1d0c4ebf6ff58a5caecab40fa1406526bca4b5b9 stable-diffusion-v1-5
cd ../..

学習向けは変わらず、

mkdir runwayml 
cd $_
ln -sf ../models/StableDiffusion/stable-diffusion-v1-5 .
cd ..

でよいです。

この記事が気に入ったらサポートをしてみませんか?