diff --git a/README.md b/README.md
index 6b8067b..ff097bf 100644
--- a/README.md
+++ b/README.md
@@ -1,235 +1,248 @@
-# AnimateDiff
-
-This repository is the official implementation of [AnimateDiff](https://arxiv.org/abs/2307.04725).
-
-**[AnimateDiff: Animate Your Personalized Text-to-Image Diffusion Models without Specific Tuning](https://arxiv.org/abs/2307.04725)**
-
-Yuwei Guo,
-Ceyuan Yang*,
-Anyi Rao,
-Yaohui Wang,
-Yu Qiao,
-Dahua Lin,
-Bo Dai
-
-
*Corresponding Author
-
-[Arxiv Report](https://arxiv.org/abs/2307.04725) | [Project Page](https://animatediff.github.io/)
-
-## Todo
-- [x] Code Release
-- [x] Arxiv Report
-- [x] GPU Memory Optimization
-- [ ] Gradio Interface
-
-
-
-## Common Issues
-
-Installation
-Please ensure the installation of [xformer](https://github.com/facebookresearch/xformers) that is applied to reduce the inference memory.
-
-
-
-Various resolution or number of frames
-Currently, we recommend users to generate animation with 16 frames and 512 resolution that are aligned with our training settings. Notably, various resolution/frames may affect the quality more or less.
-
-
-
-Animating a given image
-We totally agree that animating a given image is an appealing feature, which we would try to support officially in future. For now, you may enjoy other efforts from the [talesofai](https://github.com/talesofai/AnimateDiff).
-
-
-
-Contributions from community
-Contributions are always welcome!! We will create another branch which community could contribute to. As for the main branch, we would like to align it with the original technical report:)
-
-
-
-
-## Setup for Inference
-
-### Prepare Environment
-~~Our approach takes around 60 GB GPU memory to inference. NVIDIA A100 is recommanded.~~
-
-***We updated our inference code with xformers and a sequential decoding trick. Now AnimateDiff takes only ~12GB VRAM to inference, and run on a single RTX3090 !!***
-
-```
-git clone https://github.com/guoyww/AnimateDiff.git
-cd AnimateDiff
-
-conda env create -f environment.yaml
-conda activate animatediff
-```
-
-### Download Base T2I & Motion Module Checkpoints
-We provide two versions of our Motion Module, which are trained on stable-diffusion-v1-4 and finetuned on v1-5 seperately.
-It's recommanded to try both of them for best results.
-```
-git lfs install
-git clone https://huggingface.co/runwayml/stable-diffusion-v1-5 models/StableDiffusion/
-
-bash download_bashscripts/0-MotionModule.sh
-```
-You may also directly download the motion module checkpoints from [Google Drive](https://drive.google.com/drive/folders/1EqLC65eR1-W-sGD0Im7fkED6c8GkiNFI?usp=sharing), then put them in `models/Motion_Module/` folder.
-
-### Prepare Personalize T2I
-Here we provide inference configs for 6 demo T2I on CivitAI.
-You may run the following bash scripts to download these checkpoints.
-```
-bash download_bashscripts/1-ToonYou.sh
-bash download_bashscripts/2-Lyriel.sh
-bash download_bashscripts/3-RcnzCartoon.sh
-bash download_bashscripts/4-MajicMix.sh
-bash download_bashscripts/5-RealisticVision.sh
-bash download_bashscripts/6-Tusun.sh
-bash download_bashscripts/7-FilmVelvia.sh
-bash download_bashscripts/8-GhibliBackground.sh
-```
-
-### Inference
-After downloading the above peronalized T2I checkpoints, run the following commands to generate animations. The results will automatically be saved to `samples/` folder.
-```
-python -m scripts.animate --config configs/prompts/1-ToonYou.yaml
-python -m scripts.animate --config configs/prompts/2-Lyriel.yaml
-python -m scripts.animate --config configs/prompts/3-RcnzCartoon.yaml
-python -m scripts.animate --config configs/prompts/4-MajicMix.yaml
-python -m scripts.animate --config configs/prompts/5-RealisticVision.yaml
-python -m scripts.animate --config configs/prompts/6-Tusun.yaml
-python -m scripts.animate --config configs/prompts/7-FilmVelvia.yaml
-python -m scripts.animate --config configs/prompts/8-GhibliBackground.yaml
-```
-
-To generate animations with a new DreamBooth/LoRA model, you may create a new config `.yaml` file in the following format:
-```
-NewModel:
- path: "[path to your DreamBooth/LoRA model .safetensors file]"
- base: "[path to LoRA base model .safetensors file, leave it empty string if not needed]"
-
- motion_module:
- - "models/Motion_Module/mm_sd_v14.ckpt"
- - "models/Motion_Module/mm_sd_v15.ckpt"
-
- steps: 25
- guidance_scale: 7.5
-
- prompt:
- - "[positive prompt]"
-
- n_prompt:
- - "[negative prompt]"
-```
-Then run the following commands:
-```
-python -m scripts.animate --config [path to the config file]
-```
-
-## Gallery
-Here we demonstrate several best results we found in our experiments.
-
-
-Model:ToonYou
-
-
-Model:Counterfeit V3.0
-
-
-Model:Realistic Vision V2.0
-
-
-Model: majicMIX Realistic
-
-
-Model:RCNZ Cartoon
-
-
-Model:FilmVelvia
-
-#### Community Cases
-Here are some samples contributed by the community artists. Create a Pull Request if you would like to show your results here😚.
-
-
-
-Character Model:Yoimiya
-(with an initial reference image, see WIP fork for the extended implementation.)
-
-
-
-
-Character Model:Paimon;
-Pose Model:Hold Sign
-
-## BibTeX
-```
-@article{guo2023animatediff,
- title={AnimateDiff: Animate Your Personalized Text-to-Image Diffusion Models without Specific Tuning},
- author={Guo, Yuwei and Yang, Ceyuan and Rao, Anyi and Wang, Yaohui and Qiao, Yu and Lin, Dahua and Dai, Bo},
- journal={arXiv preprint arXiv:2307.04725},
- year={2023}
-}
-```
-
-## Contact Us
-**Yuwei Guo**: [guoyuwei@pjlab.org.cn](mailto:guoyuwei@pjlab.org.cn)
-**Ceyuan Yang**: [yangceyuan@pjlab.org.cn](mailto:yangceyuan@pjlab.org.cn)
-**Bo Dai**: [daibo@pjlab.org.cn](mailto:daibo@pjlab.org.cn)
-
-## Acknowledgements
+# AnimateDiff
+
+This repository is the official implementation of [AnimateDiff](https://arxiv.org/abs/2307.04725).
+
+**[AnimateDiff: Animate Your Personalized Text-to-Image Diffusion Models without Specific Tuning](https://arxiv.org/abs/2307.04725)**
+
+Yuwei Guo,
+Ceyuan Yang*,
+Anyi Rao,
+Yaohui Wang,
+Yu Qiao,
+Dahua Lin,
+Bo Dai
+
+*Corresponding Author
+
+[Arxiv Report](https://arxiv.org/abs/2307.04725) | [Project Page](https://animatediff.github.io/)
+
+## Todo
+- [x] Code Release
+- [x] Arxiv Report
+- [x] GPU Memory Optimization
+- [ ] Gradio Interface
+
+
+
+## Common Issues
+
+Installation
+Please ensure the installation of [xformer](https://github.com/facebookresearch/xformers) that is applied to reduce the inference memory.
+
+
+
+Various resolution or number of frames
+Currently, we recommend users to generate animation with 16 frames and 512 resolution that are aligned with our training settings. Notably, various resolution/frames may affect the quality more or less.
+
+
+
+Animating a given image
+We totally agree that animating a given image is an appealing feature, which we would try to support officially in future. For now, you may enjoy other efforts from the [talesofai](https://github.com/talesofai/AnimateDiff).
+
+
+
+Contributions from community
+Contributions are always welcome!! We will create another branch which community could contribute to. As for the main branch, we would like to align it with the original technical report:)
+
+
+
+
+## Setup for Inference
+
+### Prepare Environment
+~~Our approach takes around 60 GB GPU memory to inference. NVIDIA A100 is recommanded.~~
+
+***We updated our inference code with xformers and a sequential decoding trick. Now AnimateDiff takes only ~12GB VRAM to inference, and run on a single RTX3090 !!***
+
+```
+git clone https://github.com/guoyww/AnimateDiff.git
+cd AnimateDiff
+
+conda env create -f environment.yaml
+conda activate animatediff
+```
+
+### Download Base T2I & Motion Module Checkpoints
+We provide two versions of our Motion Module, which are trained on stable-diffusion-v1-4 and finetuned on v1-5 seperately.
+It's recommanded to try both of them for best results.
+```
+git lfs install
+git clone https://huggingface.co/runwayml/stable-diffusion-v1-5 models/StableDiffusion/
+
+bash download_bashscripts/0-MotionModule.sh
+```
+You may also directly download the motion module checkpoints from [Google Drive](https://drive.google.com/drive/folders/1EqLC65eR1-W-sGD0Im7fkED6c8GkiNFI?usp=sharing), then put them in `models/Motion_Module/` folder.
+
+### Prepare Personalize T2I
+Here we provide inference configs for 6 demo T2I on CivitAI.
+You may run the following bash scripts to download these checkpoints.
+```
+bash download_bashscripts/1-ToonYou.sh
+bash download_bashscripts/2-Lyriel.sh
+bash download_bashscripts/3-RcnzCartoon.sh
+bash download_bashscripts/4-MajicMix.sh
+bash download_bashscripts/5-RealisticVision.sh
+bash download_bashscripts/6-Tusun.sh
+bash download_bashscripts/7-FilmVelvia.sh
+bash download_bashscripts/8-GhibliBackground.sh
+```
+
+### Inference
+After downloading the above peronalized T2I checkpoints, run the following commands to generate animations. The results will automatically be saved to `samples/` folder.
+```
+python -m scripts.animate --config configs/prompts/1-ToonYou.yaml
+python -m scripts.animate --config configs/prompts/2-Lyriel.yaml
+python -m scripts.animate --config configs/prompts/3-RcnzCartoon.yaml
+python -m scripts.animate --config configs/prompts/4-MajicMix.yaml
+python -m scripts.animate --config configs/prompts/5-RealisticVision.yaml
+python -m scripts.animate --config configs/prompts/6-Tusun.yaml
+python -m scripts.animate --config configs/prompts/7-FilmVelvia.yaml
+python -m scripts.animate --config configs/prompts/8-GhibliBackground.yaml
+```
+
+### Optionally Run with WebUI
+Configure yaml options, model settings & generate animations as desired.
+```
+python webui.py
+```
+
+
+
+  |
+  |
+
+
+
+To generate animations with a new DreamBooth/LoRA model, you may create a new config `.yaml` file in the following format:
+```
+NewModel:
+ path: "[path to your DreamBooth/LoRA model .safetensors file]"
+ base: "[path to LoRA base model .safetensors file, leave it empty string if not needed]"
+
+ motion_module:
+ - "models/Motion_Module/mm_sd_v14.ckpt"
+ - "models/Motion_Module/mm_sd_v15.ckpt"
+
+ steps: 25
+ guidance_scale: 7.5
+
+ prompt:
+ - "[positive prompt]"
+
+ n_prompt:
+ - "[negative prompt]"
+```
+Then run the following commands:
+```
+python -m scripts.animate --config [path to the config file]
+```
+
+## Gallery
+Here we demonstrate several best results we found in our experiments.
+
+
+Model:ToonYou
+
+
+Model:Counterfeit V3.0
+
+
+Model:Realistic Vision V2.0
+
+
+Model: majicMIX Realistic
+
+
+Model:RCNZ Cartoon
+
+
+Model:FilmVelvia
+
+#### Community Cases
+Here are some samples contributed by the community artists. Create a Pull Request if you would like to show your results here😚.
+
+
+
+Character Model:Yoimiya
+(with an initial reference image, see WIP fork for the extended implementation.)
+
+
+
+
+Character Model:Paimon;
+Pose Model:Hold Sign
+
+## BibTeX
+```
+@article{guo2023animatediff,
+ title={AnimateDiff: Animate Your Personalized Text-to-Image Diffusion Models without Specific Tuning},
+ author={Guo, Yuwei and Yang, Ceyuan and Rao, Anyi and Wang, Yaohui and Qiao, Yu and Lin, Dahua and Dai, Bo},
+ journal={arXiv preprint arXiv:2307.04725},
+ year={2023}
+}
+```
+
+## Contact Us
+**Yuwei Guo**: [guoyuwei@pjlab.org.cn](mailto:guoyuwei@pjlab.org.cn)
+**Ceyuan Yang**: [yangceyuan@pjlab.org.cn](mailto:yangceyuan@pjlab.org.cn)
+**Bo Dai**: [daibo@pjlab.org.cn](mailto:daibo@pjlab.org.cn)
+
+## Acknowledgements
Codebase built upon [Tune-a-Video](https://github.com/showlab/Tune-A-Video).
\ No newline at end of file
diff --git a/environment.yaml b/environment.yaml
index 2e2e36a..a675b3f 100644
--- a/environment.yaml
+++ b/environment.yaml
@@ -1,20 +1,22 @@
-name: animatediff
-channels:
- - pytorch
- - xformers
-dependencies:
- - python=3.10
- - pytorch==1.12.1
- - torchvision==0.13.1
- - torchaudio==0.12.1
- - cudatoolkit=11.3
- - xformers
- - pip
- - pip:
- - diffusers[torch]==0.11.1
- - transformers==4.25.1
- - imageio==2.27.0
- - gdown
- - einops
- - omegaconf
- - safetensors
+name: animatediff
+channels:
+ - pytorch
+ - xformers
+dependencies:
+ - python=3.10
+ - pytorch==1.12.1
+ - torchvision==0.13.1
+ - torchaudio==0.12.1
+ - cudatoolkit=11.3
+ - xformers
+ - pip
+ - pip:
+ - diffusers[torch]==0.11.1
+ - transformers==4.25.1
+ - imageio==2.27.0
+ - gdown
+ - einops
+ - omegaconf
+ - safetensors
+ - pyyaml
+ - gradio=3.36.1
\ No newline at end of file
diff --git a/ui/first-tab.png b/ui/first-tab.png
new file mode 100644
index 0000000..6f89e1d
Binary files /dev/null and b/ui/first-tab.png differ
diff --git a/ui/second-tab.png b/ui/second-tab.png
new file mode 100644
index 0000000..78c1a48
Binary files /dev/null and b/ui/second-tab.png differ
diff --git a/utils.py b/utils.py
new file mode 100644
index 0000000..90435d6
--- /dev/null
+++ b/utils.py
@@ -0,0 +1,41 @@
+import copy
+import os
+import subprocess as sub
+import gdown
+import yaml
+
+def yaml_to_dict(filename):
+ with open(filename, 'r') as file:
+ data = yaml.safe_load(file)
+ return copy.deepcopy(data)
+
+def dict_to_yaml(data, filename):
+ with open(filename, 'w') as file:
+ yaml.safe_dump(data, file)
+
+def download_from_drive_gdown(file_id, output_path):
+ url = f'https://drive.google.com/uc?id={file_id}'
+ gdown.download(url, output_path, quiet=False)
+
+def verbose_print(text):
+ print(f"{text}")
+
+def create_dirs(arb_path):
+ if not os.path.exists(arb_path):
+ os.makedirs(arb_path)
+
+def make_all_dirs(list_of_paths):
+ for path in list_of_paths:
+ create_dirs(path)
+
+def execute(cmd):
+ popen = sub.Popen(cmd, stdout=sub.PIPE, universal_newlines=True)
+ for stdout_line in iter(popen.stdout.readline, ""):
+ yield stdout_line
+ popen.stdout.close()
+ return_code = popen.wait()
+ if return_code:
+ raise sub.CalledProcessError(return_code, cmd)
+
+def is_windows():
+ return os.name == 'nt'
diff --git a/webui.py b/webui.py
new file mode 100644
index 0000000..9481404
--- /dev/null
+++ b/webui.py
@@ -0,0 +1,307 @@
+import argparse
+import gradio as gr
+import copy
+import os
+import glob
+
+import utils as help
+
+sep = '\\' if help.is_windows() else '/'
+all_motion_model_opts = ["mm_sd_v14.ckpt", "mm_sd_v15.ckpt"]
+
+def get_available_motion_models():
+ motion_model_opts_path = os.path.join(os.getcwd(), os.path.join("models", "Motion_Module"))
+ motion_model_opts = sorted([ckpt for ckpt in glob.glob(os.path.join(motion_model_opts_path, f"*.ckpt"))])
+ return motion_model_opts
+
+def get_available_sd_models():
+ sd_model_opts_path = os.path.join(os.getcwd(), os.path.join("models", "StableDiffusion"))
+ sd_model_opts = sorted([safetensor.split(sep)[-1] for safetensor in glob.glob(os.path.join(sd_model_opts_path, f"*.safetensors"))])
+ return sd_model_opts
+
+def get_available_db_models():
+ db_model_opts_path = os.path.join(os.getcwd(), os.path.join("models", "DreamBooth_LoRA"))
+ db_model_opts = sorted([safetensor.split(sep)[-1] for safetensor in glob.glob(os.path.join(db_model_opts_path, f"*.safetensors"))])
+ return db_model_opts
+
+def get_db_config():
+ prompt_configs_path = os.path.join(os.path.join(os.getcwd(), "configs"), "prompts")
+ return sorted([(prompt_yaml.split(sep)[-1]) for prompt_yaml in glob.glob(os.path.join(prompt_configs_path, f"*.yaml"))])
+
+def get_sd_config():
+ inference_configs_path = os.path.join(os.path.join(os.getcwd(), "configs"), "inference")
+ return sorted([(inference_yaml.split(sep)[-1]) for inference_yaml in glob.glob(os.path.join(inference_configs_path, f"*.yaml"))])
+
+def set_motion_model(menu_opt: gr.SelectData):
+ model_name = menu_opt.value
+ motion_model_opts_path = os.path.join(os.getcwd(), os.path.join("models", "Motion_Module"))
+ motion_model_opts = sorted([ckpt for ckpt in glob.glob(os.path.join(motion_model_opts_path, f"*.ckpt"))])
+ motion_model_map = {"mm_sd_v14.ckpt": "1RqkQuGPaCO5sGZ6V6KZ-jUWmsRu48Kdq",
+ "mm_sd_v15.ckpt": "1ql0g_Ys4UCz2RnokYlBjyOYPbttbIpbu"}
+ if not os.path.join(motion_model_opts_path, model_name) in motion_model_opts: # download
+ help.download_from_drive_gdown(motion_model_map[model_name], os.path.join(motion_model_opts_path, model_name))
+ return gr.update(value=os.path.join(motion_model_opts_path, model_name)) # model path
+
+def set_sd_model(menu_opt: gr.SelectData):
+ model_name = menu_opt.value
+ sd_model_opts_path = os.path.join(os.getcwd(), os.path.join("models", "StableDiffusion"))
+ return gr.update(value=os.path.join(sd_model_opts_path, model_name)), gr.update(value=os.path.join(sd_model_opts_path, model_name)) # sd path, pretrained path
+
+def set_db_model(menu_opt: gr.SelectData):
+ model_name = menu_opt.value
+ db_model_opts_path = os.path.join(os.getcwd(), os.path.join("models", "DreamBooth_LoRA"))
+ return gr.update(value=os.path.join(db_model_opts_path, model_name)) # db path
+
+def update_available_sd_models():
+ sd_model_opts_path = os.path.join(os.getcwd(), os.path.join("models", "StableDiffusion"))
+ sd_model_opts = sorted([safetensor.split(sep)[-1] for safetensor in glob.glob(os.path.join(sd_model_opts_path, f"*.safetensors"))])
+ return gr.update(choices=sd_model_opts)
+
+def update_available_db_models():
+ db_model_opts_path = os.path.join(os.getcwd(), os.path.join("models", "DreamBooth_LoRA"))
+ db_model_opts = sorted([safetensor.split(sep)[-1] for safetensor in glob.glob(os.path.join(db_model_opts_path, f"*.safetensors"))])
+ return gr.update(choices=db_model_opts)
+
+def update_sd_config():
+ inference_configs_path = os.path.join(os.path.join(os.getcwd(), "configs"), "inference")
+ return gr.update(choices=sorted([(inference_yaml.split(sep)[-1]) for inference_yaml in glob.glob(os.path.join(inference_configs_path, f"*.yaml"))]))
+
+def update_db_config():
+ prompt_configs_path = os.path.join(os.path.join(os.getcwd(), "configs"), "prompts")
+ return gr.update(choices=sorted([(prompt_yaml.split(sep)[-1]) for prompt_yaml in glob.glob(os.path.join(prompt_configs_path, f"*.yaml"))]))
+
+def load_db_config(filename: gr.SelectData):
+ filename = filename.value
+
+ global prompt_config_dict
+ prompt_configs_path = os.path.join(os.path.join(os.getcwd(), "configs"), "prompts")
+ # populate the dictionary
+ prompt_config_dict = help.yaml_to_dict(os.path.join(prompt_configs_path, f"{filename}"))
+
+ name_only = list(prompt_config_dict.keys())[0]
+ help.verbose_print(f"Config Key Name:\t{name_only}")
+
+ # return populated UI components
+ config_name = name_only
+
+ motion_model_path = list(prompt_config_dict[name_only]["motion_module"])[0]
+
+
+ base_path = str(prompt_config_dict[name_only]["base"])
+ db_path = str(prompt_config_dict[name_only]["path"])
+ steps = int(prompt_config_dict[name_only]["steps"])
+ guidance_scale = float(prompt_config_dict[name_only]["guidance_scale"])
+ lora_alpha = float(prompt_config_dict[name_only]["lora_alpha"]) if "lora_alpha" in prompt_config_dict[name_only] else 1.0
+
+ seed_list = list(prompt_config_dict[name_only]["seed"])
+ prompt_list = list(prompt_config_dict[name_only]["prompt"])
+ n_prompt_list = list(prompt_config_dict[name_only]["n_prompt"])
+
+ seed1 = str(seed_list[0]) if len(seed_list) > 0 else "-1"
+ prompt1 = str(prompt_list[0]) if len(prompt_list) > 0 else ""
+ n_prompt1 = str(n_prompt_list[0]) if len(n_prompt_list) > 0 else ""
+ seed2 = str(seed_list[1]) if len(seed_list) > 1 else "-1"
+ prompt2 = str(prompt_list[1]) if len(prompt_list) > 1 else ""
+ n_prompt2 = str(n_prompt_list[1]) if len(n_prompt_list) > 1 else ""
+ seed3 = str(seed_list[2]) if len(seed_list) > 2 else "-1"
+ prompt3 = str(prompt_list[2]) if len(prompt_list) > 2 else ""
+ n_prompt3 = str(n_prompt_list[2]) if len(n_prompt_list) > 2 else ""
+ seed4 = str(seed_list[3]) if len(seed_list) > 3 else "-1"
+ prompt4 = str(prompt_list[3]) if len(prompt_list) > 3 else ""
+ n_prompt4 = str(n_prompt_list[3]) if len(n_prompt_list) > 3 else ""
+ help.verbose_print(f"Done Loading Prompt Config!")
+
+ motion_model_dropdown = gr.update(value=motion_model_path.split(sep)[-1])
+ sd_model_dropdown = gr.update(value=base_path.split(sep)[-1])
+ db_model_dropdown = gr.update(value=db_path.split(sep)[-1])
+ pretrained_model_path = gr.update(value=base_path)
+
+ return config_name, motion_model_path, base_path, db_path, steps, guidance_scale, lora_alpha, \
+ seed1, prompt1, n_prompt1, seed2, prompt2, n_prompt2, seed3, prompt3, n_prompt3, seed4, prompt4, n_prompt4, \
+ motion_model_dropdown, sd_model_dropdown, db_model_dropdown, pretrained_model_path
+
+def save_db_config(filename):
+ global prompt_config_dict
+ prompt_configs_path = os.path.join(os.path.join(os.getcwd(), "configs"), "prompts")
+ help.dict_to_yaml(copy.deepcopy(prompt_config_dict), os.path.join(prompt_configs_path, f"{filename}.yaml"))
+ help.verbose_print(f"Done Creating NEW Prompt Config!")
+
+def save_prompt_dict(config_name, motion_model_path, base_path, db_path, steps, guidance_scale, lora_alpha,
+ seed1, prompt1, n_prompt1, seed2, prompt2, n_prompt2, seed3, prompt3, n_prompt3, seed4, prompt4, n_prompt4):
+ global prompt_config_dict
+ prompt_config_dict[config_name] = {}
+ prompt_config_dict[config_name]["base"] = base_path
+ prompt_config_dict[config_name]["path"] = db_path
+
+ prompt_config_dict[config_name]["motion_module"] = []
+ prompt_config_dict[config_name]["motion_module"].append(motion_model_path)
+
+ prompt_config_dict[config_name]["seed"] = [0] * 4
+ prompt_config_dict[config_name]["steps"] = steps
+ prompt_config_dict[config_name]["guidance_scale"] = guidance_scale
+ prompt_config_dict[config_name]["lora_alpha"] = lora_alpha
+
+
+ prompt_config_dict[config_name]["prompt"] = [""]*4
+ prompt_config_dict[config_name]["n_prompt"] = [""]*4
+
+ prompt_config_dict[config_name]["seed"][0] = int(seed1)
+ prompt_config_dict[config_name]["prompt"][0] = prompt1
+ prompt_config_dict[config_name]["n_prompt"][0] = n_prompt1
+ prompt_config_dict[config_name]["seed"][1] = int(seed2)
+ prompt_config_dict[config_name]["prompt"][1] = prompt2
+ prompt_config_dict[config_name]["n_prompt"][1] = n_prompt2
+ prompt_config_dict[config_name]["seed"][2] = int(seed3)
+ prompt_config_dict[config_name]["prompt"][2] = prompt3
+ prompt_config_dict[config_name]["n_prompt"][2] = n_prompt3
+ prompt_config_dict[config_name]["seed"][3] = int(seed4)
+ prompt_config_dict[config_name]["prompt"][3] = prompt4
+ prompt_config_dict[config_name]["n_prompt"][3] = n_prompt4
+
+ prompt_configs_path = os.path.join(os.path.join(os.getcwd(), "configs"), "prompts")
+ help.dict_to_yaml(copy.deepcopy(prompt_config_dict), os.path.join(prompt_configs_path, f"{config_name}.yaml"))
+ help.verbose_print(f"Done Updating Prompt Config!")
+
+def animate(pretrained_model_path, frame_count, width, height, inference_yaml_select, prompt_yaml_select):
+ prompt_configs_path = os.path.join(os.path.join(os.getcwd(), "configs"), "prompts")
+ inference_configs_path = os.path.join(os.path.join(os.getcwd(), "configs"), "inference")
+
+ command_str = f"python -m scripts.animate --config {os.path.join(prompt_configs_path, prompt_yaml_select)}"
+ if pretrained_model_path is not None and len(pretrained_model_path) > 0:
+ command_str += f" --pretrained_model_path {pretrained_model_path}"
+ command_str += f" --L {frame_count}"
+ command_str += f" --W {width}"
+ command_str += f" --H {height}"
+ if inference_yaml_select is not None and len(inference_yaml_select) > 0:
+ command_str += f" --inference_config {os.path.join(inference_configs_path, inference_yaml_select)}"
+
+ help.verbose_print(f"Running Command:\t{command_str}")
+ for line in help.execute(command_str.split(" ")):
+ help.verbose_print(line)
+ help.verbose_print(f"Done Generating!")
+
+def build_ui():
+ with gr.Blocks() as demo:
+ with gr.Tab("Model Selection & Setup"):
+ with gr.Row():
+ motion_model_dropdown = gr.Dropdown(interactive=True, label="Select Motion Model", info="Downloads model if not present", choices=all_motion_model_opts)
+ sd_model_dropdown = gr.Dropdown(interactive=True, label="Select Stable Diffusion Model", info="At user/s discretion to download", choices=get_available_sd_models())
+ db_model_dropdown = gr.Dropdown(interactive=True, label="Select LoRA/Dreambooth Model", info="At user/s discretion to download", choices=get_available_db_models())
+ with gr.Row():
+ pretrained_model_path = gr.Textbox(info="Pretrained Model Path", interactive=True, show_label=False)
+ with gr.Row():
+ frame_count = gr.Slider(info="Total Frames", minimum=0, maximum=1000, step=1, value=16, show_label=False)
+ width = gr.Slider(info="Width", minimum=0, maximum=4096, step=1, value=512, show_label=False)
+ height = gr.Slider(info="Height", minimum=0, maximum=4096, step=1, value=512, show_label=False)
+ with gr.Row():
+ inference_yaml_select = gr.Dropdown(info='YAML Select', interactive=True, choices=get_sd_config(), show_label=False)
+ animate_button = gr.Button(value="Generate", variant='primary')
+
+ with gr.Tab("LoRA/Dreambooth Prompt Config"):
+ with gr.Row():
+ config_save = gr.Button(value="Apply & Save Settings", variant='primary')
+ create_prompt_yaml = gr.Button(value="Create Prompt Config", variant='secondary')
+ with gr.Row():
+ prompt_yaml_select = gr.Dropdown(info='YAML Select', interactive=True, choices=get_db_config(), show_label=False)
+ config_name = gr.Textbox(info="Config Name", interactive=True, show_label=False)
+ motion_model_path = gr.Textbox(info="Motion Model Path", interactive=True, show_label=False)
+ with gr.Row():
+ base_path = gr.Textbox(info="Base Model Path", interactive=True, show_label=False)
+ db_path = gr.Textbox(info="LoRA/Dreambooth Path", interactive=True, show_label=False)
+ with gr.Row():
+ steps = gr.Slider(info="Steps", minimum=0, maximum=1000, step=1, value=25, show_label=False)
+ with gr.Row():
+ guidance_scale = gr.Slider(info="Guidance Scale", minimum=0.0, maximum=100.0, step=0.05, value=6.5, show_label=False)
+ lora_alpha = gr.Slider(info="LoRA Alpha", minimum=0.0, maximum=1.0, step=0.025, value=1.0, show_label=False)
+ with gr.Accordion("Prompt 1", visible=True, open=False):
+ with gr.Column():
+ seed1 = gr.Textbox(info="Seed", interactive=True, show_label=False)
+ prompt1 = gr.Textbox(info="Prompt", interactive=True, show_label=False)
+ n_prompt1 = gr.Textbox(info="Negative Prompt", interactive=True, show_label=False)
+ with gr.Accordion("Prompt 2", visible=True, open=False):
+ with gr.Column():
+ seed2 = gr.Textbox(info="Seed", interactive=True, show_label=False)
+ prompt2 = gr.Textbox(info="Prompt", interactive=True, show_label=False)
+ n_prompt2 = gr.Textbox(info="Negative Prompt", interactive=True, show_label=False)
+ with gr.Accordion("Prompt 3", visible=True, open=False):
+ with gr.Column():
+ seed3 = gr.Textbox(info="Seed", interactive=True, show_label=False)
+ prompt3 = gr.Textbox(info="Prompt", interactive=True, show_label=False)
+ n_prompt3 = gr.Textbox(info="Negative Prompt", interactive=True, show_label=False)
+ with gr.Accordion("Prompt 4", visible=True, open=False):
+ with gr.Column():
+ seed4 = gr.Textbox(info="Seed", interactive=True, show_label=False)
+ prompt4 = gr.Textbox(info="Prompt", interactive=True, show_label=False)
+ n_prompt4 = gr.Textbox(info="Negative Prompt", interactive=True, show_label=False)
+
+ motion_model_dropdown.select(fn=set_motion_model, inputs=[], outputs=[motion_model_path])
+ sd_model_dropdown.select(fn=set_sd_model, inputs=[], outputs=[base_path, pretrained_model_path])
+ db_model_dropdown.select(fn=set_db_model, inputs=[], outputs=[db_path])
+ prompt_yaml_select.select(fn=load_db_config, inputs=[],
+ outputs=[config_name, motion_model_path, base_path, db_path, steps, guidance_scale, lora_alpha,
+ seed1, prompt1, n_prompt1, seed2, prompt2, n_prompt2, seed3, prompt3, n_prompt3,
+ seed4, prompt4, n_prompt4, motion_model_dropdown, sd_model_dropdown,
+ db_model_dropdown, pretrained_model_path]).then(
+ fn=update_db_config, inputs=[], outputs=[prompt_yaml_select])
+ create_prompt_yaml.click(fn=save_db_config, inputs=[config_name], outputs=[])
+ config_save.click(fn=save_prompt_dict, inputs=[config_name, motion_model_path, base_path, db_path, steps, guidance_scale, lora_alpha,
+ seed1, prompt1, n_prompt1, seed2, prompt2, n_prompt2, seed3, prompt3, n_prompt3, seed4, prompt4, n_prompt4],
+ outputs=[])
+ animate_button.click(fn=animate, inputs=[pretrained_model_path, frame_count, width, height, inference_yaml_select, prompt_yaml_select], outputs=[])
+ return demo
+
+def UI(**kwargs):
+ # Show the interface
+ launch_kwargs = {}
+ if not kwargs.get('username', None) == '':
+ launch_kwargs['auth'] = (
+ kwargs.get('username', None),
+ kwargs.get('password', None),
+ )
+ if kwargs.get('server_port', 0) > 0:
+ launch_kwargs['server_port'] = kwargs.get('server_port', 0)
+ if kwargs.get('share', True):
+ launch_kwargs['share'] = True
+
+ print(launch_kwargs)
+ demo.queue().launch(**launch_kwargs)
+
+if __name__ == "__main__":
+ # init client & server connection
+ HOST = "127.0.0.1"
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ '--username', type=str, default='', help='Username for authentication'
+ )
+ parser.add_argument(
+ '--password', type=str, default='', help='Password for authentication'
+ )
+ parser.add_argument(
+ '--server_port',
+ type=int,
+ default=0,
+ help='Port to run the server listener on',
+ )
+ parser.add_argument(
+ '--share',
+ action='store_true',
+ help='Share live gradio link',
+ )
+
+ args = parser.parse_args()
+ demo = build_ui()
+
+ global prompt_config_dict
+ prompt_config_dict = {}
+
+ help.verbose_print(f"Motion models available to use:\t{get_available_motion_models()}")
+ help.verbose_print(f"Stable Diffusion models available to use:\t{get_available_sd_models()}")
+ help.verbose_print(f"LoRA/Dreambooth models available to use:\t{get_available_db_models()}")
+
+ UI(
+ username=args.username,
+ password=args.password,
+ server_port=args.server_port,
+ share=args.share,
+ )