From 9f34f7c8c5a7c96f2bc98bc43f46fab74d8232b7 Mon Sep 17 00:00:00 2001 From: Bubbliiiing <47347516+bubbliiiing@users.noreply.github.com> Date: Wed, 22 Jan 2025 15:30:47 +0800 Subject: [PATCH] Update to V5.1 (#179) * Update Flow * Update Flow * Update Flow * add image recaptioning * Fix bug in t2v * update train_reward_lora.py * update reward training * Update V5.1 and mix multi text_encoders to one pipeline * Update V5.1 training Code * Update ComfyUI * Update Comment * Delete files * update reward training * Update Readme * fix extract frames in compute_semantic_consistency * Update Readme && Remove to in prediction * Update Demo * Update Readme * Update ui * support vae gradient checkpointing in reward training * Update Training Readme --------- Co-authored-by: hkunzhe --- .gitignore | 1 + README.md | 247 ++- README_ja-JP.md | 225 ++- README_zh-CN.md | 237 ++- app.py | 12 +- asset/0a3b5fb184936a83.txt | 175 ++ asset/1.mp4 | Bin 0 -> 467060 bytes asset/pose.mp4 | Bin 0 -> 288849 bytes comfyui/README.md | 100 +- comfyui/README_zh-CN.md | 146 ++ comfyui/comfyui_nodes.py | 877 +++++---- comfyui/utils.py | 80 + comfyui/v4/easyanimatev4_workflow_v2v.json | 2 +- ...syanimatev5.1_workflow_control_camera.json | 673 +++++++ ...imatev5.1_workflow_control_trajectory.json | 1038 ++++++++++ .../v5.1/easyanimatev5.1_workflow_i2v.json | 495 +++++ .../v5.1/easyanimatev5.1_workflow_t2v.json | 400 ++++ .../v5.1/easyanimatev5.1_workflow_v2v.json | 553 ++++++ .../easyanimatev5.1_workflow_v2v_control.json | 548 ++++++ comfyui/v5/easyanimatev5_workflow_i2v.json | 2 +- comfyui/v5/easyanimatev5_workflow_t2v.json | 2 +- comfyui/v5/easyanimatev5_workflow_v2v.json | 4 +- .../easyanimatev5_workflow_v2v_control.json | 2 +- .../easyanimate_video_v5.1_magvit_qwen.yaml | 21 + easyanimate/api/post_infer.py | 4 +- easyanimate/data/dataset_image_video.py | 248 ++- easyanimate/models/__init__.py | 7 +- easyanimate/models/attention.py | 39 +- easyanimate/models/autoencoder_magvit.py | 114 -- easyanimate/models/embeddings.py | 5 +- easyanimate/models/norm.py | 16 + easyanimate/models/processor.py | 146 ++ easyanimate/models/transformer2d.py | 2 +- easyanimate/models/transformer3d.py | 138 +- easyanimate/pipeline/pipeline_easyanimate.py | 1194 +++++++----- ...rol.py => pipeline_easyanimate_control.py} | 648 ++++--- .../pipeline/pipeline_easyanimate_inpaint.py | 1681 +++++++++++------ ...pipeline_easyanimate_multi_text_encoder.py | 918 --------- ..._easyanimate_multi_text_encoder_inpaint.py | 1327 ------------- easyanimate/ui/ui.py | 438 ++--- easyanimate/utils/utils.py | 86 +- easyanimate/vae/ldm/models/autoencoder.py | 8 +- easyanimate/vae/ldm/models/casual3dcnn.py | 10 +- .../vae/ldm/models/cogvideox_casual3dcnn.py | 10 +- .../vae/ldm/models/omnigen_casual3dcnn.py | 10 +- easyanimate/vae/ldm/models/omnigen_enc_dec.py | 22 +- .../vae/ldm/modules/vaemodules/__init__.py | 0 .../vae/ldm/modules/vaemodules/activations.py | 0 .../vae/ldm/modules/vaemodules/common.py | 0 .../vae/ldm/modules/vaemodules/down_blocks.py | 0 .../vae/ldm/modules/vaemodules/mid_blocks.py | 0 .../vae/ldm/modules/vaemodules/up_blocks.py | 0 .../compute_semantic_consistency.py | 16 +- .../internvl2_video_recaptioning.py | 18 +- .../video_caption/utils/video_utils.py | 24 +- predict_i2v.py | 136 +- predict_t2v.py | 170 +- predict_v2v.py | 133 +- predict_v2v_control.py | 142 +- reports/report_v5_1.md | 70 + reports/report_v5_1_zh-CN.md | 67 + requirements.txt | 4 +- scripts/README_TRAIN.md | 105 +- scripts/README_TRAIN_CONTROL.md | 102 +- scripts/README_TRAIN_LORA.md | 100 +- scripts/README_TRAIN_REWARD.md | 23 +- scripts/train.py | 448 +++-- scripts/train.sh | 8 +- scripts/train_control.py | 480 ++++- scripts/train_control.sh | 7 +- scripts/train_lcm_lora.py | 106 +- scripts/train_lora.py | 378 ++-- scripts/train_lora.sh | 8 +- scripts/train_reward_lora.py | 791 +++++--- scripts/train_reward_lora.sh | 42 +- 75 files changed, 10625 insertions(+), 5664 deletions(-) mode change 100644 => 100755 README.md mode change 100644 => 100755 README_ja-JP.md mode change 100644 => 100755 README_zh-CN.md create mode 100644 asset/0a3b5fb184936a83.txt create mode 100644 asset/1.mp4 create mode 100644 asset/pose.mp4 create mode 100644 comfyui/README_zh-CN.md create mode 100644 comfyui/utils.py create mode 100644 comfyui/v5.1/easyanimatev5.1_workflow_control_camera.json create mode 100644 comfyui/v5.1/easyanimatev5.1_workflow_control_trajectory.json create mode 100644 comfyui/v5.1/easyanimatev5.1_workflow_i2v.json create mode 100644 comfyui/v5.1/easyanimatev5.1_workflow_t2v.json create mode 100644 comfyui/v5.1/easyanimatev5.1_workflow_v2v.json create mode 100644 comfyui/v5.1/easyanimatev5.1_workflow_v2v_control.json create mode 100644 config/easyanimate_video_v5.1_magvit_qwen.yaml rename easyanimate/pipeline/{pipeline_easyanimate_multi_text_encoder_control.py => pipeline_easyanimate_control.py} (63%) delete mode 100644 easyanimate/pipeline/pipeline_easyanimate_multi_text_encoder.py delete mode 100644 easyanimate/pipeline/pipeline_easyanimate_multi_text_encoder_inpaint.py mode change 100644 => 100755 easyanimate/ui/ui.py mode change 100755 => 100644 easyanimate/vae/ldm/modules/vaemodules/__init__.py mode change 100755 => 100644 easyanimate/vae/ldm/modules/vaemodules/activations.py mode change 100755 => 100644 easyanimate/vae/ldm/modules/vaemodules/common.py mode change 100755 => 100644 easyanimate/vae/ldm/modules/vaemodules/down_blocks.py mode change 100755 => 100644 easyanimate/vae/ldm/modules/vaemodules/mid_blocks.py mode change 100755 => 100644 easyanimate/vae/ldm/modules/vaemodules/up_blocks.py create mode 100644 reports/report_v5_1.md create mode 100644 reports/report_v5_1_zh-CN.md mode change 100644 => 100755 scripts/README_TRAIN.md mode change 100644 => 100755 scripts/README_TRAIN_CONTROL.md mode change 100644 => 100755 scripts/README_TRAIN_LORA.md diff --git a/.gitignore b/.gitignore index 50d7a84..0505166 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ _* __pycache__/ *.py[cod] *$py.class +scripts_demo* # C extensions *.so diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 6d3ae90..2f275bb --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ EasyAnimate is a pipeline based on the transformer architecture, designed for ge We will support quick pull-ups from different platforms, refer to [Quick Start](#quick-start). **New Features:** +- **Updated to version v5.1**, the Qwen2 VL is used as the text encoder, and Flow is used as the sampling method. It supports bilingual prediction in both Chinese and English. In addition to common controls such as Canny and Pose, it also supports trajectory control, camera control. [2025.01.21] - Use reward backpropagation to train Lora and optimize the video, aligning it better with human preferences, detailes in [here](scripts/README_TRAIN_REWARD.md). EasyAnimateV5-7b is released now. [2024.11.27] - **Updated to v5**, supporting video generation up to 1024x1024, 49 frames, 6s, 8fps, with expanded model scale to 12B, incorporating the MMDIT structure, and enabling control models with diverse inputs; supports bilingual predictions in Chinese and English. [2024.11.08] - **Updated to v4**, allowing for video generation up to 1024x1024, 144 frames, 6s, 24fps; supports video generation from text, image, and video, with a single model handling resolutions from 512 to 1280; bilingual predictions in Chinese and English enabled. [2024.08.15] @@ -83,13 +84,12 @@ mkdir models/Diffusion_Transformer mkdir models/Motion_Module mkdir models/Personalized_Model -# Please use the hugginface link or modelscope link to download the EasyAnimateV5 model. -# I2V models -# https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh-InP -# https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh-InP -# T2V models -# https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh -# https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh +# Please use the hugginface link or modelscope link to download the EasyAnimateV5.1 model. +# https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-InP +# https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-InP + +# https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh +# https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh ``` ### 2. Local install: Environment Check/Downloading/Installation @@ -114,14 +114,16 @@ The detailed of Linux: We need about 60GB available on disk (for saving weights), please check! -The video size for EasyAnimateV5-12B can be generated by different GPU Memory, including: -| GPU memory |384x672x25|384x672x49|576x1008x25|576x1008x49|768x1344x25|768x1344x49| -|----------|----------|----------|----------|----------|----------|----------| -| 16GB | 🧡 | 🧡 | ❌ | ❌ | ❌ | ❌ | +The video size for EasyAnimateV5.1-12B can be generated by different GPU Memory, including: +| GPU memory | 384x672x25 | 384x672x49 | 576x1008x25 | 576x1008x49 | 768x1344x25 | 768x1344x49 | +|------------|------------|------------|------------|------------|------------|------------| +| 16GB | 🧡 | 🧡 | ❌ | ❌ | ❌ | ❌ | | 24GB | 🧡 | 🧡 | 🧡 | 🧡 | 🧡 | ❌ | | 40GB | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | 80GB | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +Due to the float16 weights of qwen2-vl-7b, it cannot run on a 16GB GPU. If your GPU memory is 16GB, please visit [Huggingface](https://huggingface.co/Qwen/Qwen2-VL-7B-Instruct-GPTQ-Int8) or [Modelscope](https://modelscope.cn/models/Qwen/Qwen2-VL-7B-Instruct-GPTQ-Int8) to download the quantized version of qwen2-vl-7b to replace the original text encoder, and install the corresponding dependency libraries (auto-gptq, optimum). + The video size for EasyAnimateV5-7B can be generated by different GPU Memory, including: | GPU memory |384x672x25|384x672x49|576x1008x25|576x1008x49|768x1344x25|768x1344x49| |----------|----------|----------|----------|----------|----------|----------| @@ -135,61 +137,58 @@ The video size for EasyAnimateV5-7B can be generated by different GPU Memory, in Some GPUs that do not support torch.bfloat16, such as 2080ti and V100, require changing the weight_dtype in app.py and predict files to torch.float16 in order to run. -The generation time for EasyAnimateV5-12B using different GPUs over 25 steps is as follows: +The generation time for EasyAnimateV5.1-12B using different GPUs over 25 steps is as follows: | GPU | 384x672x25 | 384x672x49 | 576x1008x25 | 576x1008x49 | 768x1344x25 | 768x1344x49 | |-----------|------------------|------------------|------------------|------------------|------------------|-----------------| | A10 24GB | ~120s (4.8s/it) | ~240s (9.6s/it) | ~320s (12.7s/it) | ~750s (29.8s/it) | ❌ | ❌ | | A100 80GB | ~45s (1.75s/it) | ~90s (3.7s/it) | ~120s (4.7s/it) | ~300s (11.4s/it) | ~265s (10.6s/it) | ~710s (28.3s/it) | -(⭕️) indicates it can run with low_gpu_memory_mode=True, but at a slower speed, and ❌ means it can't run. -
(Obsolete) EasyAnimateV3: The video size for EasyAnimateV3 can be generated by different GPU Memory, including: -| GPU memory | 384x672x25 | 384x672x144 | 576x1008x72 | 576x1008x144 | 720x1280x72 | 720x1280x144 | +| GPU memory | 384x672x72 | 384x672x144 | 576x1008x72 | 576x1008x144 | 720x1280x72 | 720x1280x144 | |------------|------------|-------------|-------------|--------------|-------------|--------------| | 12GB | ⭕️ | ⭕️ | ⭕️ | ⭕️ | ❌ | ❌ | | 16GB | ✅ | ✅ | ⭕️ | ⭕️ | ⭕️ | ❌ | | 24GB | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | 40GB | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | 80GB | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | + +(⭕️) indicates it can run with low_gpu_memory_mode=True, but at a slower speed, and ❌ means it can't run.
#### b. Weights We'd better place the [weights](#model-zoo) along the specified path: -EasyAnimateV5: +EasyAnimateV5.1: ``` 📦 models/ ├── 📂 Diffusion_Transformer/ -│ ├── 📂 EasyAnimateV5-12b-zh-InP/ -│ └── 📂 EasyAnimateV5-12b-zh/ +│ ├── 📂 EasyAnimateV5.1-12b-zh-InP/ +│ └── 📂 EasyAnimateV5.1-12b-zh/ ├── 📂 Personalized_Model/ │ └── your trained trainformer model / your trained lora model (for UI load) ``` -# 视频作品 -The results displayed are all based on image. +# Video Result -### EasyAnimateV5-12b-zh-InP - -#### I2V +### Image to Video with EasyAnimateV5.1-12b-zh-InP
- + - + - + - +
@@ -198,16 +197,16 @@ The results displayed are all based on image.
- + - + - + - +
@@ -215,34 +214,35 @@ The results displayed are all based on image.
- + - + - + - +
-#### T2V +### Text to Video with EasyAnimateV5.1-12b-zh +
- + - + - + - +
@@ -250,22 +250,38 @@ The results displayed are all based on image.
- + - + - + - +
-### EasyAnimateV5-12b-zh-Control +### Control Video with EasyAnimateV5.1-12b-zh-Control +Trajectory Control: + + + + + + +
+ + + + + +
+ +Generic Control Video (Canny, Pose, Depth, etc.):
@@ -290,32 +306,105 @@ The results displayed are all based on image.
+### Camera Control with EasyAnimateV5.1-12b-zh-Control-Camera + + + + + + + + + + + + + + + + + + + +
+ Pan Up + + Pan Left + + Pan Right +
+ + + + + +
+ Pan Down + + Pan Up + Pan Left + + Pan Up + Pan Right +
+ + + + + +
# How to use

1. Inference

-#### a. Using Python Code +#### a. Memory-Saving Options +Since EasyAnimateV5 and V5.1 have very large parameters, we need to consider memory-saving options to adapt to consumer-grade graphics cards. We provide GPU_memory_mode for each prediction file, allowing you to choose from model_cpu_offload, model_cpu_offload_and_qfloat8, or sequential_cpu_offload. + +- model_cpu_offload means the entire model will move to the CPU after use, saving some memory. +- model_cpu_offload_and_qfloat8 means the entire model will move to the CPU after use and applies float8 quantization to the transformer model, saving more memory. +- sequential_cpu_offload means each layer of the model moves to CPU after use, which is slower but saves a lot of memory. + +qfloat8 may reduce model performance but saves more memory. If memory is sufficient, it's recommended to use model_cpu_offload. + +#### b. Via ComfyUI +For more details, see the [ComfyUI README](comfyui/README.md). + +#### c. Run Python Files - Step 1: Download the corresponding [weights](#model-zoo) and place them in the models folder. -- Step 2: Modify prompt, neg_prompt, guidance_scale, and seed in the predict_t2v.py file. -- Step 3: Run the predict_t2v.py file, wait for the generated results, and save the results in the samples/easyanimate-videos folder. -- Step 4: If you want to combine other backbones you have trained with Lora, modify the predict_t2v.py and Lora_path in predict_t2v.py depending on the situation. +- Step 2: Use different files for predictions based on the weights and prediction goals. + - Text-to-Video: + - Modify the prompt, neg_prompt, guidance_scale, and seed in the predict_t2v.py file. + - Then run the predict_t2v.py file and wait for the results, which are stored in the samples/easyanimate-videos folder. + - Image-to-Video: + - Modify validation_image_start, validation_image_end, prompt, neg_prompt, guidance_scale, and seed in the predict_i2v.py file. + - validation_image_start is the starting image, and validation_image_end is the ending image of the video. + - Then run the predict_i2v.py file and wait for the results, which are stored in the samples/easyanimate-videos_i2v folder. + - Video-to-Video: + - Modify validation_video, validation_image_end, prompt, neg_prompt, guidance_scale, and seed in the predict_v2v.py file. + - validation_video is the reference video for video-to-video. You can run a demo with the following video: [Demo Video](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1/play_guitar.mp4) + - Then run the predict_v2v.py file and wait for the results, which are stored in samples/easyanimate-videos_v2v folder. + - Generic Control Video (Canny, Pose, Depth, etc.): + - Modify control_video, validation_image_end, prompt, neg_prompt, guidance_scale, and seed in the predict_v2v_control.py file. + - control_video is the control video for video generation, extracted using Canny, Pose, Depth, etc. You can run a demo with the following video: [Demo Video](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1.1/pose.mp4) + - Then run the predict_v2v_control.py file and wait for the results, which are stored in samples/easyanimate-videos_v2v_control folder. + - Trajectory Control Video: + - Modify control_video, ref_image, validation_image_end, prompt, neg_prompt, guidance_scale, and seed in the predict_v2v_control.py file. + - control_video is the control video, and ref_image is the reference first frame image. You can run a demo with the following image and video: [Demo Image](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/dog.png), [Demo Video](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/trajectory_demo.mp4) + - Then run the predict_v2v_control.py file and wait for the results, which are stored in samples/easyanimate-videos_v2v_control folder. + - Interaction via ComfyUI is recommended. + - Camera Control Video: + - Modify control_video, ref_image, validation_image_end, prompt, neg_prompt, guidance_scale, and seed in the predict_v2v_control.py file. + - control_camera_txt is the control file for camera control video, and ref_image is the reference first frame image. You can run a demo with the following image and control file: [Demo Image](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1/firework.png), [Demo File (from CameraCtrl)](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/0a3b5fb184936a83.txt) + - Then run the predict_v2v_control.py file and wait for the results, which are stored in samples/easyanimate-videos_v2v_control folder. + - Interaction via ComfyUI is recommended. +- Step 3: To combine with other backbones and Lora trained by yourself, modify predict_t2v.py and lora_path accordingly in the predict_t2v.py file. + +#### d. Via WebUI Interface + +WebUI supports text-to-video, image-to-video, video-to-video, and control-based video generation (such as Canny, Pose, Depth, etc.). -#### b. Using webui - Step 1: Download the corresponding [weights](#model-zoo) and place them in the models folder. -- Step 2: Run the app.py file to enter the graph page. -- Step 3: Select the generated model based on the page, fill in prompt, neg_prompt, guidance_scale, and seed, click on generate, wait for the generated result, and save the result in the samples folder. - -#### c. From ComfyUI -Please refer to [ComfyUI README](comfyui/README.md) for details. - -#### d. GPU Memory Saving Schemes - -Due to the large parameters of EasyAnimateV5, we need to consider GPU memory saving schemes to conserve memory. We provide a `GPU_memory_mode` option for each prediction file, which can be selected from `model_cpu_offload`, `model_cpu_offload_and_qfloat8`, and `sequential_cpu_offload`. - -- `model_cpu_offload` indicates that the entire model will be offloaded to the CPU after use, saving some GPU memory. -- `model_cpu_offload_and_qfloat8` indicates that the entire model will be offloaded to the CPU after use, and the transformer model is quantized to float8, saving even more GPU memory. -- `sequential_cpu_offload` means that each layer of the model will be offloaded to the CPU after use, which is slower but saves a substantial amount of GPU memory. +- Step 2: Run the app.py file to enter the Gradio page. +- Step 3: Choose the generation model from the page, fill in prompt, neg_prompt, guidance_scale, seed, etc., click generate, and wait for the results, which are stored in the sample folder. ### 2. Model Training @@ -410,7 +499,18 @@ For details on setting some parameters, please refer to [Readme Train](scripts/R # Model zoo -EasyAnimateV5: +EasyAnimateV5.1: + +12B: +| Name | Type | Storage Space | Hugging Face | Model Scope | Description | +|--|--|--|--|--|--| +| EasyAnimateV5.1-12b-zh-InP | EasyAnimateV5.1 | 39 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-InP) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-InP) | Official image-to-video weights. Supports video prediction at multiple resolutions (512, 768, 1024), trained with 49 frames at 8 frames per second, and supports for multilingual prediction. | +| EasyAnimateV5.1-12b-zh-Control | EasyAnimateV5.1 | 39 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-Control) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-Control) | Official video control weights, supporting various control conditions such as Canny, Depth, Pose, MLSD, and trajectory control. Supports video prediction at multiple resolutions (512, 768, 1024), trained with 49 frames at 8 frames per second, and supports for multilingual prediction. | +| EasyAnimateV5.1-12b-zh-Control-Camera | EasyAnimateV5.1 | 39 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-Control-Camera) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-Control-Camera) | Official video camera control weights, supporting direction generation control by inputting camera motion trajectories. Supports video prediction at multiple resolutions (512, 768, 1024), trained with 49 frames at 8 frames per second, and supports for multilingual prediction. | +| EasyAnimateV5.1-12b-zh | EasyAnimateV5.1 | 39 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh) | Official text-to-video weights. Supports video prediction at multiple resolutions (512, 768, 1024), trained with 49 frames at 8 frames per second, and supports for multilingual prediction. | + +
+ (Obsolete) EasyAnimateV5: 7B: | Name | Type | Storage Space | Hugging Face | Model Scope | Description | @@ -426,13 +526,14 @@ EasyAnimateV5: | EasyAnimateV5-12b-zh-Control | EasyAnimateV5 | 34 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh-Control) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh-Control) | Official video control weights, supporting various control conditions such as Canny, Depth, Pose, MLSD, etc. Supports video prediction at multiple resolutions (512, 768, 1024) and is trained with 49 frames at 8 frames per second. Bilingual prediction in Chinese and English is supported. | | EasyAnimateV5-12b-zh | EasyAnimateV5 | 34 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh) | Official text-to-video weights. Supports video prediction at multiple resolutions (512, 768, 1024), trained with 49 frames at 8 frames per second, and supports bilingual prediction in Chinese and English. | | EasyAnimateV5-Reward-LoRAs | EasyAnimateV5 | - | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-Reward-LoRAs) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-Reward-LoRAs) | The official reward backpropagation technology model optimizes the videos generated by EasyAnimateV5-12b to better match human preferences. | +
(Obsolete) EasyAnimateV4: | Name | Type | Storage Space | Hugging Face | Model Scope | Description | |--|--|--|--|--|--| -| EasyAnimateV4-XL-2-InP.tar.gz | EasyAnimateV4 | Before extraction: 8.9 GB \/ After extraction: 14.0 GB |[🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV4-XL-2-InP)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV4-XL-2-InP)| | Our official graph-generated video model is capable of predicting videos at multiple resolutions (512, 768, 1024, 1280) and has been trained on 144 frames at a rate of 24 frames per second. | +| EasyAnimateV4-XL-2-InP | EasyAnimateV4 | Before extraction: 8.9 GB \/ After extraction: 14.0 GB |[🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV4-XL-2-InP)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV4-XL-2-InP)| | Our official graph-generated video model is capable of predicting videos at multiple resolutions (512, 768, 1024, 1280) and has been trained on 144 frames at a rate of 24 frames per second. |
@@ -440,9 +541,9 @@ EasyAnimateV5: | Name | Type | Storage Space | Hugging Face | Model Scope | Description | |--|--|--|--|--|--| -| EasyAnimateV3-XL-2-InP-512x512.tar | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-512x512)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-512x512) | EasyAnimateV3 official weights for 512x512 text and image to video resolution. Training with 144 frames and fps 24 | -| EasyAnimateV3-XL-2-InP-768x768.tar | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-768x768) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-768x768) | EasyAnimateV3 official weights for 768x768 text and image to video resolution. Training with 144 frames and fps 24 | -| EasyAnimateV3-XL-2-InP-960x960.tar | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-960x960) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-960x960) | EasyAnimateV3 official weights for 960x960 text and image to video resolution. Training with 144 frames and fps 24 | +| EasyAnimateV3-XL-2-InP-512x512 | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-512x512)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-512x512) | EasyAnimateV3 official weights for 512x512 text and image to video resolution. Training with 144 frames and fps 24 | +| EasyAnimateV3-XL-2-InP-768x768 | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-768x768) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-768x768) | EasyAnimateV3 official weights for 768x768 text and image to video resolution. Training with 144 frames and fps 24 | +| EasyAnimateV3-XL-2-InP-960x960 | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-960x960) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-960x960) | EasyAnimateV3 official weights for 960x960 text and image to video resolution. Training with 144 frames and fps 24 |
@@ -450,8 +551,8 @@ EasyAnimateV5: | Name | Type | Storage Space | Url | Hugging Face | Model Scope | Description | |--|--|--|--|--|--|--| -| EasyAnimateV2-XL-2-512x512.tar | EasyAnimateV2 | 16.2GB | - | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV2-XL-2-512x512)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV2-XL-2-512x512)| EasyAnimateV2 official weights for 512x512 resolution. Training with 144 frames and fps 24 | -| EasyAnimateV2-XL-2-768x768.tar | EasyAnimateV2 | 16.2GB | - | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV2-XL-2-768x768) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV2-XL-2-768x768)| EasyAnimateV2 official weights for 768x768 resolution. Training with 144 frames and fps 24 | +| EasyAnimateV2-XL-2-512x512 | EasyAnimateV2 | 16.2GB | - | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV2-XL-2-512x512)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV2-XL-2-512x512)| EasyAnimateV2 official weights for 512x512 resolution. Training with 144 frames and fps 24 | +| EasyAnimateV2-XL-2-768x768 | EasyAnimateV2 | 16.2GB | - | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV2-XL-2-768x768) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV2-XL-2-768x768)| EasyAnimateV2 official weights for 768x768 resolution. Training with 144 frames and fps 24 | | easyanimatev2_minimalism_lora.safetensors | Lora of Pixart | 485.1MB | [Download](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/Personalized_Model/easyanimatev2_minimalism_lora.safetensors)| - | - | A lora training with a specifial type images. Images can be downloaded from [Url](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v2/Minimalism.zip). |
@@ -491,8 +592,12 @@ EasyAnimateV5: - Open-Sora-Plan: https://github.com/PKU-YuanGroup/Open-Sora-Plan - Open-Sora: https://github.com/hpcaitech/Open-Sora - Animatediff: https://github.com/guoyww/AnimateDiff -- ComfyUI-EasyAnimateWrapper: https://github.com/kijai/ComfyUI-EasyAnimateWrapper - HunYuan DiT: https://github.com/tencent/HunyuanDiT +- ComfyUI-KJNodes: https://github.com/kijai/ComfyUI-KJNodes +- ComfyUI-EasyAnimateWrapper: https://github.com/kijai/ComfyUI-EasyAnimateWrapper +- ComfyUI-CameraCtrl-Wrapper: https://github.com/chaojie/ComfyUI-CameraCtrl-Wrapper +- CameraCtrl: https://github.com/hehao13/CameraCtrl +- DragAnything: https://github.com/showlab/DragAnything # License This project is licensed under the [Apache License (Version 2.0)](https://github.com/modelscope/modelscope/blob/master/LICENSE). diff --git a/README_ja-JP.md b/README_ja-JP.md old mode 100644 new mode 100755 index dcaaf3c..155906a --- a/README_ja-JP.md +++ b/README_ja-JP.md @@ -31,6 +31,7 @@ EasyAnimateは、トランスフォーマーアーキテクチャに基づいた 異なるプラットフォームからのクイックプルアップをサポートします。詳細は[クイックスタート](#クイックスタート)を参照してください。 **新機能:** +- **バージョンv5.1に更新**、Qwen2 VLがテキストエンコーダーとして使用され、Flowがサンプリング方法として使用されます。中国語と英語の両方でバイリンガル予測をサポートしています。CannyやPoseといった一般的なコントロールに加えて、軌道制御やカメラ制御もサポートしています。[2025.01.21] - インセンティブ逆伝播を使用してLoraを訓練し、人間の好みに合うようにビデオを最適化します。詳細は、[ここ](scripts/README _ train _ REVARD.md)を参照してください。EasyAnimateV 5-7 bがリリースされました。[2024.11.27] - **v5に更新**、1024x1024までの動画生成をサポート、49フレーム、6秒、8fps、モデルスケールを12Bに拡張、MMDIT構造を組み込み、さまざまな入力を持つ制御モデルをサポート。中国語と英語のバイリンガル予測をサポート。[2024.11.08] - **v4に更新**、1024x1024までの動画生成をサポート、144フレーム、6秒、24fps、テキスト、画像、動画からの動画生成をサポート、512から1280までの解像度を単一モデルで処理。中国語と英語のバイリンガル予測をサポート。[2024.08.15] @@ -85,11 +86,11 @@ mkdir models/Personalized_Model # EasyAnimateV5モデルをダウンロードするには、hugginfaceリンクまたはmodelscopeリンクを使用してください。 # I2Vモデル -# https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh-InP -# https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh-InP +# https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-InP +# https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-InP # T2Vモデル -# https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh -# https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh +# https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh +# https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh ``` ### 2. ローカルインストール: 環境チェック/ダウンロード/インストール @@ -114,14 +115,16 @@ Linuxの詳細: ディスクに約60GBの空き容量が必要です(重みを保存するため)、確認してください! -EasyAnimateV5-12Bのビデオサイズは異なるGPUメモリにより生成できます。以下の表をご覧ください: -| GPU memory |384x672x25|384x672x49|576x1008x25|576x1008x49|768x1344x25|768x1344x49| +EasyAnimateV5.1-12Bのビデオサイズは異なるGPUメモリにより生成できます。以下の表をご覧ください: +| GPUメモリ |384x672x25|384x672x49|576x1008x25|576x1008x49|768x1344x25|768x1344x49| |----------|----------|----------|----------|----------|----------|----------| | 16GB | 🧡 | 🧡 | ❌ | ❌ | ❌ | ❌ | | 24GB | 🧡 | 🧡 | 🧡 | 🧡 | 🧡 | ❌ | | 40GB | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | 80GB | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +qwen2-vl-7bのfloat16の重みのため、16GBのVRAMでは実行できません。もしお使いのVRAMが16GBである場合は、[Huggingface](https://huggingface.co/Qwen/Qwen2-VL-7B-Instruct-GPTQ- + EasyAnimateV5-7Bのビデオサイズは異なるGPUメモリにより生成できます。以下の表をご覧ください: | GPU memory |384x672x25|384x672x49|576x1008x25|576x1008x49|768x1344x25|768x1344x49| |----------|----------|----------|----------|----------|----------|----------| @@ -140,18 +143,18 @@ EasyAnimateV5-12Bは異なるGPUで25ステップ生成する時間は次の通 | A10 24GB |約120秒 (4.8s/it)|約240秒 (9.6s/it)|約320秒 (12.7s/it)|約750秒 (29.8s/it)| ❌ | ❌ | | A100 80GB |約45秒 (1.75s/it)|約90秒 (3.7s/it)|約120秒 (4.7s/it)|約300秒 (11.4s/it)|約265秒 (10.6s/it)| 約710秒 (28.3s/it)| -(⭕️) はlow_gpu_memory_mode=Trueの条件で実行可能であるが、速度が遅くなることを示しています。また、❌は実行できないことを示します。 -
(廃止予定) EasyAnimateV3: EasyAnimateV3のビデオサイズは異なるGPUメモリにより生成できます。以下の表をご覧ください: -| GPUメモリ | 384x672x25 | 384x672x144 | 576x1008x72 | 576x1008x144 | 720x1280x72 | 720x1280x144 | +| GPUメモリ | 384x672x72 | 384x672x144 | 576x1008x72 | 576x1008x144 | 720x1280x72 | 720x1280x144 | |----------|----------|----------|----------|----------|----------|----------| | 12GB | ⭕️ | ⭕️ | ⭕️ | ⭕️ | ❌ | ❌ | | 16GB | ✅ | ✅ | ⭕️ | ⭕️ | ⭕️ | ❌ | | 24GB | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | 40GB | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | 80GB | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | + +(⭕️) はlow_gpu_memory_mode=Trueの条件で実行可能であるが、速度が遅くなることを示しています。また、❌は実行できないことを示します。
#### b. 重み @@ -161,31 +164,28 @@ EasyAnimateV5: ``` 📦 models/ ├── 📂 Diffusion_Transformer/ -│ ├── 📂 EasyAnimateV5-12b-zh-InP/ -│ └── 📂 EasyAnimateV5-12b-zh/ +│ ├── 📂 EasyAnimateV5.1-12b-zh-InP/ +│ └── 📂 EasyAnimateV5.1-12b-zh/ ├── 📂 Personalized_Model/ │ └── あなたのトレーニング済みのトランスフォーマーモデル / あなたのトレーニング済みのLoraモデル(UIロード用) ``` # ビデオ結果 -表示されている結果はすべて画像からの生成に基づいています。 -### EasyAnimateV5-12b-zh-InP - -#### I2V +### Image to Video with EasyAnimateV5.1-12b-zh-InP
- + - + - + - +
@@ -194,16 +194,16 @@ EasyAnimateV5:
- + - + - + - +
@@ -211,34 +211,34 @@ EasyAnimateV5:
- + - + - + - +
-#### T2V +### Text to Video with EasyAnimateV5.1-12b-zh
- + - + - + - +
@@ -246,22 +246,38 @@ EasyAnimateV5:
- + - + - + - +
-### EasyAnimateV5-12b-zh-Control +### Control Video with EasyAnimateV5.1-12b-zh-Control +Trajectory Control: + + + + + + +
+ + + + + +
+ +Generic Control Video (Canny, Pose, Depth, etc.):
@@ -286,32 +302,105 @@ EasyAnimateV5:
+### Camera Control with EasyAnimateV5.1-12b-zh-Control-Camera + + + + + + + + + + + + + + + + + + + +
+ Pan Up + + Pan Left + + Pan Right +
+ + + + + +
+ Pan Down + + Pan Up + Pan Left + + Pan Up + Pan Right +
+ + + + + +
# 使い方

1. 推論

-#### a. Pythonコードを使用する -- ステップ1:対応する[重み](#model-zoo)をダウンロードし、modelsフォルダに配置します。 -- ステップ2:predict_t2v.pyファイルでprompt、neg_prompt、guidance_scale、およびseedを変更します。 -- ステップ3:predict_t2v.pyファイルを実行し、生成された結果を待ちます。結果はsamples/easyanimate-videosフォルダに保存されます。 -- ステップ4:他のバックボーンとLoraを組み合わせたい場合は、状況に応じてpredict_t2v.pyおよびLora_pathを変更します。 +#### a、メモリ節約策 +EasyAnimateV5およびV5.1のパラメータが非常に大きいため、消費者向けグラフィックスカードに適応させるためにメモリの節約策を考慮する必要があります。各予測ファイルにはGPU_memory_modeを提供しており、model_cpu_offload、model_cpu_offload_and_qfloat8、sequential_cpu_offloadから選択することができます。 -#### b. WebUIを使用する -- ステップ1:対応する[重み](#model-zoo)をダウンロードし、modelsフォルダに配置します。 -- ステップ2:app.pyファイルを実行してグラフページに入ります。 -- ステップ3:ページに基づいて生成モデルを選択し、prompt、neg_prompt、guidance_scale、およびseedを入力し、生成をクリックして生成結果を待ちます。結果はsamplesフォルダに保存されます。 +- model_cpu_offloadは、使用後にモデル全体がCPUに移動することを示し、メモリの一部を節約できます。 +- model_cpu_offload_and_qfloat8は、使用後にモデル全体がCPUに移動し、トランスフォーマーモデルをfloat8に量子化することを示し、さらに多くのメモリを節約できます。 +- sequential_cpu_offloadは、使用後に各レイヤーが順次CPUに移動することを示し、速度は遅くなりますが、大量のメモリを節約できます。 -#### c. ComfyUIから -詳細は[ComfyUI README](comfyui/README.md)を参照してください。 +qfloat8はモデルの性能を低下させますが、さらに多くのメモリを節約できます。メモリが十分にある場合は、model_cpu_offloadを使用することをお勧めします。 -#### d. GPUメモリ節約スキーム +#### b、ComfyUIを使用する +詳細は[ComfyUI README](comfyui/README.md)をご覧ください。 -EasyAnimateV5のパラメータが大きいため、メモリを節約するためにGPUメモリ節約スキームを検討する必要があります。各予測ファイルには、`GPU_memory_mode`オプションがあり、`model_cpu_offload`、`model_cpu_offload_and_qfloat8`、および`sequential_cpu_offload`から選択できます。 +#### c、pythonファイルを実行する +- ステップ1:対応する[重み](#model-zoo)をダウンロードし、modelsフォルダに入れます。 +- ステップ2:異なる重みと予測目標に応じて異なるファイルを使用して予測を行います。 + - テキストからビデオの生成: + - predict_t2v.pyファイルでprompt、neg_prompt、guidance_scale、seedを変更します。 + - 次にpredict_t2v.pyファイルを実行し、生成結果を待ちます。結果はsamples/easyanimate-videosフォルダに保存されます。 + - 画像からビデオの生成: + - predict_i2v.pyファイルでvalidation_image_start、validation_image_end、prompt、neg_prompt、guidance_scale、seedを変更します。 + - validation_image_startはビデオの開始画像、validation_image_endはビデオの終了画像です。 + - 次にpredict_i2v.pyファイルを実行し、生成結果を待ちます。結果はsamples/easyanimate-videos_i2vフォルダに保存されます。 + - ビデオからビデオの生成: + - predict_v2v.pyファイルでvalidation_video、validation_image_end、prompt、neg_prompt、guidance_scale、seedを変更します。 + - validation_videoはビデオの参照ビデオです。以下のビデオを使用してデモを実行できます:[デモビデオ](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1/play_guitar.mp4) + - 次にpredict_v2v.pyファイルを実行し、生成結果を待ちます。結果はsamples/easyanimate-videos_v2vフォルダに保存されます。 + - 通常のコントロールビデオ生成(Canny、Pose、Depthなど): + - predict_v2v_control.pyファイルでcontrol_video、validation_image_end、prompt、neg_prompt、guidance_scale、seedを変更します。 + - control_videoはCanny、Pose、Depthなどのフィルタを適用した後のビデオです。以下のビデオを使用してデモを実行できます:[デモビデオ](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1.1/pose.mp4) + - 次にpredict_v2v_control.pyファイルを実行し、生成結果を待ちます。結果はsamples/easyanimate-videos_v2v_controlフォルダに保存されます。 + - トラジェクトリーコントロールビデオ: + - predict_v2v_control.pyファイルでcontrol_video、ref_image、validation_image_end、prompt、neg_prompt、guidance_scale、seedを変更します。 + - control_videoはトラジェクトリーコントロールビデオのコントロールビデオ、ref_imageは参照の初期フレーム画像です。以下の画像とコントロールビデオを使用してデモを実行できます:[デモ画像](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/dog.png)、[デモビデオ](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/trajectory_demo.mp4) + - 次にpredict_v2v_control.pyファイルを実行し、生成結果を待ちます。結果はsamples/easyanimate-videos_v2v_controlフォルダに保存されます。 + - 交互利用にComfyUIの使用を推奨します。 + - カメラコントロールビデオ: + - predict_v2v_control.pyファイルでcontrol_video、ref_image、validation_image_end、prompt、neg_prompt、guidance_scale、seedを変更します。 + - control_camera_txtはカメラコントロールビデオのコントロールファイル、ref_imageは参照の初期フレーム画像です。以下の画像とコントロールビデオを使用してデモを実行できます:[デモ画像](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1/firework.png)、[デモファイル(CameraCtrlから)](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/0a3b5fb184936a83.txt) + - 次にpredict_v2v_control.pyファイルを実行し、生成結果を待ちます。結果はsamples/easyanimate-videos_v2v_controlフォルダに保存されます。 + - 交互利用にComfyUIの使用を推奨します。 +- ステップ3:他のトレーニング済みバックボーンとLoraを組み合わせたい場合、predict_t2v.pyでpredict_t2v.pyとlora_pathを適宜変更してください。 -- `model_cpu_offload`は、使用後にモデル全体がCPUにオフロードされることを示し、一部のGPUメモリを節約します。 -- `model_cpu_offload_and_qfloat8`は、使用後にモデル全体がCPUにオフロードされ、トランスフォーマーモデルがfloat8に量子化され、さらに多くのGPUメモリを節約します。 -- `sequential_cpu_offload`は、使用後にモデルの各層がCPUにオフロードされることを意味し、速度は遅くなりますが、大量のGPUメモリを節約します。 +#### d、UIインターフェイスを使用する + +webuiはテキストからビデオ、画像からビデオ、ビデオからビデオ、および通常のコントロールビデオ(Canny、Pose、Depthなど)の生成をサポートしています。 + +- ステップ1:対応する[重み](#model-zoo)をダウンロードし、modelsフォルダに入れます。 +- ステップ2:app.pyファイルを実行し、gradioページに入ります。 +- ステップ3:ページで生成モデルを選択し、prompt、neg_prompt、guidance_scale、seedなどを入力して生成をクリックし、生成結果を待ちます。結果はsampleフォルダに保存されます。 ### 2. モデルトレーニング 完全なEasyAnimateトレーニングパイプラインには、データ前処理、Video VAEトレーニング、およびVideo DiTトレーニングが含まれる必要があります。これらの中で、Video VAEトレーニングはオプションです。すでにトレーニング済みのVideo VAEを提供しているためです。 @@ -404,7 +493,16 @@ sh scripts/train.sh # モデルズー -EasyAnimateV5: +12B: +| 名前 | タイプ | ストレージスペース | Hugging Face | モデルスコープ | 説明 | +|--|--|--|--|--|--| +| EasyAnimateV5.1-12b-zh-InP | EasyAnimateV5.1 | 39 GB | [🤗リンク](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-InP) | [😄リンク](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-InP) | 公式の画像からビデオへの変換用の重み。支持多解像度(512、768、1024)的ビデオ予測、49フレームで毎秒8フレームの訓練、多言語予測をサポート | +| EasyAnimateV5.1-12b-zh-Control | EasyAnimateV5.1 | 39 GB | [🤗リンク](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-Control) | [😄リンク](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-Control) | 公式のビデオ制御用の重み。Canny、Depth、Pose、MLSD、および軌道制御などのさまざまな制御条件をサポートします。支持多解像度(512、768、1024)的ビデオ予測、49フレームで毎秒8フレームの訓練、多言語予測をサポート | +| EasyAnimateV5.1-12b-zh-Control-Camera | EasyAnimateV5.1 | 39 GB | [🤗リンク](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-Control-Camera) | [😄リンク](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-Control-Camera) | 公式のビデオカメラ制御用の重み。カメラの動きの軌跡を入力することで方向生成を制御します。支持多解像度(512、768、1024)的ビデオ予測、49フレームで毎秒8フレームの訓練、多言語予測をサポート | +| EasyAnimateV5.1-12b-zh | EasyAnimateV5.1 | 39 GB | [🤗リンク](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh) | [😄リンク](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh) | 公式のテキストからビデオへの変換用の重み。支持多解像度(512、768、1024)的ビデオ予測、49フレームで毎秒8フレームの訓練、多言語予測をサポート | + +
+ (Obsolete) EasyAnimateV5: 7B: | 名前 | 種類 | ストレージスペース | Hugging Face | Model Scope | 説明 | @@ -420,13 +518,14 @@ EasyAnimateV5: | EasyAnimateV5-12b-zh-Control | EasyAnimateV5 | 34 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh-Control) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh-Control) | 公式の動画制御重み。Canny、Depth、Pose、MLSDなどのさまざまな制御条件をサポートします。複数の解像度(512、768、1024)での動画予測をサポートし、49フレーム、毎秒8フレームでトレーニングされ、中国語と英語のバイリンガル予測をサポートします。 | | EasyAnimateV5-12b-zh | EasyAnimateV5 | 34 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh) | 公式のテキストから動画への重み。複数の解像度(512、768、1024)での動画予測をサポートし、49フレーム、毎秒8フレームでトレーニングされ、中国語と英語のバイリンガル予測をサポートします。 | | EasyAnimateV5-Reward-LoRAs | EasyAnimateV5 | - | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-Reward-LoRAs) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-Reward-LoRAs) | 公式インバース伝播技術モデルによるEasyAnimateV 5-12 b生成ビデオの最適化によるヒト選好の最適化| +
(Obsolete) EasyAnimateV4: | 名前 | 種類 | ストレージスペース | Hugging Face | Model Scope | 説明 | |--|--|--|--|--|--| -| EasyAnimateV4-XL-2-InP.tar.gz | EasyAnimateV4 | 解凍前: 8.9 GB / 解凍後: 14.0 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV4-XL-2-InP)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV4-XL-2-InP) | 公式のグラフ生成動画モデル。複数の解像度(512、768、1024、1280)での動画予測をサポートし、144フレーム、毎秒24フレームでトレーニングされています。 | +| EasyAnimateV4-XL-2-InP | EasyAnimateV4 | 解凍前: 8.9 GB / 解凍後: 14.0 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV4-XL-2-InP)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV4-XL-2-InP) | 公式のグラフ生成動画モデル。複数の解像度(512、768、1024、1280)での動画予測をサポートし、144フレーム、毎秒24フレームでトレーニングされています。 |
@@ -434,9 +533,9 @@ EasyAnimateV5: | 名前 | 種類 | ストレージスペース | Hugging Face | Model Scope | 説明 | |--|--|--|--|--|--| -| EasyAnimateV3-XL-2-InP-512x512.tar | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-512x512)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-512x512) | EasyAnimateV3公式の512x512テキストおよび画像から動画への重み。144フレーム、毎秒24フレームでトレーニングされています。 | -| EasyAnimateV3-XL-2-InP-768x768.tar | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-768x768) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-768x768) | EasyAnimateV3公式の768x768テキストおよび画像から動画への重み。144フレーム、毎秒24フレームでトレーニングされています。 | -| EasyAnimateV3-XL-2-InP-960x960.tar | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-960x960) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-960x960) | EasyAnimateV3公式の960x960テキストおよび画像から動画への重み。144フレーム、毎秒24フレームでトレーニングされています。 | +| EasyAnimateV3-XL-2-InP-512x512 | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-512x512)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-512x512) | EasyAnimateV3公式の512x512テキストおよび画像から動画への重み。144フレーム、毎秒24フレームでトレーニングされています。 | +| EasyAnimateV3-XL-2-InP-768x768 | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-768x768) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-768x768) | EasyAnimateV3公式の768x768テキストおよび画像から動画への重み。144フレーム、毎秒24フレームでトレーニングされています。 | +| EasyAnimateV3-XL-2-InP-960x960 | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-960x960) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-960x960) | EasyAnimateV3公式の960x960テキストおよび画像から動画への重み。144フレーム、毎秒24フレームでトレーニングされています。 |
@@ -444,8 +543,8 @@ EasyAnimateV5: | 名前 | 種類 | ストレージスペース | URL | Hugging Face | Model Scope | 説明 | |--|--|--|--|--|--|--| -| EasyAnimateV2-XL-2-512x512.tar | EasyAnimateV2 | 16.2GB | - | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV2-XL-2-512x512)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV2-XL-2-512x512) | EasyAnimateV2公式の512x512解像度の重み。144フレーム、毎秒24フレームでトレーニングされています。 | -| EasyAnimateV2-XL-2-768x768.tar | EasyAnimateV2 | 16.2GB | - | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV2-XL-2-768x768) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV2-XL-2-768x768) | EasyAnimateV2公式の768x768解像度の重み。144フレーム、毎秒24フレームでトレーニングされています。 | +| EasyAnimateV2-XL-2-512x512 | EasyAnimateV2 | 16.2GB | - | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV2-XL-2-512x512)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV2-XL-2-512x512) | EasyAnimateV2公式の512x512解像度の重み。144フレーム、毎秒24フレームでトレーニングされています。 | +| EasyAnimateV2-XL-2-768x768 | EasyAnimateV2 | 16.2GB | - | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV2-XL-2-768x768) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV2-XL-2-768x768) | EasyAnimateV2公式の768x768解像度の重み。144フレーム、毎秒24フレームでトレーニングされています。 | | easyanimatev2_minimalism_lora.safetensors | Lora of Pixart | 485.1MB | [ダウンロード](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/Personalized_Model/easyanimatev2_minimalism_lora.safetensors) | - | - | 特定のタイプの画像でトレーニングされたLora。画像は[URL](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v2/Minimalism.zip)からダウンロードできます。 |
@@ -485,8 +584,12 @@ EasyAnimateV5: - Open-Sora-Plan: https://github.com/PKU-YuanGroup/Open-Sora-Plan - Open-Sora: https://github.com/hpcaitech/Open-Sora - Animatediff: https://github.com/guoyww/AnimateDiff -- ComfyUI-EasyAnimateWrapper: https://github.com/kijai/ComfyUI-EasyAnimateWrapper - HunYuan DiT: https://github.com/tencent/HunyuanDiT +- ComfyUI-KJNodes: https://github.com/kijai/ComfyUI-KJNodes +- ComfyUI-EasyAnimateWrapper: https://github.com/kijai/ComfyUI-EasyAnimateWrapper +- ComfyUI-CameraCtrl-Wrapper: https://github.com/chaojie/ComfyUI-CameraCtrl-Wrapper +- CameraCtrl: https://github.com/hehao13/CameraCtrl +- DragAnything: https://github.com/showlab/DragAnything # ライセンス このプロジェクトは[Apache License (Version 2.0)](https://github.com/modelscope/modelscope/blob/master/LICENSE)の下でライセンスされています。 diff --git a/README_zh-CN.md b/README_zh-CN.md old mode 100644 new mode 100755 index 9c98406..880fc13 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -26,11 +26,12 @@ - [许可证](#许可证) # 简介 -EasyAnimate是一个基于transformer结构的pipeline,可用于生成AI图片与视频、训练Diffusion Transformer的基线模型与Lora模型,我们支持从已经训练好的EasyAnimate模型直接进行预测,生成不同分辨率,6秒左右、fps8的视频(EasyAnimateV5,1 ~ 49帧),也支持用户训练自己的基线模型与Lora模型,进行一定的风格变换。 +EasyAnimate是一个基于transformer结构的pipeline,可用于生成AI图片与视频、训练Diffusion Transformer的基线模型与Lora模型,我们支持从已经训练好的EasyAnimate模型直接进行预测,生成不同分辨率,6秒左右、fps8的视频(EasyAnimateV5.1,1 ~ 49帧),也支持用户训练自己的基线模型与Lora模型,进行一定的风格变换。 我们会逐渐支持从不同平台快速启动,请参阅 [快速启动](#快速启动)。 新特性: +- 更新到v5.1版本,应用Qwen2 VL作为文本编码器,支持多语言预测,使用Flow作为采样方式,除去常见控制如Canny、Pose外,还支持轨迹控制,相机控制等。[ 2025.01.21 ] - 使用奖励反向传播来训练Lora并优化视频,使其更好地符合人类偏好,详细信息请参见[此处](scripts/README_train_REVARD.md)。EasyAnimateV5-7b现已发布。[ 2024.11.27 ] - 更新到v5版本,最大支持1024x1024,49帧, 6s, 8fps视频生成,拓展模型规模到12B,应用MMDIT结构,支持不同输入的控制模型,支持中文与英文双语预测。[ 2024.11.08 ] - 更新到v4版本,最大支持1024x1024,144帧, 6s, 24fps视频生成,支持文、图、视频生视频,单个模型可支持512到1280任意分辨率,支持中文与英文双语预测。[ 2024.08.15 ] @@ -81,13 +82,12 @@ mkdir models/Diffusion_Transformer mkdir models/Motion_Module mkdir models/Personalized_Model -# Please use the hugginface link or modelscope link to download the EasyAnimateV5 model. -# I2V models -# https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh-InP -# https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh-InP -# T2V models -# https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh -# https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh +# Please use the hugginface link or modelscope link to download the EasyAnimateV5.1 model. +# https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-InP +# https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-InP + +# https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh +# https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh ``` ### 2. 本地安装: 环境检查/下载/安装 @@ -112,7 +112,7 @@ Linux 的详细信息: 我们需要大约 60GB 的可用磁盘空间,请检查! -EasyAnimateV5-12B的视频大小可以由不同的GPU Memory生成,包括: +EasyAnimateV5.1-12B的视频大小可以由不同的GPU Memory生成,包括: | GPU memory |384x672x25|384x672x49|576x1008x25|576x1008x49|768x1344x25|768x1344x49| |----------|----------|----------|----------|----------|----------|----------| | 16GB | 🧡 | 🧡 | ❌ | ❌ | ❌ | ❌ | @@ -120,6 +120,8 @@ EasyAnimateV5-12B的视频大小可以由不同的GPU Memory生成,包括: | 40GB | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | 80GB | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +由于qwen2-vl-7b的float16的权重,无法在16GB显存下运行,如果您的显存是16GB,请前往[Huggingface](https://huggingface.co/Qwen/Qwen2-VL-7B-Instruct-GPTQ-Int8)或者[Modelscope](https://modelscope.cn/models/Qwen/Qwen2-VL-7B-Instruct-GPTQ-Int8)下载量化后的qwen2-vl-7b对原有的text encoder进行替换,并安装对应的依赖库(auto-gptq, optimum)。 + EasyAnimateV5-7B的视频大小可以由不同的GPU Memory生成,包括: | GPU memory |384x672x25|384x672x49|576x1008x25|576x1008x49|768x1344x25|768x1344x49| |----------|----------|----------|----------|----------|----------|----------| @@ -132,59 +134,56 @@ EasyAnimateV5-7B的视频大小可以由不同的GPU Memory生成,包括: 有一些不支持torch.bfloat16的卡型,如2080ti、V100,需要将app.py、predict文件中的weight_dtype修改为torch.float16才可以运行。 -EasyAnimateV5-12B使用不同GPU在25个steps中的生成时间如下: +EasyAnimateV5.1-12B使用不同GPU在25个steps中的生成时间如下: | GPU |384x672x25|384x672x49|576x1008x25|576x1008x49|768x1344x25|768x1344x49| |----------|----------|----------|----------|----------|----------|----------| | A10 24GB |约120秒 (4.8s/it)|约240秒 (9.6s/it)|约320秒 (12.7s/it)| 约750秒 (29.8s/it)| ❌ | ❌ | | A100 80GB |约45秒 (1.75s/it)|约90秒 (3.7s/it)|约120秒 (4.7s/it)|约300秒 (11.4s/it)|约265秒 (10.6s/it)| 约710秒 (28.3s/it)| -(⭕️) 表示它可以在low_gpu_memory_mode=True的情况下运行,但速度较慢,同时❌ 表示它无法运行。 -
(Obsolete) EasyAnimateV3: EasyAnimateV3的视频大小可以由不同的GPU Memory生成,包括: -| GPU memory | 384x672x25 | 384x672x144 | 576x1008x72 | 576x1008x144 | 720x1280x72 | 720x1280x144 | +| GPU memory | 384x672x72 | 384x672x144 | 576x1008x72 | 576x1008x144 | 720x1280x72 | 720x1280x144 | |----------|----------|----------|----------|----------|----------|----------| | 12GB | ⭕️ | ⭕️ | ⭕️ | ⭕️ | ❌ | ❌ | | 16GB | ✅ | ✅ | ⭕️ | ⭕️ | ⭕️ | ❌ | | 24GB | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | 40GB | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | 80GB | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | + +(⭕️) 表示它可以在low_gpu_memory_mode=True的情况下运行,但速度较慢,同时❌ 表示它无法运行。
#### b. 权重放置 我们最好将[权重](#model-zoo)按照指定路径进行放置: -EasyAnimateV5: +EasyAnimateV5.1: ``` 📦 models/ ├── 📂 Diffusion_Transformer/ -│ ├── 📂 EasyAnimateV5-12b-zh-InP/ -│ └── 📂 EasyAnimateV5-12b-zh/ +│ ├── 📂 EasyAnimateV5.1-12b-zh-InP/ +│ └── 📂 EasyAnimateV5.1-12b-zh/ ├── 📂 Personalized_Model/ │ └── your trained trainformer model / your trained lora model (for UI load) ``` # 视频作品 -所展示的结果都是图生视频获得。 -### EasyAnimateV5-12b-zh-InP - -#### I2V +### 图生视频 EasyAnimateV5.1-12b-zh-InP
- + - + - + - +
@@ -193,16 +192,16 @@ EasyAnimateV5:
- + - + - + - +
@@ -210,34 +209,34 @@ EasyAnimateV5:
- + - + - + - +
-#### T2V +### 文生视频 EasyAnimateV5.1-12b-zh
- + - + - + - +
@@ -245,22 +244,38 @@ EasyAnimateV5:
- + - + - + - +
-### EasyAnimateV5-12b-zh-Control +### 控制生视频 EasyAnimateV5.1-12b-zh-Control +轨迹控制 + + + + + + +
+ + + + + +
+ +普通控制生视频(Canny、Pose、Depth等)
@@ -285,26 +300,59 @@ EasyAnimateV5:
+### 相机镜头控制 EasyAnimateV5.1-12b-zh-Control-Camera + + + + + + + + + + + + + + + + + + + +
+ Pan Up + + Pan Left + + Pan Right +
+ + + + + +
+ Pan Down + + Pan Up + Pan Left + + Pan Up + Pan Right +
+ + + + + +
+ + # 如何使用

1. 生成

-#### a、运行python文件 -- 步骤1:下载对应[权重](#model-zoo)放入models文件夹。 -- 步骤2:在predict_t2v.py文件中修改prompt、neg_prompt、guidance_scale和seed。 -- 步骤3:运行predict_t2v.py文件,等待生成结果,结果保存在samples/easyanimate-videos文件夹中。 -- 步骤4:如果想结合自己训练的其他backbone与Lora,则看情况修改predict_t2v.py中的predict_t2v.py和lora_path。 - -#### b、通过ui界面 -- 步骤1:下载对应[权重](#model-zoo)放入models文件夹。 -- 步骤2:运行app.py文件,进入gradio页面。 -- 步骤3:根据页面选择生成模型,填入prompt、neg_prompt、guidance_scale和seed等,点击生成,等待生成结果,结果保存在sample文件夹中。 - -#### c、通过comfyui -具体查看[ComfyUI README](comfyui/README.md)。 - -#### d、显存节省方案 -由于EasyAnimateV5的参数非常大,我们需要考虑显存节省方案,以节省显存适应消费级显卡。我们给每个预测文件都提供了GPU_memory_mode,可以在model_cpu_offload,model_cpu_offload_and_qfloat8,sequential_cpu_offload中进行选择。 +#### a、显存节省方案 +由于EasyAnimateV5和V5.1的参数非常大,我们需要考虑显存节省方案,以节省显存适应消费级显卡。我们给每个预测文件都提供了GPU_memory_mode,可以在model_cpu_offload,model_cpu_offload_and_qfloat8,sequential_cpu_offload中进行选择。 - model_cpu_offload代表整个模型在使用后会进入cpu,可以节省部分显存。 - model_cpu_offload_and_qfloat8代表整个模型在使用后会进入cpu,并且对transformer模型进行了float8的量化,可以节省更多的显存。 @@ -312,6 +360,47 @@ EasyAnimateV5: qfloat8会降低模型的性能,但可以节省更多的显存。如果显存足够,推荐使用model_cpu_offload。 +#### b、通过comfyui +具体查看[ComfyUI README](comfyui/README.md)。 + +#### c、运行python文件 +- 步骤1:下载对应[权重](#model-zoo)放入models文件夹。 +- 步骤2:根据不同的权重与预测目标使用不同的文件进行预测。 + - 文生视频: + - 使用predict_t2v.py文件中修改prompt、neg_prompt、guidance_scale和seed。 + - 而后运行predict_t2v.py文件,等待生成结果,结果保存在samples/easyanimate-videos文件夹中。 + - 图生视频: + - 使用predict_i2v.py文件中修改validation_image_start、validation_image_end、prompt、neg_prompt、guidance_scale和seed。 + - validation_image_start是视频的开始图片,validation_image_end是视频的结尾图片。 + - 而后运行predict_i2v.py文件,等待生成结果,结果保存在samples/easyanimate-videos_i2v文件夹中。 + - 视频生视频: + - 使用predict_v2v.py文件中修改validation_video、validation_image_end、prompt、neg_prompt、guidance_scale和seed。 + - validation_video是视频生视频的参考视频。您可以使用以下视频运行演示:[演示视频](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1/play_guitar.mp4) + - 而后运行predict_v2v.py文件,等待生成结果,结果保存在samples/easyanimate-videos_v2v文件夹中。 + - 普通控制生视频(Canny、Pose、Depth等): + - 使用predict_v2v_control.py文件中修改control_video、validation_image_end、prompt、neg_prompt、guidance_scale和seed。 + - control_video是控制生视频的控制视频,是使用Canny、Pose、Depth等算子提取后的视频。您可以使用以下视频运行演示:[演示视频](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1.1/pose.mp4) + - 而后运行predict_v2v_control.py文件,等待生成结果,结果保存在samples/easyanimate-videos_v2v_control文件夹中。 + - 轨迹控制视频: + - 使用predict_v2v_control.py文件中修改control_video、ref_image、validation_image_end、prompt、neg_prompt、guidance_scale和seed。 + - control_video是轨迹控制视频的控制视频,ref_image是参考的首帧图片。您可以使用以下图片和控制视频运行演示:[演示图像](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/dog.png),[演示视频](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/trajectory_demo.mp4) + - 而后运行predict_v2v_control.py文件,等待生成结果,结果保存在samples/easyanimate-videos_v2v_control文件夹中。 + - 推荐使用ComfyUI进行交互。 + - 相机控制视频: + - 使用predict_v2v_control.py文件中修改control_video、ref_image、validation_image_end、prompt、neg_prompt、guidance_scale和seed。 + - control_camera_txt是相机控制视频的控制文件,ref_image是参考的首帧图片。您可以使用以下图片和控制视频运行演示:[演示图像](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1/firework.png),[演示文件(来自于CameraCtrl)](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/0a3b5fb184936a83.txt) + - 而后运行predict_v2v_control.py文件,等待生成结果,结果保存在samples/easyanimate-videos_v2v_control文件夹中。 + - 推荐使用ComfyUI进行交互。 +- 步骤3:如果想结合自己训练的其他backbone与Lora,则看情况修改predict_t2v.py中的predict_t2v.py和lora_path。 + +#### d、通过ui界面 + +webui支持文生视频、图生视频、视频生视频和普通控制生视频(Canny、Pose、Depth等) + +- 步骤1:下载对应[权重](#model-zoo)放入models文件夹。 +- 步骤2:运行app.py文件,进入gradio页面。 +- 步骤3:根据页面选择生成模型,填入prompt、neg_prompt、guidance_scale和seed等,点击生成,等待生成结果,结果保存在sample文件夹中。 + ### 2. 模型训练 一个完整的EasyAnimate训练链路应该包括数据预处理、Video VAE训练、Video DiT训练。其中Video VAE训练是一个可选项,因为我们已经提供了训练好的Video VAE。 @@ -404,7 +493,18 @@ sh scripts/train.sh # 模型地址 -EasyAnimateV5: +EasyAnimateV5.1: + +12B: +| 名称 | 种类 | 存储空间 | Hugging Face | Model Scope | 描述 | +|--|--|--|--|--|--| +| EasyAnimateV5.1-12b-zh-InP | EasyAnimateV5.1 | 39 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-InP) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-InP)| 官方的图生视频权重。支持多分辨率(512,768,1024)的视频预测,支持多分辨率(512,768,1024)的视频预测,以49帧、每秒8帧进行训练,支持多语言预测 | +| EasyAnimateV5.1-12b-zh-Control | EasyAnimateV5.1 | 39 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-Control) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-Control)| 官方的视频控制权重,支持不同的控制条件,如Canny、Depth、Pose、MLSD等,同时支持使用轨迹控制。支持多分辨率(512,768,1024)的视频预测,支持多分辨率(512,768,1024)的视频预测,以49帧、每秒8帧进行训练,支持多语言预测 | +| EasyAnimateV5.1-12b-zh-Control-Camera | EasyAnimateV5.1 | 39 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-Control-Camera) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-Control-Camera)| 官方的视频相机控制权重,支持通过输入相机运动轨迹控制生成方向。支持多分辨率(512,768,1024)的视频预测,支持多分辨率(512,768,1024)的视频预测,以49帧、每秒8帧进行训练,支持多语言预测 | +| EasyAnimateV5.1-12b-zh | EasyAnimateV5.1 | 39 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh)| 官方的文生视频权重。支持多分辨率(512,768,1024)的视频预测,支持多分辨率(512,768,1024)的视频预测,以49帧、每秒8帧进行训练,支持多语言预测 | + +
+ (Obsolete) EasyAnimateV5: 7B: | 名称 | 种类 | 存储空间 | Hugging Face | Model Scope | 描述 | @@ -420,13 +520,14 @@ EasyAnimateV5: | EasyAnimateV5-12b-zh-Control | EasyAnimateV5 | 34 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh-Control) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh-Control)| 官方的视频控制权重,支持不同的控制条件,如Canny、Depth、Pose、MLSD等。支持多分辨率(512,768,1024)的视频预测,支持多分辨率(512,768,1024)的视频预测,以49帧、每秒8帧进行训练,支持中文与英文双语预测 | | EasyAnimateV5-12b-zh | EasyAnimateV5 | 34 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh)| 官方的文生视频权重。可用于进行下游任务的fientune。支持多分辨率(512,768,1024)的视频预测,支持多分辨率(512,768,1024)的视频预测,以49帧、每秒8帧进行训练,支持中文与英文双语预测 | | EasyAnimateV5-Reward-LoRAs | EasyAnimateV5 | - | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-Reward-LoRAs) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-Reward-LoRAs) | 通过奖励反向传播技术,优化了EasyAnimateV5-12b生成的视频,以更好地匹配人类偏好| +
(Obsolete) EasyAnimateV4: | 名称 | 种类 | 存储空间 | Hugging Face | Model Scope | 描述 | |--|--|--|--|--|--| -| EasyAnimateV4-XL-2-InP.tar.gz | EasyAnimateV4 | 解压前 8.9 GB / 解压后 14.0 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV4-XL-2-InP)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV4-XL-2-InP)| 官方的图生视频权重。支持多分辨率(512,768,1024,1280)的视频预测,以144帧、每秒24帧进行训练 | +| EasyAnimateV4-XL-2-InP | EasyAnimateV4 | 解压前 8.9 GB / 解压后 14.0 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV4-XL-2-InP)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV4-XL-2-InP)| 官方的图生视频权重。支持多分辨率(512,768,1024,1280)的视频预测,以144帧、每秒24帧进行训练 |
@@ -434,9 +535,9 @@ EasyAnimateV5: | 名称 | 种类 | 存储空间 | Hugging Face | Model Scope | 描述 | |--|--|--|--|--|--| -| EasyAnimateV3-XL-2-InP-512x512.tar | EasyAnimateV3 | 18.2GB| [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-512x512)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-512x512)| 官方的512x512分辨率的图生视频权重。以144帧、每秒24帧进行训练 | -| EasyAnimateV3-XL-2-InP-768x768.tar | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-768x768) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-768x768)| 官方的768x768分辨率的图生视频权重。以144帧、每秒24帧进行训练 | -| EasyAnimateV3-XL-2-InP-960x960.tar | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-960x960) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-960x960)| 官方的960x960(720P)分辨率的图生视频权重。以144帧、每秒24帧进行训练 | +| EasyAnimateV3-XL-2-InP-512x512 | EasyAnimateV3 | 18.2GB| [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-512x512)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-512x512)| 官方的512x512分辨率的图生视频权重。以144帧、每秒24帧进行训练 | +| EasyAnimateV3-XL-2-InP-768x768 | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-768x768) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-768x768)| 官方的768x768分辨率的图生视频权重。以144帧、每秒24帧进行训练 | +| EasyAnimateV3-XL-2-InP-960x960 | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-960x960) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-960x960)| 官方的960x960(720P)分辨率的图生视频权重。以144帧、每秒24帧进行训练 |
@@ -444,8 +545,8 @@ EasyAnimateV5: | 名称 | 种类 | 存储空间 | 下载地址 | Hugging Face | Model Scope | 描述 | |--|--|--|--|--|--|--| -| EasyAnimateV2-XL-2-512x512.tar | EasyAnimateV2 | 16.2GB | - | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV2-XL-2-512x512)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV2-XL-2-512x512)| 官方的512x512分辨率的重量。以144帧、每秒24帧进行训练 | -| EasyAnimateV2-XL-2-768x768.tar | EasyAnimateV2 | 16.2GB | - | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV2-XL-2-768x768) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV2-XL-2-768x768)| 官方的768x768分辨率的重量。以144帧、每秒24帧进行训练 | +| EasyAnimateV2-XL-2-512x512 | EasyAnimateV2 | 16.2GB | - | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV2-XL-2-512x512)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV2-XL-2-512x512)| 官方的512x512分辨率的重量。以144帧、每秒24帧进行训练 | +| EasyAnimateV2-XL-2-768x768 | EasyAnimateV2 | 16.2GB | - | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV2-XL-2-768x768) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV2-XL-2-768x768)| 官方的768x768分辨率的重量。以144帧、每秒24帧进行训练 | | easyanimatev2_minimalism_lora.safetensors | Lora of Pixart | 485.1MB | [Download](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/Personalized_Model/easyanimatev2_minimalism_lora.safetensors)| - | - | 使用特定类型的图像进行lora训练的结果。图片可从这里[下载](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/webui/Minimalism.zip). |
@@ -483,8 +584,12 @@ EasyAnimateV5: - Open-Sora-Plan: https://github.com/PKU-YuanGroup/Open-Sora-Plan - Open-Sora: https://github.com/hpcaitech/Open-Sora - Animatediff: https://github.com/guoyww/AnimateDiff -- ComfyUI-EasyAnimateWrapper: https://github.com/kijai/ComfyUI-EasyAnimateWrapper - HunYuan DiT: https://github.com/tencent/HunyuanDiT +- ComfyUI-KJNodes: https://github.com/kijai/ComfyUI-KJNodes +- ComfyUI-EasyAnimateWrapper: https://github.com/kijai/ComfyUI-EasyAnimateWrapper +- ComfyUI-CameraCtrl-Wrapper: https://github.com/chaojie/ComfyUI-CameraCtrl-Wrapper +- CameraCtrl: https://github.com/hehao13/CameraCtrl +- DragAnything: https://github.com/showlab/DragAnything # 许可证 本项目采用 [Apache License (Version 2.0)](https://github.com/modelscope/modelscope/blob/master/LICENSE). diff --git a/app.py b/app.py index c305319..eafead6 100644 --- a/app.py +++ b/app.py @@ -19,7 +19,11 @@ if __name__ == "__main__": # # "sequential_cpu_offload" means that each layer of the model will be moved to the CPU after use, # resulting in slower speeds but saving a large amount of GPU memory. - GPU_memory_mode = "model_cpu_offload" + # + # EasyAnimateV1, V2 and V3 support "model_cpu_offload" "sequential_cpu_offload" + # EasyAnimateV4, V5 support "model_cpu_offload" "model_cpu_offload_and_qfloat8" "sequential_cpu_offload" + # EasyAnimateV5.1 support "model_cpu_offload" "model_cpu_offload_and_qfloat8" + GPU_memory_mode = "model_cpu_offload_and_qfloat8" # Use torch.float16 if GPU does not support torch.bfloat16 # ome graphics cards, such as v100, 2080ti, do not support torch.bfloat16 weight_dtype = torch.bfloat16 @@ -29,11 +33,11 @@ if __name__ == "__main__": server_port = 7860 # Params below is used when ui_mode = "modelscope" - edition = "v5" + edition = "v5.1" # Config - config_path = "config/easyanimate_video_v5_magvit_multi_text_encoder.yaml" + config_path = "config/easyanimate_video_v5.1_magvit_qwen.yaml" # Model path of the pretrained model - model_name = "models/Diffusion_Transformer/EasyAnimateV5-12b-zh-InP" + model_name = "models/Diffusion_Transformer/EasyAnimateV5.1-12b-zh-InP" # "Inpaint" or "Control" model_type = "Inpaint" # Save dir diff --git a/asset/0a3b5fb184936a83.txt b/asset/0a3b5fb184936a83.txt new file mode 100644 index 0000000..4c64c81 --- /dev/null +++ b/asset/0a3b5fb184936a83.txt @@ -0,0 +1,175 @@ +https://www.youtube.com/watch?v=jQRHwqNC_0U +308341367 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.978989959 -0.010294991 -0.203648433 -0.000762398 -0.007398812 0.996273518 -0.085932352 -0.031535059 0.203774214 0.085633665 0.975265563 -0.153683138 +308374733 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.977586806 -0.011497887 -0.210218683 0.002481976 -0.007218716 0.996089876 -0.088050455 -0.033528951 0.210409090 0.087594472 0.973681271 -0.161050474 +308408100 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.976103604 -0.012630552 -0.216938347 0.005673227 -0.007174566 0.995891988 -0.090264283 -0.034554699 0.217187256 0.089663729 0.972003162 -0.168504957 +308441467 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.974509835 -0.013677491 -0.223927394 0.008982419 -0.007251760 0.995697796 -0.092376187 -0.035320741 0.224227488 0.091645375 0.970218122 -0.175504380 +308474833 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.972881317 -0.014926891 -0.230822623 0.012480344 -0.007060312 0.995534182 -0.094137549 -0.036223930 0.231196985 0.093214348 0.968431234 -0.182418105 +308508200 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.971116245 -0.015677260 -0.238091335 0.016362104 -0.007245381 0.995441616 -0.095097564 -0.037379468 0.238496885 0.094075851 0.966575921 -0.188874438 +308541567 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.969348371 -0.016915115 -0.245107263 0.019519189 -0.007186836 0.995248139 -0.097105585 -0.037570019 0.245585099 0.095890686 0.964620590 -0.194434889 +308608300 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.965482831 -0.019274237 -0.259752661 0.026318709 -0.007045615 0.994960845 -0.100016415 -0.039387193 0.260371476 0.098394245 0.960481763 -0.206582088 +308641667 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.963333905 -0.020359756 -0.267531812 0.029517279 -0.007176768 0.994804621 -0.101549059 -0.039716119 0.268209398 0.099745661 0.958182931 -0.212002640 +308675033 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.961007357 -0.021468673 -0.275688171 0.032829264 -0.007240514 0.994686186 -0.102698565 -0.040377398 0.276428014 0.100690201 0.955745280 -0.217063216 +308708400 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.958558679 -0.022696253 -0.283989727 0.036218875 -0.007334619 0.994525313 -0.104238495 -0.041102245 0.284800768 0.102001667 0.953144372 -0.221993067 +308741767 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.955935478 -0.023643453 -0.292623252 0.039282347 -0.007694451 0.994391501 -0.105481185 -0.040878463 0.293476015 0.103084780 0.950392187 -0.226182594 +308775133 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.953253388 -0.024266239 -0.301196188 0.041521166 -0.008146173 0.994344234 -0.105892323 -0.041338713 0.302062303 0.103395812 0.947664320 -0.229231401 +308808500 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.950509310 -0.025124749 -0.309678584 0.044002359 -0.008489858 0.994252503 -0.106723674 -0.041918199 0.310580105 0.104070969 0.944832921 -0.232545524 +308875233 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.944740891 -0.027402855 -0.326670647 0.049495607 -0.008745467 0.994038582 -0.108677343 -0.043024623 0.327701300 0.105528817 0.938869298 -0.238573853 +308908600 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.941721439 -0.028621495 -0.335173875 0.052471544 -0.008895036 0.993906736 -0.109864593 -0.043136616 0.336276084 0.106443226 0.935728729 -0.241383039 +308941967 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.938513279 -0.029339867 -0.343994170 0.055158821 -0.009417908 0.993835866 -0.110460714 -0.042776764 0.345114648 0.106908552 0.932451844 -0.243680639 +308975333 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.935223758 -0.030297186 -0.352758616 0.057885988 -0.009723495 0.993758440 -0.111129038 -0.043273624 0.353923738 0.107360564 0.929091871 -0.245835520 +309008700 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.931820571 -0.030954622 -0.361596853 0.060782047 -0.010214265 0.993724287 -0.111389861 -0.043572254 0.362775594 0.107488804 0.925656557 -0.247905504 +309042067 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.928349078 -0.031636182 -0.370360881 0.063609461 -0.010624910 0.993705988 -0.111514710 -0.043950611 0.371557742 0.107459627 0.922169864 -0.249844265 +309075433 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.924848616 -0.032647923 -0.378931642 0.066337543 -0.010918945 0.993619144 -0.112257645 -0.044287495 0.380178690 0.107958861 0.918590784 -0.251641562 +309108800 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.921171725 -0.033373199 -0.387722611 0.069763984 -0.011345040 0.993589520 -0.112477288 -0.045101364 0.388990849 0.108009629 0.914887965 -0.254094049 +309142167 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.917566240 -0.034442890 -0.396088243 0.072676557 -0.011466603 0.993533552 -0.112958498 -0.045261007 0.397417575 0.108188689 0.911237895 -0.255692348 +309208900 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.910201550 -0.035699584 -0.412624091 0.078700093 -0.012179646 0.993540049 -0.112826422 -0.046712792 0.413986415 0.107720405 0.903886914 -0.259251707 +309242267 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.906504273 -0.036408246 -0.420623928 0.081863254 -0.012601309 0.993497729 -0.113152504 -0.047517248 0.422008604 0.107873634 0.900151134 -0.260734715 +309275633 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.902823627 -0.037298322 -0.428390414 0.085099882 -0.012867143 0.993441820 -0.113612421 -0.048487376 0.429818511 0.108084142 0.896422803 -0.262961863 +309309000 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.899192631 -0.037919387 -0.435906827 0.088240571 -0.013205825 0.993431985 -0.113659412 -0.050131037 0.437353671 0.107958212 0.892785966 -0.264952805 +309342367 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.895653009 -0.038608752 -0.443074495 0.091415472 -0.013500394 0.993405759 -0.113854058 -0.051581030 0.444548517 0.107955411 0.889225662 -0.267106652 +309409100 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.889143944 -0.039823636 -0.455891609 0.096863763 -0.014223916 0.993320107 -0.114511266 -0.055615774 0.457406580 0.108301558 0.882638097 -0.271985441 +309442467 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.886038363 -0.040410291 -0.461847425 0.099748874 -0.014641317 0.993258059 -0.114996016 -0.057240949 0.463380694 0.108652942 0.879473090 -0.275233826 +309475833 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.883017659 -0.040438525 -0.467594445 0.102214218 -0.015467658 0.993232727 -0.115106329 -0.059105627 0.469084859 0.108873509 0.876416564 -0.278934678 +309509200 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.880132735 -0.040309701 -0.473013163 0.104434028 -0.016339598 0.993225932 -0.115044698 -0.062218033 0.474446356 0.108983450 0.873512030 -0.284099169 +309542567 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.877503335 -0.040934134 -0.477820396 0.106557835 -0.016707798 0.993136227 -0.115763828 -0.063666219 0.479279459 0.109566472 0.870796442 -0.287968235 +309575933 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.874932587 -0.041235302 -0.482485890 0.109189737 -0.017189724 0.993095100 -0.116045728 -0.065114870 0.483939558 0.109825991 0.868182421 -0.292159517 +309609300 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.872594893 -0.041835159 -0.486649781 0.111891410 -0.017455684 0.993017972 -0.116664611 -0.066478178 0.488132656 0.110295743 0.865772128 -0.296800241 +309642667 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.870423913 -0.042362280 -0.490476996 0.114751898 -0.017655376 0.992963910 -0.117093928 -0.068415958 0.491986305 0.110580906 0.863551557 -0.302172177 +309676033 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.868541598 -0.042488880 -0.493791699 0.117357209 -0.018038228 0.992948353 -0.117167257 -0.070397371 0.495287955 0.110671766 0.861650527 -0.307614305 +309709400 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.867060125 -0.042669602 -0.496372908 0.120216022 -0.018459057 0.992890000 -0.117595725 -0.072785828 0.497861445 0.111125141 0.860107660 -0.313736773 +309742767 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.866088688 -0.043403506 -0.498002529 0.122453533 -0.018637195 0.992727280 -0.118933745 -0.074490817 0.499542832 0.112288542 0.858980954 -0.320628504 +309776133 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.865360856 -0.043743186 -0.499236524 0.125043974 -0.018964697 0.992611408 -0.119845577 -0.076056429 0.500790298 0.113177545 0.858137488 -0.327066266 +309809500 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.864906728 -0.043624546 -0.500033319 0.127037753 -0.019370638 0.992572725 -0.120100662 -0.077751779 0.501558721 0.113561831 0.857637763 -0.333684160 +309842867 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.864720166 -0.043874834 -0.500333965 0.129334470 -0.019549016 0.992482126 -0.120818146 -0.078636717 0.501873374 0.114254922 0.857361615 -0.339359986 +309876233 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.864809155 -0.044859517 -0.500092745 0.131949856 -0.019065719 0.992348671 -0.121986344 -0.079543457 0.501738608 0.115029529 0.857336879 -0.345644978 +309909600 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.864958882 -0.045732468 -0.499754608 0.135265495 -0.018738804 0.992201388 -0.123228706 -0.079543122 0.501492739 0.115952566 0.857356429 -0.352907848 +309942967 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.865252912 -0.046075005 -0.499213874 0.137627428 -0.018783100 0.992089391 -0.124120452 -0.079804843 0.500983596 0.116772369 0.857542753 -0.358817645 +309976333 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.865726292 -0.046780419 -0.498326808 0.140424549 -0.018578010 0.991933227 -0.125392660 -0.079780661 0.500172853 0.117813639 0.857873559 -0.365907578 +310009700 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.866338551 -0.047223259 -0.497219771 0.142905036 -0.018469006 0.991810381 -0.126376569 -0.079630830 0.499115646 0.118668057 0.858371377 -0.372282108 +310043067 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.867112100 -0.048142657 -0.495781094 0.145746867 -0.017913677 0.991660655 -0.127625570 -0.079277595 0.497790813 0.119546935 0.859018505 -0.379002051 +310076433 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.868119121 -0.048691329 -0.493961900 0.147833429 -0.017613675 0.991528034 -0.128693298 -0.078908849 0.496043295 0.120421596 0.859906793 -0.385541694 +310109800 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.869378269 -0.049083445 -0.491703421 0.149461353 -0.017440626 0.991386771 -0.129800156 -0.078681040 0.493839294 0.121421054 0.861034095 -0.391950834 +310143167 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.870869160 -0.049489144 -0.489017129 0.150919036 -0.017325647 0.991209030 -0.131166071 -0.078495760 0.491209477 0.122701019 0.862355888 -0.397968385 +310176533 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.872643054 -0.050130539 -0.485778838 0.152483740 -0.016998386 0.990996718 -0.132802665 -0.078367440 0.488062710 0.124146774 0.863934219 -0.404034113 +310209900 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.874584794 -0.050529797 -0.482232451 0.154256000 -0.016926475 0.990767121 -0.134513766 -0.078088113 0.484577030 0.125806183 0.865654588 -0.410133718 +310243267 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.876766086 -0.051406279 -0.478161752 0.155479703 -0.016476333 0.990476072 -0.136695534 -0.077475491 0.480634779 0.127728358 0.867568851 -0.416093417 +310276633 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.878964126 -0.051730625 -0.474073857 0.156369104 -0.016295806 0.990260482 -0.138270065 -0.077875636 0.476609409 0.129259840 0.869560421 -0.421790538 +310310000 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.881164610 -0.052391429 -0.469897866 0.158341644 -0.015933618 0.989986777 -0.140258059 -0.077393435 0.472541004 0.131077617 0.871506572 -0.427604406 +310343367 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.883479238 -0.053010881 -0.465461344 0.159226902 -0.015646443 0.989683807 -0.142412066 -0.076457552 0.468208939 0.133100927 0.873535633 -0.432891901 +310376733 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.885817289 -0.053641621 -0.460923284 0.160340201 -0.015189376 0.989411891 -0.144337848 -0.076142363 0.463785470 0.134858102 0.875623405 -0.438094773 +310410100 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.888150871 -0.054433405 -0.456316859 0.161588987 -0.014720289 0.989080846 -0.146636873 -0.075492546 0.459316224 0.136952788 0.877651751 -0.443043392 +310443467 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.890383422 -0.055029280 -0.451872855 0.163150185 -0.014452326 0.988748491 -0.148887515 -0.074526466 0.454981804 0.139097601 0.879570007 -0.448171618 +310476833 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.892586112 -0.055750020 -0.447417051 0.164995991 -0.014085147 0.988394022 -0.151257530 -0.074047945 0.450656950 0.141312301 0.881441534 -0.453008463 +310510200 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.894740224 -0.056834452 -0.442955762 0.167782038 -0.013566600 0.987951994 -0.154165044 -0.073001057 0.446380883 0.143947065 0.883189321 -0.458082426 +310543567 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.896918535 -0.057157692 -0.438486159 0.169308129 -0.013389797 0.987645686 -0.156130597 -0.072796601 0.441993028 0.145907670 0.885072410 -0.463078899 +310576933 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.899071574 -0.057735413 -0.433977962 0.171331268 -0.012979353 0.987315476 -0.158239439 -0.073365528 0.437609196 0.147901341 0.886917949 -0.467917732 +310610300 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.901260018 -0.058569729 -0.429301769 0.173732582 -0.012589230 0.986863136 -0.161067307 -0.073096514 0.433095753 0.150568098 0.888682902 -0.473122013 +310643667 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.903436303 -0.058904551 -0.424656391 0.175884090 -0.012623640 0.986431837 -0.163685232 -0.072987367 0.428536385 0.153239891 0.890434802 -0.478237266 +310677033 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.905687928 -0.059230026 -0.419787079 0.177477414 -0.012393922 0.986069798 -0.165869713 -0.073552826 0.423763841 0.155429006 0.892337382 -0.483350707 +310710400 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.907836795 -0.059959110 -0.415014774 0.180778921 -0.011716512 0.985710561 -0.168039829 -0.074532453 0.419159949 0.157415256 0.894161820 -0.488501040 +310743767 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.910057962 -0.060243253 -0.410079598 0.183003510 -0.011557028 0.985307992 -0.170395508 -0.075045629 0.414319873 0.159809083 0.895991147 -0.493310403 +310777133 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.912262857 -0.061014563 -0.405035436 0.186047988 -0.010837990 0.984901488 -0.172776058 -0.075995106 0.409461886 0.162006959 0.897827804 -0.498587911 +310810500 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.914368153 -0.061986543 -0.400110722 0.189918152 -0.009896113 0.984494388 -0.175136760 -0.076662609 0.404762864 0.164099008 0.899576843 -0.503910219 +310843867 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.916438997 -0.062444899 -0.395272344 0.193107816 -0.009283510 0.984166741 -0.177001923 -0.078113470 0.400066763 0.165880978 0.901349068 -0.509387915 +310877233 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.918424070 -0.063240312 -0.390509814 0.197583308 -0.008470051 0.983769834 -0.179234952 -0.079494934 0.395506650 0.167921335 0.902982235 -0.515165633 +310910600 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.920403063 -0.064143844 -0.385673106 0.202006428 -0.007444195 0.983395875 -0.181320533 -0.080844478 0.390899926 0.169759005 0.904643118 -0.521350926 +310943967 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.922320426 -0.064726412 -0.380966574 0.206782136 -0.006681100 0.983053684 -0.183196262 -0.082257295 0.386368215 0.171510920 0.906258047 -0.527740396 +310977333 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.924230337 -0.065651573 -0.376149088 0.212224392 -0.005523140 0.982706308 -0.185088485 -0.084043648 0.381795466 0.173141927 0.907884419 -0.534609231 +311010700 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.926216066 -0.066453293 -0.371089995 0.217445108 -0.004528342 0.982309401 -0.187210441 -0.086343467 0.376965940 0.175077736 0.909529805 -0.542115507 +311044067 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.928198338 -0.067681506 -0.365878463 0.223651886 -0.003151126 0.981852353 -0.189620674 -0.087078935 0.372072458 0.177158520 0.911140442 -0.549962431 +311077433 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.930172324 -0.068023682 -0.360766143 0.229434932 -0.002271302 0.981599092 -0.190939993 -0.089419263 0.367116153 0.178426504 0.912901819 -0.557824120 +311110800 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.932240486 -0.069168136 -0.355166763 0.236034988 -0.000758263 0.981183887 -0.193074211 -0.090408553 0.361838460 0.180260912 0.914646864 -0.565607851 +311144167 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.934392452 -0.069684349 -0.349363536 0.241615506 0.000344464 0.980858505 -0.194721580 -0.091157813 0.356245220 0.181826025 0.916530788 -0.573942644 +311177533 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.936547995 -0.069909394 -0.343497574 0.247953960 0.001326483 0.980611086 -0.195959508 -0.092038047 0.350536942 0.183069825 0.918482065 -0.582354554 +311210900 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.938818872 -0.070407048 -0.337137878 0.254541679 0.002780362 0.980399191 -0.197001785 -0.093128492 0.344399989 0.184011623 0.920613050 -0.591251028 +311244267 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.941219509 -0.071606763 -0.330118626 0.261408430 0.004858018 0.980041802 -0.198732078 -0.093668373 0.337760627 0.185446784 0.922782362 -0.600339638 +311277633 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.943640530 -0.073040113 -0.322812200 0.268115280 0.007165964 0.979625583 -0.200704545 -0.093540800 0.330894560 0.187079668 0.924937844 -0.610000653 +311311000 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.945890248 -0.073155127 -0.316132903 0.274995138 0.008447010 0.979476154 -0.201382905 -0.093009238 0.324376851 0.187815741 0.927094877 -0.618876927 +311344367 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.948223889 -0.073267952 -0.309036076 0.280257918 0.010031201 0.979450643 -0.201434463 -0.094604409 0.317444265 0.187904969 0.929473460 -0.627696107 +311377733 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.950452030 -0.073764659 -0.301992863 0.286158851 0.011713448 0.979248285 -0.202325478 -0.094314557 0.310650468 0.188763276 0.931592584 -0.636671149 +311411100 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.952679396 -0.074046955 -0.294820279 0.291001410 0.013235929 0.979062200 -0.203130454 -0.093537715 0.303688586 0.189615980 0.933712482 -0.646112429 +311444467 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.954840362 -0.073838852 -0.287797987 0.295123006 0.014388267 0.978982508 -0.203435913 -0.093086854 0.296770692 0.190107912 0.935834467 -0.654897124 +311477833 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.956956148 -0.073810153 -0.280690134 0.298572477 0.015708711 0.978876293 -0.203849196 -0.091982212 0.289807051 0.190665469 0.937901139 -0.663605042 +311511200 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.958909094 -0.073471151 -0.274035364 0.302887300 0.016908780 0.978969991 -0.203302488 -0.091291349 0.283209264 0.190314993 0.939985514 -0.671861542 +311544567 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.960915208 -0.073034637 -0.267035455 0.305233885 0.018035194 0.979039550 -0.202870086 -0.090740338 0.276254803 0.190124914 0.942091167 -0.679444737 +311577933 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.962860346 -0.072711810 -0.260024965 0.307762635 0.019370908 0.979177117 -0.202081606 -0.090920256 0.269304216 0.189539433 0.944219291 -0.687383897 +311611300 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.964723289 -0.072647713 -0.253043920 0.310300920 0.020861125 0.979244888 -0.201604083 -0.090013857 0.262438059 0.189213380 0.946215928 -0.695448574 +311644667 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.966474175 -0.072109833 -0.246430144 0.312982566 0.021857465 0.979376078 -0.200860038 -0.089453733 0.255831778 0.188739702 0.948117852 -0.703693245 +311678033 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.968180656 -0.071329243 -0.239871487 0.315451422 0.022735778 0.979626119 -0.199538723 -0.090076508 0.249217331 0.187735870 0.950076818 -0.711800049 +311711400 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.969955564 -0.071214139 -0.232625648 0.317100588 0.024302205 0.979777157 -0.198610634 -0.090612638 0.242065176 0.186990172 0.952070951 -0.720312801 +311744767 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.971625566 -0.070924461 -0.225640222 0.319752746 0.025612244 0.979922652 -0.197726145 -0.089705197 0.235133588 0.186336622 0.953934431 -0.728574924 +311778133 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.973283887 -0.070123084 -0.218634889 0.321794502 0.026567144 0.980219960 -0.196119979 -0.090112218 0.228062809 0.185071915 0.955895245 -0.736742499 +311811500 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.974936903 -0.069585592 -0.211319387 0.323677056 0.027854756 0.980532587 -0.194370747 -0.091601931 0.220730945 0.183612958 0.957895696 -0.745155898 +311844867 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.976595521 -0.069111675 -0.203678071 0.325412651 0.029160401 0.980770290 -0.192974925 -0.093024940 0.213098213 0.182519123 0.959831178 -0.754124007 +311878233 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.978225887 -0.068719827 -0.195835873 0.326756322 0.030567350 0.981006324 -0.191552296 -0.094584758 0.205279663 0.181395233 0.961746335 -0.763424584 +311911600 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.979814947 -0.068927020 -0.187647790 0.328006537 0.032526776 0.981138051 -0.190552205 -0.095768335 0.197242588 0.180602327 0.963575721 -0.773234588 +311944967 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.981304646 -0.068062313 -0.180024162 0.328447396 0.033387616 0.981400371 -0.189046592 -0.097650805 0.189542726 0.179501727 0.965325177 -0.782386835 +312011700 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.984019220 -0.066852629 -0.165036008 0.330236824 0.035566866 0.981961370 -0.185706273 -0.102535450 0.174473941 0.176868737 0.968646646 -0.801399816 +312045067 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.985290170 -0.067055240 -0.157184348 0.331143493 0.037411377 0.982126057 -0.184468970 -0.104100012 0.166744456 0.175874978 0.970187783 -0.810926836 +312078433 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.986511946 -0.066422537 -0.149607107 0.331300563 0.038505107 0.982488394 -0.182301641 -0.108530280 0.159096181 0.174082100 0.971794128 -0.821033556 +312111800 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.987675488 -0.066199258 -0.141826585 0.331072149 0.039902102 0.982707620 -0.180813685 -0.111372361 0.151343793 0.172926068 0.973237693 -0.830963007 +312145167 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.988770187 -0.066454358 -0.133855835 0.331553583 0.041716520 0.982821703 -0.179780975 -0.112955349 0.143503651 0.172178060 0.974557042 -0.841682363 +312178533 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.989837110 -0.066110969 -0.125903890 0.331052202 0.042937610 0.982986569 -0.178588212 -0.114563927 0.135568470 0.171367228 0.975835264 -0.852094252 +312211900 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.990878463 -0.065578103 -0.117725685 0.330035525 0.044033892 0.983213663 -0.177064568 -0.116183646 0.127361059 0.170265540 0.977132976 -0.862277506 +312278633 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.992744386 -0.066010535 -0.100504406 0.327745317 0.047590412 0.983286500 -0.175735101 -0.116441532 0.110424995 0.169676989 0.979293644 -0.882789347 +312312000 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.993589461 -0.066247106 -0.091604158 0.325707106 0.049457088 0.983374178 -0.174726233 -0.116631901 0.101656273 0.169075668 0.980346560 -0.892507297 +312345367 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.994361401 -0.066342220 -0.082729384 0.323188511 0.051096663 0.983346462 -0.174410120 -0.115774985 0.092922404 0.169199482 0.981191576 -0.902159014 +312378733 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.995042205 -0.066394515 -0.074045502 0.321123021 0.052643880 0.983293295 -0.174249545 -0.114348298 0.084377661 0.169487610 0.981913626 -0.912162258 +312412100 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.995613933 -0.066976570 -0.065322898 0.318750973 0.054698888 0.983161271 -0.174361438 -0.112374767 0.075901076 0.170023575 0.982512593 -0.921916724 +312445467 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.996080637 -0.067227937 -0.057478175 0.317307963 0.056290012 0.983075321 -0.174339861 -0.110280604 0.068225883 0.170421124 0.983006537 -0.931334752 +312478833 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.996468782 -0.067571491 -0.049840629 0.315618106 0.057968128 0.983067632 -0.173832446 -0.109043532 0.060742829 0.170329422 0.983513176 -0.939837206 +312545567 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.996968269 -0.069315284 -0.035350382 0.314066124 0.062181991 0.982864857 -0.173522487 -0.105838595 0.046772409 0.170798257 0.984195232 -0.955363982 +312578933 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.997107208 -0.070450135 -0.028530471 0.313899569 0.064466320 0.982708693 -0.173573241 -0.103689727 0.040265400 0.171231866 0.984407604 -0.963730355 +312612300 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.997229338 -0.070999384 -0.022197181 0.313870797 0.066098705 0.982622564 -0.173446819 -0.101718329 0.034126069 0.171499059 0.984593034 -0.971128799 +312645667 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.997287095 -0.071806230 -0.016196592 0.314430778 0.067936778 0.982572377 -0.173020676 -0.100299084 0.028338285 0.171450943 0.984785020 -0.978330016 +312679033 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.997283638 -0.072916023 -0.010419844 0.315631738 0.070025228 0.982450604 -0.172879487 -0.098055672 0.022842666 0.171680242 0.984887838 -0.984845557 +312712400 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.997224033 -0.074311025 -0.004705389 0.317342441 0.072381146 0.982274473 -0.172909766 -0.096280689 0.017471086 0.172089189 0.984926403 -0.992249970 +312745767 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.997132242 -0.075674556 0.000820772 0.318938381 0.074675784 0.982096016 -0.172947705 -0.094996659 0.012281665 0.172513023 0.984930694 -0.999476186 +312812500 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.996909559 -0.077861786 0.010432968 0.324937323 0.078491226 0.981783450 -0.173032805 -0.093071054 0.003229727 0.173316956 0.984860778 -1.013745687 +312845867 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.996714592 -0.079571702 0.015111177 0.328924485 0.080987111 0.981538177 -0.173274204 -0.092338295 -0.001044474 0.173928753 0.984757662 -1.021159174 +312879233 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.996513069 -0.081097923 0.019618591 0.333397250 0.083276160 0.981306016 -0.173503771 -0.091893403 -0.005181046 0.174532533 0.984637797 -1.029133014 +312912600 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.996304870 -0.082457803 0.024027303 0.337992655 0.085388854 0.981065631 -0.173836112 -0.091045184 -0.009238216 0.175245434 0.984481454 -1.037087884 +312945967 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.996070623 -0.083987780 0.028095186 0.343686830 0.087608948 0.980874479 -0.173810199 -0.091655046 -0.012959917 0.175588638 0.984378338 -1.044999310 +312979333 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.995813906 -0.085612535 0.032017611 0.350273173 0.089899555 0.980658352 -0.173859864 -0.091970538 -0.016513752 0.176010445 0.984249771 -1.053555188 +313012700 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.995503247 -0.087631822 0.035970747 0.357148609 0.092598148 0.980293870 -0.174497828 -0.090711195 -0.019970341 0.177043974 0.984000325 -1.061743164 +313079433 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.994937420 -0.090959743 0.042729396 0.373297310 0.097084567 0.979798555 -0.174840838 -0.090398274 -0.025962725 0.178104073 0.983669102 -1.078977520 +313112800 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.994614422 -0.092794865 0.046166051 0.381723551 0.099512480 0.979511738 -0.175082847 -0.089482401 -0.028973402 0.178734019 0.983470738 -1.087453627 +313146167 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.994313717 -0.094416864 0.049250986 0.390708714 0.101667836 0.979261696 -0.175243229 -0.088835057 -0.031683687 0.179253995 0.983292520 -1.095919010 +313179533 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.993896365 -0.096884072 0.052758712 0.399868176 0.104732476 0.978918135 -0.175357893 -0.087236466 -0.034657072 0.179813117 0.983090103 -1.104234639 +313212900 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.993500292 -0.099100336 0.056002490 0.409121225 0.107507646 0.978583992 -0.175543502 -0.085376763 -0.037406720 0.180423230 0.982877493 -1.112553390 +313246267 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.993204832 -0.100486375 0.058708660 0.418360786 0.109358117 0.978399456 -0.175428808 -0.084241278 -0.039812319 0.180656999 0.982740045 -1.120491631 +313279633 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.992889166 -0.101999812 0.061376773 0.427805427 0.111317404 0.978242636 -0.175070733 -0.083516541 -0.042184193 0.180658147 0.982640922 -1.127647949 +313346367 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.992061853 -0.106166579 0.067394227 0.445514137 0.116490223 0.977736056 -0.174534425 -0.080255502 -0.047364041 0.180999696 0.982341945 -1.142586657 +313379733 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.991662741 -0.107884496 0.070469089 0.453512451 0.118734807 0.977493227 -0.174381718 -0.078337505 -0.050069973 0.181294993 0.982153296 -1.150170997 +313413100 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.991388381 -0.108525760 0.073288999 0.460772594 0.119887300 0.977330446 -0.174505711 -0.076005143 -0.052689210 0.181789353 0.981924891 -1.158226337 +313446467 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.991075039 -0.109311312 0.076297723 0.467606044 0.121208653 0.977176785 -0.174453244 -0.073937978 -0.055486653 0.182144195 0.981705010 -1.166156226 +313479833 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.990619421 -0.110958062 0.079758711 0.474376029 0.123461276 0.976910770 -0.174363598 -0.071721072 -0.058570098 0.182575077 0.981445789 -1.174459386 +313513200 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.990172505 -0.112342887 0.083291881 0.480516238 0.125477433 0.976650715 -0.174381196 -0.068654050 -0.061756589 0.183118701 0.981149137 -1.183004429 +313546567 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.989827931 -0.113005586 0.086431257 0.486888950 0.126704708 0.976506293 -0.174302593 -0.067375589 -0.064703502 0.183480829 0.980891585 -1.191320360 +313613300 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.988945186 -0.115346938 0.093179770 0.499662732 0.130252182 0.976069808 -0.174132317 -0.063686413 -0.070864335 0.184344187 0.980303764 -1.208898578 +313646667 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.988459945 -0.116609581 0.096691161 0.506144929 0.132137433 0.975849390 -0.173947304 -0.062244953 -0.074072085 0.184716463 0.979996502 -1.217641786 +313680033 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.988017082 -0.117491372 0.100090228 0.512718848 0.133605868 0.975730240 -0.173493326 -0.061754347 -0.077277094 0.184787005 0.979735672 -1.226863594 +313713400 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.987563848 -0.118110009 0.103767216 0.518689193 0.134914964 0.975524366 -0.173638180 -0.060329507 -0.080719039 0.185478538 0.979327381 -1.236867288 +313746767 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.987033010 -0.118996739 0.107729606 0.524762689 0.136519402 0.975330830 -0.173470974 -0.059829060 -0.084429525 0.185928762 0.978929102 -1.246822833 +313780133 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.986401439 -0.120181613 0.112109698 0.530664721 0.138509735 0.975059330 -0.173419476 -0.059006379 -0.088471778 0.186589509 0.978446245 -1.258217434 +313813500 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.985843003 -0.120521255 0.116568401 0.535510951 0.139647990 0.974971712 -0.172998726 -0.059314780 -0.092800871 0.186828136 0.977999628 -1.269093504 +313846867 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.985232770 -0.121064983 0.121076837 0.540980122 0.140994951 0.974857450 -0.172549531 -0.060076193 -0.097142950 0.187072679 0.977531075 -1.280287059 +313880233 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.984595537 -0.121475510 0.125759080 0.546086741 0.142260700 0.974723399 -0.172267690 -0.060268856 -0.101654008 0.187504575 0.976989508 -1.291598254 +313913600 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.983899355 -0.121927045 0.130674735 0.550774390 0.143620268 0.974562824 -0.172047913 -0.060330612 -0.106373444 0.188045368 0.976382911 -1.304011370 +313946967 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.983338177 -0.121466361 0.135247782 0.555621417 0.143982768 0.974595249 -0.171560779 -0.061902538 -0.110972978 0.188175604 0.975845754 -1.315990335 +313980333 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.982553363 -0.122138359 0.140253618 0.560540623 0.145558864 0.974434435 -0.171143770 -0.061990912 -0.115764737 0.188573048 0.975212157 -1.328550227 +314013700 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.981700897 -0.122885726 0.145473063 0.564752855 0.147349611 0.974100709 -0.171510577 -0.060449997 -0.120629206 0.189807490 0.974382758 -1.341307995 +314047067 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.981288731 -0.121079043 0.149707228 0.568971736 0.146342263 0.974299014 -0.171246439 -0.061612007 -0.125125244 0.189950690 0.973787665 -1.353429746 +314080433 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.980634212 -0.120555021 0.154347181 0.573425937 0.146657199 0.974337697 -0.170756325 -0.061823666 -0.129800752 0.190085620 0.973149121 -1.365053305 +314113800 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.979800701 -0.120869070 0.159314975 0.577789203 0.147821948 0.974305928 -0.169931293 -0.061812832 -0.134682089 0.190049052 0.972492695 -1.376315743 +314147167 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.979101181 -0.120271996 0.163998693 0.582034585 0.148152247 0.974241316 -0.170014083 -0.060640746 -0.139326364 0.190757766 0.971699357 -1.388087496 +314180533 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.978274286 -0.120084383 0.168994710 0.585730462 0.148978561 0.974074721 -0.170246392 -0.058376753 -0.144169539 0.191724256 0.970802248 -1.399741900 +314213900 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.977639973 -0.118906699 0.173439533 0.589550700 0.148618758 0.974200964 -0.169837952 -0.057725391 -0.148770094 0.191816747 0.970089555 -1.410344264 +314247267 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.977026641 -0.117842659 0.177572533 0.593727427 0.148278132 0.974358559 -0.169230476 -0.057729606 -0.153076753 0.191672817 0.969447792 -1.420295571 +314280633 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.976238608 -0.117690220 0.181953743 0.597938800 0.148924977 0.974331498 -0.168817803 -0.056156679 -0.157415062 0.191903919 0.968707085 -1.430101872 +314314000 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.975512862 -0.117311463 0.186044857 0.602367459 0.149293035 0.974342108 -0.168431297 -0.054473966 -0.161512420 0.192082092 0.967997015 -1.439945870 +314347367 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.974990189 -0.115997307 0.189575255 0.606349966 0.148653150 0.974467874 -0.168269381 -0.053204794 -0.165216208 0.192241952 0.967339993 -1.448945088 +314380733 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.974489450 -0.115080222 0.192683354 0.612068472 0.148202047 0.974687278 -0.167394280 -0.053188083 -0.168542251 0.191680029 0.966877580 -1.457338892 +314414100 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.974016428 -0.114069194 0.195653155 0.617461597 0.147714734 0.974824429 -0.167025849 -0.052650804 -0.171674982 0.191586778 0.966344774 -1.466093030 +314480833 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.973019421 -0.112725042 0.201311350 0.630637185 0.147350907 0.975013077 -0.166244537 -0.051408918 -0.177541271 0.191422582 0.965316772 -1.483657565 +314514200 0.532139961 0.946026558 0.500000000 0.500000000 0.000000000 0.000000000 0.972666502 -0.111541182 0.203662574 0.637904932 0.146565586 0.975191951 -0.165888965 -0.051916880 -0.180106655 0.191204563 0.964884639 -1.492338334 diff --git a/asset/1.mp4 b/asset/1.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..d6db2e4fd4d4b2af1f939934bb2bf763e788fa03 GIT binary patch literal 467060 zcmX_lV_+s-ux4!A6Wewswyg=@*tTuk6Whtewr$%sHs8Iw`=igPQ}vYVN1tvWARs~$ zCwDt@M_X$kAP}Jc_MeB@z{QBk+K!b82nYzu!~p;Rg2Y+2Ha2kj!7M|7e}B(!h@N&H ztxB|{(5?`!l3ZQ8F|)H0(h(ZjIsgcn*jWf2SQyzE3E7Md*$oWXe*_ZrKL7?<1yON2 zRzg8F;UAv9)tDx3zKPCNwfIG%(_0B6I+l@G%n_0}QQfjV$??xEZ+_2@Pxv ztlS*|e2i`^+>CBaOe}=f06sH-8=<4K;Sa@5Xy@quqx!SzIT-UX(KG%i{Vasm=57FE zz5gsS{b=Yp7}%Hs_?XxUjm#Wutqt^kRGA2!8~|2U=8iuUryHlSk<$-hWN*#K_!EMG zv4^b&(6`(-0nZb{~EBj)3Y@(aRfN=(J>P`nK}Gu{21aSw6e9e zG%)))>HR+@3!$TxxzSHB|Bt~)XyfodPK?a04V?Z9#N5US;9zC&1Nz|`S~)uyxa%3& zTH6^o{hW<{YUJc#U~cnc;s@wp@E^v+!N3~e$j3rxsAuQ?Lz^4_RL)S(z}Ud z49yK3|8rvQ0QjH8Tmj~$W=@7bGFv-gcpQHcT4cz$HxqcXqP5?VTRzf2?E4Tk@ z!N>g5P(u6vAsOk}2+i$&y7@CXKbC%iGO+&{l>gceW1s0+LTemC*Viy%3F2 zKq=F9`m|kkyeWdF)1qW@6YtiHM&=jki&xYzJ6v0G+>LNXZ|#S-BoDPS$!m+JL^>f_ z_e7{}mXL6 zkb`SE;^nSar@4v@bJj#x#y&tS=V-j zz*2}((Suqegn-F&7FWL(29Mz0WFhNfjcg#$^7I~FY>>PabvsFKea9tq9)mHe-=jvK zuW}V-i9MMfu&Dq9qU{2=F6V>t#^IRhgHnp=;par!P%p3ID@6{&yxiGlb&Fl~ST>F= zwfY2puU33(RHb;ao4gl7s3D_Y9F2rto)AH~5c=AJFBFI|dKaM>O1qWM^9uc^S`8-- z`LpxW^0XoYUTs6fgFrj4X4f$6{Ym7dQSIHm`QAooYf(1z`Bvco|My}Yo|9EV!`Giu z1V8B8-bM}I=cOt($GoYY4y-*22i6ALZ1eA8&2OSSri;2g2I$+c)^jIen;n$+r3DSx zd2HLGF2T0)4~w7>Vf{co+Ruzy3A&t}&SPuc!4esr2yOuy1 zhT5&r$YECH3s2HD?#2k7>ZzcERS(9V_ukdW+_XP-h^>rPR*f_5 zhjVyez3G~9Z2fw`Fg@Yx8O7|0Lu?b8gUlby7+o zVuO+Y#`iO((sLS_oCz*T9ol%>v>kD%@Bj(@}*OxD;ydAZjk9lXJZ?34uu<2v}v)HJ?Mn^w&A+vY07BxoTtXolFr33g_a# z!;^?%P_KG8i~?(COOp40)>_0`YbqO>51cjh|LAJXUJ{rP+-h1;Dpu| zzDK`)B+-;lR`x;}K0C}FU-}!jO}<-=csn6d2Zw=N&z7*T=KXFAqaB-NmpfKa6rj4z zE{7)lPXS>wJXN;H<>~CSeb=+x&^FgK$b9vVBD(CCL1-H#Og6@4pN+=R!Ymq*r$cg) zf6JPvDH=@X2-?9AEaL`_nD=Tb|5V5>>=8xx z?Bx$oJj2edqh=eQSM@l)!PWO5&Of!JBJF!qD9EZe+NE{sA#|In_o^+MEC-=%uL+DT z3dNt}lEG5kPrn5ftg_}LYPD#}T%y-x%Z0(M6TbC{D&JdI@;o5x${jLwCX>7v9tURl z=;Q&3%WG+#;GW97WFr3Kh+{~8vczKStCwyT4VP9{K@NS1dQ@KC7s%SG_k06uo85LJ z#H{6#(zw(HkLU>L_lLohOsuC+dsxTy0LdWbfMSOdVKUd`UqE6{;$0_PNg7Y*7TZBW zBCPo85U3+==DTQ?o@~{zw2%X82hDDTp&ctSq_`(TwDt+F!oIAlKuUD&lvdqu~ zGZ{UWG$$S5B(&X5h44{g3%PqG6=h~k+b5(iWTc~4# zJWmI`QMBM&#V{YeZBjrE5#J!%l@jxtiPgzt`fDPUhQVmT5g`@{zHr zky@asE6#M5bBBbZ^um}|U3nYmuiEN)(BavMp+kpD6kbBNq3n~MesSY24vOqaTGWp$ zlb-gPhk02OYD6;E0L-iKU+V6tgLfwEB3;I@g|%G*X^*~?L zp^~aF%cY;;cV#)diOj^Knm2Qzrdy83JzD5|A`5?#^zFqU1*8a0k4VN*V~CpbU^)Bx zV)Vsl=S?kK()bdNN(#EdCP1>77C^`^p*c>XdU{s4<7p_P zRV3^+Da0;|c5c6YwS2s7WRG1H7g%$ku&Rl%cH>%>YU;N(H#Ffy9{ zT>HoT(NaYiihZw+?Q4S?S|bh_iT2k-Qp9Y?L&cj;tmUPT^0s3_`q^;FT^|yfPqqz; zrBs7R2j#2Z&?B%Bf~`pHL>cNQY;c96?}WWjduRppcdigz)_Ne+$HMT<5*Sn^d#+WB zv@ERZ0Y8Png(I`J-hvO()?br7a(OlMj7%ro_{&5*f{C-=ww@SvP97Dv-+?i#iZqX>*FFgCIbmY%!?GX^!( zO29EWFg0coU9x1&=G`gV=n`I_LQ0nL;GLKTu7NJ+x37w8N>@OhP@kw#y`G*%dW!L= z`cm;|*c(Kcf`IJ?K>`d>nhN#Db@Fh(&118LyF`52V!)-xQp zVGOS>VbJ(=o_Cxf^T51XPNgr2 z=WD0k*2r0Wtb)t|t~BvI_FFcB|KuX8<9|vV!&SZPDBOMs)aSzXCDMm`Nf)3`OnMEe zS)WYH#hFjaCORj&<#Oi)RgNw>>*0og#E< zBrYVey-=1YgGGIfL?Owmr+v$8&Go;1pR9ZaZkHCw7NRxR%b2Kd-?X3>N2B9E`uBND z>QOmBGop+NLUqCsIzO-}_$idmMP-k=??53U424SwkMW!#XY0E!|6wNZK#Y(>6SG7tDcXAT(3aWR3#mS0&M-`kz^d~&Z+Be)@;_`9Uui}&W#LII< zuMo6g3iada$KR;mw|mGF%7&+Of>_0j7k;%w%VCySdJ;vD+zC#9In{$tvM?7^-3(rP zFmfE9>kr$7U_}>bz-=~!tFt@yL`mKuAQZ!xt8XE|0xc91HNWVj6mZ#~-t5TwB{{f& z7fekBXu9wk`;9?9ENOevJIp0J4`X4O#(Uv#&UT-P4uOaOftXSeF78cG<{U; z7S(-PESjk`J-6{Isy99gJUaUG3}>xxP}0Xy?tyzi{<| zHkNw~h9vP1-{T9&zT>s}4oz~ufq0=Qz#Mkb&qQhj3*-hR7X5C@)khW^+INdqfyFl; zG7rp?3p3r%&PK}?ek<&G0;=kKrq*jT_c;+D+Iz_ArOHgCWwp&=bJ}V0wQc>~ce0Wc zg3Isb7gQ}6rr)7Ad zFLDSRsV-pwDsQZ-W{-S8V;Ks2KJ^A>r$q^T=Dm)GQI$~dLEmQ4AK}PbUS0|Ok{Y+# z$CFZ@60)jTSlbf?x4;81@k>VA(VBy9tKG7Ob<>OQgPAGv4YRpLfNR9XBeWkaJTB!7 zOfw>Kw8zm@EI(=0an}@iSm`?fHq}yEFS_+M&8-U6iX3r#>>1)Mz1o20lPk&yWpz9H zKJ}VbT0TTkhh|CkusT6j=?~cE7_u6=x1mo3T5PKpx0sM+FLwLrpt9X zK`fU*7};P9ym!jD+zg)a&CyijKXXcc;qyP`mRB(dt|*k1crwqJv_Y&BUMpW4RQ+Y!- zrwxV6V8&->FCt!0gs*hs-r(2<25ei$>oq_JIu)i5lV~{`)qMEo^HVWj7d<@ZyLV;w zeSev$g)iCc9fjAy-ptTBatGb}1-1}a623|yE!lGj~@)tZ(N4ga5Q-AjS>Gd{2PvA3$WcA>ogBr zoi#7b;1mZZJgE&?&-T#t2r+kgOghkk9KT26lI80rYR+*F&ZuD}$uM(wqqqcQ8_hqLkXi#La+dvnJVfdeSx|AGZW za645m{9Wb3(>GzU+!N+a%9l$Ny8@ z_l=vK&e^^{I{bRl8Q134!$_-qKy>jgB3Oe#8x{Tlbih`XsnM~Rbl?W>8x0|Bt}fYy zgQ3+nNq^kmY&*u$MHF}i4PV;lv}BNngrKNJ4d1e)deOr3ki25e?pj?zDMzWl!x(Q5 z{LjOYAyOo=3$lO0O%4LcFp`&1xC-YEPs=`E`L=31(*@B-F3Rr*n%Z3UrO(a!ze=7= z%h7ZoP1wWNS(#F>1?wn%d9%p_0@@I}6+BeuN`{4EN!}4F13s8*`BJ0#n8FFaOuizB z|K8qCG@K0~+5`Os)6@F}X$%l^*${NNFm1Pdjx_J2%I+7hG4<->cG9YKe%{z@F+luS z0vR-Xr6FV)34%Z*N0CmT3>M?23n9ww5F?}chuIR1zUEJtyMp?$#|X3G{24p8=ltDW z`>*Zswu|btF-G98x=n1zz}Do`W3xOLB&tVmTv*64(p|(|Wr54#A@zP|Txhr3dv9@D z5sTbt@$~2OV>P#SFNIS?K@!U8h!NRHBXLPYSDi`^SkQvr$#x#$8b|eMK5bu7{;T^d z3myt$A%G?)RIWi30T_LepW0j6q9pQ#aH}Ms9z+M@Dw-ceURWs})U4)~uvq=HS%+B)uuH*QO4pn@6L2Lr zI4doA-fGIN(H>X7=xA5x|H2T)HicJT$+Y359>aYWMbtvGF|(`R`3xvSNOjr(p$gn6 zgHvKOVmb~GXl;v0f9T-bAt)`y1rz!=Oc_J52p-$=%`Soa7EY$TS`>9V2l=nRlS=FN z)`Xf{HMN$m0)|LnFs5SMgV@nBw{3krM%N%LLz&6HZsR~D>hx+%*Y1HG;hQ6NV@)>j z(K++%p^tQDfBo}8f)>p(wgX(xdSs;ZeCxUhikxe~OCw6Hoj@QC^EKqLJZo+mI+$VB zn#~f=*H4Jm*ZS)^+~YweYwXmqY}0gNGInA@CV3?sgj%>JwA!T>8KDPUIW}!kN#~ zx{g7-?mU!J;D26|9ym^EgyhJu5PB5*Q-OMl$XI^OD*}{){@K5~o-?nv-zexWK}B_& zVX-3%7HJVZqP_+Tg3>T2I|{iS-SX2ih^?nfwDh26VVWG1cHX|-@II|X<*y*Po*`W- zqu};V)wa%J2d9oFQc{yAH?fU4=c}|#t1VS!&zMg^jWH&3y`XBv2cF(y!tED++u;Fw z`%&+z&k4(|4!RLhC8)uVK%#y|H|Bj8mEF=!U;ah(&Da)eKeUXqBNEFjkYT;mK%~V0 zrwFWvg5JnkdCwyU_%cg~8y8<#uN9}!Q&OuB0iAp=Unq$MWkOwNJNZl(4D#97?5gysPs-+IVjY3dt)w4KxAoU$1_W zQ0BV`Q}m3zx%ttogrw25n(1C!HFvl3bBDH-X?LgVLv^@ZhmU)`2*>s^f-5MUqa(Ea z-iv93@H>|dH6^6BTFD>J-u7uVA0O0fb5$}(C6vJXnj20=rJ%hnXlGY0a3cwKpT?7N zrHx=0E{zxV}@oIukxHd^^^5 zm0(o=TmBP;c^UU^tV?#=2N-QSxBVHhF+9~c=C+cA6iuzXKXNUL3nRjzEtZ!}&EMF9 z?rqkfK)vQ}n|l)66^qW|bhF`LL`(Ip&)qK?P)M#IR)Q7Rn`;%{iXaz9`b=1m$IwFeA!gTW zgJc<7s3xf&+(d|jVb*AuChE%;z0Rq3CJyN{iItT2WSZ6E`87pg=yxf>uJK!{he`Pd=+-4PAs3;{b!RNuT}&&I;8eL4ORM zCJ)K+S$_%Bo#p(%i$QM6W5#V1*ymM_ORj`mbFqnv9v*?0se+jX4|B8{?=;MBy-W}W zx0eE%C(eB=M)r1;pvVW2hO&Svq+&L>7C|9;BBtgnDcKg~cAc9Fvyg=FTpLux-VC@q zM>Ev18uIhBg0~o&qAlN&8C|W>t*R9)RFqsmnIuw1B`vR1#>NCv`+-$o)yc(nD{XErXJHYDXla5`n8I;7A?GCM4Jw$s&6*Vq zAB^g1Ta2e-Ypitl^i{729g=O&^+En?4r4};`ZOaOWgiS)T$N@5;c`0TVjtIjvugIY zA!OYz{u!q$xnRok%T)MY==bv*qxdNZ|g`n>=o_K5)hq-I?ZEvYkx|@Qj zYF}oBLG_{qY(orNZAd9^6R}UJZg4W%MmK1+THr_Ug#`QhK^zkJkz{=68_&M1FaFC*rj3TT!FRk+)?QyF>+$M zb{|n?`*t_y+-0C6Chui#V^BM3w&I%75%JgC?%uEBac{ntU^u2dTuq_4YajphozzS% zDy_tJpNsPIMHaXxO_()ps!@Alum}AU;JjdE%i(ZAJ|XIU1MVTgsRwG}8RNNdr~>`I zx87TPV7)i$0%4vUmXwLl9SDHe`(kNKP!Mh9SCYJP!#!?ALQ2EA_Q^~`;e6MLk7dMk zmoUHDF3n`mzDA{?e6)kaWFc~ml`QdfP|_b10tzycJL zYtuUe;?!Er8`ndBI+PH)iTO?L%~;FWIgtIstvXqCRq8l#@)vqUm-1|qL zbh_aB7haFj8%PVUu`rd?u934-?euLf6sa<+sQ_JO(R7|_qu~6YXsQ+61_xx6nbTv3 zfA16A^|$pn)A{V?9MWXJ(E*5=MZ8nXsoL%QPEWc^Zztan*VF_l-k z7<~q%mOHQ>N^r?*ZSIO%W9P4u$yqer?@xkI^MKWgxkOvox4h zfUuhq2`D-R623zoz{2UZhv?#Tlu;qVmP@f&BrqrerO`KK3?p^_9FjVQFuuD|T)bmo zbMfy7ju6v@i?J8O)!nswqA(Yoq__Zl`BdX{29Ru{DUouwDEOFfqt~e9-ZT zqz--FGqQiwcc166K8X^=r8;59`eQ`5L)89wyvFs#66LcpBV{T(!Or{9y!UCAnt)ZN z0!SgttxVvEDLm>Zg}R{4f3e`^+*KXgv%KR5O64{A%@{nz3;r4#LYF!GCu zj>-;ZQp`Rp5HA~NyL*4wBgJ%R4GwOD-~r^oUesW&Q{(rwe{o~~V>1SV(2=I(lS5?P z^h!2rCC9w`UMU?kBrFd5IA4@tjh{W&HvSZu@nJEct9N)}ha$wv3NH%cyy*$2C#dEa znm}d*=otL#2!YFYT|T0PI1@#Edz`E1@xp9cidCd)QGK$-RLYombQeRt?U2WP)@oVG zVs+n~e`hSVE||xaYkb&XL#)}m$D>pzRwmYab{-5Gnq7#PO&O`-bEdiQ_;kC3S7RS5 zqA&v}X0@TWyrZr_jan<#VN;k$j^9W(fU~#iD}uK+&g1kPch3V=|6kwO0cKCnNdoj! zk+HzseC{8(@diC8e}Cjm5U)3~L;UnzDjyH30pLQ?%45S!AkX2({szRl4N4Rl7CC#& zr<#MoI8xx*r;P`Z6Yy;yp|A*R!;*&VTX=XY=OpnBNaK$-(L>HAEg)^{uDxCj8K<^Y zIxJH=P}Dqls=<{Noh|qE&{F6l`bLBWI6vZBZGD$%zy$#~_{CxGcRcZo4l)n#Ibs)5P;7!22RYaqw^HM1JiZ+m+n zYVibD+;sbtW%Ub}@Oy8Hik^M=J}mht?5awBwmB6Wx7*qa((Ok?dtWv}|5=a#6P|cP zLYSbj0C8Vds=3Hr*Eh+wjNF$;MTUwVXldK2ONpH|Bva_~D&v`s4qu}q?8&WBP%3#` zNDl13>TBu0{`ky)NmX$xn-+1xr5XP%i`2Y}H@e*{Yo~@%IxgdE*@8bD z*bM55Oq{zb&ugsHfKMTii!WFdRj226Z;%?sAO!A{C*Tv%uHiI~2~+J0?x-^RO>bHZ z`OGGEY)#-*lP1Ns%RMc$iI80`6QeCJrf00r-hPUm=XXd3Ne@KfUrcijhP}3h z{Rf6jVZE{*slg41Bp-n|A&8P^a4zM*d9f|dY>Vs4<#v?@&X_1e(ptIvY9V(##EfG= zp@J6+E~gTRU65wr7hxT4Np^F7`lk(srS&e$&0h_M?-PMV8QK2gZ2zGTflR}uMXh1i zEF{|t`MM0>SyDNkWRDPfs(KPcZJy<`u%3&CDT`qLIfo!&V!ig|+h|YQ`q8$1yF+gsU-B?&_@K zEC9^&U%w7}@?z#aNfx`3{Wq_Zfe<)67+EeajA%$G&E6LDY;si6Jo(m~WGwtFZVQeu z{EewxAu55~U*%>;_9iTBX>hc{5@I%Fpz;I(1#!kV5k|u8aIq?d2pj%PjS5OQ0xd1z zdieebdsx(6Jj#z*a5@%H^Blh(@elbObtf#{&%gDQ)>)1$@4G3p(Jel~6t${+w_5HV z&UM|N=9>&SJ}|AUicxlnrG3{`y8U|e6Nkuz6b~gQ`<-G@Lwf@13B^9lZ%cc6+0O92 z0iQjj_YEv_gBdn{xZ&C8SUJW>qrACJfC!q2Oc$I zWFyyaj2X%j)y~z)8)*EWQ5yW*_xLUj;nUbUO~c?Kkm#c*gB)u4i* zFMMRa$l<-*rJ=?V)rc0n1^cck?&)3(?d$$QG=ea0I7j#w_mn3pCRQv14W(E-05`EH zlw?k(?o<`Upa7%>egpp)41twCDBRuDky8gv+I9?9Nzq;TTPXB`;FlcXBvYJeQXV|DN=2)L*-;a8Wpwl5<6EK)$)<|Kh&Ee6^kJv9WxzGxLb}o6Zi-oK(>k>L_#gzq$}5Dm-zERw0j7?Yds<9906Clp7F8Y#vyj`l2TuhKyg7z zeiVDoYnM}W3cNr!1U^|hvZQxmUvVNYdx}-$>6K0&EprE^j46LX;!aNob7Z1G(D5eh z1GIFbrtIrPOFYnh~aH2cftf=2KEE=Q_9+yKBT)Qwe|1NMIUWEY@KeEnc zekOpC0p+Q>1f+%K*D1F@c^c+r>KcPpY-K?Zek_Vj>M!zw!tHd z7#4(YUK3|P@6VL2t}Fu0P#);1p<-NAFAo=JAUeE4HoDW6_ia_R%UX^cpSFHu3T-S` zwq4I7pAhdDX@UwsD`2qVtX9YDkOwo@=AK78Yg?*M=%E$OX(EbR2o(M!;CHga3}|#c zuTJ2)!)7^*T~jIQ`-nFF_kMqivWB8QoW0bSqz=F{z9KXqvgr8T^mGk~%hzL&|L7_- zEMBueQXYhZiWvK6Z~NP2|3Up~0JyeNV2OOWS;B*>(U63sH4@f9+HNREuMkEw4gEZ$ z$c0W@UA%_vl1g6Mt8#j-&Okx!f(JllZ4*`CDMs|0iD&_tSpxfGD49B&y)q)aPu}pyX&2fNeurVA z@b8&Fhe3Uyz8k%hUh;MW+QDu?ezcSjKefg(_K62O#r1+sv@L37x=?c%L3 zTdh9>U1uZnm0x_kr|I2J60YHuVPZZju8%;L)`jlV_E_7D@{kdH3sp|V;c|^cS%l!; z;yCExuR7!knbEd9bV{@#ejit3fy!HI@D>2n4Is9r!c2*(b(1-P>E3hA!@CnUuomVn z<)f1p__b}`ZGpJCc6RS_&!*A9>#?D}ugof8brGhlRuYrApKFE)|Fjcfw$3ld5h}Fs z=)^~1Kie;B$J#o^1l0OdeW5o#@}PG>rMs$NQqJ!kJmaN8JsNIIl#|;|r-T8iq zEebtQ7yPDQ+5cT5^=@x{QrvQzS?!l%HS>~wE8ER228*^XshkAxbOJ(;dZ1uvJnv@@ zLGk}h4b1!?p4g$?6rxM4!0#8!K(zM+_9=P)CLSK*o*EETuG5v6V(-aZSNTK4443h< z0dpEld?K&~pLVYTS!rX8N-pQ0*L275vn|Fi=yY*2ccR8$It3rY{v}Pp+|^i zIJ_0g^EqZET99iMA}{YQDQlUIISK<_HQE~S=%M3^=%r#h?3&RBAuilkTAIfR96!46L z4)3Vo`shLrw~OW3E^Q2EuL_`$;)*5hIKta@_2g^p7l~y&KN@jg>?&)Z+n%yDY^fab z*0vuK#Bz)dc4lBqIAVzBJq;t3wh$Pc4 z-G5v`n19z?ANw4|&jBvQC(yZ9(Zsr7_}&9Ci@^zI544nIHNBI8yw$1W#M| zCIuNX{zc{7@ea2FfAw&P>AE;o2(*S{DfeJVGK>U>6@IUwIX5{dZ_wf#`4rU0kie!^ z42X3MA!_fJl|p@%Sgz+4)*W~-vr?!FALtQ@kF}8J6dE+PypwuY*F%?0+pxKa`|@Q7 z@bN$)Nzh#ONp*#v$jbjvXh`UDDUJcd zZD9_?i4-x7m6HSqWeBs?%8Vj_4lK)Jff)_EphcVYKW?KaaeOMX(fwKCJjsoUuil-@ zc=C~quJ7pu77<8)pK}%bU?%HCfgOA!_&W-$uEwVM@#rqfbd_4Rm-BVSOqe=Lk1ozH zy%D)-WZ#vse4r(S*O^5xAu9W?AZXKjE#gw{M$t~a3DaJaMk>lS=c&7bHU!jeP)#rv zTm(z2ymntE>DqQk^(3Bp$*;j#a=AD<94(5_`Y$X8M|efmF6MH$!kSC7{WVA7$7~p7 zSvi?e#8LmiQ|e-=Jfb@+@yl+)Yhn>;M<#r{%*^K{L)BeJ zUGF7$4a#}X@9qv&1dFO+jMgJfhHgqk?33|LmG8ak1-$V~|A^IEn!&CKB_!2!cVT3H z`xgf?|6Reu=h7&Wiooyo&rYcWU=`w-MDH;yg|WtaH(%?K$+ye*vjH&hn-PHuxF&vA zFz#-~>1=BLakC{}yiXyr!8jHBOpQ=Yr9;NQ6^kbu84G(*-|cc*lPKN_H?s8q=o}tI zYLXRXPFY*s23uuwbe-lNX%vjw>4%-t)z{+3KW7vSvgT$`4@QvDD|<_u)rk6qA%Q8c zcoPSFCdvFyKz|()AflL6%)0PDZK-7T~baBa@9Xm-glzLq|dE0mG zrm*c3d>b%;^J4VC{qnC|IkOWYlA9_^QiblmN_BPQxFc~TyFAHE6fhvltJc+sS%A{W zz_>d!c6w!q~YgSCM(dvQPC z-$%R$nG>wNAEdR{47@Jge@t#s|nGS`XYhRl%ND7y945Gj~7KU+I~-nJcVcwV#|=}>j<&M( zraA8<Ya11(utW%fq6h54K3M6@XJ1p$Tl>v`_ymbNGN zEW|TyrKT%Yg`s*G`Rija|4WnH{*+wA`Ry6oDEokNblacA86I4tk7gV-PM~^f%2s=n zUnb5t?+3An2_>lRVHcP1l-yUIH7Z%!)2il&FXPhyDNye`&5dYw5vWZN2)TlhpXfPvm}hj!C5K!eu;4j+o+%qj|<-|niIp$X99Ss2q#~Yy|JwoOH2eB zD3)WRbBNnUgC7vu8*wk3A6Xx1MfCBZw_gm$)?KQ{G~B%7e69`IaW<6K?Qckg0>Yk? zkcUS6M>WNhZ>k7JCiBtvrt0wMay(ql1%9g&rU}c@wGzA-{WV37x?Je?;)U1w@=J2& z)Ajt1F2UO_8=~)PmUUz7X=hPeScQv_0?O#>IlnearUh$@8q| z-Yo2S;OVyY0&YRTkj?|3x7)iNoz^roY^O@SV&v()3q*J7Et36fp$dPb8GBJtew6~LCBC<$*Ok1o4Wwlt2$vUlt)IzRGpJs1Ji*Ff!`ug%tGx^R+?Nzdmam+yYESaRI0Ki1ls z9Pm(|*Go7Pg6~lt#pCpMutn+#Ju`KJgj2-MH|Us6H8e)QSk~~qR9!JaFVk=rNzLVZ z>9N!l`(#hngb|0iCPWfLeD*dq^W)nkhGma;g>aaYV>-C1?;F1#`GdQ{@-9bh?7a^j z%Ex5(I>VNc%qv$HLVe+xn<-|=o~tWY`Xl!(rvE!j*IBvd!{(PM<0HM*^m4tYziQ;L ztqzR|we`UgrgwwuE^i`+xplWbc zQvw)gEv1^RZ8M>y($4}N3U29mCINdW%-?au;{H;b`@=Gzx2T!DBee1*$2#~3O%2o2 z81d?GDy64j55F|xHVm4#)Aa8TO;Hfftks|R@y>2@v**z4HqD1NW>o9QB`!g0c8UgC zmfTG9S33&@jB%z|kNdksOITh`QoUg6P(h{c>c&O4VD}Y`y61px*8yjLNx`LXGrS&^ z+hsUZ!|k{dmUI~d@F8Jmbxm>3BQzV<-NB)TYg6lcNZ@~bN83+BX{x=TX0lYh#In0f zrw65dRq4aERhP&YL4g+RBRPIH5IF8CrKjD0zc1_kT-3bHog^}toiSqJA{b*>fBuC! zflPzbn<%mq;s8baW#gOl<@EGBr8$=b!#4|g3C_-NnWa!!jw@^0s~J+anD0{6FCt$z zQy?di?3U z>LE;&_FNm?n3UE5Q+#5SGnu6XWw0SdPO|H~Eq4&NV!-dJcJ7xQ=e>4u!X1+Q(p(RF zb0M9QtE4E(9T!~+g82Mxw7KZ>*`TD9zG9l}Lp+)yQ^W{7u2BkOGyvyxcD7S+4R)S8 zQ~be-RvP`QrvPIu%Xash(mzm%)y9{?7{>B`+3Kn0J#t7{1MbB2t=dj@zf2yOA1h&- z4nq%3?%+h4&`t0!+6wbY*Dqc+7~aGxeV#!y4j}oePhrZz-|uR{C1(@$Qw>bck~(~7 z@obNWzw*5XM1)b+hART-x2i24%f(9%sjoM!kJziSJAi4$h;^@b%8Mfs> zCBPVd8$!fo)|rW8axBR3Wnphjh2|;6MTOePu0>*Hr->wCRjJs@e)+sC|8X@eZ4m&g zJ-Tw`vASNy8m>L0slQFS$!$Abh|+hYSA5Ys5#RTA0v&)EKP%i8oIgh zaJHt?cxEkk$VcD@)zB)^qEQ6F<=6dNE&7v@@B<1TQxyGC}g4)>2T=4o85|~ zs5^;m)S^pD(_cWJ7LDHaFLtq{KJtpD z>#%hj^zv0&7eQiG zrbOq|^9hx?6Nw(X6A=k9TN=;s`n&z&$C*6+^h$!a+Pn?~fe`L%d~2BNh9=f1W?-aV zBZa7cc2~^dH{(~22n!P!UqjwVcnNov$)B8F&zph>Qx&PQ<`F==Lg#xg>Kj1EEp<{W zN}RI+YQC_LadoDv<@=}R>{P@8zrM^s2oxIMFG^IFigxhmagvq%HJlCZ8UV7Biw6CQ3AGMBzCkDpkyHk(`tr(o&PMwNQSuUr#1GNPN1kMqW?;7W`@B?$k zFx>g6Gx*?}eDV2UzbA$)6l2rM(x)7X|CYJkl(xYI>o9dME0l=BO$`)&Jgms^=1Nl; z3XWEVHl|d>9>4+t{kavL$cJBpbrA`}zhm^^SRp-~bm1=V>li#1GpCmXnZc!(QB(4}WAU(*BElYnkYG(?&zikUfjuy*G!Q*ifoq+9mXSar#}- zl-v3pwh;o9saidzFjkh+X9=iniYDbTy&2hhtmBU6zPUl#E+OlpTmayN=FWHgvW@L3m< zt@yMn%(KR_93;GN+&_!Zq|&77-S1B*coaxCL2O2tMIbv+ZR04J*)f3;ymcAjVDx1? zkpX6y)Pqf3Lect14p%)!vvDg5ZIug$j>Ta=_b2HW`+Z4@RYL0(TZw&#Y4-Q6+hI4F zrC@z+#Khr%cv*P*E-}1h7@ImbI>pwZ&?_Kh6K(!lQGNDk2fgU1mlQpz?qkbQ%}N<`t$u4o?I{yH{s$SA%HP!EDH%S<=k#a0JSSa=C%(-Pm6ZEx_PYWIQ?e`LTn4D$e`ncY~<=m7RT z6egm#Ql{f~eSXIv?QB#$p4L#1k^JqA;V=})nSObGUtPGK>qHK{|12gk#ehQ0ikfUE z1-n?_^puIh{{cHd#J_&3LJ)Zn&q^Y~dI+uWEi+o%;eApT%sKkPvF&(aV0Uq(3vBF0 zN&pl`YowsqP%3*+)4evGO`M<)Fco)54)3}B;y%%`;mQzM$Za-o7Y#6c&F_v~X;q

#Le1%;O6)B2u7)^7q5G3bxSQADO<8`X-xU0sI-=`ufnF0C0r@ zGuH8FD;^eW3Wi=smx4-=+(NW#k5F71@9c@x_@RMkdb%FKXGnoCXOuqEx0klOV%??U zm4bCZ*OaII7b!&gAd>w8_tUABDg4iE+cL0?t}E7NdUyP58TN{ctt0htL4@VQ2E6-3 zaq*m?oHE)1-lq%C!1b5?U9W;Tbj~|0*O|_ft>!|qKcZt*@@!^7hkFH4za9_2N$IgY zO7Ji+4h|d%e}2&o3P#!RhlIInC&^rt^-ElRxW0p-D16z3uN2hgU2m zIt{xp?(?!~?&s7DlZJ}on)Pn8E$;=>D(Sf@H+JLX^tb+itc}`CyL-gEn%}L30}Ixl zKPzJD)6a-<@0g62SlNrWrSfMzF&s|{Yg8`?fo7Fo4oow6^+$h%w+ShW3aZXWvL-L@jb;@`h&1 zEBwkH;9k~TwGZLhvRv-j5~D2k1rJ~ex)nMH5*MFH7fdfvs6*>o@UBd8v=!N>Q6Wef zSx_ZkFR;I}tKScdL}fNo0pH?pVDou;dZqIEEY0{g?>DAmvwK~1NC-aEdZzAc@5ET1 z!<78+S(b%JlIeO$4bQQl8P9apy(%_xw+m=WER>ni9hmAjXj`$G>QXXw^Gl;o{f8DPn(?N}Km4JdCnE{voN#Wnwt1ShG$%M7zJXVmgWjsLxD!sbEJG z?mbG&kKmUV=G5y*uQwXXV}*wP^p}7Gl!15-KLPm4WUFo3Dex2=*Iq*T;~*)toxXNV zfq!uRtK>ME%69&3UY&l3IAog|!06QBZL+UFBor>xx37agK4FAs>z)yeK>A`6TE{&)jv`HNn1)=XlKiW$dXdBDNp6F}0dLQay<*$|^j!;kg1HY*}j z5k6^-;WM5Y^5@&mri?0IP({XzMGzWv2Yg=}^E9@5ous2GlyXVg->pc2@<`xHI;xX+ zd(a( zD9t9@i;ZbN+RL)$V?gkWL(T5T|20KQV@XtbXuQ~aJ0ZywAtutoV{;0-qqhJ31_1gy z+*QLHlFRR6|JR8=(KXEe>_HW-*950ldR+H1;IZgFN z-lGi@d2nh~oFD?F4;W7)4LtmzER-p0^O6f3f1cE0OD9d5+DtszVDSqUrqLt=2v#`b zkdxgp;-UjvQR3%)*Bmd6S`zglC%mi(s(XZ!9&izT+OZ2RtzL1#xPh;`l$!(_jJQq% z2BZK~6T4piXqb>nti$8fF`VslQ!~c48f)RgD@=6eX7kpHy zAzwCLCf|HY?*Ww00(cCvGV5~&Ub0{KRC#208lAT#d10`=9`FkP@YJp4lr>TKC3;wz zvORuT>y+HIGvA(ZX51E`W`Q8G;wHK@{xu{5OUa0{vRVvqyz#^MD0WNSiKBkj)JhYN zfO2+XaB5x=b5|>gP~Cs2r}8WcNdxqxs;PMg$EeLxHX0po)cTcJEjlPHB=P}wD1MvM z6NL0dW_ht~+apq-1l6G8#f2|E*3L`c84kxhe$Ne1q!yS#QH>y-CE5!pdS$kW8F$Fl zpbTN3@IF$u=~?x^@d}x9f=r9|(mXb5iYZWaxglOv{z-LAn5Piz<_wOZ;B}1^7M7j> z)~)^jG%015^9im%sT~b2NBTAY9%dL?qVwl6;NdrsEBCA9k--Y+Hwnpm3&@Ga>91{@ z@&|4LSUjTdj{S{fj=^Hltv3&1#E(Z%Bc-kLEE5HWuv?nJt_s-6GbB>)4MCK{R)^TJ zc|N8{U(F53ma2(P3um*@7%cts(GH}IFJc6$zv!YUbt=c8&mO6Hyu6gj833rcVReMy z`aT(r!0vZXo4?N27l^2TfBcFk&GSKzyU~amEo=q>^S*nHS8lkR=u>a8SV550(JD#0 z$_0n9t$w!sri~lsL<<=ZR}2Lp9JSUCNu7cM6~8#c7SqTlq@V`nTt2j%FPXt-OAUfE znzovaj;}gxx1OsdTS{!`xj)-xbv@NIrda(4*)qwYLKL!~x#uAs?!qtyPeo(P>0^1G zhD}4O*1#+c%I;S0&Oi0G31s_6jsJ_!VTAQ+7CU+osQOYf2yr#`Kjexr0^!Kqp+H=|4mYR;6Ea@B*^O4Xs(sKn4 zw!xC`CoMqnGKts|9+|FzwS?&_ARCFGDOu~L78I*L5i;jdrz=z{Ul2HhY)TLP8_=%*nQ`4MMsQCF*Ex?UT$HQsuKBpaT%|mDo$T$^I=_Y-#oM$;Lp=H-y{P8 z%2UJKhN2Q5yIBa>U?~8(Y>*)3PGmw|BV0Q%aurg;JT;zbm^|wK~Ojiu`DppnT zMoQ7nnc$7y>&X4hL5$M8T+@+t-n*`TPC1GSwZ+#ldh*=hTKAyVrZesflnyQnv8{YH zPO>Ea%F*gFHLP+?Fjg3ojJ@DnMJya@WDh&Cy_;jLIda#aj04n?4wYx=IL7}++@8s$ zu>$7T_E=zNI2iYb#JU7DjTKbtn#vbU@HoH8oPe+tq*YBj1bfpWNZf2b-~a&JvS+=% z+`itzS4fEWIPy(yAAE$G#+IVm&ET*gagRS3>X9(2+_@{TElLNYYe+*rgT4Hc+@gaB z?lPQ=^KL1aq&pv3P^U}eMI9Q}UrQry*3p$d!ttu(aF|R)rCC4^%hWBG) z0X|xjdRV1tag91MLgo$yB2cOD3fqjpK18WlOYu?n=r^~Gtv}f3KK9QS&gU6DVa@Hes@oUFqW{J3C+Ohj!SLq}vvVW~+XiXUBy^qu5I zLf)lAwufJy1sERqb0=}iCUzZsLlG13TH|v{f|114j!zda@EHO12L!-0$*mUJeqs7v zJbUGy^}Y_}?oNo>yO*g)K4h%5MQ`-L`!qQ64=%?zuzjA$q$~B`R3={mePyx@RvG05 zcB_^*4pmBxmmU8}VDGg%w*nX2?@(YK3asjR$FoxCYJQ_&=Y$3G@njtS8ae)Wjq7rR za^7J)ZOgufal!2^`Vse*%t5hQ*VW613&I@N@20|GRs> z!Un2cZNMWL!lXVq3H%19*X}gxm@!T->r+baeKl_z0Bl1;+tWNpJ?y_2#+wOltghF4Afrb zYr^Y!kpYk2Q=4sngcSzphD;Bw)@*)4WAYEk8*V6iIOC6g*C84881NuzH^=9qv8e7k zJcXeIOWz~&c5)2gY98LSZQ0)TE}c5Y8A{?M%jovW-f6)wI8L~CE)h8#|12x&#uXkP zVku7ceEtUEd5|)cmLC4vYxv+ zL1u5vuadwwoR$nqQ?1YQY;UnMU~x>$A9Li|CL8lsR;b`gO8*w?0D#41p?IP7fvj1S zk~iq=l(jAEB-RGZaCy-p!tZzeZyGNJ>9`(><*>OG_tl)z9|}jRbh=uiXXd_tIksg*x-)~z86>eJz0bxB^^Q$2gxVgVQYIy zA?f0>5bR~@W5h+qJ&5a1rS@GueWShh*@Yi5RdxSjMyHkYOhnVO?nugnP>^lJ%Jj+> zKywQ|ju^(QIxmZ9e&K09VB4EKGAj7bzqxxNA{)>#g#Wl7cC46Tk}-N`(kvGZwbPqA#RBIPOXGn;!z?qgKfRGG)PjGAJLU40 zK1Ii-B${Sp^jR#kb$V^)VaWMZrn@;x#*3C0C)t|b%%53EDmiHZf7J(-f!+DQ%6Jeh zY4`y`iI+ghTM2iDo_JHwe5CsM9iRg7Slw~|vo#F^<(KfErsE;xtGz=Vv3|a$>O!>aV-oRUDaIk?5`>}fCq{g|4dmGhz&#yoYh8v2v=wA ze>9ti?lc&)U2CMEbZx|a;+^)R5bW?g57XUmZrp;NBN$%pj@R6`0$9cE4jZ;=+nxVt zZ$|Vey=v$v=5iP;_+xRP7*}}Q?8!y~)y*>2G;GRUiHtGyFt_dd2D{4dikX$&K+xHk zb*c~EkRH`26AiJDBAX8jSSwBpwa_Qj42=#wk%=j(poCWyUQqIwJ4M)afM6B>!bWe-Ics>Y+_g>XmhFgMJiBwXEptlKtS|+8Q=%M+zBchbf?7 z&u&=Q&m`S`u_;)80Xn{jw)5vdRw5KbgDT|U1)BG>CaHfqKEN8{>VLiRR;okrL0ypr zeQR_>xJUU}YEP4d7L7f=i%Rj14-CZUZZVERe^=_`MF*PMKlG<7GJGI|W*zxMqnMO= zXdB*SZe!07lp!v8vib8bz<{o9Z}Q2#L8nzKRP8pydhe2M4GA(2nw-k`Q2~B-js@$( zqkUz`EPRXRZ8bpD<$?&=NV(SDrOqk zwMO3(X`hLfK+Jpn4l5G3l1V_DdsY|aG)iLz)~p5-PDn$td_o1QD-#a~&>XFF(SZ;g zgM)JW+7X*?m$Xl%Q3vg2WLNRp`)^8*QdR;JJEN{U!fJJc3{GHAV-CJXkz%aI7W2C` z`bKf*(xMo$3_944U_e0GJ_Qys16^DtTxqFGCvVOso=Kvv6i56f++vV{-GA0xy}5IK zqVCR`XPHuAsL}JNxb1)M?}|2gOXV<>gdP|*@Z@}b-rnYq`W9&^U(4iX72Dl#$uqHaHwx;*$_sAgL_fKdFMn*mx`*%?%<0w zdz<>OOCWT4NtR^oGSz98j`M)aqR;oDM*`sI-fhBjJ|BKo73?d?E;-TYze4b72n3Fm zRij8*v1(}?q0U0MqQ3M0NJhadbZ0ku^F3LR)>d5n7bFtM973iecy_~DuQ()WdhJ@Y zOixqdxP|EDc`L%&HuyM3iJPuXp->U7sRJ$ttaNGpC5*R#fyHE(n%`|ij^k-NHTq|i zVJc`5+V5TncsT-b3*&;jJDSR--&lb+Ad8tm|F;vN5?rcecT%>H)_GuLlWSLUDp(|s zQEIaQ%R5>Z%S6-br7bEBo|;qn2wP+;le(~K(TQ@R% z*qXGemewNf$a z6VDu2VGHd${!-94xqmjysAB}?E-_`I|4%mIhi~+byc_P7XB_szNItBXc~lL7?<8~g z>)v}o$x5&oj{KtwwN}k)zvgW3g6c%w_Vvq^%T>p}IVV451TgEgc;JOXy2)H?&8^ZO z$=u%%C*3AijU;vpj6bfq=H%lC*IISO*+Kcjp9H2v`wDEi@~-i|`rQ1fZ{rT3bhKJt z{#jdr@i|;(8%R93J8oIa0_C8#D7M!0?10_@(j~Nk>MZiu` z6jn95&-N(^x}bpKeoG~##5Jyhf8l9@kOSq)zm$l^i&b_&X?_PS-;BC2bF%Dp>`0wS z;`)HTBM9aeLU+TF{4nW^8iXB3(o;rLBsrIe^P(_50c5(u@Dt~-P6DT2gpAZxLQ@>o zDu>BRO24I7IaC@7_|0@#95U{tzVl_6T}ji$nI4NoBaH^aTb*myhwAET^`uaK5>Xi| zEgxd5c1+SJu_gk1ZcGJJ759aTLS}Kngya+|c?A8yiU+d<+ndg6`5Bat=gldY zeO7w^q{is-6T$O0@@tP*V5Xl<*yHR6Fx1gP<-NOY4w*L4(sBOW!Z7`+L?cZ=*{2}r zTq93QzMI#z@~(SdJ3R83A|H5WN5sH!f6VHyq>qHGDN?8}4#57$P5iLvGqlIQHAWaf zvD7n*zP;dV3${D&Q+Q?6V_9U<1Z`pKwh+PF< zxbxn=P3x~Mve{n2DPRpJG%M$*iZZM}?G-(-gQaUJOVt&I&ZmHrMk&!HLll#IGoA>J zA8d*N*rg!vc-`s2f5E_ABa4R3>(u^)$s>u?t2_m~vq*PD9O)gEsPS9%NUnRYipa|2@V(;CFEzhpj#3~rgKP&2UN<>pZJ zy5sXJeNNnpInLr|r8LTW9&u9PH`LE@)(QzZWYn?N`2ZXPp2tJiBlbU3C(1CW0c>h7 z59@U6*z%uc^XW(s=+++ywu#t2d!D2Xa{h)A1u#z(HR@PD|5R`NY8>8JQQ4okE&O*) z(K`*klSzPdx)eCXaqKapHAB7Z?jL@Bm?M!71E0X%8TpgG>1YOq%ad3c)-xsP`bFvk zXwj->9FmGB-E()aR&FtrdTd#4SIaCsyd>-QI#O})#!dww%_;&k`0p03WcSexW?S}z z3FQewj@g9`se7(JJxg=qF-n{`SycVbIB|3MQW{G|c6~REevPn(Up`(mj~3`!{MtTAWGd@_D>Tlou<~!n$#-!7a89OdwuV}^vkxAN{C|>g z=Lx|C!FXu`3s@xY3uN$61dM4;lJoC6;#_`j`NIF_269JHzrSKq1t3DOt_j;$`tU*k z$9&r&6NgwW)&>hbS9ej2S+5*w`lCw&bL!jkM(;#bD^@SU@lQFkz|a&8mMP8m)rv1ozC_+15Dg(%%Sb#Wrc!fH#Nt$rxIy^7MX%ef~7Mhtf z6g<@ZG1kr3VkosqH{-Q0lv`^#AoFv15|0wJt1(-qrz@XhwUP8zol4DI180Sg6=SD4 z$@H7bd7~v!puS66?MPuC!UTk1t-#?Aq>N7xC2TgQ>zwSmW}r|@Og%sSB)|nQAr3X@ z9lLjaUd3G@`zk4kiBn%d;^8D9C+zyBPgU=pyDhb()Ct%L%s^k|MZwUpGUOk0m2ypK z(oiwXaqM%;;b^xkK zXP~Y)E3`WAy(bD851WN-Mtrxqs5Z7e>JK-6IDim-$NNLAIjHB}kqjkIv4A;pnfB!a zY)J_d$L7f7?d-wF13}zLyt3H5mdECoq%6aDawb!-#3w{waB5K_u?+M?Y{5F0%XuzE z!ky2+Z1ZWlyKZ-lh~z+0cJn8RJSB;DXVsv`b-eHsN@5*xKxM27G}^Szkuq1aQV`n1 z7X7XXj9PoiePM}7{E+M_-=n2|hv6bennev1XJ;bEAGDK#zb=|o&NJxgp-7M~bl(o& zN%B?5HO>wbJ_zx}1%fs3GWB|Q2SQ=B54O1&+kQ{uaG?ZHB;5~}AD*u4L$1ht}x^kjAf4 zsOp@AtLq6G6TsBK#f03e_5npDi2`+{8G&ex#H~2xLdPwmGI%~tIZx-Sp;z^M28um8 z$d}`%gb}<%sYi1c2a7J;r4*HPa>lrjkI@Bw1t@EAR_1kdND;cIPh)qh$xcL1hd=Wh zd7-pUdgU~Lons|};2QbGOlsIF+F`4oav}B$iaqGM>6n*bY}ZIfYG679D@^^e0}GbJ z!4F41D|kC12k~8z8125Qm25eaB_LTP2Ai!b$kMsk~_%-YMoa!|Z6hjUD zEwN1pYK?45tO&$PLRe$1V(g~n=F(-JSA8a<+CX%*P`guBckm3ihC^TxW{ZBz`8kiY zPZ_ZU#D`!X3v9nWO!6(C%&tsHThVC6m1G7z1M#ztJQh=To_l(8s| zYGpurE5sm8q|Pbvj;O_nE!|Ml;~{$AS1bcv&mYm6*`c~$Kmoq&l(FZI(^+B4JL{0N z+a=p3CDg~IAW`Sm^m3DtQfd?mv|JOl%}t=^AYNQ_+cQIYdd}xc^Qft8Zuk~lV_;CofHJ!@(4_M*`T%3-Jx2rPIt-( zS$R{|Y0m2U)dP7wh7w{}Lrx0%UKBcRApIb0zqzl6&r{Az?dBRE>#78{!|HVm zg7`(UQp&ICWgkFDDRh&yYk#~)>!A($*@uSt(%SnvYz;AiAF>w%EzgvRl$K#pueUjrh7+j97!9RnZM4Vh&DDpo zqc^hzjRP+bQ3&kxcaM!YiI1nYIMCP;vE^Tpl*wynrI6(_V{{pckG zjNL=Y9y8$`qIyXA3n%bl(A}&J;Gu3+5f4u5Y-TgXA&YYL#c4wmlGETGM&^Y4MusL3 zi8@&JAJ~d<#1<@H2Utu~fxh%L1BfzP`E&AtS`6Y_3o>7XBb(!SHTS$4ZRLWG-y>|K)NbX9+kChn4>+!eNDa0@^aw@j~#ORx)vY~7vdEr<-jTtSl7GQw3F&D zw{8eklpr^=R{+-!G6O{m2(kxZvPi=^b8BWiEu?n6-%|sodmo{@(3Lh_^!`y(MPA68 zFY`68aeXiW_WJwEDzC<^J>-Z%0+`07sLZmDCck1o9)8?MWTAnKq%5>7hyIkXFY;Or zJ6gEsV4yg`Pl1fd6Yk;LtlgAJIk5=xDO6|6(ZVzZw*N^%fEv&{GB%&qV`%Yj;VFuZ zX>}8qGf_u=%a8nb8B3piSfeZ=O5_6Y4fVvulNj z{dO;Q*CB2-_2ztUt=c_f88hTe-hnzKo0ATRuL%ZEsZ8b0o~z_>&OQ;{LA66fmsmGB z_CrMDw#hY+R2`aFqzcjl4toi>axKjoJ-zKSz{Wr_q2ZN$Dd1+^l8w-1K7>s1bpPZ= zS3YLBS7^ShB+Z!^m6fyh$qQ5e?odIQa9I-VKGpi&_NC$J4_0#YYyBX500yrlFp@|) znVrGvSL~$NzZ~olZ*-3Nfr50SJj2@Wjzj>o?=0a(pP1o7YDA6kj5@dhT$FgAi5%?k ztz}4sje7mWe>HuYs!35PCHA=!H3kI!Ca{g16tj4*)~yhB&MNiTU|vtgo<7s6uwOO5 zL@_;PK*u=iK#^UM86cpJJAAj5Jp&&hDLN`LUi0t$MStZg`11w}K-$3OLq`Xsh~ohG zYsJCdmq1%|4_CLwJ#e(Yc{5jsLR{ zs7R)MUQ=RtUA*arX=Qao^DQR)Yrja1;R-R%KmRh)Z9^Iu)U&s1d7mUzG09vh^R%dr zXao#&OBq3VCJb(qhkXXAg9XA&wg{dpwTeFNj2Bu}$YzYpz=G$4rQmf?Ukmr&X(6DU(zyT6Wu1 zJ3CI-^X|d<#@RbX%Tm#^yrQ31iEV9x_gUxHpTs0)u7%e+_z#~d_FxO1yoXRLmEx=H8DtKZ4OH;7ZY zdwc9U^z*)DZ1ek&Ultp>#;oq2ojVu@>xxbkBQTd$6}&5=RQO{$%stPtt7;}oSsv8H ze@e(&%;ReI9{5ITR**nceZ^xt$ixWzQRaSRVpMP3R>p1ejn{o=)71&$-CZ!(-pTi; zo+mACef%qZcZ`BoI8|k#^Suji%)iqaxVvzW4(3dLd66oP6=fiieRRHWV=IzJqm@B* zr%(bkRV9c$HuTd}DlgSNJ^TZE9nowY)DpgRMQyh5T*S}SO1mu0tc3#y-@y4S>pi>LXPLfgXG0{U}W zS*nxJsZ;{P+>e7@GjZUvVI=9DKd5t<9kFBRcR17Zd9zJ);bYm}pJ2tn^9b5Dxqgz$U;-GG04vCvRPL#ra?{)5^`Toi&8Vb}CgpB{z z%zwf%IOt>$GgCSDv9}q6b`YG2;M}*}d}sJXo08UZUVno!Cv4*&2*w`;KlH*(y{Bd=@}jv&h`=Tgtzb>G59k_wm2D~h!rau_PMHav=< z09xrM=Gte2{BwJ{&liOGYK)9BI=Z-dLhxn7e=)^+m0|%T%t}JMZ4xe|W?Pt2IO9nN znaQQ~H9lNDf3VY7A?RKSG{?U79Gug=Zd45pqosBI>E5|Fb(AA7rqxq`#-0>geCU>? zpQ@jQ&%L#I=^97!Lrsc8{PbAHCB3_f`?#k)$6Z@oYpSQ?kTW5ov%7 z$~Vo)PkI^``t580uVF-}I8S5AW|hD?h2+-6I27gjouA}z<)tjy)qVK~Az(j;NJ+!Q=f>BM?JyrKMa$RSCggBX`40g9$> z>GPF(%kt&jWRw`2QSX=thNOKyjDds_bHM-54_G$RaJ@gflk$H$1&MNht}ni0x>*H9 zNxLs{c+K*M$Y?TPx{=>*F{65UF|ovIL$>rKe}$9^AV5RTqvjjrD?H!H8rDw8@^{wSyU0eIrtj zK-j!J)&*(_(P*02L*u4WCtV~aRaOY`Ce=tMH!a9oAY z1X^%amfd&}4T)fVj@xJdBImtjvy;cGsBlZHT{SSznN*YJ8S~FA4*^EI5c1MJ=EGn) zhK?A?Ct?{$4#v*zhYrpD94#YJM#A-ZS=+oH>rVo(KTgJ^-J4m^jD?tL%qmCHC_ruP z=aGwKju<^;e8C7ZwJ03Kf@I}wg~qo#`+v;L?e9i9oIvkZT{0S8&r~Y3Jk5mQh4wbx zAn%b^7<7y5DzToe+pW|p#f^l=ZDKlvG)zyMi10jJ$?zx{7k>W9e*x-C&)nNl7uEo) zoe)+d^w93=n?2_Pw@A#!W7om!C;L|Jtq`@i@TGdM`v^qy01-?UV4}WHP}&UQ{c=?q z#l)BkWAS>iT4ZDiSNLzz<4uri;vS=-NGT`_unS?Z@jm~!&Iib*Rb{w-YT7#OqaruM z&-RUzIQ}E*wTmtSCL^;SHLKba0mr4SQXM69Z86v|!5h>2oMUyR$wKF{x8@bpau{=XHacBPY^r(@tp#8}`V-_U-Aq&RfDPs^_*ooh|zGDHc z4keG8+rdV~x5oavSJ$XA1}rj!xD8JybD-xj@ty8JL1nl0p{ zLHD*RK!T6k=NV*%{N^2t@05M;wm&PF?LM%|ht-`og{G30tR2G`O$S!8^*5*l`>Pka z62Arcvx#+dpLMN7z$S8wv=w&V0>FZgqCo_?Ba);i!L$fX@Z*bTo)X6@ z`K5|x>vp#9{b3l8B{He<*~;^Df`0?$V~SsLu{-e(!WbN#6WoS_ABdou zaiVyvV{Z+5YN&Q)oEt&(##Ug@+iylm*f1ipv*6zH(ryU66n~u%5GP5OOEm@w+T}Hc zaGbcAvmvl-{clQ)SkbEef+(Q|P}W=6J%3xBmT5i{72aN3@6{O(q^c|-CZN24_Xww& zk1VUc#q^Y14YI)lF@F4|liLh*)2A%|tqd4D>^14;1x#) zex5ZzwR53<*Ad!kdZ=*cIaH$L6ML!Ak{Xrmy59Tl>r5}la&J@}p78SNL3&)3cl$qn zTYu=&7b@ajlK;a`!L(87OTq4-N-dJxK4?DeysoO_p)d{}`5Y9hE$6}S+fDA@SPk#d zTOL+;-9~99Bi{3(UiMzPTO)+26rf~OWzg;)({DUTOCYj?2T(9Z;rxEnt-g{MVu5OR z(*Me@FH*m;hHt%kMSKwZugi#YE67s{-?ayV)*5=^X>ocE4k5g~>jwtWhf&dl1cdIV z7JL zODXUj0$M|ZubI&rZz$PfCDv9V!-1vO-+&ChtNq2rJK^HUNrEm%lcSt~)v%Q*s@nA4QyFg;I=Ij>E)j<|eS9Z! zBf4yu{;>1L^sMN=!TQIhymaUQ3&&9{nk`qnrIwTxo6MAP4^r9lE+fPr9Z4hsOL=X zZ#KBKM@^J)fIItg@)bA@2I%Rs(J(?tG|j;owbkY&t7_H|`sJXPPqU}ryuY039|Lpp z4mnfg+MRMA7)}TUo2EtY@+y;DZWBBD7)t$OyW1<+HMG&}%gt6&OdH8d@dEcsK-TCF z4;JW1hD80xIw5=lbf2*d3Xr$jfT9|{{ydgBas)kdj~(1UAnsl;@D=*G=9|mtZ)<~e zvOb+&(_9*9*)LB-o7<*~++)uT$p7EGSibH4+BL4zvSpW(q7!X+PeE1TKfB4;Gnu4MH?=nZ;Tw1STe-+i&X zkTt{q%WBywd6G8ppE(b{ec^B0#8ib%)Um;Py9XLW*BK#}y8!%&=p;P+%us3in$K7W zV$slWzKv7@SdOLz+@zrnrD@c|@DzSnjy9!s5#%6}$NV@o#XmF%pYAasqjjEDb7V%Y z{&Bc-P=hYoC}(yG7GQ8S=4tMPf0P8Jb+4N=gicT0E6IKcb+NGr+Vzz)zYrN)cAMod zAE!ygWH7-2rQ)GJrC^n*MIz_|PrXoKw_c3%Sa6n@M2H*pMq=88d0{riY{LBLB&(#1Jl zhfD&-e`!Rey$^&MpaRGKs-Oz18@=z9EQ*-gFuMDVe~Gu%7zW!p7Dy@=uPBY3g&z9> z-JW2jT|eKHUX(~s|8OI^eqUmXcnVw?aN?e)(xTBvFE*KLdqU8)6%diTaU7M54PiFD z;aU=|%%KrPT4j%!5Tx`szwAt3^oP7(K-WhpatOLKD6y>7W%)`Mu*7cQB&QEjAKV+O zL`9k1ut9#C#-Fhoh%UP6fxG9B!(?_0(#z4yon$UZMf;?v8BAW2K*j1IWEDp1W45FN zF{;-E%fx$lHDY^Cfkmev?A&{W{`hr?qF z`}}gK(w*L23VE@48aCFCYe8@DSfwjt>A*JzJ5_Q>kOSAjH4kw#u<0)LFm`(_T zCucLTjEY!0*0_kAoMx+w#IBW5ktfm%gMzQzl%XTE^8V(B3WgO(DhLGad(q2+K)&-& z+k`*pi!pQ~-{E>$2%M3l4M<>bY$6GyaY83feNOmcYDE?{L+)|4(sO%-hW*@3urNhm z3KFdqJ+Kvs>XS{3eD7Xr7He%o^2qts9zO=+t2AOvI%@m=3KB>85v>ophojWf1@LmI zNar_@QyN>4T27Tb`LXbVQ|Gf9Zhhd0|B z&@R0x1o#C3+7o*vA037Ku)=pC&Tx2?riYNGPLjt14}9He^iP~KY>C<;K$?A$a&cbD zOsb>$_%SDnI$`yAn-~F6AmBY1=Q^qb5TvmQ#ric3cuFS0Iibu>_RmFR%_-le(8dcB z+&rpUS3Hfv3p4x^8^Hpg^~&~DYD;sh?K#)b7A{Jw`aGG?SD0evt;>8UTCRcRje-OW zcXASx8I7BlMUsTfOMfl}If+!z`WeRbZRk!`x7xl?nb^Kt%iVgads7_1886 z=3Bol_hqm8*DQD+;#Pg6?BprO2u5!?QAmZ=l!9r6E3<{9WDy4rb8HW7*?}I1B6sQU zO2Z7HC8%3}L7@ZQ$?IM24VPbVS3Nz4`fN|c&7*e)I)Q~AdJdZP`Kts`;Ytwc)l!uH zZV%0J-|PsH*Kry^jY6drf9m4_rN&j;*z@rA^30l_9g1gOGs5$Z{r=bI=a1`D==aK< z*7W^5%|gLq^|AB|KWJ@&^th}?NO1&&Fp0q7@qE9;;M$ijBh15 zC~JZAOZT{YUVE(ZAKMlnmJjri6cjjWFDzzuK3AO?yZOd8o=!c)r z$fLePx%J9EUC+g3FF2uz&Fg@QS2`ZoE=-lWc`ZZfaMen2hq z2*k~0LZkN~7KQ^2N$1@tD*|ce4wUg;~SkIy;)3%OV zTb|csQAYpW=fvUE%g2MHUWvkD7+QxMH7GB?a0%*P3H`?L=aj`B75!W4RowDo#Ju_V ze=G&@vwX=;`n2XWo~hDgfZ)eM{7+cprb9G}x+QF-xwypLJ&-du%K7=<(id^L_bd^6 zmEPb5u;fXg~CPM9R=ryQDD6k_D0v zo(|i*YZoUTQljE8H}Nm2UouDXKCwQSKX<{J={C&5TroYw_dW9lGQI^3^Xp|vs0zhB z20$IpxFSkdUlO#o*L0sL9-=;D)G8#1I4=lS8n$wV3;%12bQ01j$ha7gP#aQvt_HH( zZ1^zZNZjx}S6)KxE-Zsg4|@%fB@;J#NxX7ktt+RQ?5y$!0!peu#g5Stvx>RJYsf_V zxwY`*IHsXS-o4S)+PZ}>rL@Si(;a4{&v3At3Wv?g&($c=bK?f&iv+QR^@>4!bh@#!~Jo*=e?g?Kg^0pMo>OWr`9K7l6{{OaBoy3+(+)MgSPL8S_bRdCQd!At;mu0#pfH%7@#L+WB{+cLA|b= zps}pzh^7};70e^AD8&Z&gy;`F?M1~WFb?$BTny(=^wRJ7epJ!ZQ)g>a9+U@qrH>*p z+YJFYsBr9ydHeB}-M7(PJ{c3;R!H3PI)% z(k>RdYwV{lrdUa<-eUV2$@+Jwym97iOS}Gp8E^On(c@;Boy97EJ^XQ2+MzUg>Rmo~ zjC%&_6WA?1a@@t5X2g=yX%^0kKtU}W%&NHJhc+`{l#(>>{OO-4`XU`N9)x#6#>jb- z6&517&@Uk&O)WbbfgIS49bmw~Nn3ASl?Q8#Px<^!%)?f*$a^%!q)ueJ0NkY@C46YS zcEqFJ|GvY#@cxf|mCy%x8XB;n^Ad8n#;l5(+Z|nYc(Oe<2Ke%)ZC=Vp*=nr`-2yb~ zGTJHAYBY{t6a^dKexL~MDV6O&YJNys05UW<+1vKJP-|$zkUgL=2@rx+CRJ3=nU=)L zdlmDp$?;QG6uz73UX5;oA4niEjuc17ggW@KLNkmSZG1q9tKs$yts&y%-s}a$k}hG1 z$wiynh5RbQp^L2mv-UW(^=@SGf-!at2!2E*V%HaXjIUA4#ji!=9tgwn7vEMp7qeCx zcgBteRxmM}?UeQ~%}apbReeJ>Xgl9Snn^Yrk9;-oAtrg*UJneGBZ;Mbw&un8Y}q2c zG74yzP&yLL4UvLgRb=a}wxKmHda;cjThhoc*@aH6#wv*U@6AI$+62z{k((NlWaT)sYs!h4Aprsw+Q&^-M$QCpIbBh(>mE z8H0}@7`cwneDKN5YZLBoZphncxe@06-T*y7!oQi{$FG$w3<+SvR~xQb)f6COJBef@ zcCYc#(Q@QV7Q3l$Nw+QpYT8jbpy&OQVOFu5=GGs|*ZRU4IML{lwp#}uh`=)F-|?93 zMO_$Iv3T>&CB~~cGdzWF79++$M(^JS>(nZ6(pInN_}SQ!Se0vE|~`>pmuw zDK&FENeYC~mb8`UFOh{;6WFoqnx~H^UTePVa8|-12-nGt@(x-;s}!_dC6@>9ZY={y z&|y-VU=jSP0 zp%pu1e~}ezZ+f0**<Nu1UcrTbcGyqh;JB>3v`oC~pL7x>JQgaGjS zJ1{4(Og)7Sv>w5>*^**?^?tK?)h#W;yYWaCWqw#T>a;|i{N_B8Ih{2R5A2H!WL7b4 zj=HDbB1JGbo%X)%N2t(go@6v%UQQgpMA1Evct|n#$e$NS0s9maAl2Tp8O=^X!Ie(9 z!ewN|4YwWUhD&{@?%GjfGgcl}4gnU$^O#2EiRv=WRj=W@cePk6T&BVwQ_Gd0Fut#( z+NwmRMd%96CxZq3+L(8GRt0xT7p{C;9(=4X3DUy1gkv-vwc1!!a5yPuyzZep4498a zt3-t#H7dHpf?Gj~^3VnDeN?`>=?>0N7FZbH2~=jKy*&?8oId5r;q)pstalv0M8n$r zR9J`p`QAx~1LRn1Z}82Sd%MsUVueKy@Yv35+hB`v7|aNs^X@RBH}8%72VktNx^kXyI05Jou)M@pY!^-%QAH@Cr%^-J z+(z>F_}H=P+{FA)XJ;NP&S?DT37cq7Oym7pS=NiuhT1GrN3+T+rgP?%ko<%sfL=g@ z%?g`fwE3~tjt!xODIICB#>~u*XyjZ6@;929^1P0$ z*uaKf3AH9guY}_>;YNfsre7gm!%5tZIelylvQpwjP2)=TELlEPHbyJmn5(`uK@m`H z6z&fV+5X5J`?}$)_kb5b58UW?LQB zDff8fxM~yh5S{kL=%=+AC}x}92P;BIMEL@CzQchsNHb#48uQsYNhL58hKY; z_Qo?Z+gF-d&x1%q6~muxwr`rB=;%&|N+X{yRt=3h^7w?SX@OPw9kEir z4glm4I~pN(nprOz79Eo(lc{a-==x>I%0om>Ic7fD{b)@%R1IH|7oR3vROv{!)6ww{`uMNTi9IO<&ZOZUcM=dZA z3WEkH2@{F&^-i83wSw5+2k_n0!G981tKw6=r(4KRZkW!dL8JzdO;BI!LqNiBMDu0w zP39A$)9$RKzD}PgeOi8dmgM(TrBxedp@GvI_lr2Z$&8z;%J7{^x{+X1s4wJ&q8(_i z@kjqV*|NddQNufabnOx&q?vyoq|71na`@pt8_?C~h#&Z{yG`8oa%vRu8Xsl8^ zOgWSLhHjOj=e1VFI82_I8MC`EodE#YuF1-CUP!JrL|y(E=sI=KZnbMkbd{Q_Y|?i8 zDCs(=-`6Y(4G5px8(Hcl=kGJxj9#5-ggS6l+4dA*yc^PEF|Fs8d@cB{J7ARhlaNAe zdSH&=BCI5nu~WSMV9y^%u`5XWEv;i!=+u3e?xPJ$t(D%-!4lmov?1i!c;e$Rk5b5! z)AP3dS>q8hg!2a^>_QTrFqkS@KBG~Q45}7ZMZZx;)5PtpyA3H#{gaZh>w`TO->t<3 zKeQT0O9fsrK>Utu2a!hZC6D>&Cmpq(tabwJ6!y|ZqZnmr@DwohhYaw#*T`7a6K3+g z)-thF?lETdmPSjwhUF_7C)8(M*;=qmjr(wL0kp{U4B6KDEv2U79}lSNrank<2&dam z<~oD*EqJUBVew`P7jPGQ1dQq(_%`Sh@OeaUD{b|689yKiuHp&><0RPIm zg;}*G1LDU#I(|j5I$N&?2p4ivy_neh@SlxWDhyJVm3~FB7;MM<3VqXT=2cNF7PVXC zB!okGYZ`p|i?yFn_VulqD`Hh2;zehC;omz;%Vs2Ee7p@!t%b;;;` zloU?yZgUYhEV^0pU=FYR5Mud3n4Oo@AMo}u$wz%FT5_rP41CtOvyly-yAjqR5QE>T z(hALlYoX$Z*kcH%K?*hS7}w($=+r9|@WCfPn+>#ToZZWM;E?7Q))b1v2tu7<8*W8# zL4aLWGX*xGB0h)c&$W3u%}_@l@6xX_(G|{EP8<9)yLXh&vBHv;(zc6?lQ#FI@X}h8 zHpAxsnbPGkelCNoK7p}4k4M1Ra}qEv8``1?Y^N>OcC8br68I8syWus|6cz~u7;XT0 z_qo&Xvj4nq~qBf(1%+IbsXpXY9Mg>__eE!2rlsi@MPJ(_>}*m@9m}?Pb`w0L8U|`ql?Y0cZ^I<6`?1Z*M^4URV5d~^7I^tFYjn}?AdDj2TAJZ!ac z%kIaP@e2daVHYYaK89Iz9+P90=1UpHoe@TZo2dg*qB^`^^J|BjmvV(XwHD@nHx=4+ zT1yk`Q>Ewn7X#(Qh|?6l`(wIwp<8AyR<%vgbdz-zKr?|XRryHV#$CTq4`HT1QeTZQ z5?xkaGbmusB4|Yq7DC&OVWjt?W3*KPUb4t8y+2%I&q7~JZQnC3bBNWI=fbsA z5V&K{eIgnZo3_n)*4`#UV$oKqRx?da61cHVCZ|fBlX^qI;Gl^NKlKk+dVuYa%b_sd z`#N?k@LD`f^mHc|>{v_f-dw^};ktY0hL<&i(Ut|wA)qRtx;1gl#dZz|KdaqJ3j4&-r(iSX7Oc0(BZsV zWDJ@7R>K0irYx4=*R=#`9}S55EBmLf7!>e&2q=L>4E`N|n=7)vQ-tsSpQk7~3d>vU z89nN4=q2!X=aU`4kgawu>fFHjVNwWd%h-FvqQUVAs#QtAB3h6TnxQzjoNFG@la(Og zL!s@^U!Z$4nPzWqY`MPQ5^_fKi;<;HK|u0)!U36hu82t@V4ZevRpr>g9UaDIq$tk+$XwZx9*F76no&a^wK#2ZFlj4 zL4A~~^Xv`)U<4^C9Z^pd4)A0MFtjvB?!)0zf#9jcwgWq6kZR8m%Z2ZcyYmej1eggi z4v|USW}hy;@x#Rlv!wCfdb096!Fy4qflR; zCGlCJ8hS;mo(cyb#gVZyD(g7*n={8G!S+-pl}s$YY9XzR72*pfV=Gbg2kyWt19Ru0TpRiu zBHv-}3thi{QILGqh7AvqqKlz_d^KX;cKDj_DR$yxWauh3R!PK^(GvCDJcM9{UnV7q z{TpM&SzQ(RG7t-PMe4vuBJ5fZmhkWY4Ik04<;QUOM`ObZ>iah^39&Rxhy@PYB(Rdj`kxvxK4Gt(1KoO6g zwPrJtS?7e_;*O1O4Sj*-Hb_*(Oj9}Z$wc!ysQ`EH>syx>_xp>~LwCQ&hqsxRhV8fa z;p$@4)L5%mqZB2JfHmy5HO}Fove2u!Bu}l~_te|Cx7GCo?A;$)+(nGMYIvCf! zzS;@6@iSXmS$+*^p&M9QaO#Yf$Yx;uiH7tKjkOIfp3vI!5RqvsW?Grb>TyG0DR6&y z8>kTmWH9VaT?9Z;ckn?X<6YTFD2W&NuJ;X`(=ov5AnMV9`P}li!nV@F(OU zEk4J-VW9?TZ+B4YegYDD>P6sstm8H$h!6B&j8C{i!JK<=PJ^jTATm94tJj4JX6n!m z4bU=D*s?D+)~sjs)*^wxsd#JQLNw#hK8DFNyrD00{vB}xAKZ>WMZ(-S}4h?Obn|_sHpcPb_0A&WK+@@rl@MtqqAoO51{H0vcvfK1|>QVtcGB1oAX^c2Qa zOddzy%CLx#gkcvK(6YzAcghQ3t-k@4h#|=qE8Qq6`8f9?7Vj4lB{zm+t8` zsfSH(6oiAK&}B*kKi=dwnW zL7Qy?RWm$bkItMuy zqQNt~7`IRIkhxD)l(qh>lU|xcWg|I?{L=T%0D|_k27=m#7;D4N#0MH%HeW+JZlzEI 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Ý|Mbbn&mEg!VXzSP9)3N?c1DMQc=rCS1zxqy~ zti!Z*xe;wF7)nuc#jElN2=1-WOauer7`8QNi0Vt9vM_x;|DOWA!K`{l3e>N~3_!F=WA%_3qMe)SAF~`)Z3#JX zUOeMcBR5+8ReK5sT55F=cxut2^V2tPy-6ng9f}chSd~ARTIieYOM{WUGwP|>=Z%c7 ziRXYWdlSF9h9-t61U7wh*~m`pCj%xLm32umOt>$nb!IkZ9!P~m=ILL4ciozPMxPVt4jGYfQ|zsMTDg5V zF4rQ_qh>$YwhVx!n7 zBcpTMJVx`PZ{as-Kc9$H(~4EVKeu&&o&NlCZdJ-~ic=lt)WJ5B?PdR~5Cw$_0+5Cx zmFhQxv$PXE?g4IZT9FfJ0W2McfBMvzCAH}b0>&$#azjg*83b{@C1Mk?Ept%v=zrIO z2n*pr>(E0hKa^h`s;TPDO{#=o@6ZU(LwFiktyUHtG~l^87fsiuCaXjt!@c|As_}Js zNa_A}Q56R>e38TLyJn#c%QF};cmK)e@tN24v$QhKcpmB+PnPgqs($z^%(8tp02j3` z4*@R}4}GD#^vUFaL8py+Ke4`tunVAK6*D%3==v|}p$GGn?WBcQ5x3l&7DszxGqC6L zUlLBH!MC8Ww>$&n6G6E&Mfy)9~0DPrJVf_3-@;!T5IP2wVPv0H6N z@^DW*%US*T1pOq6&M7)Rd5WQ+wN)#^h_;_nqtuH=?r|HnO0oQP|1Wsq4AqQmvCr4@ zRWbNv8-xNltwJ!vKNyl+pjaY=Lk{0U*I^APy;dT%0A+uMqIA^=?qmE<`Urr(51GSd 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 z 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�(lIh%LChXxzWoi*zJlw407WIe72kVQI2yl|L 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

xc|$JdyRh@=EJvW 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%0Ag8FT_d>y(F(|aRk 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 literal 0 HcmV?d00001 diff --git a/asset/pose.mp4 b/asset/pose.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..4caafc37a5205520f335dec2054c43089b98f1b1 GIT binary patch literal 288849 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%0DD<F{u9QSTN7g^6uptx` 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 literal 0 HcmV?d00001 diff --git a/comfyui/README.md b/comfyui/README.md index 3625523..c92fe83 100644 --- a/comfyui/README.md +++ b/comfyui/README.md @@ -6,16 +6,16 @@ Easily use EasyAnimate inside ComfyUI! [![Modelscope Studio](https://img.shields.io/badge/Modelscope-Studio-blue)](https://modelscope.cn/studios/PAI/EasyAnimate/summary) [![Hugging Face Spaces](https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Spaces-yellow)](https://huggingface.co/spaces/alibaba-pai/EasyAnimate) -- [Installation](#1-installation) +English | [简体中文](./README_zh-CN.md) + +- [Installation](#installation) - [Node types](#node-types) - [Example workflows](#example-workflows) - - [Image to video](#image-to-video) - - [Image to video generation (high FPS w/ frame interpolation)](#image-to-video-generation-high-fps-w-frame-interpolation) -## 1. Installation +## Installation ### Option 1: Install via ComfyUI Manager -TBD +![](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/ComfyUI_Manager.jpg) ### Option 2: Install manually The EasyAnimate repository needs to be placed at `ComfyUI/custom_nodes/EasyAnimate/`. @@ -28,37 +28,50 @@ git clone https://github.com/aigc-apps/EasyAnimate.git # Git clone the video outout node git clone https://github.com/Kosinkadink/ComfyUI-VideoHelperSuite.git +git clone https://github.com/kijai/ComfyUI-KJNodes.git cd EasyAnimate/ pip install -r comfyui/requirements.txt ``` -### 2. Download models into `ComfyUI/models/EasyAnimate/` +### Download models into `ComfyUI/models/EasyAnimate/` -EasyAnimateV5: +EasyAnimateV5.1: + +12B: +| Name | Type | Storage Space | Hugging Face | Model Scope | Description | +|--|--|--|--|--|--| +| EasyAnimateV5.1-12b-zh-InP | EasyAnimateV5.1 | 39 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-InP) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-InP) | Official image-to-video weights. Supports video prediction at multiple resolutions (512, 768, 1024), trained with 49 frames at 8 frames per second, and supports for multilingual prediction. | +| EasyAnimateV5.1-12b-zh-Control | EasyAnimateV5.1 | 39 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-Control) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-Control) | Official video control weights, supporting various control conditions such as Canny, Depth, Pose, MLSD, and trajectory control. Supports video prediction at multiple resolutions (512, 768, 1024), trained with 49 frames at 8 frames per second, and supports for multilingual prediction. | +| EasyAnimateV5.1-12b-zh-Control-Camera | EasyAnimateV5.1 | 39 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-Control-Camera) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-Control-Camera) | Official video camera control weights, supporting direction generation control by inputting camera motion trajectories. Supports video prediction at multiple resolutions (512, 768, 1024), trained with 49 frames at 8 frames per second, and supports for multilingual prediction. | +| EasyAnimateV5.1-12b-zh | EasyAnimateV5.1 | 39 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh) | Official text-to-video weights. Supports video prediction at multiple resolutions (512, 768, 1024), trained with 49 frames at 8 frames per second, and supports for multilingual prediction. | + +<details> + <summary>(Obsolete) EasyAnimateV5:</summary> | Name | Type | Storage Space | Hugging Face | Model Scope | Description | |--|--|--|--|--|--| | EasyAnimateV5-12b-zh-InP | EasyAnimateV5 | 34 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh-InP) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh-InP) | Official image-to-video weights. Supports video prediction at multiple resolutions (512, 768, 1024), trained with 49 frames at 8 frames per second, and supports bilingual prediction in Chinese and English. | | EasyAnimateV5-12b-zh-Control | EasyAnimateV5 | 34 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh-Control) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh-Control) | Official video control weights, supporting various control conditions such as Canny, Depth, Pose, MLSD, etc. Supports video prediction at multiple resolutions (512, 768, 1024) and is trained with 49 frames at 8 frames per second. Bilingual prediction in Chinese and English is supported. | | EasyAnimateV5-12b-zh | EasyAnimateV5 | 34 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh) | Official text-to-video weights. Supports video prediction at multiple resolutions (512, 768, 1024), trained with 49 frames at 8 frames per second, and supports bilingual prediction in Chinese and English. | +</details> <details> <summary>(Obsolete) EasyAnimateV4:</summary> -| Name | Type | Storage Space | Url | Hugging Face | Description | +| Name | Type | Storage Space | Hugging Face | Model Scope | Description | |--|--|--|--|--|--| -| EasyAnimateV4-XL-2-InP.tar.gz | EasyAnimateV4 | Before extraction: 8.9 GB \/ After extraction: 14.0 GB | [Download](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/Diffusion_Transformer/EasyAnimateV4-XL-2-InP.tar.gz) | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV4-XL-2-InP)| Our official graph-generated video model is capable of predicting videos at multiple resolutions (512, 768, 1024, 1280) and has been trained on 144 frames at a rate of 24 frames per second. | +| EasyAnimateV4-XL-2-InP | EasyAnimateV4 | Before extraction: 8.9 GB \/ After extraction: 14.0 GB |[🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV4-XL-2-InP)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV4-XL-2-InP)| | Our official graph-generated video model is capable of predicting videos at multiple resolutions (512, 768, 1024, 1280) and has been trained on 144 frames at a rate of 24 frames per second. | </details> <details> <summary>(Obsolete) EasyAnimateV3:</summary> -| Name | Type | Storage Space | Url | Hugging Face | Description | +| Name | Type | Storage Space | Hugging Face | Model Scope | Description | |--|--|--|--|--|--| -| EasyAnimateV3-XL-2-InP-512x512.tar | EasyAnimateV3 | 18.2GB | [Download](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/Diffusion_Transformer/EasyAnimateV3-XL-2-InP-512x512.tar) | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-512x512) | EasyAnimateV3 official weights for 512x512 text and image to video resolution. Training with 144 frames and fps 24 | -| EasyAnimateV3-XL-2-InP-768x768.tar | EasyAnimateV3 | 18.2GB | [Download](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/Diffusion_Transformer/EasyAnimateV3-XL-2-InP-768x768.tar) | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-768x768) | EasyAnimateV3 official weights for 768x768 text and image to video resolution. Training with 144 frames and fps 24 | -| EasyAnimateV3-XL-2-InP-960x960.tar | EasyAnimateV3 | 18.2GB | [Download](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/Diffusion_Transformer/EasyAnimateV3-XL-2-InP-960x960.tar) | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-960x960) | EasyAnimateV3 official weights for 960x960 text and image to video resolution. Training with 144 frames and fps 24 | +| EasyAnimateV3-XL-2-InP-512x512 | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-512x512)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-512x512) | EasyAnimateV3 official weights for 512x512 text and image to video resolution. Training with 144 frames and fps 24 | +| EasyAnimateV3-XL-2-InP-768x768 | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-768x768) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-768x768) | EasyAnimateV3 official weights for 768x768 text and image to video resolution. Training with 144 frames and fps 24 | +| EasyAnimateV3-XL-2-InP-960x960 | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-960x960) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-960x960) | EasyAnimateV3 official weights for 960x960 text and image to video resolution. Training with 144 frames and fps 24 | </details> ## Node types @@ -75,27 +88,52 @@ EasyAnimateV5: ## Example workflows -### Video to video generation -Our ui is shown as follow, this is the [download link](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5/easyanimatev5_workflow_v2v.json) of the json: -![workflow graph](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5/easyanimatev5_workflow_v2v.jpg) +### Text to Video Generation +Our user interface is shown as follows, this is the [json](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_t2v.json): -You can run the demo using following video: -[demo video](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1/play_guitar.mp4) +![Workflow Diagram](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_t2v.jpg) -### Control video generation -Our ui is shown as follow, this is the [download link](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5/easyanimatev5_workflow_v2v_control.json) of the json: -![workflow graph](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5/easyanimatev5_workflow_v2v_control.jpg) +### Image to Video Generation +Our user interface is shown as follows, this is the [json](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_i2v.json): -You can run the demo using following video: -[demo video](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1.1/pose.mp4) +![Workflow Diagram](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_i2v.jpg) -### Image to video generation -Our ui is shown as follow, this is the [download link](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5/easyanimatev5_workflow_i2v.json) of the json: -![workflow graph](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5/easyanimatev5_workflow_i2v.jpg) +You can run a demo using the following photo: -You can run the demo using following photo: -![demo image](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1/firework.png) +![Demo Image](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1/firework.png) -### Text to video generation -Our ui is shown as follow, this is the [download link](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5/easyanimatev5_workflow_t2v.json) of the json: -![workflow graph](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5/easyanimatev5_workflow_t2v.jpg) \ No newline at end of file +### Video to Video Generation +Our user interface is shown as follows, this is the [json](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_v2v.json): + +![Workflow Diagram](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_v2v.jpg) + +You can run a demo using the following video: + +[Demo Video](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1/play_guitar.mp4) + +### Camera Control Video Generation +Our user interface is shown as follows, this is the [json](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_control_camera.json): + +![Workflow Diagram](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_control_camera.jpg) + +You can run a demo using the following photo: + +![Demo Image](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1/firework.png) + +### Trajectory Control Video Generation +Our user interface is shown as follows, this is the [json](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_control_trajectory.json): + +![Workflow Diagram](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_control_trajectory.jpg) + +You can run a demo using the following photo: + +![Demo Image](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/dog.png) + +### Control Video Generation +Our user interface is shown as follows, this is the [json](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5/easyanimatev5.1_workflow_v2v_control.json): + +![Workflow Diagram](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_v2v_control.jpg) + +You can run a demo using the following video: + +[Demo Video](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1.1/pose.mp4) \ No newline at end of file diff --git a/comfyui/README_zh-CN.md b/comfyui/README_zh-CN.md new file mode 100644 index 0000000..bb53015 --- /dev/null +++ b/comfyui/README_zh-CN.md @@ -0,0 +1,146 @@ +# ComfyUI EasyAnimate +在ComfyUI中使用EasyAnimate! + +[![Arxiv Page](https://img.shields.io/badge/Arxiv-Page-red)](https://arxiv.org/abs/2405.18991) +[![Project Page](https://img.shields.io/badge/Project-Website-green)](https://easyanimate.github.io/) +[![Modelscope Studio](https://img.shields.io/badge/Modelscope-Studio-blue)](https://modelscope.cn/studios/PAI/EasyAnimate/summary) +[![Hugging Face Spaces](https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Spaces-yellow)](https://huggingface.co/spaces/alibaba-pai/EasyAnimate) + +[English](./README.md) | 简体中文 + +- [安装](#安装) +- [节点类型](#节点类型) +- [示例工作流](#示例工作流) + +## 安装 +### 选项1:通过ComfyUI管理器安装 +![](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/ComfyUI_Manager.jpg) + +### 选项2:手动安装 +EasyAnimate存储库需要放置在`ComfyUI/custom_nodes/EasyAnimate/`。 + +``` +cd ComfyUI/custom_nodes/ + +# Git clone the easyanimate itself +git clone https://github.com/aigc-apps/EasyAnimate.git + +# Git clone the video outout node +git clone https://github.com/Kosinkadink/ComfyUI-VideoHelperSuite.git +git clone https://github.com/kijai/ComfyUI-KJNodes.git + +cd EasyAnimate/ +pip install -r comfyui/requirements.txt +``` + +## 将模型下载到`ComfyUI/models/EasyAnimate/` + +EasyAnimateV5.1: +12B: +|名称|类型|存储空间|拥抱面|型号范围|描述| +|--|--|--|--|--|--| +|EasyAnimateV5.1-12b-zh-InP | EasyAnimateV5.1 | 39 GB |[🤗链接](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-InP) | [😄链接](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-InP)|官方图像到视频权重。支持多种分辨率(5127681024)的视频预测,以每秒8帧的速度训练49帧,支持多语言预测| +|EasyAnimateV5.1-12b-zh-控件| EasyAnimateV5.1 | 39 GB |[🤗链接](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-Control) | [😄链接](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-Control)|官方视频控制权重,支持Canny、Depth、Pose、MLSD和轨迹控制等各种控制条件。支持多种分辨率(5127681024)的视频预测,以每秒8帧的速度训练49帧,支持多语言预测| +|EasyAnimateV5.1-12b-zh-控制摄像头| EasyAnimateV5.1 | 39 GB |[🤗链接](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh-Control-Camera) | [😄链接](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh-Control-Camera)|官方摄像机控制权重,支持通过输入摄像机运动轨迹进行方向生成控制。支持多种分辨率(5127681024)的视频预测,以每秒8帧的速度训练49帧,支持多语言预测| +|EasyAnimateV5.1-12b-zh| EasyAnimateV5.1 | 39 GB |[🤗链接](https://huggingface.co/alibaba-pai/EasyAnimateV5.1-12b-zh) | [😄链接](https://modelscope.cn/models/PAI/EasyAnimateV5.1-12b-zh)|官方文本到视频权重。支持多种分辨率(5127681024)的视频预测,以每秒8帧的速度训练49帧,支持多语言预测| + +<details> + <summary>(Obsolete) EasyAnimateV5:</summary> + +7B: +| 名称 | 种类 | 存储空间 | Hugging Face | Model Scope | 描述 | +|--|--|--|--|--|--| +| EasyAnimateV5-7b-zh-InP | EasyAnimateV5 | 22 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-7b-zh-InP) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-7b-zh-InP)| 官方的7B图生视频权重。支持多分辨率(512,768,1024)的视频预测,支持多分辨率(512,768,1024)的视频预测,以49帧、每秒8帧进行训练,支持中文与英文双语预测 | +| EasyAnimateV5-7b-zh | EasyAnimateV5 | 22 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-7b-zh) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh)| 官方的7B文生视频权重。可用于进行下游任务的fientune。支持多分辨率(512,768,1024)的视频预测,支持多分辨率(512,768,1024)的视频预测,以49帧、每秒8帧进行训练,支持中文与英文双语预测 | +| EasyAnimateV5-Reward-LoRAs | EasyAnimateV5 | - | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-Reward-LoRAs) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-Reward-LoRAs) | 通过奖励反向传播技术,优化了EasyAnimateV5-12b生成的视频,以更好地匹配人类偏好| + +12B: +| 名称 | 种类 | 存储空间 | Hugging Face | Model Scope | 描述 | +|--|--|--|--|--|--| +| EasyAnimateV5-12b-zh-InP | EasyAnimateV5 | 34 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh-InP) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh-InP)| 官方的图生视频权重。支持多分辨率(512,768,1024)的视频预测,支持多分辨率(512,768,1024)的视频预测,以49帧、每秒8帧进行训练,支持中文与英文双语预测 | +| EasyAnimateV5-12b-zh-Control | EasyAnimateV5 | 34 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh-Control) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh-Control)| 官方的视频控制权重,支持不同的控制条件,如Canny、Depth、Pose、MLSD等。支持多分辨率(512,768,1024)的视频预测,支持多分辨率(512,768,1024)的视频预测,以49帧、每秒8帧进行训练,支持中文与英文双语预测 | +| EasyAnimateV5-12b-zh | EasyAnimateV5 | 34 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-12b-zh) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-12b-zh)| 官方的文生视频权重。可用于进行下游任务的fientune。支持多分辨率(512,768,1024)的视频预测,支持多分辨率(512,768,1024)的视频预测,以49帧、每秒8帧进行训练,支持中文与英文双语预测 | +| EasyAnimateV5-Reward-LoRAs | EasyAnimateV5 | - | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV5-Reward-LoRAs) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV5-Reward-LoRAs) | 通过奖励反向传播技术,优化了EasyAnimateV5-12b生成的视频,以更好地匹配人类偏好| +</details> + +<details> + <summary>(Obsolete) EasyAnimateV4:</summary> + +| 名称 | 种类 | 存储空间 | Hugging Face | Model Scope | 描述 | +|--|--|--|--|--|--| +| EasyAnimateV4-XL-2-InP | EasyAnimateV4 | 解压前 8.9 GB / 解压后 14.0 GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV4-XL-2-InP)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV4-XL-2-InP)| 官方的图生视频权重。支持多分辨率(512,768,1024,1280)的视频预测,以144帧、每秒24帧进行训练 | +</details> + +<details> + <summary>(Obsolete) EasyAnimateV3:</summary> + +| 名称 | 种类 | 存储空间 | Hugging Face | Model Scope | 描述 | +|--|--|--|--|--|--| +| EasyAnimateV3-XL-2-InP-512x512 | EasyAnimateV3 | 18.2GB| [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-512x512)| [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-512x512)| 官方的512x512分辨率的图生视频权重。以144帧、每秒24帧进行训练 | +| EasyAnimateV3-XL-2-InP-768x768 | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-768x768) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-768x768)| 官方的768x768分辨率的图生视频权重。以144帧、每秒24帧进行训练 | +| EasyAnimateV3-XL-2-InP-960x960 | EasyAnimateV3 | 18.2GB | [🤗Link](https://huggingface.co/alibaba-pai/EasyAnimateV3-XL-2-InP-960x960) | [😄Link](https://modelscope.cn/models/PAI/EasyAnimateV3-XL-2-InP-960x960)| 官方的960x960(720P)分辨率的图生视频权重。以144帧、每秒24帧进行训练 | +</details> + +## 节点类型 +- **LoadEasyAnimateModel** + - 加载EasyAnimate模型 +- **EasyAnimate_TextBox** + - 编写EasyAnimate模型的提示词 +- **EasyAnimateI2VSampler** + - EasyAnimate图像到视频采样节点 +- **EasyAnimateT2VSampler** + - EasyAnimate文本到视频采样节点 +- **EasyAnimateV2VSampler** + - EasyAnimate视频到视频采样节点 + +## 示例工作流 + +### 文本到视频生成 +我们的用户界面显示如下,这是[json](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_t2v.json): + +![工作流程图](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_t2v.jpg) + +### 图像到视频生成 +我们的用户界面显示如下,这是[json](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_i2v.json): + +![工作流程图](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_i2v.jpg) + +您可以使用以下照片运行演示: + +![演示图像](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1/firework.png) + +### 视频到视频生成 +我们的用户界面显示如下,这是[json](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_v2v.json): + +![工作流程图](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_v2v.jpg) + +您可以使用以下视频运行演示: + +[演示视频](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1/play_guitar.mp4) + +### 镜头控制视频生成 +我们的用户界面显示如下,这是[json](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_control_camera.json): + +![工作流程图](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_control_camera.jpg) + +您可以使用以下照片运行演示: + +![演示图像](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1/firework.png) + +### 轨迹控制视频生成 +我们的用户界面显示如下,这是[json](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_control_trajectory.json): + +![工作流程图](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_control_trajectory.jpg) + +您可以使用以下照片运行演示: + +![演示图像](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/dog.png) + +### 控制视频生成 +我们的用户界面显示如下,这是[json](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5/easyanimatev5.1_workflow_v2v_control.json): + +![工作流程图](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/easyanimatev5.1_workflow_v2v_control.jpg) + +您可以使用以下视频运行演示: + +[演示视频](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1.1/pose.mp4) \ No newline at end of file diff --git a/comfyui/comfyui_nodes.py b/comfyui/comfyui_nodes.py index a44c643..51b0680 100644 --- a/comfyui/comfyui_nodes.py +++ b/comfyui/comfyui_nodes.py @@ -2,12 +2,14 @@ """ import gc import os +import json import comfy.model_management as mm import cv2 import folder_paths import numpy as np import torch +import torch.nn.functional as F import copy from comfy.utils import ProgressBar, load_torch_file from diffusers import (AutoencoderKL, DDIMScheduler, @@ -17,27 +19,28 @@ from diffusers import (AutoencoderKL, DDIMScheduler, from einops import rearrange from omegaconf import OmegaConf from PIL import Image -from transformers import (BertModel, BertTokenizer, CLIPImageProcessor, - CLIPVisionModelWithProjection, T5EncoderModel, - T5Tokenizer) +from transformers import (BertModel, BertTokenizer, + CLIPImageProcessor, CLIPVisionModelWithProjection, + Qwen2Tokenizer, Qwen2VLForConditionalGeneration, + T5EncoderModel, T5Tokenizer) +from .utils import combine_camera_motion, get_camera_motion, CAMERA from ..easyanimate.data.bucket_sampler import (ASPECT_RATIO_512, get_closest_ratio) +from ..easyanimate.data.dataset_image_video import process_pose_params from ..easyanimate.models import (name_to_autoencoder_magvit, name_to_transformer3d) -from ..easyanimate.pipeline.pipeline_easyanimate import EasyAnimatePipeline +from ..easyanimate.pipeline.pipeline_easyanimate import \ + EasyAnimatePipeline from ..easyanimate.pipeline.pipeline_easyanimate_inpaint import \ EasyAnimateInpaintPipeline -from ..easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder import \ - EasyAnimatePipeline_Multi_Text_Encoder -from ..easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder_inpaint import \ - EasyAnimatePipeline_Multi_Text_Encoder_Inpaint -from ..easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder_control import \ - EasyAnimatePipeline_Multi_Text_Encoder_Control +from ..easyanimate.pipeline.pipeline_easyanimate_control import \ + EasyAnimateControlPipeline from ..easyanimate.utils.lora_utils import merge_lora, unmerge_lora -from ..easyanimate.utils.utils import (get_image_to_video_latent, +from ..easyanimate.utils.utils import (get_image_to_video_latent, get_image_latent, get_video_to_video_latent) from ..easyanimate.utils.fp8_optimization import convert_weight_dtype_wrapper +from ..easyanimate.ui.ui import ddpm_scheduler_dict, flow_scheduler_dict, all_cheduler_dict # Compatible with Alibaba EAS for quick launch eas_cache_dir = '/stable-diffusion-cache/models' @@ -63,6 +66,22 @@ def to_pil(image): return numpy2pil(image) raise ValueError(f"Cannot convert {type(image)} to PIL.Image") +def gen_gaussian_heatmap(imgSize=200): + circle_img = np.zeros((imgSize, imgSize,), np.float32) + circle_mask = cv2.circle(circle_img, (imgSize//2, imgSize//2), imgSize//2 - 1, 1, -1) + + isotropicGrayscaleImage = np.zeros((imgSize, imgSize), np.float32) + + # 生成高斯图 + for i in range(imgSize): + for j in range(imgSize): + isotropicGrayscaleImage[i, j] = 1 / (2 * np.pi * (40 ** 2)) * np.exp( + -1 / 2 * ((i - imgSize / 2) ** 2 / (40 ** 2) + (j - imgSize / 2) ** 2 / (40 ** 2))) + + isotropicGrayscaleImage = isotropicGrayscaleImage * circle_mask + isotropicGrayscaleImage = (isotropicGrayscaleImage / np.max(isotropicGrayscaleImage) * 255).astype(np.uint8) + return isotropicGrayscaleImage + class LoadEasyAnimateModel: @classmethod def INPUT_TYPES(s): @@ -79,9 +98,12 @@ class LoadEasyAnimateModel: 'EasyAnimateV5-12b-zh-InP', 'EasyAnimateV5-12b-zh-Control', 'EasyAnimateV5-12b-zh', + 'EasyAnimateV5.1-12b-zh-InP', + 'EasyAnimateV5.1-12b-zh-Control', + 'EasyAnimateV5.1-12b-zh-Control-Camera', ], { - "default": 'EasyAnimateV5-7b-zh-InP', + "default": 'EasyAnimateV5.1-12b-zh-InP', } ), "GPU_memory_mode":( @@ -101,9 +123,10 @@ class LoadEasyAnimateModel: "easyanimate_video_v3_slicevae_motion_module.yaml", "easyanimate_video_v4_slicevae_multi_text_encoder.yaml", "easyanimate_video_v5_magvit_multi_text_encoder.yaml", + "easyanimate_video_v5.1_magvit_qwen.yaml", ], { - "default": "easyanimate_video_v5_magvit_multi_text_encoder.yaml", + "default": "easyanimate_video_v5.1_magvit_qwen.yaml", } ), "precision": ( @@ -179,26 +202,48 @@ class LoadEasyAnimateModel: tokenizer = BertTokenizer.from_pretrained( model_name, subfolder="tokenizer" ) - tokenizer_2 = T5Tokenizer.from_pretrained( - model_name, subfolder="tokenizer_2" - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + tokenizer_2 = Qwen2Tokenizer.from_pretrained( + os.path.join(model_name, "tokenizer_2") + ) + else: + tokenizer_2 = T5Tokenizer.from_pretrained( + model_name, subfolder="tokenizer_2" + ) else: - tokenizer = T5Tokenizer.from_pretrained( - model_name, subfolder="tokenizer" - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + tokenizer = Qwen2Tokenizer.from_pretrained( + os.path.join(model_name, "tokenizer") + ) + else: + tokenizer = T5Tokenizer.from_pretrained( + model_name, subfolder="tokenizer" + ) tokenizer_2 = None if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): text_encoder = BertModel.from_pretrained( model_name, subfolder="text_encoder", torch_dtype=weight_dtype ) - text_encoder_2 = T5EncoderModel.from_pretrained( - model_name, subfolder="text_encoder_2", torch_dtype=weight_dtype - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder_2 = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(model_name, "text_encoder_2"), + torch_dtype=weight_dtype, + ) + else: + text_encoder_2 = T5EncoderModel.from_pretrained( + model_name, subfolder="text_encoder_2" + ).to(weight_dtype) else: - text_encoder = T5EncoderModel.from_pretrained( - model_name, subfolder="text_encoder", torch_dtype=weight_dtype - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(model_name, "text_encoder"), + torch_dtype=weight_dtype, + ) + else: + text_encoder = T5EncoderModel.from_pretrained( + model_name, subfolder="text_encoder" + ).to(weight_dtype) text_encoder_2 = None # Load Clip @@ -222,59 +267,30 @@ class LoadEasyAnimateModel: pbar.update(1) if model_type == "Inpaint": - if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): - if transformer.config.in_channels != vae.config.latent_channels: - pipeline = EasyAnimatePipeline_Multi_Text_Encoder_Inpaint.from_pretrained( - model_name, - text_encoder=text_encoder, - text_encoder_2=text_encoder_2, - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - vae=vae, - transformer=transformer, - scheduler=scheduler, - torch_dtype=weight_dtype, - clip_image_encoder=clip_image_encoder, - clip_image_processor=clip_image_processor, - ) - else: - pipeline = EasyAnimatePipeline_Multi_Text_Encoder.from_pretrained( - model_name, - text_encoder=text_encoder, - text_encoder_2=text_encoder_2, - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - vae=vae, - transformer=transformer, - scheduler=scheduler, - torch_dtype=weight_dtype - ) + if transformer.config.in_channels != vae.config.latent_channels: + pipeline = EasyAnimateInpaintPipeline( + text_encoder=text_encoder, + text_encoder_2=text_encoder_2, + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + vae=vae, + transformer=transformer, + scheduler=scheduler, + clip_image_encoder=clip_image_encoder, + clip_image_processor=clip_image_processor, + ) else: - if transformer.config.in_channels != vae.config.latent_channels: - pipeline = EasyAnimateInpaintPipeline.from_pretrained( - model_name, - text_encoder=text_encoder, - tokenizer=tokenizer, - vae=vae, - transformer=transformer, - scheduler=scheduler, - torch_dtype=weight_dtype, - clip_image_encoder=clip_image_encoder, - clip_image_processor=clip_image_processor, - ) - else: - pipeline = EasyAnimatePipeline.from_pretrained( - model_name, - text_encoder=text_encoder, - tokenizer=tokenizer, - vae=vae, - transformer=transformer, - scheduler=scheduler, - torch_dtype=weight_dtype - ) + pipeline = EasyAnimatePipeline( + text_encoder=text_encoder, + text_encoder_2=text_encoder_2, + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + vae=vae, + transformer=transformer, + scheduler=scheduler, + ) else: - pipeline = EasyAnimatePipeline_Multi_Text_Encoder_Control.from_pretrained( - model_name, + pipeline = EasyAnimateControlPipeline( text_encoder=text_encoder, text_encoder_2=text_encoder_2, tokenizer=tokenizer, @@ -282,7 +298,6 @@ class LoadEasyAnimateModel: vae=vae, transformer=transformer, scheduler=scheduler, - torch_dtype=weight_dtype ) if GPU_memory_mode == "sequential_cpu_offload": pipeline.enable_sequential_cpu_offload() @@ -366,6 +381,216 @@ class EasyAnimate_TextBox: def process(self, prompt): return (prompt, ) +class EasyAnimateT2VSampler: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "easyanimate_model": ( + "EASYANIMATESMODEL", + ), + "prompt": ( + "STRING_PROMPT", + ), + "negative_prompt": ( + "STRING_PROMPT", + ), + "video_length": ( + "INT", {"default": 72, "min": 8, "max": 144, "step": 8} + ), + "width": ( + "INT", {"default": 1008, "min": 64, "max": 2048, "step": 16} + ), + "height": ( + "INT", {"default": 576, "min": 64, "max": 2048, "step": 16} + ), + "is_image":( + [ + False, + True + ], + { + "default": False, + } + ), + "seed": ( + "INT", {"default": 43, "min": 0, "max": 0xffffffffffffffff} + ), + "steps": ( + "INT", {"default": 25, "min": 1, "max": 200, "step": 1} + ), + "cfg": ( + "FLOAT", {"default": 7.0, "min": 1.0, "max": 20.0, "step": 0.01} + ), + "scheduler": ( + [ + "Euler", + "Euler A", + "DPM++", + "PNDM", + "DDIM", + ], + { + "default": 'DDIM' + } + ), + }, + } + + RETURN_TYPES = ("IMAGE",) + RETURN_NAMES =("images",) + FUNCTION = "process" + CATEGORY = "EasyAnimateWrapper" + + def process(self, easyanimate_model, prompt, negative_prompt, video_length, width, height, is_image, seed, steps, cfg, scheduler): + global transformer_cpu_cache + global lora_path_before + device = mm.get_torch_device() + offload_device = mm.unet_offload_device() + + mm.soft_empty_cache() + gc.collect() + + # Get Pipeline + pipeline = easyanimate_model['pipeline'] + model_name = easyanimate_model['model_name'] + weight_dtype = easyanimate_model['dtype'] + + # Load Sampler + pipeline.scheduler = all_cheduler_dict[scheduler].from_pretrained(model_name, subfolder='scheduler') + + generator= torch.Generator(device).manual_seed(seed) + + video_length = 1 if is_image else video_length + with torch.no_grad(): + if pipeline.vae.cache_mag_vae: + video_length = int((video_length - 1) // pipeline.vae.mini_batch_encoder * pipeline.vae.mini_batch_encoder) + 1 if video_length != 1 else 1 + else: + video_length = int(video_length // pipeline.vae.mini_batch_encoder * pipeline.vae.mini_batch_encoder) if video_length != 1 else 1 + + # Apply lora + if easyanimate_model.get("lora_cache", False): + if len(easyanimate_model.get("loras", [])) != 0: + # Save the original weights to cpu + if len(transformer_cpu_cache) == 0: + print('Save transformer state_dict to cpu memory') + transformer_state_dict = pipeline.transformer.state_dict() + for key in transformer_state_dict: + transformer_cpu_cache[key] = transformer_state_dict[key].clone().cpu() + + lora_path_now = str(easyanimate_model.get("loras", []) + easyanimate_model.get("strength_model", [])) + if lora_path_now != lora_path_before: + print('Merge Lora with Cache') + lora_path_before = copy.deepcopy(lora_path_now) + pipeline.transformer.load_state_dict(transformer_cpu_cache) + for _lora_path, _lora_weight in zip(easyanimate_model.get("loras", []), easyanimate_model.get("strength_model", [])): + pipeline = merge_lora(pipeline, _lora_path, _lora_weight, device="cuda", dtype=weight_dtype) + else: + # Clear lora when switch from lora_cache=True to lora_cache=False. + if len(transformer_cpu_cache) != 0: + print('Delete cpu state_dict') + pipeline.transformer.load_state_dict(transformer_cpu_cache) + transformer_cpu_cache = {} + lora_path_before = "" + gc.collect() + print('Merge Lora') + for _lora_path, _lora_weight in zip(easyanimate_model.get("loras", []), easyanimate_model.get("strength_model", [])): + pipeline = merge_lora(pipeline, _lora_path, _lora_weight, device="cuda", dtype=weight_dtype) + + if pipeline.transformer.config.in_channels != pipeline.vae.config.latent_channels: + input_video, input_video_mask, clip_image = get_image_to_video_latent(None, None, video_length=video_length, sample_size=(height, width)) + + sample = pipeline( + prompt, + video_length = video_length, + negative_prompt = negative_prompt, + height = height, + width = width, + generator = generator, + guidance_scale = cfg, + num_inference_steps = steps, + + video = input_video, + mask_video = input_video_mask, + clip_image = clip_image, + comfyui_progressbar = True, + ).frames + else: + sample = pipeline( + prompt, + video_length = video_length, + negative_prompt = negative_prompt, + height = height, + width = width, + generator = generator, + guidance_scale = cfg, + num_inference_steps = steps, + ).frames + videos = rearrange(sample, "b c t h w -> (b t) h w c") + + if not easyanimate_model.get("lora_cache", False): + print('Unmerge Lora') + for _lora_path, _lora_weight in zip(easyanimate_model.get("loras", []), easyanimate_model.get("strength_model", [])): + pipeline = unmerge_lora(pipeline, _lora_path, _lora_weight, device="cuda", dtype=weight_dtype) + return (videos,) + +class EasyAnimateV5_T2VSampler(EasyAnimateT2VSampler): + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "easyanimate_model": ( + "EASYANIMATESMODEL", + ), + "prompt": ( + "STRING_PROMPT", + ), + "negative_prompt": ( + "STRING_PROMPT", + ), + "video_length": ( + "INT", {"default": 49, "min": 1, "max": 49, "step": 4} + ), + "width": ( + "INT", {"default": 1008, "min": 64, "max": 2048, "step": 16} + ), + "height": ( + "INT", {"default": 576, "min": 64, "max": 2048, "step": 16} + ), + "is_image":( + [ + False, + True + ], + { + "default": False, + } + ), + "seed": ( + "INT", {"default": 43, "min": 0, "max": 0xffffffffffffffff} + ), + "steps": ( + "INT", {"default": 25, "min": 1, "max": 200, "step": 1} + ), + "cfg": ( + "FLOAT", {"default": 7.0, "min": 1.0, "max": 20.0, "step": 0.01} + ), + "scheduler": ( + [ + "Euler", + "Euler A", + "DPM++", + "PNDM", + "DDIM", + "Flow", + ], + { + "default": 'Flow' + } + ), + }, + } + class EasyAnimateI2VSampler: @classmethod def INPUT_TYPES(s): @@ -447,17 +672,7 @@ class EasyAnimateI2VSampler: weight_dtype = easyanimate_model['dtype'] # Load Sampler - if scheduler == "DPM++": - noise_scheduler = DPMSolverMultistepScheduler.from_pretrained(model_name, subfolder='scheduler') - elif scheduler == "Euler": - noise_scheduler = EulerDiscreteScheduler.from_pretrained(model_name, subfolder='scheduler') - elif scheduler == "Euler A": - noise_scheduler = EulerAncestralDiscreteScheduler.from_pretrained(model_name, subfolder='scheduler') - elif scheduler == "PNDM": - noise_scheduler = PNDMScheduler.from_pretrained(model_name, subfolder='scheduler') - elif scheduler == "DDIM": - noise_scheduler = DDIMScheduler.from_pretrained(model_name, subfolder='scheduler') - pipeline.scheduler = noise_scheduler + pipeline.scheduler = all_cheduler_dict[scheduler].from_pretrained(model_name, subfolder='scheduler') generator= torch.Generator(device).manual_seed(seed) @@ -510,7 +725,7 @@ class EasyAnimateI2VSampler: mask_video = input_video_mask, clip_image = clip_image, comfyui_progressbar = True, - ).videos + ).frames videos = rearrange(sample, "b c t h w -> (b t) h w c") if not easyanimate_model.get("lora_cache", False): @@ -560,9 +775,10 @@ class EasyAnimateV5_I2VSampler(EasyAnimateI2VSampler): "DPM++", "PNDM", "DDIM", + "Flow", ], { - "default": 'DDIM' + "default": 'Flow' } ) }, @@ -572,226 +788,6 @@ class EasyAnimateV5_I2VSampler(EasyAnimateI2VSampler): }, } - -class EasyAnimateT2VSampler: - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "easyanimate_model": ( - "EASYANIMATESMODEL", - ), - "prompt": ( - "STRING_PROMPT", - ), - "negative_prompt": ( - "STRING_PROMPT", - ), - "video_length": ( - "INT", {"default": 72, "min": 8, "max": 144, "step": 8} - ), - "width": ( - "INT", {"default": 1008, "min": 64, "max": 2048, "step": 16} - ), - "height": ( - "INT", {"default": 576, "min": 64, "max": 2048, "step": 16} - ), - "is_image":( - [ - False, - True - ], - { - "default": False, - } - ), - "seed": ( - "INT", {"default": 43, "min": 0, "max": 0xffffffffffffffff} - ), - "steps": ( - "INT", {"default": 25, "min": 1, "max": 200, "step": 1} - ), - "cfg": ( - "FLOAT", {"default": 7.0, "min": 1.0, "max": 20.0, "step": 0.01} - ), - "scheduler": ( - [ - "Euler", - "Euler A", - "DPM++", - "PNDM", - "DDIM", - ], - { - "default": 'DDIM' - } - ), - }, - } - - RETURN_TYPES = ("IMAGE",) - RETURN_NAMES =("images",) - FUNCTION = "process" - CATEGORY = "EasyAnimateWrapper" - - def process(self, easyanimate_model, prompt, negative_prompt, video_length, width, height, is_image, seed, steps, cfg, scheduler): - global transformer_cpu_cache - global lora_path_before - device = mm.get_torch_device() - offload_device = mm.unet_offload_device() - - mm.soft_empty_cache() - gc.collect() - - # Get Pipeline - pipeline = easyanimate_model['pipeline'] - model_name = easyanimate_model['model_name'] - weight_dtype = easyanimate_model['dtype'] - - # Load Sampler - if scheduler == "DPM++": - noise_scheduler = DPMSolverMultistepScheduler.from_pretrained(model_name, subfolder='scheduler') - elif scheduler == "Euler": - noise_scheduler = EulerDiscreteScheduler.from_pretrained(model_name, subfolder='scheduler') - elif scheduler == "Euler A": - noise_scheduler = EulerAncestralDiscreteScheduler.from_pretrained(model_name, subfolder='scheduler') - elif scheduler == "PNDM": - noise_scheduler = PNDMScheduler.from_pretrained(model_name, subfolder='scheduler') - elif scheduler == "DDIM": - noise_scheduler = DDIMScheduler.from_pretrained(model_name, subfolder='scheduler') - pipeline.scheduler = noise_scheduler - - generator= torch.Generator(device).manual_seed(seed) - - video_length = 1 if is_image else video_length - with torch.no_grad(): - if pipeline.vae.cache_mag_vae: - video_length = int((video_length - 1) // pipeline.vae.mini_batch_encoder * pipeline.vae.mini_batch_encoder) + 1 if video_length != 1 else 1 - else: - video_length = int(video_length // pipeline.vae.mini_batch_encoder * pipeline.vae.mini_batch_encoder) if video_length != 1 else 1 - - # Apply lora - if easyanimate_model.get("lora_cache", False): - if len(easyanimate_model.get("loras", [])) != 0: - # Save the original weights to cpu - if len(transformer_cpu_cache) == 0: - print('Save transformer state_dict to cpu memory') - transformer_state_dict = pipeline.transformer.state_dict() - for key in transformer_state_dict: - transformer_cpu_cache[key] = transformer_state_dict[key].clone().cpu() - - lora_path_now = str(easyanimate_model.get("loras", []) + easyanimate_model.get("strength_model", [])) - if lora_path_now != lora_path_before: - print('Merge Lora with Cache') - lora_path_before = copy.deepcopy(lora_path_now) - pipeline.transformer.load_state_dict(transformer_cpu_cache) - for _lora_path, _lora_weight in zip(easyanimate_model.get("loras", []), easyanimate_model.get("strength_model", [])): - pipeline = merge_lora(pipeline, _lora_path, _lora_weight, device="cuda", dtype=weight_dtype) - else: - # Clear lora when switch from lora_cache=True to lora_cache=False. - if len(transformer_cpu_cache) != 0: - print('Delete cpu state_dict') - pipeline.transformer.load_state_dict(transformer_cpu_cache) - transformer_cpu_cache = {} - lora_path_before = "" - gc.collect() - print('Merge Lora') - for _lora_path, _lora_weight in zip(easyanimate_model.get("loras", []), easyanimate_model.get("strength_model", [])): - pipeline = merge_lora(pipeline, _lora_path, _lora_weight, device="cuda", dtype=weight_dtype) - - if pipeline.transformer.config.in_channels != pipeline.vae.config.latent_channels: - input_video, input_video_mask, clip_image = get_image_to_video_latent(None, None, video_length=video_length, sample_size=(height, width)) - - sample = pipeline( - prompt, - video_length = video_length, - negative_prompt = negative_prompt, - height = height, - width = width, - generator = generator, - guidance_scale = cfg, - num_inference_steps = steps, - - video = input_video, - mask_video = input_video_mask, - clip_image = clip_image, - comfyui_progressbar = True, - ).videos - else: - sample = pipeline( - prompt, - video_length = video_length, - negative_prompt = negative_prompt, - height = height, - width = width, - generator = generator, - guidance_scale = cfg, - num_inference_steps = steps, - ).videos - videos = rearrange(sample, "b c t h w -> (b t) h w c") - - if not easyanimate_model.get("lora_cache", False): - print('Unmerge Lora') - for _lora_path, _lora_weight in zip(easyanimate_model.get("loras", []), easyanimate_model.get("strength_model", [])): - pipeline = unmerge_lora(pipeline, _lora_path, _lora_weight, device="cuda", dtype=weight_dtype) - return (videos,) - -class EasyAnimateV5_T2VSampler(EasyAnimateT2VSampler): - @classmethod - def INPUT_TYPES(s): - return { - "required": { - "easyanimate_model": ( - "EASYANIMATESMODEL", - ), - "prompt": ( - "STRING_PROMPT", - ), - "negative_prompt": ( - "STRING_PROMPT", - ), - "video_length": ( - "INT", {"default": 49, "min": 1, "max": 49, "step": 4} - ), - "width": ( - "INT", {"default": 1008, "min": 64, "max": 2048, "step": 16} - ), - "height": ( - "INT", {"default": 576, "min": 64, "max": 2048, "step": 16} - ), - "is_image":( - [ - False, - True - ], - { - "default": False, - } - ), - "seed": ( - "INT", {"default": 43, "min": 0, "max": 0xffffffffffffffff} - ), - "steps": ( - "INT", {"default": 25, "min": 1, "max": 200, "step": 1} - ), - "cfg": ( - "FLOAT", {"default": 7.0, "min": 1.0, "max": 20.0, "step": 0.01} - ), - "scheduler": ( - [ - "Euler", - "Euler A", - "DPM++", - "PNDM", - "DDIM", - ], - { - "default": 'DDIM' - } - ), - }, - } - class EasyAnimateV2VSampler: @classmethod def INPUT_TYPES(s): @@ -853,9 +849,10 @@ class EasyAnimateV2VSampler: FUNCTION = "process" CATEGORY = "EasyAnimateWrapper" - def process(self, easyanimate_model, prompt, negative_prompt, video_length, base_resolution, seed, steps, cfg, denoise_strength, scheduler, validation_video=None, control_video=None): + def process(self, easyanimate_model, prompt, negative_prompt, video_length, base_resolution, seed, steps, cfg, denoise_strength, scheduler, validation_video=None, control_video=None, ref_image=None, camera_conditions=None): global transformer_cpu_cache global lora_path_before + device = mm.get_torch_device() offload_device = mm.unet_offload_device() @@ -877,26 +874,23 @@ class EasyAnimateV2VSampler: validation_video = np.array(validation_video.cpu().numpy() * 255, np.uint8) original_width, original_height = Image.fromarray(validation_video[0]).size else: - if type(control_video) is str: + if control_video is not None and type(control_video) is str: original_width, original_height = Image.fromarray(cv2.VideoCapture(control_video).read()[1]).size - else: + elif control_video is not None: control_video = np.array(control_video.cpu().numpy() * 255, np.uint8) original_width, original_height = Image.fromarray(control_video[0]).size + else: + original_width, original_height = 384 / 512 * base_resolution, 672 / 512 * base_resolution + + if ref_image is not None: + ref_image = [to_pil(_ref_image) for _ref_image in ref_image] + original_width, original_height = ref_image[0].size if type(ref_image) is list else Image.open(ref_image).size + closest_size, closest_ratio = get_closest_ratio(original_height, original_width, ratios=aspect_ratio_sample_size) height, width = [int(x / 16) * 16 for x in closest_size] # Load Sampler - if scheduler == "DPM++": - noise_scheduler = DPMSolverMultistepScheduler.from_pretrained(model_name, subfolder='scheduler') - elif scheduler == "Euler": - noise_scheduler = EulerDiscreteScheduler.from_pretrained(model_name, subfolder='scheduler') - elif scheduler == "Euler A": - noise_scheduler = EulerAncestralDiscreteScheduler.from_pretrained(model_name, subfolder='scheduler') - elif scheduler == "PNDM": - noise_scheduler = PNDMScheduler.from_pretrained(model_name, subfolder='scheduler') - elif scheduler == "DDIM": - noise_scheduler = DDIMScheduler.from_pretrained(model_name, subfolder='scheduler') - pipeline.scheduler = noise_scheduler + pipeline.scheduler = all_cheduler_dict[scheduler].from_pretrained(model_name, subfolder='scheduler') generator= torch.Generator(device).manual_seed(seed) @@ -909,6 +903,16 @@ class EasyAnimateV2VSampler: input_video, input_video_mask, clip_image = get_video_to_video_latent(validation_video, video_length=video_length, sample_size=(height, width), fps=8) else: input_video, input_video_mask, clip_image = get_video_to_video_latent(control_video, video_length=video_length, sample_size=(height, width), fps=8) + if ref_image is not None: + ref_image = get_image_latent(sample_size=(height, width), ref_image=ref_image[0]) + if camera_conditions is not None and len(camera_conditions) > 0: + poses = json.loads(camera_conditions) + cam_params = np.array([[float(x) for x in pose] for pose in poses]) + cam_params = np.concatenate([np.zeros_like(cam_params[:, :1]), cam_params], 1) + control_camera_video = process_pose_params(cam_params, width=width, height=height) + control_camera_video = control_camera_video[:video_length].permute([3, 0, 1, 2]).unsqueeze(0) + else: + control_camera_video = None # Apply lora if easyanimate_model.get("lora_cache", False): @@ -954,7 +958,7 @@ class EasyAnimateV2VSampler: clip_image = clip_image, strength = float(denoise_strength), comfyui_progressbar = True, - ).videos + ).frames else: sample = pipeline( prompt, @@ -966,9 +970,11 @@ class EasyAnimateV2VSampler: guidance_scale = cfg, num_inference_steps = steps, + ref_image = ref_image, + control_camera_video = control_camera_video, control_video = input_video, comfyui_progressbar = True, - ).videos + ).frames videos = rearrange(sample, "b c t h w -> (b t) h w c") if not easyanimate_model.get("lora_cache", False): @@ -1021,18 +1027,221 @@ class EasyAnimateV5_V2VSampler(EasyAnimateV2VSampler): "DPM++", "PNDM", "DDIM", + "Flow", ], { - "default": 'DDIM' + "default": 'Flow' } ), }, "optional":{ "validation_video": ("IMAGE",), "control_video": ("IMAGE",), + "camera_conditions": ("STRING", {"forceInput": True}), + "ref_image": ("IMAGE",), }, } +class CreateTrajectoryBasedOnKJNodes: + # Modified from https://github.com/kijai/ComfyUI-KJNodes/blob/main/nodes/curve_nodes.py + # Modify to meet the trajectory control requirements of EasyAnimate. + RETURN_TYPES = ("IMAGE", ) + RETURN_NAMES = ("image", ) + FUNCTION = "createtrajectory" + CATEGORY = "EasyAnimateWrapper" + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "coordinates": ("STRING", {"forceInput": True}), + "masks": ("MASK", {"forceInput": True}), + }, + } + + def createtrajectory(self, coordinates, masks): + # Define the number of images in the batch + if len(coordinates) < 10: + coords_list = [] + for coords in coordinates: + coords = json.loads(coords.replace("'", '"')) + coords_list.append(coords) + else: + coords = json.loads(coordinates.replace("'", '"')) + coords_list = [coords] + + _, frame_height, frame_width = masks.size() + heatmap = gen_gaussian_heatmap() + + circle_size = int(50 * ((frame_height * frame_width) / (1280 * 720)) ** (1/2)) + + images_list = [] + for coords in coords_list: + _images_list = [] + for i in range(len(coords)): + _image = np.zeros((frame_height, frame_width, 3)) + center_coordinate = [coords[i][key] for key in coords[i]] + + y1 = max(center_coordinate[1] - circle_size, 0) + y2 = min(center_coordinate[1] + circle_size, np.shape(_image)[0] - 1) + x1 = max(center_coordinate[0] - circle_size, 0) + x2 = min(center_coordinate[0] + circle_size, np.shape(_image)[1] - 1) + + if x2 - x1 > 3 and y2 - y1 > 3: + need_map = cv2.resize(heatmap, (x2 - x1, y2 - y1))[:, :, None] + _image[y1:y2, x1:x2] = np.maximum(need_map.copy(), _image[y1:y2, x1:x2]) + + _image = np.expand_dims(_image, 0) / 255 + _images_list.append(_image) + images_list.append(np.concatenate(_images_list, axis=0)) + + out_images = torch.from_numpy(np.max(np.array(images_list), axis=0)) + return (out_images, ) + +class ImageMaximumNode: + RETURN_TYPES = ("IMAGE", ) + RETURN_NAMES = ("image", ) + FUNCTION = "imagemaximum" + CATEGORY = "EasyAnimateWrapper" + + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "video_1": ("IMAGE",), + "video_2": ("IMAGE",), + }, + } + + def imagemaximum(self, video_1, video_2): + length_1, h_1, w_1, c_1 = video_1.size() + length_2, h_2, w_2, c_2 = video_2.size() + + if h_1 != h_2 or w_1 != w_2: + video_1, video_2 = video_1.permute([0, 3, 1, 2]), video_2.permute([0, 3, 1, 2]) + video_2 = F.interpolate(video_2, video_1.size()[-2:]) + video_1, video_2 = video_1.permute([0, 2, 3, 1]), video_2.permute([0, 2, 3, 1]) + + if length_1 > length_2: + outputs = torch.maximum(video_1[:length_2], video_2) + else: + outputs = torch.maximum(video_1, video_2[:length_1]) + return (outputs, ) + +class CameraBasicFromChaoJie: + # Copied from https://github.com/chaojie/ComfyUI-CameraCtrl-Wrapper/blob/main/nodes.py + # Since ComfyUI-CameraCtrl-Wrapper requires a specific version of diffusers, which is not suitable for us. + # The code has been copied into the current repository. + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "camera_pose":(["Static","Pan Up","Pan Down","Pan Left","Pan Right","Zoom In","Zoom Out","ACW","CW"],{"default":"Static"}), + "speed":("FLOAT",{"default":1.0}), + "video_length":("INT",{"default":16}), + }, + } + + RETURN_TYPES = ("CameraPose",) + FUNCTION = "run" + CATEGORY = "CameraCtrl" + + def run(self,camera_pose,speed,video_length): + camera_dict = { + "motion":[camera_pose], + "mode": "Basic Camera Poses", # "First A then B", "Both A and B", "Custom" + "speed": speed, + "complex": None + } + motion_list = camera_dict['motion'] + mode = camera_dict['mode'] + speed = camera_dict['speed'] + angle = np.array(CAMERA[motion_list[0]]["angle"]) + T = np.array(CAMERA[motion_list[0]]["T"]) + RT = get_camera_motion(angle, T, speed, video_length) + return (RT,) + +class CameraCombineFromChaoJie: + # Copied from https://github.com/chaojie/ComfyUI-CameraCtrl-Wrapper/blob/main/nodes.py + # Since ComfyUI-CameraCtrl-Wrapper requires a specific version of diffusers, which is not suitable for us. + # The code has been copied into the current repository. + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "camera_pose1":(["Static","Pan Up","Pan Down","Pan Left","Pan Right","Zoom In","Zoom Out","ACW","CW"],{"default":"Static"}), + "camera_pose2":(["Static","Pan Up","Pan Down","Pan Left","Pan Right","Zoom In","Zoom Out","ACW","CW"],{"default":"Static"}), + "camera_pose3":(["Static","Pan Up","Pan Down","Pan Left","Pan Right","Zoom In","Zoom Out","ACW","CW"],{"default":"Static"}), + "camera_pose4":(["Static","Pan Up","Pan Down","Pan Left","Pan Right","Zoom In","Zoom Out","ACW","CW"],{"default":"Static"}), + "speed":("FLOAT",{"default":1.0}), + "video_length":("INT",{"default":16}), + }, + } + + RETURN_TYPES = ("CameraPose",) + FUNCTION = "run" + CATEGORY = "CameraCtrl" + + def run(self,camera_pose1,camera_pose2,camera_pose3,camera_pose4,speed,video_length): + angle = np.array(CAMERA[camera_pose1]["angle"]) + np.array(CAMERA[camera_pose2]["angle"]) + np.array(CAMERA[camera_pose3]["angle"]) + np.array(CAMERA[camera_pose4]["angle"]) + T = np.array(CAMERA[camera_pose1]["T"]) + np.array(CAMERA[camera_pose2]["T"]) + np.array(CAMERA[camera_pose3]["T"]) + np.array(CAMERA[camera_pose4]["T"]) + RT = get_camera_motion(angle, T, speed, video_length) + return (RT,) + +class CameraJoinFromChaoJie: + # Copied from https://github.com/chaojie/ComfyUI-CameraCtrl-Wrapper/blob/main/nodes.py + # Since ComfyUI-CameraCtrl-Wrapper requires a specific version of diffusers, which is not suitable for us. + # The code has been copied into the current repository. + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "camera_pose1":("CameraPose",), + "camera_pose2":("CameraPose",), + }, + } + + RETURN_TYPES = ("CameraPose",) + FUNCTION = "run" + CATEGORY = "CameraCtrl" + + def run(self,camera_pose1,camera_pose2): + RT = combine_camera_motion(camera_pose1, camera_pose2) + return (RT,) + +class CameraTrajectoryFromChaoJie: + # Copied from https://github.com/chaojie/ComfyUI-CameraCtrl-Wrapper/blob/main/nodes.py + # Since ComfyUI-CameraCtrl-Wrapper requires a specific version of diffusers, which is not suitable for us. + # The code has been copied into the current repository. + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "camera_pose":("CameraPose",), + "fx":("FLOAT",{"default":0.474812461, "min": 0, "max": 1, "step": 0.000000001}), + "fy":("FLOAT",{"default":0.844111024, "min": 0, "max": 1, "step": 0.000000001}), + "cx":("FLOAT",{"default":0.5, "min": 0, "max": 1, "step": 0.01}), + "cy":("FLOAT",{"default":0.5, "min": 0, "max": 1, "step": 0.01}), + }, + } + + RETURN_TYPES = ("STRING","INT",) + RETURN_NAMES = ("camera_trajectory","video_length",) + FUNCTION = "run" + CATEGORY = "CameraCtrl" + + def run(self,camera_pose,fx,fy,cx,cy): + #print(camera_pose) + camera_pose_list=camera_pose.tolist() + trajs=[] + for cp in camera_pose_list: + traj=[fx,fy,cx,cy,0,0] + traj.extend(cp[0]) + traj.extend(cp[1]) + traj.extend(cp[2]) + trajs.append(traj) + return (json.dumps(trajs),len(trajs),) + NODE_CLASS_MAPPINGS = { "TextBox": TextBox, "EasyAnimate_TextBox": EasyAnimate_TextBox, @@ -1044,6 +1253,12 @@ NODE_CLASS_MAPPINGS = { "EasyAnimateV5_I2VSampler": EasyAnimateV5_I2VSampler, "EasyAnimateV5_T2VSampler": EasyAnimateV5_T2VSampler, "EasyAnimateV5_V2VSampler": EasyAnimateV5_V2VSampler, + "CreateTrajectoryBasedOnKJNodes": CreateTrajectoryBasedOnKJNodes, + "CameraBasicFromChaoJie": CameraBasicFromChaoJie, + "CameraTrajectoryFromChaoJie": CameraTrajectoryFromChaoJie, + "CameraJoinFromChaoJie": CameraJoinFromChaoJie, + "CameraCombineFromChaoJie": CameraCombineFromChaoJie, + "ImageMaximumNode": ImageMaximumNode, } @@ -1058,4 +1273,10 @@ NODE_DISPLAY_NAME_MAPPINGS = { "EasyAnimateV5_I2VSampler": "EasyAnimateV5 Sampler for Image to Video", "EasyAnimateV5_T2VSampler": "EasyAnimateV5 Sampler for Text to Video", "EasyAnimateV5_V2VSampler": "EasyAnimateV5 Sampler for Video to Video", -} + "CreateTrajectoryBasedOnKJNodes": "Create Trajectory Based On KJNodes", + "CameraBasicFromChaoJie": "CameraBasicFromChaoJie", + "CameraTrajectoryFromChaoJie": "CameraTrajectoryFromChaoJie", + "CameraJoinFromChaoJie": "CameraJoinFromChaoJie", + "CameraCombineFromChaoJie": "CameraCombineFromChaoJie", + "ImageMaximumNode": "ImageMaximumNode", +} diff --git a/comfyui/utils.py b/comfyui/utils.py new file mode 100644 index 0000000..efd0558 --- /dev/null +++ b/comfyui/utils.py @@ -0,0 +1,80 @@ +"""Modified from https://github.com/chaojie/ComfyUI-CameraCtrl-Wrapper/blob/main/camera_utils.py +""" +import copy +import numpy as np + +CAMERA = { + # T + "base_T_norm": 1.5, + "base_angle": np.pi/3, + + "Static": { "angle":[0., 0., 0.], "T":[0., 0., 0.]}, + "Pan Up": { "angle":[0., 0., 0.], "T":[0., 1., 0.]}, + "Pan Down": { "angle":[0., 0., 0.], "T":[0.,-1.,0.]}, + "Pan Left": { "angle":[0., 0., 0.], "T":[1.,0.,0.]}, + "Pan Right": { "angle":[0., 0., 0.], "T": [-1.,0.,0.]}, + "Zoom In": { "angle":[0., 0., 0.], "T": [0.,0.,-2.]}, + "Zoom Out": { "angle":[0., 0., 0.], "T": [0.,0.,2.]}, + "ACW": { "angle": [0., 0., 1.], "T":[0., 0., 0.]}, + "CW": { "angle": [0., 0., -1.], "T":[0., 0., 0.]}, +} + +def compute_R_form_rad_angle(angles): + theta_x, theta_y, theta_z = angles + Rx = np.array([[1, 0, 0], + [0, np.cos(theta_x), -np.sin(theta_x)], + [0, np.sin(theta_x), np.cos(theta_x)]]) + + Ry = np.array([[np.cos(theta_y), 0, np.sin(theta_y)], + [0, 1, 0], + [-np.sin(theta_y), 0, np.cos(theta_y)]]) + + Rz = np.array([[np.cos(theta_z), -np.sin(theta_z), 0], + [np.sin(theta_z), np.cos(theta_z), 0], + [0, 0, 1]]) + + # 计算相机外参的旋转矩阵 + R = np.dot(Rz, np.dot(Ry, Rx)) + return R + +def get_camera_motion(angle, T, speed, n=16): + RT = [] + for i in range(n): + _angle = (i/n)*speed*(CAMERA["base_angle"])*angle + R = compute_R_form_rad_angle(_angle) + # _T = (i/n)*speed*(T.reshape(3,1)) + _T=(i/n)*speed*(CAMERA["base_T_norm"])*(T.reshape(3,1)) + _RT = np.concatenate([R,_T], axis=1) + RT.append(_RT) + RT = np.stack(RT) + return RT + +def create_relative(RT_list, K_1=4.7, dataset="syn"): + RT = copy.deepcopy(RT_list[0]) + R_inv = RT[:,:3].T + T = RT[:,-1] + + temp = [] + for _RT in RT_list: + _RT[:,:3] = np.dot(_RT[:,:3], R_inv) + _RT[:,-1] = _RT[:,-1] - np.dot(_RT[:,:3], T) + temp.append(_RT) + RT_list = temp + + return RT_list + +def combine_camera_motion(RT_0, RT_1): + RT = copy.deepcopy(RT_0[-1]) + R = RT[:,:3] + R_inv = RT[:,:3].T + T = RT[:,-1] + + temp = [] + for _RT in RT_1: + _RT[:,:3] = np.dot(_RT[:,:3], R) + _RT[:,-1] = _RT[:,-1] + np.dot(np.dot(_RT[:,:3], R_inv), T) + temp.append(_RT) + + RT_1 = np.stack(temp) + + return np.concatenate([RT_0, RT_1], axis=0) \ No newline at end of file diff --git a/comfyui/v4/easyanimatev4_workflow_v2v.json b/comfyui/v4/easyanimatev4_workflow_v2v.json index b0c799a..ddc840a 100644 --- a/comfyui/v4/easyanimatev4_workflow_v2v.json +++ b/comfyui/v4/easyanimatev4_workflow_v2v.json @@ -134,7 +134,7 @@ "Node name for S&R": "EasyAnimate_TextBox" }, "widgets_values": [ - "一个漂亮的女人在弹吉他。视频质量高,画面清晰。高质量,杰作,最好的质量,高分辨率,超仔细。" + "一只穿着小外套的猫咪正在花园秋千上安静地弹吉他。晚霞的余光洒在它柔软的毛皮上,和煦的微风轻轻拂过,周围斑驳的光影随着音乐的旋律轻轻摇曳。" ] }, { diff --git a/comfyui/v5.1/easyanimatev5.1_workflow_control_camera.json b/comfyui/v5.1/easyanimatev5.1_workflow_control_camera.json new file mode 100644 index 0000000..c9e43f3 --- /dev/null +++ b/comfyui/v5.1/easyanimatev5.1_workflow_control_camera.json @@ -0,0 +1,673 @@ +{ + "last_node_id": 133, + "last_link_id": 283, + "nodes": [ + { + "id": 105, + "type": "EasyAnimate_TextBox", + "pos": { + "0": 234, + "1": 813 + }, + "size": { + "0": 400, + "1": 200 + }, + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "prompt", + "type": "STRING_PROMPT", + "links": [ + 273 + ], + "slot_index": 0 + } + ], + "title": "Negtive Prompt(反向提示词)", + "properties": { + "Node name for S&R": "EasyAnimate_TextBox" + }, + "widgets_values": [ + "扭曲的身体,肢体残缺,文本字幕,漫画,静止,丑陋,错误,乱码。" + ] + }, + { + "id": 123, + "type": "Note", + "pos": { + "0": -5, + "1": 616 + }, + "size": { + "0": 210, + "1": 58 + }, + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "You can write prompt here\n(你可以在此填写提示词)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 125, + "type": "Note", + "pos": { + "0": -117, + "1": 843 + }, + "size": { + "0": 326.1556091308594, + "1": 145.20904541015625 + }, + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "Using longer neg prompt such as \"Blurring, mutation, deformation, distortion, dark and solid, comics.\" can increase stability. Adding words such as \"quiet, solid\" to the neg prompt can increase dynamism.\n(使用更长的neg prompt如\"模糊,突变,变形,失真,画面暗,画面固定,连环画,漫画,线稿,没有主体。\",可以增加稳定性。在neg prompt中添加\"安静,固定\"等词语可以增加动态性。)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 127, + "type": "Note", + "pos": { + "0": 1125.8018798828125, + "1": 1088.0283203125 + }, + "size": { + "0": 538.7950439453125, + "1": 127.34957885742188 + }, + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "CameraCombine is used to combine multiple camera movements, while CameraBasic produces a single camera movement. The nodes come from https://github.com/chaojie/ComfyUI-CameraCtrl-Wrapper/. Since ComfyUI-CameraCtrl-Wrapper requires a specific version of diffusers, the code has been copied into the current repository.\n(CameraCombine用于组合多个镜头运动,CameraBasic产出单个镜头运动;节点来自于https://github.com/chaojie/ComfyUI-CameraCtrl-Wrapper/,由于ComfyUI-CameraCtrl-Wrapper有具体diffusers版本要求,故复制代码到当前库中。)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 133, + "type": "Note", + "pos": { + "0": -201, + "1": 247 + }, + "size": { + "0": 427.074951171875, + "1": 143.9142608642578 + }, + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "Due to the large size of models from EasyAnimateV5 and above, when using the 12B model, if your graphics card has 24GB or less of VRAM, please set GPU_memory_mode to model_cpu_offload_and_qfloat8. This will load the model in float8 to reduce VRAM consumption, otherwise you may receive an out-of-memory error. \n(由于EasyAnimateV5以上的模型较大,当使用12B模型时,如果使用的显卡显存为24G及以下,请将GPU_memory_mode设置为model_cpu_offload_and_qfloat8,使得模型加载在float8上减少显存消耗,否则会提示显存不足。)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 100, + "type": "LoadImage", + "pos": { + "0": 238, + "1": 1165 + }, + "size": { + "0": 378.07147216796875, + "1": 314 + }, + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 274 + ], + "slot_index": 0, + "shape": 3, + "label": "图像" + }, + { + "name": "MASK", + "type": "MASK", + "links": null, + "shape": 3, + "label": "遮罩" + } + ], + "title": "Start Image(图片到视频的开始图片)", + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "5.png", + "image" + ] + }, + { + "id": 99, + "type": "LoadEasyAnimateModel", + "pos": { + "0": 234, + "1": 240 + }, + "size": { + "0": 409.7983703613281, + "1": 158.7380828857422 + }, + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "easyanimate_model", + "type": "EASYANIMATESMODEL", + "links": [ + 271 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "LoadEasyAnimateModel" + }, + "widgets_values": [ + "EasyAnimateV5.1-12b-zh-Control-Camera", + "model_cpu_offload_and_qfloat8", + "Control", + "easyanimate_video_v5.1_magvit_qwen.yaml", + "bf16" + ] + }, + { + "id": 131, + "type": "EasyAnimateV5_V2VSampler", + "pos": { + "0": 821, + "1": 242 + }, + "size": { + "0": 504, + "1": 350 + }, + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + { + "name": "easyanimate_model", + "type": "EASYANIMATESMODEL", + "link": 271 + }, + { + "name": "prompt", + "type": "STRING_PROMPT", + "link": 272 + }, + { + "name": "negative_prompt", + "type": "STRING_PROMPT", + "link": 273 + }, + { + "name": "validation_video", + "type": "IMAGE", + "link": null, + "shape": 7 + }, + { + "name": "control_video", + "type": "IMAGE", + "link": null, + "shape": 7 + }, + { + "name": "ref_image", + "type": "IMAGE", + "link": 274, + "shape": 7 + }, + { + "name": "camera_conditions", + "type": "STRING", + "link": 275, + "widget": { + "name": "camera_conditions" + }, + "shape": 7 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 276 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "EasyAnimateV5_V2VSampler" + }, + "widgets_values": [ + 49, + 512, + 43, + "fixed", + 43, + 6, + 1, + "Flow", + "" + ] + }, + { + "id": 129, + "type": "CameraTrajectoryFromChaoJie", + "pos": { + "0": 1156.0380859375, + "1": 881.3924560546875 + }, + "size": { + "0": 367.79998779296875, + "1": 150 + }, + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [ + { + "name": "camera_pose", + "type": "CameraPose", + "link": 283 + } + ], + "outputs": [ + { + "name": "camera_trajectory", + "type": "STRING", + "links": [ + 275 + ], + "slot_index": 0 + }, + { + "name": "video_length", + "type": "INT", + "links": null + } + ], + "properties": { + "Node name for S&R": "CameraTrajectoryFromChaoJie" + }, + "widgets_values": [ + 0.532139961, + 0.946026558, + 0.5, + 0.5 + ] + }, + { + "id": 128, + "type": "CameraBasicFromChaoJie", + "pos": { + "0": 779.039306640625, + "1": 1120.39013671875 + }, + "size": { + "0": 315, + "1": 106 + }, + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "CameraPose", + "type": "CameraPose", + "links": [], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CameraBasicFromChaoJie" + }, + "widgets_values": [ + "Pan Up", + 1, + 49 + ] + }, + { + "id": 130, + "type": "CameraCombineFromChaoJie", + "pos": { + "0": 779.491943359375, + "1": 881.4488525390625 + }, + "size": { + "0": 315, + "1": 178 + }, + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "CameraPose", + "type": "CameraPose", + "links": [ + 283 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CameraCombineFromChaoJie" + }, + "widgets_values": [ + "Pan Up", + "Pan Left", + "Static", + "Static", + 1, + 49 + ] + }, + { + "id": 104, + "type": "EasyAnimate_TextBox", + "pos": { + "0": 233, + "1": 539 + }, + "size": { + "0": 400, + "1": 200 + }, + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "prompt", + "type": "STRING_PROMPT", + "links": [ + 272 + ], + "slot_index": 0 + } + ], + "title": "Positive Prompt(正向提示词)", + "properties": { + "Node name for S&R": "EasyAnimate_TextBox" + }, + "widgets_values": [ + "Fireworks light up the evening sky over a sprawling cityscape with gothic-style buildings featuring pointed towers and clock faces. The city is lit by both artificial lights from the buildings and the colorful bursts of the fireworks. The scene is viewed from an elevated angle, showcasing a vibrant urban environment set against a backdrop of a dramatic, partially cloudy sky at dusk." + ] + }, + { + "id": 106, + "type": "VHS_VideoCombine", + "pos": { + "0": 1416, + "1": 170 + }, + "size": [ + 390, + 535.4285714285714 + ], + "flags": {}, + "order": 13, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 276, + "slot_index": 0, + "label": "图像", + "shape": 7 + }, + { + "name": "audio", + "type": "AUDIO", + "link": null, + "label": "音频", + "shape": 7 + }, + { + "name": "meta_batch", + "type": "VHS_BatchManager", + "link": null, + "label": "批次管理", + "shape": 7 + }, + { + "name": "vae", + "type": "VAE", + "link": null, + "shape": 7 + } + ], + "outputs": [ + { + "name": "Filenames", + "type": "VHS_FILENAMES", + "links": null, + "slot_index": 0, + "shape": 3, + "label": "文件名" + } + ], + "properties": { + "Node name for S&R": "VHS_VideoCombine" + }, + "widgets_values": { + "frame_rate": 8, + "loop_count": 0, + "filename_prefix": "EasyAnimate", + "format": "video/h264-mp4", + "pix_fmt": "yuv420p", + "crf": 22, + "save_metadata": true, + "pingpong": false, + "save_output": true, + "videopreview": { + "hidden": false, + "paused": false, + "params": { + "filename": "EasyAnimate_00049.mp4", + "subfolder": "", + "type": "output", + "format": "video/h264-mp4", + "frame_rate": 8 + } + } + } + }, + { + "id": 132, + "type": "Note", + "pos": { + "0": 819, + "1": 658 + }, + "size": [ + 517.6458089787227, + 93.61251593411134 + ], + "flags": {}, + "order": 10, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "Please set the video_length of the Camera Trajectory below to be the same as the video_length of the Sampler above.\n(请将下方Camera Trajectory的Video Length设置的与上方Sampler的video_legnth一样。)" + ], + "color": "#432", + "bgcolor": "#653" + } + ], + "links": [ + [ + 271, + 99, + 0, + 131, + 0, + "EASYANIMATESMODEL" + ], + [ + 272, + 104, + 0, + 131, + 1, + "STRING_PROMPT" + ], + [ + 273, + 105, + 0, + 131, + 2, + "STRING_PROMPT" + ], + [ + 274, + 100, + 0, + 131, + 5, + "IMAGE" + ], + [ + 275, + 129, + 0, + 131, + 6, + "STRING" + ], + [ + 276, + 131, + 0, + 106, + 0, + "IMAGE" + ], + [ + 283, + 130, + 0, + 129, + 0, + "CameraPose" + ] + ], + "groups": [ + { + "title": "Load EasyAnimate", + "bounding": [ + 191, + 151, + 475, + 287 + ], + "color": "#b06634", + "font_size": 24, + "flags": {} + }, + { + "title": "Prompts", + "bounding": [ + 191, + 456, + 475, + 587 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "title": "First Image of Trajectory", + "bounding": [ + 191, + 1068, + 475, + 456 + ], + "color": "#a1309b", + "font_size": 24, + "flags": {} + }, + { + "title": "Generate Camera Control Video", + "bounding": [ + 750, + 781, + 932, + 470 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + } + ], + "config": {}, + "extra": { + "ds": { + "scale": 0.6209213230591558, + "offset": [ + 417.7460035994012, + -70.36580413723722 + ] + } + }, + "version": 0.4 +} \ No newline at end of file diff --git a/comfyui/v5.1/easyanimatev5.1_workflow_control_trajectory.json b/comfyui/v5.1/easyanimatev5.1_workflow_control_trajectory.json new file mode 100644 index 0000000..1dd2ddc --- /dev/null +++ b/comfyui/v5.1/easyanimatev5.1_workflow_control_trajectory.json @@ -0,0 +1,1038 @@ +{ + "last_node_id": 119, + "last_link_id": 267, + "nodes": [ + { + "id": 105, + "type": "EasyAnimate_TextBox", + "pos": { + "0": 234, + "1": 813 + }, + "size": { + "0": 400, + "1": 200 + }, + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "prompt", + "type": "STRING_PROMPT", + "links": [ + 258 + ], + "slot_index": 0 + } + ], + "title": "Negtive Prompt(反向提示词)", + "properties": { + "Node name for S&R": "EasyAnimate_TextBox" + }, + "widgets_values": [ + "扭曲的身体,肢体残缺,文本字幕,漫画,静止,丑陋,错误,乱码。" + ] + }, + { + "id": 107, + "type": "Note", + "pos": { + "0": 4, + "1": 634 + }, + "size": { + "0": 210, + "1": 58 + }, + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "You can write prompt here\n(你可以在此填写提示词)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 108, + "type": "Note", + "pos": { + "0": -110, + "1": 842 + }, + "size": { + "0": 326.1556091308594, + "1": 145.20904541015625 + }, + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "Using longer neg prompt such as \"Blurring, mutation, deformation, distortion, dark and solid, comics.\" can increase stability. Adding words such as \"quiet, solid\" to the neg prompt can increase dynamism.\n(使用更长的neg prompt如\"模糊,突变,变形,失真,画面暗,画面固定,连环画,漫画,线稿,没有主体。\",可以增加稳定性。在neg prompt中添加\"安静,固定\"等词语可以增加动态性。)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 112, + "type": "Note", + "pos": { + "0": -203, + "1": 252 + }, + "size": { + "0": 427.074951171875, + "1": 143.9142608642578 + }, + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "Due to the large size of models from EasyAnimateV5 and above, when using the 12B model, if your graphics card has 24GB or less of VRAM, please set GPU_memory_mode to model_cpu_offload_and_qfloat8. This will load the model in float8 to reduce VRAM consumption, otherwise you may receive an out-of-memory error. \n(由于EasyAnimateV5以上的模型较大,当使用12B模型时,如果使用的显卡显存为24G及以下,请将GPU_memory_mode设置为model_cpu_offload_and_qfloat8,使得模型加载在float8上减少显存消耗,否则会提示显存不足。)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 104, + "type": "EasyAnimate_TextBox", + "pos": { + "0": 233, + "1": 539 + }, + "size": { + "0": 400, + "1": 200 + }, + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "prompt", + "type": "STRING_PROMPT", + "links": [ + 257 + ], + "slot_index": 0 + } + ], + "title": "Positive Prompt(正向提示词)", + "properties": { + "Node name for S&R": "EasyAnimate_TextBox" + }, + "widgets_values": [ + "一只棕褐色的狗在摇晃脑袋,坐在一个舒适的房间里的浅色沙发上。在狗的后面,架子上有一幅镶框的画,周围是粉红色的花朵。房间里的灯光柔和温暖,营造出舒适的氛围。" + ] + }, + { + "id": 100, + "type": "LoadImage", + "pos": { + "0": 238, + "1": 1165 + }, + "size": { + "0": 378.07147216796875, + "1": 314 + }, + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 260 + ], + "slot_index": 0, + "shape": 3, + "label": "图像" + }, + { + "name": "MASK", + "type": "MASK", + "links": null, + "shape": 3, + "label": "遮罩" + } + ], + "title": "Start Image(图片到视频的开始图片)", + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "1.png", + "image" + ] + }, + { + "id": 110, + "type": "Note", + "pos": { + "0": 847, + "1": 613 + }, + "size": { + "0": 608.1410522460938, + "1": 188.2682342529297 + }, + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "Please set the mask height and mask width according to the height and width of the reference image. \nPlease set the video_length of the Spline Editor below to be the same as the video_length of the Sampler above. \nThe nodes are from KJNodes. For more details, please check https://github.com/kijai/ComfyUI-KJNodes/tree/main. \n\n请根据参考图片的高和宽设置mask height和mask width;\n请将下方Spline Editor的video_legnth置的与上方Sampler的video_legnth一样;\n部分节点来自于KJNodes,具体查看https://github.com/kijai/ComfyUI-KJNodes/tree/main;" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 106, + "type": "VHS_VideoCombine", + "pos": { + "0": 1497, + "1": 204 + }, + "size": [ + 390, + 546 + ], + "flags": {}, + "order": 14, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 261, + "slot_index": 0, + "label": "图像", + "shape": 7 + }, + { + "name": "audio", + "type": "AUDIO", + "link": null, + "label": "音频", + "shape": 7 + }, + { + "name": "meta_batch", + "type": "VHS_BatchManager", + "link": null, + "label": "批次管理", + "shape": 7 + }, + { + "name": "vae", + "type": "VAE", + "link": null, + "shape": 7 + } + ], + "outputs": [ + { + "name": "Filenames", + "type": "VHS_FILENAMES", + "links": null, + "slot_index": 0, + "shape": 3, + "label": "文件名" + } + ], + "properties": { + "Node name for S&R": "VHS_VideoCombine" + }, + "widgets_values": { + "frame_rate": 8, + "loop_count": 0, + "filename_prefix": "EasyAnimate", + "format": "video/h264-mp4", + "pix_fmt": "yuv420p", + "crf": 22, + "save_metadata": true, + "pingpong": false, + "save_output": true, + "videopreview": { + "hidden": false, + "paused": false, + "params": { + "filename": "EasyAnimate_00105.mp4", + "subfolder": "", + "type": "output", + "format": "video/h264-mp4", + "frame_rate": 8 + } + } + } + }, + { + "id": 99, + "type": "LoadEasyAnimateModel", + "pos": { + "0": 242, + "1": 250 + }, + "size": { + "0": 402.6313781738281, + "1": 154 + }, + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "easyanimate_model", + "type": "EASYANIMATESMODEL", + "links": [ + 256 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "LoadEasyAnimateModel" + }, + "widgets_values": [ + "EasyAnimateV5.1-12b-zh-Control", + "model_cpu_offload", + "Control", + "easyanimate_video_v5.1_magvit_qwen.yaml", + "bf16" + ] + }, + { + "id": 111, + "type": "EasyAnimateV5_V2VSampler", + "pos": { + "0": 905, + "1": 201 + }, + "size": { + "0": 504, + "1": 350 + }, + "flags": {}, + "order": 13, + "mode": 0, + "inputs": [ + { + "name": "easyanimate_model", + "type": "EASYANIMATESMODEL", + "link": 256 + }, + { + "name": "prompt", + "type": "STRING_PROMPT", + "link": 257 + }, + { + "name": "negative_prompt", + "type": "STRING_PROMPT", + "link": 258 + }, + { + "name": "validation_video", + "type": "IMAGE", + "link": null, + "shape": 7 + }, + { + "name": "control_video", + "type": "IMAGE", + "link": 259, + "shape": 7 + }, + { + "name": "ref_image", + "type": "IMAGE", + "link": 260, + "shape": 7 + }, + { + "name": "camera_conditions", + "type": "STRING", + "link": null, + "widget": { + "name": "camera_conditions" + }, + "shape": 7 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 261, + 263 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "EasyAnimateV5_V2VSampler" + }, + "widgets_values": [ + 49, + 512, + 43, + "fixed", + 50, + 6, + 1, + "Flow", + "" + ] + }, + { + "id": 97, + "type": "SplineEditor", + "pos": { + "0": 855.1397705078125, + "1": 1058.91943359375 + }, + "size": { + "0": 645, + "1": 812 + }, + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "name": "bg_image", + "type": "IMAGE", + "link": null, + "shape": 7 + } + ], + "outputs": [ + { + "name": "mask", + "type": "MASK", + "links": [ + 249 + ], + "slot_index": 0 + }, + { + "name": "coord_str", + "type": "STRING", + "links": [ + 265 + ], + "slot_index": 1 + }, + { + "name": "float", + "type": "FLOAT", + "links": null + }, + { + "name": "count", + "type": "INT", + "links": null + }, + { + "name": "normalized_str", + "type": "STRING", + "links": null + } + ], + "properties": { + "Node name for S&R": "SplineEditor", + "points": "SplineEditor", + "imgData": null + }, + "widgets_values": [ + "[{\"x\":236.74497000000005,\"y\":169.10355000000004},{\"x\":263.53799999999995,\"y\":230.59575},{\"x\":321.61075881587004,\"y\":229.72197058276433},{\"x\":355.3934015486295,\"y\":168.9132136637973},{\"x\":343.23165016483614,\"y\":82.42964826793309},{\"x\":275.6663646993172,\"y\":55.40353408172552},{\"x\":197.29063355931524,\"y\":85.13225968655384},{\"x\":177.02104791965957,\"y\":148.64362802414163},{\"x\":205.39846781517753,\"y\":232.4245820013851},{\"x\":259.45069618759265,\"y\":167.56190795448694}]", + "[{\"x\":236.74496459960938,\"y\":169.10354614257812},{\"x\":240.51321411132812,\"y\":183.380126953125},{\"x\":244.89556884765625,\"y\":197.47930908203125},{\"x\":250.2393035888672,\"y\":211.23939514160156},{\"x\":257.3768310546875,\"y\":224.13796997070312},{\"x\":268.3490295410156,\"y\":233.83712768554688},{\"x\":281.6380920410156,\"y\":240.17092895507812},{\"x\":296.2393493652344,\"y\":241.24598693847656},{\"x\":310.1653137207031,\"y\":236.51937866210938},{\"x\":322.80859375,\"y\":228.9126739501953},{\"x\":334.5792541503906,\"y\":220.0128173828125},{\"x\":344.1842346191406,\"y\":208.8701629638672},{\"x\":350.05450439453125,\"y\":195.3665771484375},{\"x\":353.41900634765625,\"y\":180.99649047851562},{\"x\":355.757568359375,\"y\":166.41757202148438},{\"x\":357.7420959472656,\"y\":151.78565979003906},{\"x\":359.0423889160156,\"y\":137.07997131347656},{\"x\":358.7975158691406,\"y\":122.32791900634766},{\"x\":356.0333251953125,\"y\":107.84730529785156},{\"x\":350.4529113769531,\"y\":94.20045471191406},{\"x\":342.6852722167969,\"y\":81.65638732910156},{\"x\":333.4718322753906,\"y\":70.13098907470703},{\"x\":322.0600891113281,\"y\":60.85353088378906},{\"x\":308.1234130859375,\"y\":56.22242736816406},{\"x\":293.40484619140625,\"y\":55.21137619018555},{\"x\":278.6397399902344,\"y\":55.34805679321289},{\"x\":263.8834228515625,\"y\":55.852020263671875},{\"x\":249.2041473388672,\"y\":57.398460388183594},{\"x\":234.8509979248047,\"y\":60.79948425292969},{\"x\":221.34671020507812,\"y\":66.71607971191406},{\"x\":209.08375549316406,\"y\":74.91584777832031},{\"x\":197.90423583984375,\"y\":84.55458068847656},{\"x\":187.44732666015625,\"y\":94.97555541992188},{\"x\":178.9163055419922,\"y\":106.95783233642578},{\"x\":175.8837890625,\"y\":121.3009262084961},{\"x\":176.28488159179688,\"y\":136.05682373046875},{\"x\":177.14378356933594,\"y\":150.79808044433594},{\"x\":178.22998046875,\"y\":165.5237579345703},{\"x\":179.88259887695312,\"y\":180.19593811035156},{\"x\":182.37294006347656,\"y\":194.7476043701172},{\"x\":186.19667053222656,\"y\":209.0009307861328},{\"x\":192.4387664794922,\"y\":222.34014892578125},{\"x\":203.41249084472656,\"y\":231.83749389648438},{\"x\":216.6136932373047,\"y\":227.41598510742188},{\"x\":226.70738220214844,\"y\":216.66171264648438},{\"x\":235.608642578125,\"y\":204.8833770751953},{\"x\":243.90171813964844,\"y\":192.6669921875},{\"x\":251.81112670898438,\"y\":180.19815063476562},{\"x\":259.45068359375,\"y\":167.56190490722656}]", + 600, + 382, + 49, + "path", + "cardinal", + 0.5, + 1, + "list", + 0, + 1, + null, + null, + null + ] + }, + { + "id": 44, + "type": "VHS_VideoCombine", + "pos": { + "0": 2241.138427734375, + "1": 1051.91943359375 + }, + "size": [ + 530, + 650.4 + ], + "flags": {}, + "order": 12, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 237, + "shape": 7 + }, + { + "name": "audio", + "type": "AUDIO", + "link": null, + "shape": 7 + }, + { + "name": "meta_batch", + "type": "VHS_BatchManager", + "link": null, + "shape": 7 + }, + { + "name": "vae", + "type": "VAE", + "link": null, + "shape": 7 + } + ], + "outputs": [ + { + "name": "Filenames", + "type": "VHS_FILENAMES", + "links": null, + "slot_index": 0, + "shape": 3 + } + ], + "title": "Trajectory Outputs", + "properties": { + "Node name for S&R": "VHS_VideoCombine" + }, + "widgets_values": { + "frame_rate": 8, + "loop_count": 0, + "filename_prefix": "EasyAnimate-Trajectory", + "format": "video/h264-mp4", + "pix_fmt": "yuv420p", + "crf": 22, + "save_metadata": true, + "pingpong": false, + "save_output": true, + "videopreview": { + "hidden": false, + "paused": false, + "params": { + "filename": "EasyAnimate-Trajectory_00030.mp4", + "subfolder": "", + "type": "output", + "format": "video/h264-mp4", + "frame_rate": 8 + }, + "muted": false + } + } + }, + { + "id": 95, + "type": "CreateTrajectoryBasedOnKJNodes", + "pos": { + "0": 1574.139404296875, + "1": 929.9193115234375 + }, + "size": { + "0": 428.4000244140625, + "1": 58 + }, + "flags": {}, + "order": 11, + "mode": 0, + "inputs": [ + { + "name": "masks", + "type": "MASK", + "link": 249 + }, + { + "name": "coordinates", + "type": "STRING", + "link": 267, + "widget": { + "name": "coordinates" + } + } + ], + "outputs": [ + { + "name": "image", + "type": "IMAGE", + "links": [ + 237, + 259, + 262 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "CreateTrajectoryBasedOnKJNodes" + }, + "widgets_values": [ + "" + ] + }, + { + "id": 118, + "type": "AppendStringsToList", + "pos": { + "0": 1140.1396484375, + "1": 909.9193115234375 + }, + "size": [ + 315, + 82 + ], + "flags": { + "collapsed": false + }, + "order": 10, + "mode": 0, + "inputs": [ + { + "name": "string1", + "type": "STRING", + "link": 265, + "widget": { + "name": "string1" + } + }, + { + "name": "string2", + "type": "STRING", + "link": 266, + "widget": { + "name": "string2" + } + } + ], + "outputs": [ + { + "name": "STRING", + "type": "STRING", + "links": [ + 267 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "AppendStringsToList" + }, + "widgets_values": [ + "", + "" + ] + }, + { + "id": 114, + "type": "ImageMaximumNode", + "pos": { + "0": 2123.13818359375, + "1": 909.9193115234375 + }, + "size": { + "0": 210, + "1": 46 + }, + "flags": {}, + "order": 15, + "mode": 0, + "inputs": [ + { + "name": "video_1", + "type": "IMAGE", + "link": 263 + }, + { + "name": "video_2", + "type": "IMAGE", + "link": 262 + } + ], + "outputs": [ + { + "name": "image", + "type": "IMAGE", + "links": [ + 264 + ] + } + ], + "properties": { + "Node name for S&R": "ImageMaximumNode" + }, + "widgets_values": [] + }, + { + "id": 115, + "type": "VHS_VideoCombine", + "pos": { + "0": 2819, + "1": 1056 + }, + "size": [ + 530, + 630 + ], + "flags": {}, + "order": 16, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 264, + "shape": 7 + }, + { + "name": "audio", + "type": "AUDIO", + "link": null, + "shape": 7 + }, + { + "name": "meta_batch", + "type": "VHS_BatchManager", + "link": null, + "shape": 7 + }, + { + "name": "vae", + "type": "VAE", + "link": null, + "shape": 7 + } + ], + "outputs": [ + { + "name": "Filenames", + "type": "VHS_FILENAMES", + "links": null, + "slot_index": 0, + "shape": 3 + } + ], + "title": "Video with Trajectory Outputs", + "properties": { + "Node name for S&R": "VHS_VideoCombine" + }, + "widgets_values": { + "frame_rate": 8, + "loop_count": 0, + "filename_prefix": "EasyAnimate-Trajectory-Merge", + "format": "video/h264-mp4", + "pix_fmt": "yuv420p", + "crf": 22, + "save_metadata": true, + "pingpong": false, + "save_output": true, + "videopreview": { + "hidden": false, + "paused": false, + "params": { + "filename": "EasyAnimate-Trajectory-Merge_00009.mp4", + "subfolder": "", + "type": "output", + "format": "video/h264-mp4", + "frame_rate": 8 + }, + "muted": false + } + } + }, + { + "id": 119, + "type": "SplineEditor", + "pos": { + "0": 1544.139404296875, + "1": 1047.919189453125 + }, + "size": [ + 645, + 812 + ], + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [ + { + "name": "bg_image", + "type": "IMAGE", + "link": null, + "shape": 7 + } + ], + "outputs": [ + { + "name": "mask", + "type": "MASK", + "links": [], + "slot_index": 0 + }, + { + "name": "coord_str", + "type": "STRING", + "links": [ + 266 + ], + "slot_index": 1 + }, + { + "name": "float", + "type": "FLOAT", + "links": null + }, + { + "name": "count", + "type": "INT", + "links": null + }, + { + "name": "normalized_str", + "type": "STRING", + "links": null + } + ], + "properties": { + "Node name for S&R": "SplineEditor", + "points": "SplineEditor", + "imgData": null + }, + "widgets_values": [ + "[{\"x\":63.916760050380844,\"y\":114.45559357858895},{\"x\":71.34894145158792,\"y\":114.45559357858895}]", + "[{\"x\":63.9167594909668,\"y\":114.45559692382812},{\"x\":64.07159423828125,\"y\":114.45559692382812},{\"x\":64.22643280029297,\"y\":114.45559692382812},{\"x\":64.38127136230469,\"y\":114.45559692382812},{\"x\":64.5361099243164,\"y\":114.45559692382812},{\"x\":64.69094848632812,\"y\":114.45559692382812},{\"x\":64.84577941894531,\"y\":114.45559692382812},{\"x\":65.00061798095703,\"y\":114.45559692382812},{\"x\":65.15545654296875,\"y\":114.45559692382812},{\"x\":65.31029510498047,\"y\":114.45559692382812},{\"x\":65.46513366699219,\"y\":114.45559692382812},{\"x\":65.61996459960938,\"y\":114.45559692382812},{\"x\":65.7748031616211,\"y\":114.45559692382812},{\"x\":65.92964172363281,\"y\":114.45559692382812},{\"x\":66.08448028564453,\"y\":114.45559692382812},{\"x\":66.23931884765625,\"y\":114.45559692382812},{\"x\":66.39414978027344,\"y\":114.45559692382812},{\"x\":66.54898834228516,\"y\":114.45559692382812},{\"x\":66.70382690429688,\"y\":114.45559692382812},{\"x\":66.8586654663086,\"y\":114.45559692382812},{\"x\":67.01350402832031,\"y\":114.45559692382812},{\"x\":67.1683349609375,\"y\":114.45559692382812},{\"x\":67.32317352294922,\"y\":114.45559692382812},{\"x\":67.47801208496094,\"y\":114.45559692382812},{\"x\":67.63285064697266,\"y\":114.45559692382812},{\"x\":67.78768920898438,\"y\":114.45559692382812},{\"x\":67.94252014160156,\"y\":114.45559692382812},{\"x\":68.09735870361328,\"y\":114.45559692382812},{\"x\":68.252197265625,\"y\":114.45559692382812},{\"x\":68.40703582763672,\"y\":114.45559692382812},{\"x\":68.56187438964844,\"y\":114.45559692382812},{\"x\":68.71670532226562,\"y\":114.45559692382812},{\"x\":68.87154388427734,\"y\":114.45559692382812},{\"x\":69.02638244628906,\"y\":114.45559692382812},{\"x\":69.18122100830078,\"y\":114.45559692382812},{\"x\":69.3360595703125,\"y\":114.45559692382812},{\"x\":69.49089050292969,\"y\":114.45559692382812},{\"x\":69.6457290649414,\"y\":114.45559692382812},{\"x\":69.80056762695312,\"y\":114.45559692382812},{\"x\":69.95540618896484,\"y\":114.45559692382812},{\"x\":70.11024475097656,\"y\":114.45559692382812},{\"x\":70.26507568359375,\"y\":114.45559692382812},{\"x\":70.41991424560547,\"y\":114.45559692382812},{\"x\":70.57475280761719,\"y\":114.45559692382812},{\"x\":70.7295913696289,\"y\":114.45559692382812},{\"x\":70.88442993164062,\"y\":114.45559692382812},{\"x\":71.03926086425781,\"y\":114.45559692382812},{\"x\":71.19409942626953,\"y\":114.45559692382812},{\"x\":71.34893798828125,\"y\":114.45559692382812}]", + 600, + 382, + 49, + "path", + "cardinal", + 0.5, + 1, + "list", + 0, + 1, + null, + null, + null + ] + } + ], + "links": [ + [ + 237, + 95, + 0, + 44, + 0, + "IMAGE" + ], + [ + 249, + 97, + 0, + 95, + 0, + "MASK" + ], + [ + 256, + 99, + 0, + 111, + 0, + "EASYANIMATESMODEL" + ], + [ + 257, + 104, + 0, + 111, + 1, + "STRING_PROMPT" + ], + [ + 258, + 105, + 0, + 111, + 2, + "STRING_PROMPT" + ], + [ + 259, + 95, + 0, + 111, + 4, + "IMAGE" + ], + [ + 260, + 100, + 0, + 111, + 5, + "IMAGE" + ], + [ + 261, + 111, + 0, + 106, + 0, + "IMAGE" + ], + [ + 262, + 95, + 0, + 114, + 1, + "IMAGE" + ], + [ + 263, + 111, + 0, + 114, + 0, + "IMAGE" + ], + [ + 264, + 114, + 0, + 115, + 0, + "IMAGE" + ], + [ + 265, + 97, + 1, + 118, + 0, + "STRING" + ], + [ + 266, + 119, + 1, + 118, + 1, + "STRING" + ], + [ + 267, + 118, + 0, + 95, + 1, + "STRING" + ] + ], + "groups": [ + { + "title": "Generate Control Video", + "bounding": [ + 786, + 841, + 2616, + 1056 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "title": "First Image of Trajectory", + "bounding": [ + 191, + 1068, + 475, + 456 + ], + "color": "#a1309b", + "font_size": 24, + "flags": {} + }, + { + "title": "Prompts", + "bounding": [ + 191, + 456, + 475, + 587 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "title": "Load EasyAnimate", + "bounding": [ + 189, + 160, + 475, + 269 + ], + "color": "#b06634", + "font_size": 24, + "flags": {} + } + ], + "config": {}, + "extra": { + "ds": { + "scale": 0.5054470284993016, + "offset": [ + -239.62344289721364, + 114.98345539297088 + ] + } + }, + "version": 0.4 +} \ No newline at end of file diff --git a/comfyui/v5.1/easyanimatev5.1_workflow_i2v.json b/comfyui/v5.1/easyanimatev5.1_workflow_i2v.json new file mode 100644 index 0000000..90daeb3 --- /dev/null +++ b/comfyui/v5.1/easyanimatev5.1_workflow_i2v.json @@ -0,0 +1,495 @@ +{ + "last_node_id": 85, + "last_link_id": 49, + "nodes": [ + { + "id": 79, + "type": "Note", + "pos": { + "0": 16, + "1": 460 + }, + "size": { + "0": 210, + "1": 58 + }, + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "You can upload image here\n(在此上传开始图像)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 17, + "type": "VHS_VideoCombine", + "pos": { + "0": 1134, + "1": 93 + }, + "size": [ + 390.9534912109375, + 535.9734235491071 + ], + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 42, + "slot_index": 0, + "label": "图像", + "shape": 7 + }, + { + "name": "audio", + "type": "AUDIO", + "link": null, + "label": "音频", + "shape": 7 + }, + { + "name": "meta_batch", + "type": "VHS_BatchManager", + "link": null, + "label": "批次管理", + "shape": 7 + }, + { + "name": "vae", + "type": "VAE", + "link": null, + "shape": 7 + } + ], + "outputs": [ + { + "name": "Filenames", + "type": "VHS_FILENAMES", + "links": null, + "slot_index": 0, + "shape": 3, + "label": "文件名" + } + ], + "properties": { + "Node name for S&R": "VHS_VideoCombine" + }, + "widgets_values": { + "frame_rate": 8, + "loop_count": 0, + "filename_prefix": "EasyAnimate", + "format": "video/h264-mp4", + "pix_fmt": "yuv420p", + "crf": 22, + "save_metadata": true, + "pingpong": false, + "save_output": true, + "videopreview": { + "hidden": false, + "paused": false, + "params": { + "filename": "EasyAnimate_00050.mp4", + "subfolder": "", + "type": "output", + "format": "video/h264-mp4", + "frame_rate": 8 + } + } + } + }, + { + "id": 73, + "type": "EasyAnimate_TextBox", + "pos": { + "0": 250, + "1": 160 + }, + "size": { + "0": 383.7149963378906, + "1": 183.83506774902344 + }, + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "prompt", + "type": "STRING_PROMPT", + "links": [ + 45 + ], + "slot_index": 0, + "shape": 3 + } + ], + "title": "Negtive Prompt(反向提示词)", + "properties": { + "Node name for S&R": "EasyAnimate_TextBox" + }, + "widgets_values": [ + "扭曲的身体,肢体残缺,文本字幕,漫画,静止,丑陋,错误,乱码。" + ] + }, + { + "id": 78, + "type": "Note", + "pos": { + "0": 18, + "1": -46 + }, + "size": { + "0": 210, + "1": 58 + }, + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "You can write prompt here\n(你可以在此填写提示词)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 84, + "type": "Note", + "pos": { + "0": -98, + "1": 198 + }, + "size": { + "0": 326.1556091308594, + "1": 145.20904541015625 + }, + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "Using longer neg prompt such as \"Blurring, mutation, deformation, distortion, dark and solid, comics.\" can increase stability. Adding words such as \"quiet, solid\" to the neg prompt can increase dynamism.\n(使用更长的neg prompt如\"模糊,突变,变形,失真,画面暗,画面固定,连环画,漫画,线稿,没有主体。\",可以增加稳定性。在neg prompt中添加\"安静,固定\"等词语可以增加动态性。)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 75, + "type": "EasyAnimate_TextBox", + "pos": { + "0": 250, + "1": -50 + }, + "size": { + "0": 383.54010009765625, + "1": 156.71620178222656 + }, + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "prompt", + "type": "STRING_PROMPT", + "links": [ + 44 + ], + "slot_index": 0, + "shape": 3 + } + ], + "title": "Positive Prompt(正向提示词)", + "properties": { + "Node name for S&R": "EasyAnimate_TextBox" + }, + "widgets_values": [ + "Fireworks light up the evening sky over a sprawling cityscape with gothic-style buildings featuring pointed towers and clock faces. The city is lit by both artificial lights from the buildings and the colorful bursts of the fireworks. The scene is viewed from an elevated angle, showcasing a vibrant urban environment set against a backdrop of a dramatic, partially cloudy sky at dusk." + ] + }, + { + "id": 82, + "type": "EasyAnimateV5_I2VSampler", + "pos": { + "0": 767, + "1": 93 + }, + "size": { + "0": 336, + "1": 282 + }, + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "name": "easyanimate_model", + "type": "EASYANIMATESMODEL", + "link": 48 + }, + { + "name": "prompt", + "type": "STRING_PROMPT", + "link": 44 + }, + { + "name": "negative_prompt", + "type": "STRING_PROMPT", + "link": 45 + }, + { + "name": "start_img", + "type": "IMAGE", + "link": 49, + "shape": 7 + }, + { + "name": "end_img", + "type": "IMAGE", + "link": null, + "shape": 7 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 42 + ], + "slot_index": 0, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "EasyAnimateV5_I2VSampler" + }, + "widgets_values": [ + 49, + 512, + 43, + "fixed", + 50, + 6, + "Flow" + ] + }, + { + "id": 83, + "type": "LoadEasyAnimateModel", + "pos": { + "0": 258, + "1": -324 + }, + "size": { + "0": 427.9729919433594, + "1": 154 + }, + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "easyanimate_model", + "type": "EASYANIMATESMODEL", + "links": [ + 48 + ], + "slot_index": 0, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "LoadEasyAnimateModel" + }, + "widgets_values": [ + "EasyAnimateV5.1-12b-zh-InP", + "model_cpu_offload_and_qfloat8", + "Inpaint", + "easyanimate_video_v5.1_magvit_qwen.yaml", + "bf16" + ] + }, + { + "id": 7, + "type": "LoadImage", + "pos": { + "0": 259, + "1": 468 + }, + "size": { + "0": 378.07147216796875, + "1": 314 + }, + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 49 + ], + "slot_index": 0, + "shape": 3, + "label": "图像" + }, + { + "name": "MASK", + "type": "MASK", + "links": null, + "shape": 3, + "label": "遮罩" + } + ], + "title": "Start Image(图片到视频的开始图片)", + "properties": { + "Node name for S&R": "LoadImage" + }, + "widgets_values": [ + "5.png", + "image" + ] + }, + { + "id": 85, + "type": "Note", + "pos": { + "0": -179, + "1": -318 + }, + "size": [ + 427.074951171875, + 143.9142608642578 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "Due to the large size of models from EasyAnimateV5 and above, when using the 12B model, if your graphics card has 24GB or less of VRAM, please set GPU_memory_mode to model_cpu_offload_and_qfloat8. This will load the model in float8 to reduce VRAM consumption, otherwise you may receive an out-of-memory error. \n(由于EasyAnimateV5以上的模型较大,当使用12B模型时,如果使用的显卡显存为24G及以下,请将GPU_memory_mode设置为model_cpu_offload_and_qfloat8,使得模型加载在float8上减少显存消耗,否则会提示显存不足。)" + ], + "color": "#432", + "bgcolor": "#653" + } + ], + "links": [ + [ + 42, + 82, + 0, + 17, + 0, + "IMAGE" + ], + [ + 44, + 75, + 0, + 82, + 1, + "STRING_PROMPT" + ], + [ + 45, + 73, + 0, + 82, + 2, + "STRING_PROMPT" + ], + [ + 48, + 83, + 0, + 82, + 0, + "EASYANIMATESMODEL" + ], + [ + 49, + 7, + 0, + 82, + 3, + "IMAGE" + ] + ], + "groups": [ + { + "title": "Prompts", + "bounding": [ + 218, + -127, + 450, + 483 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "title": "Load EasyAnimate", + "bounding": [ + 219, + -410, + 492, + 259 + ], + "color": "#b06634", + "font_size": 24, + "flags": {} + }, + { + "title": "Upload Your Start Image", + "bounding": [ + 218, + 382, + 452, + 418 + ], + "color": "#a1309b", + "font_size": 24, + "flags": {} + } + ], + "config": {}, + "extra": { + "ds": { + "scale": 0.6830134553650716, + "offset": [ + 353.6981370759636, + 518.5082328158873 + ] + }, + "workspace_info": { + "id": "776b62b4-bd17-4ed3-9923-b7aad000b1ea" + } + }, + "version": 0.4 +} \ No newline at end of file diff --git a/comfyui/v5.1/easyanimatev5.1_workflow_t2v.json b/comfyui/v5.1/easyanimatev5.1_workflow_t2v.json new file mode 100644 index 0000000..74b10e7 --- /dev/null +++ b/comfyui/v5.1/easyanimatev5.1_workflow_t2v.json @@ -0,0 +1,400 @@ +{ + "last_node_id": 90, + "last_link_id": 53, + "nodes": [ + { + "id": 78, + "type": "Note", + "pos": { + "0": 18, + "1": -46 + }, + "size": { + "0": 210, + "1": 58 + }, + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "You can write prompt here\n(你可以在此填写提示词)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 88, + "type": "EasyAnimateV5_T2VSampler", + "pos": { + "0": 786, + "1": 15 + }, + "size": { + "0": 327.6000061035156, + "1": 290 + }, + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "name": "easyanimate_model", + "type": "EASYANIMATESMODEL", + "link": 51, + "slot_index": 0 + }, + { + "name": "prompt", + "type": "STRING_PROMPT", + "link": 52, + "slot_index": 1 + }, + { + "name": "negative_prompt", + "type": "STRING_PROMPT", + "link": 53, + "slot_index": 2 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 50 + ], + "slot_index": 0, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "EasyAnimateV5_T2VSampler" + }, + "widgets_values": [ + 49, + 672, + 384, + false, + 43, + "fixed", + 50, + 6, + "Flow" + ] + }, + { + "id": 73, + "type": "EasyAnimate_TextBox", + "pos": { + "0": 250, + "1": 160 + }, + "size": { + "0": 383.7149963378906, + "1": 183.83506774902344 + }, + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "prompt", + "type": "STRING_PROMPT", + "links": [ + 53 + ], + "slot_index": 0, + "shape": 3 + } + ], + "title": "Negtive Prompt(反向提示词)", + "properties": { + "Node name for S&R": "EasyAnimate_TextBox" + }, + "widgets_values": [ + "扭曲的身体,肢体残缺,文本字幕,漫画,静止,丑陋,错误,乱码。" + ] + }, + { + "id": 17, + "type": "VHS_VideoCombine", + "pos": { + "0": 1148, + "1": 15 + }, + "size": [ + 390.9534912109375, + 535.9734235491071 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 50, + "slot_index": 0, + "label": "图像", + "shape": 7 + }, + { + "name": "audio", + "type": "AUDIO", + "link": null, + "label": "音频", + "shape": 7 + }, + { + "name": "meta_batch", + "type": "VHS_BatchManager", + "link": null, + "label": "批次管理", + "shape": 7 + }, + { + "name": "vae", + "type": "VAE", + "link": null, + "shape": 7 + } + ], + "outputs": [ + { + "name": "Filenames", + "type": "VHS_FILENAMES", + "links": null, + "slot_index": 0, + "shape": 3, + "label": "文件名" + } + ], + "properties": { + "Node name for S&R": "VHS_VideoCombine" + }, + "widgets_values": { + "frame_rate": 8, + "loop_count": 0, + "filename_prefix": "EasyAnimate", + "format": "video/h264-mp4", + "pix_fmt": "yuv420p", + "crf": 22, + "save_metadata": true, + "pingpong": false, + "save_output": true, + "videopreview": { + "hidden": false, + "paused": false, + "params": { + "filename": "EasyAnimate_00053.mp4", + "subfolder": "", + "type": "output", + "format": "video/h264-mp4", + "frame_rate": 8 + } + } + } + }, + { + "id": 89, + "type": "Note", + "pos": { + "0": -97, + "1": 193 + }, + "size": { + "0": 326.1556091308594, + "1": 145.20904541015625 + }, + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "Using longer neg prompt such as \"Blurring, mutation, deformation, distortion, dark and solid, comics.\" can increase stability. Adding words such as \"quiet, solid\" to the neg prompt can increase dynamism.\n(使用更长的neg prompt如\"模糊,突变,变形,失真,画面暗,画面固定,连环画,漫画,线稿,没有主体。\",可以增加稳定性。在neg prompt中添加\"安静,固定\"等词语可以增加动态性。)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 87, + "type": "LoadEasyAnimateModel", + "pos": { + "0": 252, + "1": -308 + }, + "size": { + "0": 441.4525451660156, + "1": 154 + }, + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "easyanimate_model", + "type": "EASYANIMATESMODEL", + "links": [ + 51 + ], + "slot_index": 0, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "LoadEasyAnimateModel" + }, + "widgets_values": [ + "EasyAnimateV5.1-12b-zh-InP", + "model_cpu_offload_and_qfloat8", + "Inpaint", + "easyanimate_video_v5.1_magvit_qwen.yaml", + "bf16" + ] + }, + { + "id": 90, + "type": "Note", + "pos": { + "0": -180, + "1": -301 + }, + "size": [ + 427.074951171875, + 143.9142608642578 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "Due to the large size of models from EasyAnimateV5 and above, when using the 12B model, if your graphics card has 24GB or less of VRAM, please set GPU_memory_mode to model_cpu_offload_and_qfloat8. This will load the model in float8 to reduce VRAM consumption, otherwise you may receive an out-of-memory error. \n(由于EasyAnimateV5以上的模型较大,当使用12B模型时,如果使用的显卡显存为24G及以下,请将GPU_memory_mode设置为model_cpu_offload_and_qfloat8,使得模型加载在float8上减少显存消耗,否则会提示显存不足。)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 75, + "type": "EasyAnimate_TextBox", + "pos": { + "0": 250, + "1": -50 + }, + "size": { + "0": 383.54010009765625, + "1": 156.71620178222656 + }, + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "prompt", + "type": "STRING_PROMPT", + "links": [ + 52 + ], + "slot_index": 0, + "shape": 3 + } + ], + "title": "Positive Prompt(正向提示词)", + "properties": { + "Node name for S&R": "EasyAnimate_TextBox" + }, + "widgets_values": [ + "一只棕褐色的狗在摇晃脑袋,坐在一个舒适的房间里的浅色沙发上。在狗的后面,架子上有一幅镶框的画,周围是粉红色的花朵。房间里的灯光柔和温暖,营造出舒适的氛围。" + ] + } + ], + "links": [ + [ + 50, + 88, + 0, + 17, + 0, + "IMAGE" + ], + [ + 51, + 87, + 0, + 88, + 0, + "EASYANIMATESMODEL" + ], + [ + 52, + 75, + 0, + 88, + 1, + "STRING_PROMPT" + ], + [ + 53, + 73, + 0, + 88, + 2, + "STRING_PROMPT" + ] + ], + "groups": [ + { + "title": "Load EasyAnimate", + "bounding": [ + 218, + -393, + 503, + 254 + ], + "color": "#b06634", + "font_size": 24, + "flags": {} + }, + { + "title": "Prompts", + "bounding": [ + 218, + -127, + 450, + 483 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + } + ], + "config": {}, + "extra": { + "ds": { + "scale": 0.6830134553650716, + "offset": [ + 351.74219098221363, + 574.4414281283872 + ] + }, + "workspace_info": { + "id": "776b62b4-bd17-4ed3-9923-b7aad000b1ea" + } + }, + "version": 0.4 +} \ No newline at end of file diff --git a/comfyui/v5.1/easyanimatev5.1_workflow_v2v.json b/comfyui/v5.1/easyanimatev5.1_workflow_v2v.json new file mode 100644 index 0000000..3b5b504 --- /dev/null +++ b/comfyui/v5.1/easyanimatev5.1_workflow_v2v.json @@ -0,0 +1,553 @@ +{ + "last_node_id": 90, + "last_link_id": 58, + "nodes": [ + { + "id": 78, + "type": "Note", + "pos": { + "0": 18, + "1": -46 + }, + "size": { + "0": 210, + "1": 58 + }, + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "You can write prompt here\n(你可以在此填写提示词)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 79, + "type": "Note", + "pos": { + "0": 15.739953994750977, + "1": 462.38665771484375 + }, + "size": { + "0": 210, + "1": 58 + }, + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "You can upload video here\n(在此上传视频)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 73, + "type": "EasyAnimate_TextBox", + "pos": { + "0": 250, + "1": 160 + }, + "size": { + "0": 383.7149963378906, + "1": 183.83506774902344 + }, + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "prompt", + "type": "STRING_PROMPT", + "links": [ + 55 + ], + "slot_index": 0, + "shape": 3 + } + ], + "title": "Negtive Prompt(反向提示词)", + "properties": { + "Node name for S&R": "EasyAnimate_TextBox" + }, + "widgets_values": [ + "扭曲的身体,肢体残缺,文本字幕,漫画,静止,丑陋,错误,乱码。" + ] + }, + { + "id": 75, + "type": "EasyAnimate_TextBox", + "pos": { + "0": 250, + "1": -50 + }, + "size": { + "0": 383.54010009765625, + "1": 156.71620178222656 + }, + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "prompt", + "type": "STRING_PROMPT", + "links": [ + 54 + ], + "slot_index": 0, + "shape": 3 + } + ], + "title": "Positive Prompt(正向提示词)", + "properties": { + "Node name for S&R": "EasyAnimate_TextBox" + }, + "widgets_values": [ + "一只穿着小外套的猫咪正在花园秋千上安静地弹吉他。晚霞的余光洒在它柔软的毛皮上,和煦的微风轻轻拂过,周围斑驳的光影随着音乐的旋律轻轻摇曳。" + ] + }, + { + "id": 88, + "type": "Note", + "pos": { + "0": -97, + "1": 195 + }, + "size": { + "0": 326.1556091308594, + "1": 145.20904541015625 + }, + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "Using longer neg prompt such as \"Blurring, mutation, deformation, distortion, dark and solid, comics.\" can increase stability. Adding words such as \"quiet, solid\" to the neg prompt can increase dynamism.\n(使用更长的neg prompt如\"模糊,突变,变形,失真,画面暗,画面固定,连环画,漫画,线稿,没有主体。\",可以增加稳定性。在neg prompt中添加\"安静,固定\"等词语可以增加动态性。)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 17, + "type": "VHS_VideoCombine", + "pos": { + "0": 1314, + "1": -57 + }, + "size": [ + 390.9534912109375, + 535.9734235491071 + ], + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 57, + "slot_index": 0, + "label": "图像", + "shape": 7 + }, + { + "name": "audio", + "type": "AUDIO", + "link": null, + "label": "音频", + "shape": 7 + }, + { + "name": "meta_batch", + "type": "VHS_BatchManager", + "link": null, + "label": "批次管理", + "shape": 7 + }, + { + "name": "vae", + "type": "VAE", + "link": null, + "shape": 7 + } + ], + "outputs": [ + { + "name": "Filenames", + "type": "VHS_FILENAMES", + "links": null, + "slot_index": 0, + "shape": 3, + "label": "文件名" + } + ], + "properties": { + "Node name for S&R": "VHS_VideoCombine" + }, + "widgets_values": { + "frame_rate": 8, + "loop_count": 0, + "filename_prefix": "EasyAnimate", + "format": "video/h264-mp4", + "pix_fmt": "yuv420p", + "crf": 22, + "save_metadata": true, + "pingpong": false, + "save_output": true, + "videopreview": { + "hidden": false, + "paused": false, + "params": { + "filename": "EasyAnimate_00055.mp4", + "subfolder": "", + "type": "output", + "format": "video/h264-mp4", + "frame_rate": 8 + } + } + } + }, + { + "id": 89, + "type": "EasyAnimateV5_V2VSampler", + "pos": { + "0": 774, + "1": -57 + }, + "size": { + "0": 504, + "1": 350 + }, + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "name": "easyanimate_model", + "type": "EASYANIMATESMODEL", + "link": 53 + }, + { + "name": "prompt", + "type": "STRING_PROMPT", + "link": 54 + }, + { + "name": "negative_prompt", + "type": "STRING_PROMPT", + "link": 55 + }, + { + "name": "validation_video", + "type": "IMAGE", + "link": 58, + "shape": 7 + }, + { + "name": "control_video", + "type": "IMAGE", + "link": null, + "shape": 7 + }, + { + "name": "ref_image", + "type": "IMAGE", + "link": null, + "shape": 7 + }, + { + "name": "camera_conditions", + "type": "STRING", + "link": null, + "widget": { + "name": "camera_conditions" + }, + "shape": 7 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 57 + ], + "slot_index": 0 + } + ], + "properties": { + "Node name for S&R": "EasyAnimateV5_V2VSampler" + }, + "widgets_values": [ + 49, + 512, + 43, + "fixed", + 50, + 6, + 0.7000000000000001, + "Flow", + "" + ] + }, + { + "id": 31, + "type": "LoadEasyAnimateModel", + "pos": { + "0": 238.2776641845703, + "1": -307.4300537109375 + }, + "size": { + "0": 482.8221435546875, + "1": 154 + }, + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "easyanimate_model", + "type": "EASYANIMATESMODEL", + "links": [ + 53 + ], + "slot_index": 0, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "LoadEasyAnimateModel" + }, + "widgets_values": [ + "EasyAnimateV5.1-12b-zh-InP", + "model_cpu_offload_and_qfloat8", + "Inpaint", + "easyanimate_video_v5.1_magvit_qwen.yaml", + "bf16" + ] + }, + { + "id": 85, + "type": "VHS_LoadVideo", + "pos": { + "0": 335, + "1": 476 + }, + "size": [ + 252.056640625, + 408.6037946428571 + ], + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "name": "meta_batch", + "type": "VHS_BatchManager", + "link": null, + "shape": 7 + }, + { + "name": "vae", + "type": "VAE", + "link": null, + "shape": 7 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 58 + ], + "slot_index": 0, + "shape": 3 + }, + { + "name": "frame_count", + "type": "INT", + "links": null, + "shape": 3 + }, + { + "name": "audio", + "type": "AUDIO", + "links": null, + "shape": 3 + }, + { + "name": "video_info", + "type": "VHS_VIDEOINFO", + "links": null, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "VHS_LoadVideo" + }, + "widgets_values": { + "video": "1.mp4", + "force_rate": 8, + "force_size": "Disabled", + "custom_width": 512, + "custom_height": 512, + "frame_load_cap": 0, + "skip_first_frames": 0, + "select_every_nth": 1, + "choose video to upload": "image", + "videopreview": { + "hidden": false, + "paused": false, + "params": { + "frame_load_cap": 0, + "skip_first_frames": 0, + "force_rate": 8, + "filename": "1.mp4", + "type": "input", + "format": "video/mp4", + "select_every_nth": 1 + } + } + } + }, + { + "id": 90, + "type": "Note", + "pos": { + "0": -186, + "1": -295 + }, + "size": [ + 427.074951171875, + 143.9142608642578 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "Due to the large size of models from EasyAnimateV5 and above, when using the 12B model, if your graphics card has 24GB or less of VRAM, please set GPU_memory_mode to model_cpu_offload_and_qfloat8. This will load the model in float8 to reduce VRAM consumption, otherwise you may receive an out-of-memory error. \n(由于EasyAnimateV5以上的模型较大,当使用12B模型时,如果使用的显卡显存为24G及以下,请将GPU_memory_mode设置为model_cpu_offload_and_qfloat8,使得模型加载在float8上减少显存消耗,否则会提示显存不足。)" + ], + "color": "#432", + "bgcolor": "#653" + } + ], + "links": [ + [ + 53, + 31, + 0, + 89, + 0, + "EASYANIMATESMODEL" + ], + [ + 54, + 75, + 0, + 89, + 1, + "STRING_PROMPT" + ], + [ + 55, + 73, + 0, + 89, + 2, + "STRING_PROMPT" + ], + [ + 57, + 89, + 0, + 17, + 0, + "IMAGE" + ], + [ + 58, + 85, + 0, + 89, + 3, + "IMAGE" + ] + ], + "groups": [ + { + "title": "Prompts", + "bounding": [ + 218, + -127, + 450, + 483 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "title": "Load EasyAnimate", + "bounding": [ + 218, + -387, + 542, + 248 + ], + "color": "#b06634", + "font_size": 24, + "flags": {} + }, + { + "title": "Upload Your Video", + "bounding": [ + 218, + 385, + 479, + 529 + ], + "color": "#a1309b", + "font_size": 24, + "flags": {} + } + ], + "config": {}, + "extra": { + "ds": { + "scale": 0.6209213230591561, + "offset": [ + 447.5231554509637, + 537.020461913544 + ] + }, + "workspace_info": { + "id": "776b62b4-bd17-4ed3-9923-b7aad000b1ea" + } + }, + "version": 0.4 +} \ No newline at end of file diff --git a/comfyui/v5.1/easyanimatev5.1_workflow_v2v_control.json b/comfyui/v5.1/easyanimatev5.1_workflow_v2v_control.json new file mode 100644 index 0000000..2665324 --- /dev/null +++ b/comfyui/v5.1/easyanimatev5.1_workflow_v2v_control.json @@ -0,0 +1,548 @@ +{ + "last_node_id": 89, + "last_link_id": 53, + "nodes": [ + { + "id": 78, + "type": "Note", + "pos": { + "0": 18, + "1": -46 + }, + "size": { + "0": 210, + "1": 58 + }, + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "You can write prompt here\n(你可以在此填写提示词)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 79, + "type": "Note", + "pos": { + "0": 15.739953994750977, + "1": 462.38665771484375 + }, + "size": { + "0": 210, + "1": 58 + }, + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "You can upload video here\n(在此上传视频)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 73, + "type": "EasyAnimate_TextBox", + "pos": { + "0": 250, + "1": 160 + }, + "size": { + "0": 383.7149963378906, + "1": 183.83506774902344 + }, + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "prompt", + "type": "STRING_PROMPT", + "links": [ + 51 + ], + "slot_index": 0, + "shape": 3 + } + ], + "title": "Negtive Prompt(反向提示词)", + "properties": { + "Node name for S&R": "EasyAnimate_TextBox" + }, + "widgets_values": [ + "扭曲的身体,肢体残缺,文本字幕,漫画,静止,丑陋,错误,乱码。" + ] + }, + { + "id": 75, + "type": "EasyAnimate_TextBox", + "pos": { + "0": 250, + "1": -50 + }, + "size": { + "0": 383.54010009765625, + "1": 156.71620178222656 + }, + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "prompt", + "type": "STRING_PROMPT", + "links": [ + 50 + ], + "slot_index": 0, + "shape": 3 + } + ], + "title": "Positive Prompt(正向提示词)", + "properties": { + "Node name for S&R": "EasyAnimate_TextBox" + }, + "widgets_values": [ + "一个穿着及膝白色无袖连衣裙和白色高跟凉鞋的美女在一个光线充足、木地板的房间里跳舞。房间的背景是一扇紧闭的门、一个展示透明玻璃瓶酒精饮料的架子和一个部分可见的深色沙发。" + ] + }, + { + "id": 88, + "type": "Note", + "pos": { + "0": -99, + "1": 197 + }, + "size": { + "0": 326.1556091308594, + "1": 145.20904541015625 + }, + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "Using longer neg prompt such as \"Blurring, mutation, deformation, distortion, dark and solid, comics.\" can increase stability. Adding words such as \"quiet, solid\" to the neg prompt can increase dynamism.\n(使用更长的neg prompt如\"模糊,突变,变形,失真,画面暗,画面固定,连环画,漫画,线稿,没有主体。\",可以增加稳定性。在neg prompt中添加\"安静,固定\"等词语可以增加动态性。)" + ], + "color": "#432", + "bgcolor": "#653" + }, + { + "id": 17, + "type": "VHS_VideoCombine", + "pos": { + "0": 1173, + "1": 15 + }, + "size": [ + 390.9534912109375, + 973.1686096191406 + ], + "flags": {}, + "order": 9, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 48, + "slot_index": 0, + "label": "图像", + "shape": 7 + }, + { + "name": "audio", + "type": "AUDIO", + "link": null, + "label": "音频", + "shape": 7 + }, + { + "name": "meta_batch", + "type": "VHS_BatchManager", + "link": null, + "label": "批次管理", + "shape": 7 + }, + { + "name": "vae", + "type": "VAE", + "link": null, + "shape": 7 + } + ], + "outputs": [ + { + "name": "Filenames", + "type": "VHS_FILENAMES", + "links": null, + "slot_index": 0, + "shape": 3, + "label": "文件名" + } + ], + "properties": { + "Node name for S&R": "VHS_VideoCombine" + }, + "widgets_values": { + "frame_rate": 8, + "loop_count": 0, + "filename_prefix": "EasyAnimate", + "format": "video/h264-mp4", + "pix_fmt": "yuv420p", + "crf": 22, + "save_metadata": true, + "pingpong": false, + "save_output": true, + "videopreview": { + "hidden": false, + "paused": false, + "params": { + "filename": "EasyAnimate_00054.mp4", + "subfolder": "", + "type": "output", + "format": "video/h264-mp4", + "frame_rate": 8 + } + } + } + }, + { + "id": 87, + "type": "EasyAnimateV5_V2VSampler", + "pos": { + "0": 816, + "1": 13 + }, + "size": { + "0": 336, + "1": 350 + }, + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + { + "name": "easyanimate_model", + "type": "EASYANIMATESMODEL", + "link": 49 + }, + { + "name": "prompt", + "type": "STRING_PROMPT", + "link": 50, + "slot_index": 1 + }, + { + "name": "negative_prompt", + "type": "STRING_PROMPT", + "link": 51, + "slot_index": 2 + }, + { + "name": "validation_video", + "type": "IMAGE", + "link": null, + "slot_index": 3, + "shape": 7 + }, + { + "name": "control_video", + "type": "IMAGE", + "link": 53, + "shape": 7 + }, + { + "name": "ref_image", + "type": "IMAGE", + "link": null, + "shape": 7 + } + ], + "outputs": [ + { + "name": "images", + "type": "IMAGE", + "links": [ + 48 + ], + "slot_index": 0, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "EasyAnimateV5_V2VSampler" + }, + "widgets_values": [ + 49, + 512, + 43, + "fixed", + 50, + 6, + 1, + "Flow", + "" + ] + }, + { + "id": 31, + "type": "LoadEasyAnimateModel", + "pos": { + "0": 238.2776641845703, + "1": -307.4300537109375 + }, + "size": { + "0": 482.8221435546875, + "1": 154 + }, + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [ + { + "name": "easyanimate_model", + "type": "EASYANIMATESMODEL", + "links": [ + 49 + ], + "slot_index": 0, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "LoadEasyAnimateModel" + }, + "widgets_values": [ + "EasyAnimateV5.1-12b-zh-Control", + "model_cpu_offload_and_qfloat8", + "Control", + "easyanimate_video_v5.1_magvit_qwen.yaml", + "bf16" + ] + }, + { + "id": 85, + "type": "VHS_LoadVideo", + "pos": { + "0": 335, + "1": 476 + }, + "size": [ + 252.056640625, + 685.7 + ], + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + { + "name": "meta_batch", + "type": "VHS_BatchManager", + "link": null, + "shape": 7 + }, + { + "name": "vae", + "type": "VAE", + "link": null, + "shape": 7 + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 53 + ], + "slot_index": 0, + "shape": 3 + }, + { + "name": "frame_count", + "type": "INT", + "links": null, + "shape": 3 + }, + { + "name": "audio", + "type": "AUDIO", + "links": null, + "shape": 3 + }, + { + "name": "video_info", + "type": "VHS_VIDEOINFO", + "links": null, + "shape": 3 + } + ], + "properties": { + "Node name for S&R": "VHS_LoadVideo" + }, + "widgets_values": { + "video": "demo_pose.mp4", + "force_rate": 0, + "force_size": "Disabled", + "custom_width": 512, + "custom_height": 512, + "frame_load_cap": 0, + "skip_first_frames": 0, + "select_every_nth": 1, + "choose video to upload": "image", + "videopreview": { + "hidden": false, + "paused": false, + "params": { + "frame_load_cap": 0, + "skip_first_frames": 0, + "force_rate": 0, + "filename": "demo_pose.mp4", + "type": "input", + "format": "video/mp4", + "select_every_nth": 1 + } + } + } + }, + { + "id": 89, + "type": "Note", + "pos": { + "0": -192, + "1": -293 + }, + "size": [ + 427.074951171875, + 143.9142608642578 + ], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [], + "outputs": [], + "properties": { + "text": "" + }, + "widgets_values": [ + "Due to the large size of models from EasyAnimateV5 and above, when using the 12B model, if your graphics card has 24GB or less of VRAM, please set GPU_memory_mode to model_cpu_offload_and_qfloat8. This will load the model in float8 to reduce VRAM consumption, otherwise you may receive an out-of-memory error. \n(由于EasyAnimateV5以上的模型较大,当使用12B模型时,如果使用的显卡显存为24G及以下,请将GPU_memory_mode设置为model_cpu_offload_and_qfloat8,使得模型加载在float8上减少显存消耗,否则会提示显存不足。)" + ], + "color": "#432", + "bgcolor": "#653" + } + ], + "links": [ + [ + 48, + 87, + 0, + 17, + 0, + "IMAGE" + ], + [ + 49, + 31, + 0, + 87, + 0, + "EASYANIMATESMODEL" + ], + [ + 50, + 75, + 0, + 87, + 1, + "STRING_PROMPT" + ], + [ + 51, + 73, + 0, + 87, + 2, + "STRING_PROMPT" + ], + [ + 53, + 85, + 0, + 87, + 4, + "IMAGE" + ] + ], + "groups": [ + { + "title": "Prompts", + "bounding": [ + 218, + -127, + 450, + 483 + ], + "color": "#3f789e", + "font_size": 24, + "flags": {} + }, + { + "title": "Load EasyAnimate", + "bounding": [ + 218, + -387, + 542, + 248 + ], + "color": "#b06634", + "font_size": 24, + "flags": {} + }, + { + "title": "Upload Your Video", + "bounding": [ + 218, + 385, + 487, + 789 + ], + "color": "#a1309b", + "font_size": 24, + "flags": {} + } + ], + "config": {}, + "extra": { + "ds": { + "scale": 0.5644739300537782, + "offset": [ + 634.4708817322136, + 478.05663679245043 + ] + }, + "workspace_info": { + "id": "776b62b4-bd17-4ed3-9923-b7aad000b1ea" + } + }, + "version": 0.4 +} \ No newline at end of file diff --git a/comfyui/v5/easyanimatev5_workflow_i2v.json b/comfyui/v5/easyanimatev5_workflow_i2v.json index a44141f..d0e4f92 100644 --- a/comfyui/v5/easyanimatev5_workflow_i2v.json +++ b/comfyui/v5/easyanimatev5_workflow_i2v.json @@ -230,7 +230,7 @@ }, "widgets_values": [ "EasyAnimateV5-12b-zh-InP", - "model_cpu_offload", + "model_cpu_offload_and_qfloat8", "Inpaint", "easyanimate_video_v5_magvit_multi_text_encoder.yaml", "bf16" diff --git a/comfyui/v5/easyanimatev5_workflow_t2v.json b/comfyui/v5/easyanimatev5_workflow_t2v.json index 4ce48b7..c4aaa2f 100644 --- a/comfyui/v5/easyanimatev5_workflow_t2v.json +++ b/comfyui/v5/easyanimatev5_workflow_t2v.json @@ -83,7 +83,7 @@ }, "widgets_values": [ "EasyAnimateV5-12b-zh-InP", - "model_cpu_offload", + "model_cpu_offload_and_qfloat8", "Inpaint", "easyanimate_video_v5_magvit_multi_text_encoder.yaml", "bf16" diff --git a/comfyui/v5/easyanimatev5_workflow_v2v.json b/comfyui/v5/easyanimatev5_workflow_v2v.json index 3c4fd5f..6903ecf 100644 --- a/comfyui/v5/easyanimatev5_workflow_v2v.json +++ b/comfyui/v5/easyanimatev5_workflow_v2v.json @@ -108,7 +108,7 @@ }, "widgets_values": [ "EasyAnimateV5-12b-zh-InP", - "model_cpu_offload", + "model_cpu_offload_and_qfloat8", "Inpaint", "easyanimate_video_v5_magvit_multi_text_encoder.yaml", "bf16" @@ -179,7 +179,7 @@ "Node name for S&R": "EasyAnimate_TextBox" }, "widgets_values": [ - "一个漂亮的女人在弹吉他。视频质量高,画面清晰。高质量,杰作,最好的质量,高分辨率,超仔细。" + "一只穿着小外套的猫咪正在花园秋千上安静地弹吉他。晚霞的余光洒在它柔软的毛皮上,和煦的微风轻轻拂过,周围斑驳的光影随着音乐的旋律轻轻摇曳。" ] }, { diff --git a/comfyui/v5/easyanimatev5_workflow_v2v_control.json b/comfyui/v5/easyanimatev5_workflow_v2v_control.json index 2d48294..9af90be 100644 --- a/comfyui/v5/easyanimatev5_workflow_v2v_control.json +++ b/comfyui/v5/easyanimatev5_workflow_v2v_control.json @@ -222,7 +222,7 @@ }, "widgets_values": [ "EasyAnimateV5-12b-zh-Control", - "model_cpu_offload", + "model_cpu_offload_and_qfloat8", "Control", "easyanimate_video_v5_magvit_multi_text_encoder.yaml", "bf16" diff --git a/config/easyanimate_video_v5.1_magvit_qwen.yaml b/config/easyanimate_video_v5.1_magvit_qwen.yaml new file mode 100644 index 0000000..126b7d9 --- /dev/null +++ b/config/easyanimate_video_v5.1_magvit_qwen.yaml @@ -0,0 +1,21 @@ +transformer_additional_kwargs: + transformer_type: "EasyAnimateTransformer3DModel" + after_norm: false + time_position_encoding_type: "3d_rope" + resize_inpaint_mask_directly: true + enable_text_attention_mask: true + enable_clip_in_inpaint: false + add_ref_latent_in_control_model: true + +vae_kwargs: + vae_type: "AutoencoderKLMagvit" + mini_batch_encoder: 4 + mini_batch_decoder: 1 + slice_mag_vae: false + slice_compression_vae: false + cache_compression_vae: false + cache_mag_vae: true + +text_encoder_kwargs: + enable_multi_text_encoder: false + replace_t5_to_llm: true \ No newline at end of file diff --git a/easyanimate/api/post_infer.py b/easyanimate/api/post_infer.py index 950e6df..38ef4fa 100644 --- a/easyanimate/api/post_infer.py +++ b/easyanimate/api/post_infer.py @@ -54,14 +54,14 @@ if __name__ == '__main__': # -------------------------- # # Step 1: update edition # -------------------------- # - edition = "v5" + edition = "v5.1" outputs = post_update_edition(edition) print('Output update edition: ', outputs) # -------------------------- # # Step 2: update edition # -------------------------- # - diffusion_transformer_path = "models/Diffusion_Transformer/EasyAnimateV5-12b-zh-InP" + diffusion_transformer_path = "models/Diffusion_Transformer/EasyAnimateV5.1-12b-zh-InP" outputs = post_diffusion_transformer(diffusion_transformer_path) print('Output update edition: ', outputs) diff --git a/easyanimate/data/dataset_image_video.py b/easyanimate/data/dataset_image_video.py index 3065838..829cdad 100644 --- a/easyanimate/data/dataset_image_video.py +++ b/easyanimate/data/dataset_image_video.py @@ -12,9 +12,12 @@ import albumentations import cv2 import numpy as np import torch +import torch.nn.functional as F import torchvision.transforms as transforms from decord import VideoReader +from einops import rearrange from func_timeout import FunctionTimedOut, func_timeout +from packaging import version as pver from PIL import Image from torch.utils.data import BatchSampler, Sampler from torch.utils.data.dataset import Dataset @@ -100,6 +103,152 @@ def get_random_mask(shape): else: raise ValueError(f"The mask_index {mask_index} is not define") return mask + +class Camera(object): + """Copied from https://github.com/hehao13/CameraCtrl/blob/main/inference.py + """ + def __init__(self, entry): + fx, fy, cx, cy = entry[1:5] + self.fx = fx + self.fy = fy + self.cx = cx + self.cy = cy + w2c_mat = np.array(entry[7:]).reshape(3, 4) + w2c_mat_4x4 = np.eye(4) + w2c_mat_4x4[:3, :] = w2c_mat + self.w2c_mat = w2c_mat_4x4 + self.c2w_mat = np.linalg.inv(w2c_mat_4x4) + +def custom_meshgrid(*args): + """Copied from https://github.com/hehao13/CameraCtrl/blob/main/inference.py + """ + # ref: https://pytorch.org/docs/stable/generated/torch.meshgrid.html?highlight=meshgrid#torch.meshgrid + if pver.parse(torch.__version__) < pver.parse('1.10'): + return torch.meshgrid(*args) + else: + return torch.meshgrid(*args, indexing='ij') + +def get_relative_pose(cam_params): + """Copied from https://github.com/hehao13/CameraCtrl/blob/main/inference.py + """ + abs_w2cs = [cam_param.w2c_mat for cam_param in cam_params] + abs_c2ws = [cam_param.c2w_mat for cam_param in cam_params] + cam_to_origin = 0 + target_cam_c2w = np.array([ + [1, 0, 0, 0], + [0, 1, 0, -cam_to_origin], + [0, 0, 1, 0], + [0, 0, 0, 1] + ]) + abs2rel = target_cam_c2w @ abs_w2cs[0] + ret_poses = [target_cam_c2w, ] + [abs2rel @ abs_c2w for abs_c2w in abs_c2ws[1:]] + ret_poses = np.array(ret_poses, dtype=np.float32) + return ret_poses + +def ray_condition(K, c2w, H, W, device): + """Copied from https://github.com/hehao13/CameraCtrl/blob/main/inference.py + """ + # c2w: B, V, 4, 4 + # K: B, V, 4 + + B = K.shape[0] + + j, i = custom_meshgrid( + torch.linspace(0, H - 1, H, device=device, dtype=c2w.dtype), + torch.linspace(0, W - 1, W, device=device, dtype=c2w.dtype), + ) + i = i.reshape([1, 1, H * W]).expand([B, 1, H * W]) + 0.5 # [B, HxW] + j = j.reshape([1, 1, H * W]).expand([B, 1, H * W]) + 0.5 # [B, HxW] + + fx, fy, cx, cy = K.chunk(4, dim=-1) # B,V, 1 + + zs = torch.ones_like(i) # [B, HxW] + xs = (i - cx) / fx * zs + ys = (j - cy) / fy * zs + zs = zs.expand_as(ys) + + directions = torch.stack((xs, ys, zs), dim=-1) # B, V, HW, 3 + directions = directions / directions.norm(dim=-1, keepdim=True) # B, V, HW, 3 + + rays_d = directions @ c2w[..., :3, :3].transpose(-1, -2) # B, V, 3, HW + rays_o = c2w[..., :3, 3] # B, V, 3 + rays_o = rays_o[:, :, None].expand_as(rays_d) # B, V, 3, HW + # c2w @ dirctions + rays_dxo = torch.cross(rays_o, rays_d) + plucker = torch.cat([rays_dxo, rays_d], dim=-1) + plucker = plucker.reshape(B, c2w.shape[1], H, W, 6) # B, V, H, W, 6 + # plucker = plucker.permute(0, 1, 4, 2, 3) + return plucker + +def process_pose_file(pose_file_path, width=672, height=384, original_pose_width=1280, original_pose_height=720, device='cpu', return_poses=False): + """Modified from https://github.com/hehao13/CameraCtrl/blob/main/inference.py + """ + with open(pose_file_path, 'r') as f: + poses = f.readlines() + + poses = [pose.strip().split(' ') for pose in poses[1:]] + cam_params = [[float(x) for x in pose] for pose in poses] + if return_poses: + return cam_params + else: + cam_params = [Camera(cam_param) for cam_param in cam_params] + + sample_wh_ratio = width / height + pose_wh_ratio = original_pose_width / original_pose_height # Assuming placeholder ratios, change as needed + + if pose_wh_ratio > sample_wh_ratio: + resized_ori_w = height * pose_wh_ratio + for cam_param in cam_params: + cam_param.fx = resized_ori_w * cam_param.fx / width + else: + resized_ori_h = width / pose_wh_ratio + for cam_param in cam_params: + cam_param.fy = resized_ori_h * cam_param.fy / height + + intrinsic = np.asarray([[cam_param.fx * width, + cam_param.fy * height, + cam_param.cx * width, + cam_param.cy * height] + for cam_param in cam_params], dtype=np.float32) + + K = torch.as_tensor(intrinsic)[None] # [1, 1, 4] + c2ws = get_relative_pose(cam_params) # Assuming this function is defined elsewhere + c2ws = torch.as_tensor(c2ws)[None] # [1, n_frame, 4, 4] + plucker_embedding = ray_condition(K, c2ws, height, width, device=device)[0].permute(0, 3, 1, 2).contiguous() # V, 6, H, W + plucker_embedding = plucker_embedding[None] + plucker_embedding = rearrange(plucker_embedding, "b f c h w -> b f h w c")[0] + return plucker_embedding + +def process_pose_params(cam_params, width=672, height=384, original_pose_width=1280, original_pose_height=720, device='cpu'): + """Modified from https://github.com/hehao13/CameraCtrl/blob/main/inference.py + """ + cam_params = [Camera(cam_param) for cam_param in cam_params] + + sample_wh_ratio = width / height + pose_wh_ratio = original_pose_width / original_pose_height # Assuming placeholder ratios, change as needed + + if pose_wh_ratio > sample_wh_ratio: + resized_ori_w = height * pose_wh_ratio + for cam_param in cam_params: + cam_param.fx = resized_ori_w * cam_param.fx / width + else: + resized_ori_h = width / pose_wh_ratio + for cam_param in cam_params: + cam_param.fy = resized_ori_h * cam_param.fy / height + + intrinsic = np.asarray([[cam_param.fx * width, + cam_param.fy * height, + cam_param.cx * width, + cam_param.cy * height] + for cam_param in cam_params], dtype=np.float32) + + K = torch.as_tensor(intrinsic)[None] # [1, 1, 4] + c2ws = get_relative_pose(cam_params) # Assuming this function is defined elsewhere + c2ws = torch.as_tensor(c2ws)[None] # [1, n_frame, 4, 4] + plucker_embedding = ray_condition(K, c2ws, height, width, device=device)[0].permute(0, 3, 1, 2).contiguous() # V, 6, H, W + plucker_embedding = plucker_embedding[None] + plucker_embedding = rearrange(plucker_embedding, "b f c h w -> b f h w c")[0] + return plucker_embedding class ImageVideoSampler(BatchSampler): """A sampler wrapper for grouping images with similar aspect ratio into a same batch. @@ -184,7 +333,7 @@ class ImageVideoDataset(Dataset): video_sample_size=512, video_sample_stride=4, video_sample_n_frames=16, image_sample_size=512, video_repeat=0, - text_drop_ratio=-1, + text_drop_ratio=0.1, enable_bucket=False, video_length_drop_start=0.1, video_length_drop_end=0.9, @@ -355,7 +504,6 @@ class ImageVideoDataset(Dataset): return sample - class ImageVideoControlDataset(Dataset): def __init__( self, @@ -363,11 +511,12 @@ class ImageVideoControlDataset(Dataset): video_sample_size=512, video_sample_stride=4, video_sample_n_frames=16, image_sample_size=512, video_repeat=0, - text_drop_ratio=-1, + text_drop_ratio=0.1, enable_bucket=False, video_length_drop_start=0.1, video_length_drop_end=0.9, enable_inpaint=False, + enable_camera_info=False, ): # Loading annotations from files print(f"loading annotations from {ann_path} ...") @@ -397,6 +546,7 @@ class ImageVideoControlDataset(Dataset): self.enable_bucket = enable_bucket self.text_drop_ratio = text_drop_ratio self.enable_inpaint = enable_inpaint + self.enable_camera_info = enable_camera_info self.video_length_drop_start = video_length_drop_start self.video_length_drop_end = video_length_drop_end @@ -412,6 +562,13 @@ class ImageVideoControlDataset(Dataset): transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5], inplace=True), ] ) + if self.enable_camera_info: + self.video_transforms_camera = transforms.Compose( + [ + transforms.Resize(min(self.video_sample_size)), + transforms.CenterCrop(self.video_sample_size) + ] + ) # Image params self.image_sample_size = tuple(image_sample_size) if not isinstance(image_sample_size, int) else (image_sample_size, image_sample_size) @@ -484,33 +641,59 @@ class ImageVideoControlDataset(Dataset): else: control_video_id = os.path.join(self.data_root, control_video_id) - with VideoReader_contextmanager(control_video_id, num_threads=2) as control_video_reader: - try: - sample_args = (control_video_reader, batch_index) - control_pixel_values = func_timeout( - VIDEO_READER_TIMEOUT, get_video_reader_batch, args=sample_args - ) - resized_frames = [] - for i in range(len(control_pixel_values)): - frame = control_pixel_values[i] - resized_frame = resize_frame(frame, self.larger_side_of_image_and_video) - resized_frames.append(resized_frame) - control_pixel_values = np.array(resized_frames) - except FunctionTimedOut: - raise ValueError(f"Read {idx} timeout.") - except Exception as e: - raise ValueError(f"Failed to extract frames from video. Error is {e}.") + if self.enable_camera_info: + if control_video_id.lower().endswith('.txt'): + if not self.enable_bucket: + control_pixel_values = torch.zeros_like(pixel_values) - if not self.enable_bucket: - control_pixel_values = torch.from_numpy(control_pixel_values).permute(0, 3, 1, 2).contiguous() - control_pixel_values = control_pixel_values / 255. - del control_video_reader + control_camera_values = process_pose_file(control_video_id, width=self.video_sample_size[1], height=self.video_sample_size[0]) + control_camera_values = torch.from_numpy(control_camera_values).permute(0, 3, 1, 2).contiguous() + control_camera_values = F.interpolate(control_camera_values, size=(len(video_reader), control_camera_values.size(3)), mode='bilinear', align_corners=True) + control_camera_values = self.video_transforms_camera(control_camera_values) + else: + control_pixel_values = np.zeros_like(pixel_values) + + control_camera_values = process_pose_file(control_video_id, width=self.video_sample_size[1], height=self.video_sample_size[0], return_poses=True) + control_camera_values = torch.from_numpy(np.array(control_camera_values)).unsqueeze(0).unsqueeze(0) + control_camera_values = F.interpolate(control_camera_values, size=(len(video_reader), control_camera_values.size(3)), mode='bilinear', align_corners=True)[0][0] + control_camera_values = np.array([control_camera_values[index] for index in batch_index]) else: - control_pixel_values = control_pixel_values + if not self.enable_bucket: + control_pixel_values = torch.zeros_like(pixel_values) + control_camera_values = None + else: + control_pixel_values = np.zeros_like(pixel_values) + control_camera_values = None + else: + with VideoReader_contextmanager(control_video_id, num_threads=2) as control_video_reader: + try: + sample_args = (control_video_reader, batch_index) + control_pixel_values = func_timeout( + VIDEO_READER_TIMEOUT, get_video_reader_batch, args=sample_args + ) + resized_frames = [] + for i in range(len(control_pixel_values)): + frame = control_pixel_values[i] + resized_frame = resize_frame(frame, self.larger_side_of_image_and_video) + resized_frames.append(resized_frame) + control_pixel_values = np.array(resized_frames) + except FunctionTimedOut: + raise ValueError(f"Read {idx} timeout.") + except Exception as e: + raise ValueError(f"Failed to extract frames from video. Error is {e}.") - if not self.enable_bucket: - control_pixel_values = self.video_transforms(control_pixel_values) - return pixel_values, control_pixel_values, text, "video" + if not self.enable_bucket: + control_pixel_values = torch.from_numpy(control_pixel_values).permute(0, 3, 1, 2).contiguous() + control_pixel_values = control_pixel_values / 255. + del control_video_reader + else: + control_pixel_values = control_pixel_values + + if not self.enable_bucket: + control_pixel_values = self.video_transforms(control_pixel_values) + control_camera_values = None + + return pixel_values, control_pixel_values, control_camera_values, text, "video" else: image_path, text = data_info['file_path'], data_info['text'] if self.data_root is not None: @@ -536,7 +719,8 @@ class ImageVideoControlDataset(Dataset): control_image = self.image_transforms(control_image).unsqueeze(0) else: control_image = np.expand_dims(np.array(control_image), 0) - return image, control_image, text, 'image' + + return image, control_image, None, text, 'image' def __len__(self): return self.length @@ -552,13 +736,17 @@ class ImageVideoControlDataset(Dataset): if data_type_local != data_type: raise ValueError("data_type_local != data_type") - pixel_values, control_pixel_values, name, data_type = self.get_batch(idx) + pixel_values, control_pixel_values, control_camera_values, name, data_type = self.get_batch(idx) + sample["pixel_values"] = pixel_values sample["control_pixel_values"] = control_pixel_values sample["text"] = name sample["data_type"] = data_type sample["idx"] = idx - + + if self.enable_camera_info: + sample["control_camera_values"] = control_camera_values + if len(sample) > 0: break except Exception as e: diff --git a/easyanimate/models/__init__.py b/easyanimate/models/__init__.py index 5f2988d..0b9b722 100644 --- a/easyanimate/models/__init__.py +++ b/easyanimate/models/__init__.py @@ -1,8 +1,7 @@ -from .autoencoder_magvit import (AutoencoderKLCogVideoX, AutoencoderKLMagvit, AutoencoderKL) +from .autoencoder_magvit import (AutoencoderKL, AutoencoderKLCogVideoX, + AutoencoderKLMagvit) from .transformer3d import (EasyAnimateTransformer3DModel, - HunyuanTransformer3DModel, - Transformer3DModel) - + HunyuanTransformer3DModel, Transformer3DModel) name_to_transformer3d = { "Transformer3DModel": Transformer3DModel, diff --git a/easyanimate/models/attention.py b/easyanimate/models/attention.py index 0c36a0e..43b8cea 100644 --- a/easyanimate/models/attention.py +++ b/easyanimate/models/attention.py @@ -29,7 +29,7 @@ from diffusers.models.embeddings import (SinusoidalPositionalEmbedding, get_3d_sincos_pos_embed) from diffusers.models.modeling_outputs import Transformer2DModelOutput from diffusers.models.modeling_utils import ModelMixin -from diffusers.models.normalization import (AdaLayerNorm, AdaLayerNormZero, +from diffusers.models.normalization import (AdaLayerNorm, AdaLayerNormZero, CogVideoXLayerNormZero) from diffusers.utils import USE_PEFT_BACKEND, is_torch_version, logging from diffusers.utils.import_utils import is_xformers_available @@ -38,12 +38,11 @@ from einops import rearrange, repeat from torch import nn from .motion_module import PositionalEncoding, get_motion_module -from .norm import AdaLayerNormShift, FP32LayerNorm, EasyAnimateLayerNormZero +from .norm import AdaLayerNormShift, EasyAnimateLayerNormZero, FP32LayerNorm from .processor import (EasyAnimateAttnProcessor2_0, + EasyAnimateSWAttnProcessor2_0, LazyKVCompressionProcessor2_0) - - if is_xformers_available(): import xformers import xformers.ops @@ -1044,6 +1043,7 @@ class EasyAnimateDiTBlock(nn.Module): after_norm: bool = False, norm_type: str="fp32_layer_norm", is_mmdit_block: bool = True, + is_swa: bool = False, ): super().__init__() @@ -1052,6 +1052,7 @@ class EasyAnimateDiTBlock(nn.Module): time_embed_dim, dim, norm_elementwise_affine, norm_eps, norm_type=norm_type, bias=True ) + self.is_swa = is_swa self.attn1 = Attention( query_dim=dim, dim_head=attention_head_dim, @@ -1059,7 +1060,7 @@ class EasyAnimateDiTBlock(nn.Module): qk_norm="layer_norm" if qk_norm else None, eps=1e-6, bias=True, - processor=EasyAnimateAttnProcessor2_0(), + processor=EasyAnimateAttnProcessor2_0() if not is_swa else EasyAnimateSWAttnProcessor2_0(), ) if is_mmdit_block: self.attn2 = Attention( @@ -1069,7 +1070,7 @@ class EasyAnimateDiTBlock(nn.Module): qk_norm="layer_norm" if qk_norm else None, eps=1e-6, bias=True, - processor=EasyAnimateAttnProcessor2_0(), + processor=EasyAnimateAttnProcessor2_0() if not is_swa else EasyAnimateSWAttnProcessor2_0(), ) else: self.attn2 = None @@ -1109,6 +1110,9 @@ class EasyAnimateDiTBlock(nn.Module): encoder_hidden_states: torch.Tensor, temb: torch.Tensor, image_rotary_emb: Optional[Tuple[torch.Tensor, torch.Tensor]] = None, + num_frames = None, + height = None, + width = None ) -> torch.Tensor: # Norm norm_hidden_states, norm_encoder_hidden_states, gate_msa, enc_gate_msa = self.norm1( @@ -1116,12 +1120,23 @@ class EasyAnimateDiTBlock(nn.Module): ) # Attn - attn_hidden_states, attn_encoder_hidden_states = self.attn1( - hidden_states=norm_hidden_states, - encoder_hidden_states=norm_encoder_hidden_states, - image_rotary_emb=image_rotary_emb, - attn2=self.attn2, - ) + if self.is_swa: + attn_hidden_states, attn_encoder_hidden_states = self.attn1( + hidden_states=norm_hidden_states, + encoder_hidden_states=norm_encoder_hidden_states, + image_rotary_emb=image_rotary_emb, + attn2=self.attn2, + num_frames=num_frames, + height=height, + width=width, + ) + else: + attn_hidden_states, attn_encoder_hidden_states = self.attn1( + hidden_states=norm_hidden_states, + encoder_hidden_states=norm_encoder_hidden_states, + image_rotary_emb=image_rotary_emb, + attn2=self.attn2 + ) hidden_states = hidden_states + gate_msa * attn_hidden_states encoder_hidden_states = encoder_hidden_states + enc_gate_msa * attn_encoder_hidden_states diff --git a/easyanimate/models/autoencoder_magvit.py b/easyanimate/models/autoencoder_magvit.py index a10f6f0..1dc1c31 100644 --- a/easyanimate/models/autoencoder_magvit.py +++ b/easyanimate/models/autoencoder_magvit.py @@ -201,82 +201,6 @@ class AutoencoderKLMagvit(ModelMixin, ConfigMixin, FromOriginalVAEMixin): if isinstance(module, (omnigen_Mag_Encoder, omnigen_Mag_Decoder)): module.gradient_checkpointing = value - @property - # Copied from diffusers.models.unets.unet_2d_condition.UNet2DConditionModel.attn_processors - def attn_processors(self) -> Dict[str, AttentionProcessor]: - r""" - Returns: - `dict` of attention processors: A dictionary containing all attention processors used in the model with - indexed by its weight name. - """ - # set recursively - processors = {} - - def fn_recursive_add_processors(name: str, module: torch.nn.Module, processors: Dict[str, AttentionProcessor]): - if hasattr(module, "get_processor"): - processors[f"{name}.processor"] = module.get_processor(return_deprecated_lora=True) - - for sub_name, child in module.named_children(): - fn_recursive_add_processors(f"{name}.{sub_name}", child, processors) - - return processors - - for name, module in self.named_children(): - fn_recursive_add_processors(name, module, processors) - - return processors - - # Copied from diffusers.models.unets.unet_2d_condition.UNet2DConditionModel.set_attn_processor - def set_attn_processor(self, processor: Union[AttentionProcessor, Dict[str, AttentionProcessor]]): - r""" - Sets the attention processor to use to compute attention. - - Parameters: - processor (`dict` of `AttentionProcessor` or only `AttentionProcessor`): - The instantiated processor class or a dictionary of processor classes that will be set as the processor - for **all** `Attention` layers. - - If `processor` is a dict, the key needs to define the path to the corresponding cross attention - processor. This is strongly recommended when setting trainable attention processors. - - """ - count = len(self.attn_processors.keys()) - - if isinstance(processor, dict) and len(processor) != count: - raise ValueError( - f"A dict of processors was passed, but the number of processors {len(processor)} does not match the" - f" number of attention layers: {count}. Please make sure to pass {count} processor classes." - ) - - def fn_recursive_attn_processor(name: str, module: torch.nn.Module, processor): - if hasattr(module, "set_processor"): - if not isinstance(processor, dict): - module.set_processor(processor) - else: - module.set_processor(processor.pop(f"{name}.processor")) - - for sub_name, child in module.named_children(): - fn_recursive_attn_processor(f"{name}.{sub_name}", child, processor) - - for name, module in self.named_children(): - fn_recursive_attn_processor(name, module, processor) - - # Copied from diffusers.models.unets.unet_2d_condition.UNet2DConditionModel.set_default_attn_processor - def set_default_attn_processor(self): - """ - Disables custom attention processors and sets the default attention implementation. - """ - if all(proc.__class__ in ADDED_KV_ATTENTION_PROCESSORS for proc in self.attn_processors.values()): - processor = AttnAddedKVProcessor() - elif all(proc.__class__ in CROSS_ATTENTION_PROCESSORS for proc in self.attn_processors.values()): - processor = AttnProcessor() - else: - raise ValueError( - f"Cannot call `set_default_attn_processor` when attention processors are of type {next(iter(self.attn_processors.values()))}" - ) - - self.set_attn_processor(processor) - def _clear_conv_cache(self): for name, module in self.named_modules(): if isinstance(module, CausalConv3d): @@ -531,44 +455,6 @@ class AutoencoderKLMagvit(ModelMixin, ConfigMixin, FromOriginalVAEMixin): return DecoderOutput(sample=dec) - # Copied from diffusers.models.unets.unet_2d_condition.UNet2DConditionModel.fuse_qkv_projections - def fuse_qkv_projections(self): - """ - Enables fused QKV projections. For self-attention modules, all projection matrices (i.e., query, - key, value) are fused. For cross-attention modules, key and value projection matrices are fused. - - <Tip warning={true}> - - This API is 🧪 experimental. - - </Tip> - """ - self.original_attn_processors = None - - for _, attn_processor in self.attn_processors.items(): - if "Added" in str(attn_processor.__class__.__name__): - raise ValueError("`fuse_qkv_projections()` is not supported for models having added KV projections.") - - self.original_attn_processors = self.attn_processors - - for module in self.modules(): - if isinstance(module, Attention): - module.fuse_projections(fuse=True) - - # Copied from diffusers.models.unets.unet_2d_condition.UNet2DConditionModel.unfuse_qkv_projections - def unfuse_qkv_projections(self): - """Disables the fused QKV projection if enabled. - - <Tip warning={true}> - - This API is 🧪 experimental. - - </Tip> - - """ - if self.original_attn_processors is not None: - self.set_attn_processor(self.original_attn_processors) - @classmethod def from_pretrained(cls, pretrained_model_path, subfolder=None, **vae_additional_kwargs): import json diff --git a/easyanimate/models/embeddings.py b/easyanimate/models/embeddings.py index dddef56..8e7531e 100644 --- a/easyanimate/models/embeddings.py +++ b/easyanimate/models/embeddings.py @@ -4,8 +4,9 @@ from typing import Optional import numpy as np import torch import torch.nn.functional as F -from diffusers.models.embeddings import (PixArtAlphaTextProjection, get_timestep_embedding, - TimestepEmbedding, Timesteps) +from diffusers.models.embeddings import (PixArtAlphaTextProjection, + TimestepEmbedding, Timesteps, + get_timestep_embedding) from einops import rearrange from torch import nn diff --git a/easyanimate/models/norm.py b/easyanimate/models/norm.py index 9bb6dc0..cb9a814 100644 --- a/easyanimate/models/norm.py +++ b/easyanimate/models/norm.py @@ -25,6 +25,22 @@ class FP32LayerNorm(nn.LayerNorm): inputs.float(), self.normalized_shape, None, None, self.eps ).to(origin_dtype) +class EasyAnimateRMSNorm(nn.Module): + def __init__(self, hidden_size, eps=1e-6): + super().__init__() + self.weight = nn.Parameter(torch.ones(hidden_size)) + self.variance_epsilon = eps + + def forward(self, hidden_states): + input_dtype = hidden_states.dtype + hidden_states = hidden_states.to(torch.float32) + variance = hidden_states.pow(2).mean(-1, keepdim=True) + hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon) + return self.weight * hidden_states.to(input_dtype) + + def extra_repr(self): + return f"{tuple(self.weight.shape)}, eps={self.variance_epsilon}" + class PixArtAlphaCombinedTimestepSizeEmbeddings(nn.Module): """ For PixArt-Alpha. diff --git a/easyanimate/models/processor.py b/easyanimate/models/processor.py index 3f92240..0cea72e 100644 --- a/easyanimate/models/processor.py +++ b/easyanimate/models/processor.py @@ -310,3 +310,149 @@ class EasyAnimateAttnProcessor2_0: hidden_states = attn.to_out[1](hidden_states) encoder_hidden_states = attn2.to_out[1](encoder_hidden_states) return hidden_states, encoder_hidden_states + +try: + from flash_attn import flash_attn_func, flash_attn_varlen_func + from flash_attn.bert_padding import pad_input, unpad_input +except: + print("Flash Attention is not installed. Please install with `pip install flash-attn`, if you want to use SWA.") + +class EasyAnimateSWAttnProcessor2_0: + def __init__(self, window_size=1024): + self.window_size = window_size + + def __call__( + self, + attn: Attention, + hidden_states: torch.Tensor, + encoder_hidden_states: torch.Tensor, + attention_mask: Optional[torch.Tensor] = None, + image_rotary_emb: Optional[torch.Tensor] = None, + num_frames: int = None, + height: int = None, + width: int = None, + attn2: Attention = None, + ) -> torch.Tensor: + text_seq_length = encoder_hidden_states.size(1) + + batch_size, sequence_length, _ = ( + hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape + ) + + if attn2 is None: + hidden_states = torch.cat([encoder_hidden_states, hidden_states], dim=1) + + query = attn.to_q(hidden_states) + key = attn.to_k(hidden_states) + value = attn.to_v(hidden_states) + + inner_dim = key.shape[-1] + head_dim = inner_dim // attn.heads + + query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2) + key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2) + value = value.view(batch_size, -1, attn.heads, head_dim) + + if attn.norm_q is not None: + query = attn.norm_q(query) + if attn.norm_k is not None: + key = attn.norm_k(key) + + if attn2 is not None: + query_txt = attn2.to_q(encoder_hidden_states) + key_txt = attn2.to_k(encoder_hidden_states) + value_txt = attn2.to_v(encoder_hidden_states) + + inner_dim = key_txt.shape[-1] + head_dim = inner_dim // attn.heads + + query_txt = query_txt.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2) + key_txt = key_txt.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2) + value_txt = value_txt.view(batch_size, -1, attn.heads, head_dim) + + if attn2.norm_q is not None: + query_txt = attn2.norm_q(query_txt) + if attn2.norm_k is not None: + key_txt = attn2.norm_k(key_txt) + + query = torch.cat([query_txt, query], dim=2) + key = torch.cat([key_txt, key], dim=2) + value = torch.cat([value_txt, value], dim=1) + + # Apply RoPE if needed + if image_rotary_emb is not None: + query[:, :, text_seq_length:] = apply_rotary_emb(query[:, :, text_seq_length:], image_rotary_emb) + if not attn.is_cross_attention: + key[:, :, text_seq_length:] = apply_rotary_emb(key[:, :, text_seq_length:], image_rotary_emb) + + query = query.transpose(1, 2).to(value) + key = key.transpose(1, 2).to(value) + interval = max((query.size(1) - text_seq_length) // (self.window_size - text_seq_length), 1) + + cross_key = torch.cat([key[:, :text_seq_length], key[:, text_seq_length::interval]], dim=1) + cross_val = torch.cat([value[:, :text_seq_length], value[:, text_seq_length::interval]], dim=1) + cross_hidden_states = flash_attn_func(query, cross_key, cross_val, dropout_p=0.0, causal=False) + + # Split and rearrange to six directions + querys = torch.tensor_split(query[:, text_seq_length:], 6, 2) + keys = torch.tensor_split(key[:, text_seq_length:], 6, 2) + values = torch.tensor_split(value[:, text_seq_length:], 6, 2) + + new_querys = [querys[0]] + new_keys = [keys[0]] + new_values = [values[0]] + for index, mode in enumerate( + [ + "bs (f h w) hn hd -> bs (f w h) hn hd", + "bs (f h w) hn hd -> bs (h f w) hn hd", + "bs (f h w) hn hd -> bs (h w f) hn hd", + "bs (f h w) hn hd -> bs (w f h) hn hd", + "bs (f h w) hn hd -> bs (w h f) hn hd" + ] + ): + new_querys.append(rearrange(querys[index + 1], mode, f=num_frames, h=height, w=width)) + new_keys.append(rearrange(keys[index + 1], mode, f=num_frames, h=height, w=width)) + new_values.append(rearrange(values[index + 1], mode, f=num_frames, h=height, w=width)) + query = torch.cat(new_querys, dim=2) + key = torch.cat(new_keys, dim=2) + value = torch.cat(new_values, dim=2) + + # apply attention + hidden_states = flash_attn_func(query, key, value, dropout_p=0.0, causal=False, window_size=(self.window_size, self.window_size)) + + hidden_states = torch.tensor_split(hidden_states, 6, 2) + new_hidden_states = [hidden_states[0]] + for index, mode in enumerate( + [ + "bs (f w h) hn hd -> bs (f h w) hn hd", + "bs (h f w) hn hd -> bs (f h w) hn hd", + "bs (h w f) hn hd -> bs (f h w) hn hd", + "bs (w f h) hn hd -> bs (f h w) hn hd", + "bs (w h f) hn hd -> bs (f h w) hn hd" + ] + ): + new_hidden_states.append(rearrange(hidden_states[index + 1], mode, f=num_frames, h=height, w=width)) + hidden_states = torch.cat([cross_hidden_states[:, :text_seq_length], torch.cat(new_hidden_states, dim=2)], dim=1) + cross_hidden_states + + hidden_states = hidden_states.reshape(batch_size, -1, attn.heads * head_dim) + + if attn2 is None: + # linear proj + hidden_states = attn.to_out[0](hidden_states) + # dropout + hidden_states = attn.to_out[1](hidden_states) + + encoder_hidden_states, hidden_states = hidden_states.split( + [text_seq_length, hidden_states.size(1) - text_seq_length], dim=1 + ) + else: + encoder_hidden_states, hidden_states = hidden_states.split( + [text_seq_length, hidden_states.size(1) - text_seq_length], dim=1 + ) + # linear proj + hidden_states = attn.to_out[0](hidden_states) + encoder_hidden_states = attn2.to_out[0](encoder_hidden_states) + # dropout + hidden_states = attn.to_out[1](hidden_states) + encoder_hidden_states = attn2.to_out[1](encoder_hidden_states) + return hidden_states, encoder_hidden_states \ No newline at end of file diff --git a/easyanimate/models/transformer2d.py b/easyanimate/models/transformer2d.py index 971a02b..907f0fd 100644 --- a/easyanimate/models/transformer2d.py +++ b/easyanimate/models/transformer2d.py @@ -377,7 +377,7 @@ class Transformer2DModel(ModelMixin, ConfigMixin): encoder_hidden_states = encoder_hidden_states.view(batch_size, -1, hidden_states.shape[-1]) for block in self.transformer_blocks: - if self.training and self.gradient_checkpointing: + if torch.is_grad_enabled() and self.gradient_checkpointing: args = { "basic": [], }[self.basic_block_type] diff --git a/easyanimate/models/transformer3d.py b/easyanimate/models/transformer3d.py index 42fa305..7793ac2 100644 --- a/easyanimate/models/transformer3d.py +++ b/easyanimate/models/transformer3d.py @@ -39,8 +39,9 @@ from torch import nn from .attention import (EasyAnimateDiTBlock, HunyuanDiTBlock, SelfAttentionTemporalTransformerBlock, TemporalTransformerBlock, zero_module) -from .embeddings import HunyuanCombinedTimestepTextSizeStyleEmbedding, TimePositionalEncoding -from .norm import AdaLayerNormSingle +from .embeddings import (HunyuanCombinedTimestepTextSizeStyleEmbedding, + TimePositionalEncoding) +from .norm import AdaLayerNormSingle, EasyAnimateRMSNorm from .patch import (CasualPatchEmbed3D, PatchEmbed3D, PatchEmbedF3D, TemporalUpsampler3D, UnPatch1D) from .resampler import Resampler @@ -142,6 +143,7 @@ class Transformer3DModel(ModelMixin, ConfigMixin): norm_eps: float = 1e-5, attention_type: str = "default", caption_channels: int = None, + n_query=8, # block type basic_block_type: str = "motionmodule", # enable_uvit @@ -168,6 +170,8 @@ class Transformer3DModel(ModelMixin, ConfigMixin): after_norm = False, resize_inpaint_mask_directly: bool = False, enable_clip_in_inpaint: bool = True, + position_of_clip_embedding: str = "head", + enable_zero_in_inpaint: bool = False, enable_text_attention_mask: bool = True, add_noise_in_inpaint_model: bool = False, ): @@ -192,6 +196,7 @@ class Transformer3DModel(ModelMixin, ConfigMixin): self.time_patch_size = self.patch_size if time_patch_size is None else time_patch_size interpolation_scale = self.config.sample_size // 64 # => 64 (= 512 pixart) has interpolation scale 1 interpolation_scale = max(interpolation_scale, 1) + self.n_query = n_query if self.casual_3d: self.pos_embed = CasualPatchEmbed3D( @@ -397,16 +402,22 @@ class Transformer3DModel(ModelMixin, ConfigMixin): def forward( self, hidden_states: torch.Tensor, + timestep: Optional[torch.LongTensor] = None, + timestep_cond = None, + encoder_hidden_states: Optional[torch.Tensor] = None, + text_embedding_mask: Optional[torch.Tensor] = None, + encoder_hidden_states_t5: Optional[torch.Tensor] = None, + text_embedding_mask_t5: Optional[torch.Tensor] = None, + image_meta_size = None, + style = None, + image_rotary_emb: Optional[torch.Tensor] = None, inpaint_latents: torch.Tensor = None, control_latents: torch.Tensor = None, - encoder_hidden_states: Optional[torch.Tensor] = None, - clip_encoder_hidden_states: Optional[torch.Tensor] = None, - timestep: Optional[torch.LongTensor] = None, added_cond_kwargs: Dict[str, torch.Tensor] = None, class_labels: Optional[torch.LongTensor] = None, cross_attention_kwargs: Dict[str, Any] = None, attention_mask: Optional[torch.Tensor] = None, - encoder_attention_mask: Optional[torch.Tensor] = None, + clip_encoder_hidden_states: Optional[torch.Tensor] = None, clip_attention_mask: Optional[torch.Tensor] = None, return_dict: bool = True, ): @@ -432,7 +443,7 @@ class Transformer3DModel(ModelMixin, ConfigMixin): An attention mask of shape `(batch, key_tokens)` is applied to `encoder_hidden_states`. If `1` the mask is kept, otherwise if `0` it is discarded. Mask will be converted into a bias, which adds large negative values to the attention scores corresponding to "discard" tokens. - encoder_attention_mask ( `torch.Tensor`, *optional*): + text_embedding_mask ( `torch.Tensor`, *optional*): Cross-attention mask applied to `encoder_hidden_states`. Two formats supported: * Mask `(batch, sequence_length)` True = keep, False = discard. @@ -466,11 +477,12 @@ class Transformer3DModel(ModelMixin, ConfigMixin): attention_mask = (1 - attention_mask.to(hidden_states.dtype)) * -10000.0 attention_mask = attention_mask.unsqueeze(1) + text_embedding_mask = text_embedding_mask.squeeze(1) if clip_attention_mask is not None: - encoder_attention_mask = torch.cat([encoder_attention_mask, clip_attention_mask], dim=1) + text_embedding_mask = torch.cat([text_embedding_mask, clip_attention_mask], dim=1) # convert encoder_attention_mask to a bias the same way we do for attention_mask - if encoder_attention_mask is not None and encoder_attention_mask.ndim == 2: - encoder_attention_mask = (1 - encoder_attention_mask.to(encoder_hidden_states.dtype)) * -10000.0 + if text_embedding_mask is not None and text_embedding_mask.ndim == 2: + encoder_attention_mask = (1 - text_embedding_mask.to(encoder_hidden_states.dtype)) * -10000.0 encoder_attention_mask = encoder_attention_mask.unsqueeze(1) if inpaint_latents is not None: @@ -532,7 +544,7 @@ class Transformer3DModel(ModelMixin, ConfigMixin): video_length = (video_length - 1) * 2 + 1 hidden_states = rearrange(hidden_states, "b c f h w -> b (f h w) c", f=video_length, h=height, w=width) - if self.training and self.gradient_checkpointing: + if torch.is_grad_enabled() and self.gradient_checkpointing: def create_custom_forward(module, return_dict=None): def custom_forward(*inputs): @@ -658,8 +670,10 @@ class Transformer3DModel(ModelMixin, ConfigMixin): if low_cpu_mem_usage: try: import re + + from diffusers.models.modeling_utils import \ + load_model_dict_into_meta from diffusers.utils import is_accelerate_available - from diffusers.models.modeling_utils import load_model_dict_into_meta if is_accelerate_available(): import accelerate @@ -828,6 +842,7 @@ class HunyuanTransformer3DModel(ModelMixin, ConfigMixin): after_norm = False, resize_inpaint_mask_directly: bool = False, enable_clip_in_inpaint: bool = True, + position_of_clip_embedding: str = "full", enable_text_attention_mask: bool = True, add_noise_in_inpaint_model: bool = False, ): @@ -968,6 +983,7 @@ class HunyuanTransformer3DModel(ModelMixin, ConfigMixin): control_latents: torch.Tensor = None, clip_encoder_hidden_states: Optional[torch.Tensor]=None, clip_attention_mask: Optional[torch.Tensor]=None, + added_cond_kwargs: Dict[str, torch.Tensor] = None, return_dict=True, ): """ @@ -1040,7 +1056,7 @@ class HunyuanTransformer3DModel(ModelMixin, ConfigMixin): for layer, block in enumerate(self.blocks): if layer > self.config.num_layers // 2: skip = skips.pop() - if self.training and self.gradient_checkpointing: + if torch.is_grad_enabled() and self.gradient_checkpointing: def create_custom_forward(module, return_dict=None): def custom_forward(*inputs): @@ -1082,7 +1098,7 @@ class HunyuanTransformer3DModel(ModelMixin, ConfigMixin): **kwargs ) # (N, L, D) else: - if self.training and self.gradient_checkpointing: + if torch.is_grad_enabled() and self.gradient_checkpointing: def create_custom_forward(module, return_dict=None): def custom_forward(*inputs): @@ -1165,8 +1181,10 @@ class HunyuanTransformer3DModel(ModelMixin, ConfigMixin): if low_cpu_mem_usage: try: import re + + from diffusers.models.modeling_utils import \ + load_model_dict_into_meta from diffusers.utils import is_accelerate_available - from diffusers.models.modeling_utils import load_model_dict_into_meta if is_accelerate_available(): import accelerate @@ -1297,8 +1315,10 @@ class EasyAnimateTransformer3DModel(ModelMixin, ConfigMixin): freq_shift: int = 0, num_layers: int = 30, mmdit_layers: int = 10000, + swa_layers: list = None, dropout: float = 0.0, time_embed_dim: int = 512, + add_norm_text_encoder: bool = False, text_embed_dim: int = 4096, text_embed_dim_t5: int = 4096, norm_eps: float = 1e-5, @@ -1310,8 +1330,10 @@ class EasyAnimateTransformer3DModel(ModelMixin, ConfigMixin): after_norm = False, resize_inpaint_mask_directly: bool = False, enable_clip_in_inpaint: bool = True, + position_of_clip_embedding: str = "full", enable_text_attention_mask: bool = True, add_noise_in_inpaint_model: bool = False, + add_ref_latent_in_control_model: bool = False, ): super().__init__() self.num_heads = num_attention_heads @@ -1330,8 +1352,20 @@ class EasyAnimateTransformer3DModel(ModelMixin, ConfigMixin): self.proj = nn.Conv2d( in_channels, self.inner_dim, kernel_size=(patch_size, patch_size), stride=patch_size, bias=True ) - self.text_proj = nn.Linear(text_embed_dim, self.inner_dim) - self.text_proj_t5 = nn.Linear(text_embed_dim_t5, self.inner_dim) + if not add_norm_text_encoder: + self.text_proj = nn.Linear(text_embed_dim, self.inner_dim) + if text_embed_dim_t5 is not None: + self.text_proj_t5 = nn.Linear(text_embed_dim_t5, self.inner_dim) + else: + self.text_proj = nn.Sequential( + EasyAnimateRMSNorm(text_embed_dim), + nn.Linear(text_embed_dim, self.inner_dim) + ) + if text_embed_dim_t5 is not None: + self.text_proj_t5 = nn.Sequential( + EasyAnimateRMSNorm(text_embed_dim), + nn.Linear(text_embed_dim_t5, self.inner_dim) + ) if ref_channels is not None: self.ref_proj = nn.Conv2d( @@ -1343,24 +1377,45 @@ class EasyAnimateTransformer3DModel(ModelMixin, ConfigMixin): if clip_channels is not None: self.clip_proj = nn.Linear(clip_channels, self.inner_dim) - - self.transformer_blocks = nn.ModuleList( - [ - EasyAnimateDiTBlock( - dim=self.inner_dim, - num_attention_heads=num_attention_heads, - attention_head_dim=attention_head_dim, - time_embed_dim=time_embed_dim, - dropout=dropout, - activation_fn=activation_fn, - norm_elementwise_affine=norm_elementwise_affine, - norm_eps=norm_eps, - after_norm=after_norm, - is_mmdit_block=True if _ < mmdit_layers else False, - ) - for _ in range(num_layers) - ] - ) + + self.swa_layers = swa_layers + if swa_layers is not None: + self.transformer_blocks = nn.ModuleList( + [ + EasyAnimateDiTBlock( + dim=self.inner_dim, + num_attention_heads=num_attention_heads, + attention_head_dim=attention_head_dim, + time_embed_dim=time_embed_dim, + dropout=dropout, + activation_fn=activation_fn, + norm_elementwise_affine=norm_elementwise_affine, + norm_eps=norm_eps, + after_norm=after_norm, + is_mmdit_block=True if index < mmdit_layers else False, + is_swa=True if index in swa_layers else False, + ) + for index in range(num_layers) + ] + ) + else: + self.transformer_blocks = nn.ModuleList( + [ + EasyAnimateDiTBlock( + dim=self.inner_dim, + num_attention_heads=num_attention_heads, + attention_head_dim=attention_head_dim, + time_embed_dim=time_embed_dim, + dropout=dropout, + activation_fn=activation_fn, + norm_elementwise_affine=norm_elementwise_affine, + norm_eps=norm_eps, + after_norm=after_norm, + is_mmdit_block=True if _ < mmdit_layers else False, + ) + for _ in range(num_layers) + ] + ) self.norm_final = nn.LayerNorm(self.inner_dim, norm_eps, norm_elementwise_affine) # 5. Output blocks @@ -1395,6 +1450,7 @@ class EasyAnimateTransformer3DModel(ModelMixin, ConfigMixin): ref_latents: Optional[torch.Tensor] = None, clip_encoder_hidden_states: Optional[torch.Tensor] = None, clip_attention_mask: Optional[torch.Tensor] = None, + added_cond_kwargs: Dict[str, torch.Tensor] = None, return_dict=True, ): batch_size, channels, video_length, height, width = hidden_states.size() @@ -1446,7 +1502,7 @@ class EasyAnimateTransformer3DModel(ModelMixin, ConfigMixin): # 4. Transformer blocks for i, block in enumerate(self.transformer_blocks): - if self.training and self.gradient_checkpointing: + if torch.is_grad_enabled() and self.gradient_checkpointing: def create_custom_forward(module, return_dict=None): def custom_forward(*inputs): if return_dict is not None: @@ -1463,6 +1519,9 @@ class EasyAnimateTransformer3DModel(ModelMixin, ConfigMixin): encoder_hidden_states, temb, image_rotary_emb, + video_length, + height // self.patch_size, + width // self.patch_size, **ckpt_kwargs, ) else: @@ -1471,6 +1530,9 @@ class EasyAnimateTransformer3DModel(ModelMixin, ConfigMixin): encoder_hidden_states=encoder_hidden_states, temb=temb, image_rotary_emb=image_rotary_emb, + num_frames=video_length, + height=height // self.patch_size, + width=width // self.patch_size ) hidden_states = torch.cat([encoder_hidden_states, hidden_states], dim=1) @@ -1512,8 +1574,10 @@ class EasyAnimateTransformer3DModel(ModelMixin, ConfigMixin): if low_cpu_mem_usage: try: import re + + from diffusers.models.modeling_utils import \ + load_model_dict_into_meta from diffusers.utils import is_accelerate_available - from diffusers.models.modeling_utils import load_model_dict_into_meta if is_accelerate_available(): import accelerate diff --git a/easyanimate/pipeline/pipeline_easyanimate.py b/easyanimate/pipeline/pipeline_easyanimate.py index 4e0ce6c..79b84f6 100644 --- a/easyanimate/pipeline/pipeline_easyanimate.py +++ b/easyanimate/pipeline/pipeline_easyanimate.py @@ -1,4 +1,4 @@ -# Copyright 2023 PixArt-Alpha Authors and The HuggingFace Team. All rights reserved. +# Copyright 2024 EasyAnimate Authors and The HuggingFace Team. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,61 +12,113 @@ # See the License for the specific language governing permissions and # limitations under the License. -import copy -import html import inspect -import re -import urllib.parse as ul from dataclasses import dataclass -from typing import Callable, List, Optional, Tuple, Union +from typing import Callable, Dict, List, Optional, Tuple, Union import numpy as np import torch -from diffusers import DiffusionPipeline, ImagePipelineOutput +import torch.nn.functional as F +from diffusers import DiffusionPipeline +from diffusers.callbacks import MultiPipelineCallbacks, PipelineCallback from diffusers.image_processor import VaeImageProcessor -from diffusers.models import AutoencoderKL -from diffusers.schedulers import DPMSolverMultistepScheduler +from diffusers.models import AutoencoderKL, HunyuanDiT2DModel +from diffusers.models.embeddings import (get_2d_rotary_pos_embed, + get_3d_rotary_pos_embed) +from diffusers.pipelines.pipeline_utils import DiffusionPipeline +from diffusers.pipelines.stable_diffusion import StableDiffusionPipelineOutput +from diffusers.pipelines.stable_diffusion.safety_checker import \ + StableDiffusionSafetyChecker +from diffusers.schedulers import DDIMScheduler, FlowMatchEulerDiscreteScheduler from diffusers.utils import (BACKENDS_MAPPING, BaseOutput, deprecate, - is_bs4_available, is_ftfy_available, logging, + is_bs4_available, is_ftfy_available, + is_torch_xla_available, logging, replace_example_docstring) from diffusers.utils.torch_utils import randn_tensor from einops import rearrange +from PIL import Image from tqdm import tqdm -from transformers import T5EncoderModel, T5Tokenizer +from transformers import (BertModel, BertTokenizer, CLIPImageProcessor, + Qwen2Tokenizer, Qwen2VLForConditionalGeneration, + T5EncoderModel, T5Tokenizer) + +from ..models import AutoencoderKLMagvit, EasyAnimateTransformer3DModel +from .pipeline_easyanimate_inpaint import EasyAnimatePipelineOutput + +if is_torch_xla_available(): + import torch_xla.core.xla_model as xm + + XLA_AVAILABLE = True +else: + XLA_AVAILABLE = False -from ..models.transformer3d import Transformer3DModel logger = logging.get_logger(__name__) # pylint: disable=invalid-name -if is_bs4_available(): - from bs4 import BeautifulSoup - -if is_ftfy_available(): - import ftfy - - EXAMPLE_DOC_STRING = """ Examples: - ```py + ```python >>> import torch >>> from diffusers import EasyAnimatePipeline + >>> from diffusers.utils import export_to_video - >>> # You can replace the checkpoint id with "PixArt-alpha/PixArt-XL-2-512x512" too. - >>> pipe = EasyAnimatePipeline.from_pretrained("PixArt-alpha/PixArt-XL-2-1024-MS", torch_dtype=torch.float16) - >>> # Enable memory optimizations. - >>> pipe.enable_model_cpu_offload() - - >>> prompt = "A small cactus with a happy face in the Sahara desert." - >>> image = pipe(prompt).images[0] + >>> # Models: "alibaba-pai/EasyAnimateV5.1-12b-zh" or "alibaba-pai/EasyAnimateV5.1-7b-zh" + >>> pipe = EasyAnimatePipeline.from_pretrained("alibaba-pai/EasyAnimateV5.1-7b-zh", torch_dtype=torch.float16).to("cuda") + >>> prompt = ( + ... "A panda, dressed in a small, red jacket and a tiny hat, sits on a wooden stool in a serene bamboo forest. " + ... "The panda's fluffy paws strum a miniature acoustic guitar, producing soft, melodic tunes. Nearby, a few other " + ... "pandas gather, watching curiously and some clapping in rhythm. Sunlight filters through the tall bamboo, " + ... "casting a gentle glow on the scene. The panda's face is expressive, showing concentration and joy as it plays. " + ... "The background includes a small, flowing stream and vibrant green foliage, enhancing the peaceful and magical " + ... "atmosphere of this unique musical performance." + ... ) + >>> video = pipe(prompt=prompt, guidance_scale=6, num_inference_steps=50).sample[0] + >>> export_to_video(video, "output.mp4", fps=8) ``` """ + +# Similar to diffusers.pipelines.hunyuandit.pipeline_hunyuandit.get_resize_crop_region_for_grid +def get_resize_crop_region_for_grid(src, tgt_width, tgt_height): + tw = tgt_width + th = tgt_height + h, w = src + r = h / w + if r > (th / tw): + resize_height = th + resize_width = int(round(th / h * w)) + else: + resize_width = tw + resize_height = int(round(tw / w * h)) + + crop_top = int(round((th - resize_height) / 2.0)) + crop_left = int(round((tw - resize_width) / 2.0)) + + return (crop_top, crop_left), (crop_top + resize_height, crop_left + resize_width) + + +# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.rescale_noise_cfg +def rescale_noise_cfg(noise_cfg, noise_pred_text, guidance_rescale=0.0): + """ + Rescale `noise_cfg` according to `guidance_rescale`. Based on findings of [Common Diffusion Noise Schedules and + Sample Steps are Flawed](https://arxiv.org/pdf/2305.08891.pdf). See Section 3.4 + """ + std_text = noise_pred_text.std(dim=list(range(1, noise_pred_text.ndim)), keepdim=True) + std_cfg = noise_cfg.std(dim=list(range(1, noise_cfg.ndim)), keepdim=True) + # rescale the results from guidance (fixes overexposure) + noise_pred_rescaled = noise_cfg * (std_text / std_cfg) + # mix with the original results from guidance by factor guidance_rescale to avoid "plain looking" images + noise_cfg = guidance_rescale * noise_pred_rescaled + (1 - guidance_rescale) * noise_cfg + return noise_cfg + + # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.retrieve_timesteps def retrieve_timesteps( scheduler, num_inference_steps: Optional[int] = None, device: Optional[Union[str, torch.device]] = None, timesteps: Optional[List[int]] = None, + sigmas: Optional[List[float]] = None, **kwargs, ): """ @@ -77,19 +129,23 @@ def retrieve_timesteps( scheduler (`SchedulerMixin`): The scheduler to get timesteps from. num_inference_steps (`int`): - The number of diffusion steps used when generating samples with a pre-trained model. If used, - `timesteps` must be `None`. + The number of diffusion steps used when generating samples with a pre-trained model. If used, `timesteps` + must be `None`. device (`str` or `torch.device`, *optional*): The device to which the timesteps should be moved to. If `None`, the timesteps are not moved. timesteps (`List[int]`, *optional*): - Custom timesteps used to support arbitrary spacing between timesteps. If `None`, then the default - timestep spacing strategy of the scheduler is used. If `timesteps` is passed, `num_inference_steps` - must be `None`. + Custom timesteps used to override the timestep spacing strategy of the scheduler. If `timesteps` is passed, + `num_inference_steps` and `sigmas` must be `None`. + sigmas (`List[float]`, *optional*): + Custom sigmas used to override the timestep spacing strategy of the scheduler. If `sigmas` is passed, + `num_inference_steps` and `timesteps` must be `None`. Returns: `Tuple[torch.Tensor, int]`: A tuple where the first element is the timestep schedule from the scheduler and the second element is the number of inference steps. """ + if timesteps is not None and sigmas is not None: + raise ValueError("Only one of `timesteps` or `sigmas` can be passed. Please choose one to set custom values") if timesteps is not None: accepts_timesteps = "timesteps" in set(inspect.signature(scheduler.set_timesteps).parameters.keys()) if not accepts_timesteps: @@ -100,85 +156,113 @@ def retrieve_timesteps( scheduler.set_timesteps(timesteps=timesteps, device=device, **kwargs) timesteps = scheduler.timesteps num_inference_steps = len(timesteps) + elif sigmas is not None: + accept_sigmas = "sigmas" in set(inspect.signature(scheduler.set_timesteps).parameters.keys()) + if not accept_sigmas: + raise ValueError( + f"The current scheduler class {scheduler.__class__}'s `set_timesteps` does not support custom" + f" sigmas schedules. Please check whether you are using the correct scheduler." + ) + scheduler.set_timesteps(sigmas=sigmas, device=device, **kwargs) + timesteps = scheduler.timesteps + num_inference_steps = len(timesteps) else: scheduler.set_timesteps(num_inference_steps, device=device, **kwargs) timesteps = scheduler.timesteps return timesteps, num_inference_steps -@dataclass -class EasyAnimatePipelineOutput(BaseOutput): - videos: Union[torch.Tensor, np.ndarray] class EasyAnimatePipeline(DiffusionPipeline): r""" - Pipeline for text-to-image generation using PixArt-Alpha. + Pipeline for text-to-video generation using EasyAnimate. This model inherits from [`DiffusionPipeline`]. Check the superclass documentation for the generic methods the library implements for all the pipelines (such as downloading or saving, running on a particular device, etc.) - Args: - vae ([`AutoencoderKL`]): - Variational Auto-Encoder (VAE) Model to encode and decode images to and from latent representations. - text_encoder ([`T5EncoderModel`]): - Frozen text-encoder. PixArt-Alpha uses - [T5](https://huggingface.co/docs/transformers/model_doc/t5#transformers.T5EncoderModel), specifically the - [t5-v1_1-xxl](https://huggingface.co/PixArt-alpha/PixArt-alpha/tree/main/t5-v1_1-xxl) variant. - tokenizer (`T5Tokenizer`): - Tokenizer of class - [T5Tokenizer](https://huggingface.co/docs/transformers/model_doc/t5#transformers.T5Tokenizer). - transformer ([`Transformer3DModel`]): - A text conditioned `Transformer3DModel` to denoise the encoded image latents. - scheduler ([`SchedulerMixin`]): - A scheduler to be used in combination with `transformer` to denoise the encoded image latents. - """ - bad_punct_regex = re.compile( - r"[" + "#®•©™&@·º½¾¿¡§~" + "\)" + "\(" + "\]" + "\[" + "\}" + "\{" + "\|" + "\\" + "\/" + "\*" + r"]{1,}" - ) # noqa + EasyAnimate uses one text encoder [qwen2 vl](https://huggingface.co/Qwen/Qwen2-VL-7B-Instruct) in V5.1. + EasyAnimate uses two text encoders: [mT5](https://huggingface.co/google/mt5-base) and [bilingual CLIP](fine-tuned by + HunyuanDiT team) in V5. - _optional_components = ["tokenizer", "text_encoder"] - model_cpu_offload_seq = "text_encoder->transformer->vae" + Args: + vae ([`AutoencoderKLMagvit`]): + Variational Auto-Encoder (VAE) Model to encode and decode video to and from latent representations. + text_encoder (Optional[`~transformers.Qwen2VLForConditionalGeneration`, `~transformers.BertModel`]): + EasyAnimate uses [qwen2 vl](https://huggingface.co/Qwen/Qwen2-VL-7B-Instruct) in V5.1. + EasyAnimate uses [bilingual CLIP](https://huggingface.co/Tencent-Hunyuan/HunyuanDiT-v1.2-Diffusers) in V5. + tokenizer (Optional[`~transformers.Qwen2Tokenizer`, `~transformers.BertTokenizer`]): + A `Qwen2Tokenizer` or `BertTokenizer` to tokenize text. + transformer ([`EasyAnimateTransformer3DModel`]): + The EasyAnimate model designed by EasyAnimate Team. + text_encoder_2 (`T5EncoderModel`): + EasyAnimate does not use text_encoder_2 in V5.1. + EasyAnimate uses [mT5](https://huggingface.co/google/mt5-base) embedder in V5. + tokenizer_2 (`T5Tokenizer`): + The tokenizer for the mT5 embedder. + scheduler ([`FlowMatchEulerDiscreteScheduler`]): + A scheduler to be used in combination with EasyAnimate to denoise the encoded image latents. + """ + + model_cpu_offload_seq = "text_encoder->text_encoder_2->transformer->vae" + _optional_components = [ + "text_encoder_2", + "tokenizer_2", + "text_encoder", + "tokenizer", + ] + _callback_tensor_inputs = [ + "latents", + "prompt_embeds", + "negative_prompt_embeds", + "prompt_embeds_2", + "negative_prompt_embeds_2", + ] def __init__( self, - tokenizer: T5Tokenizer, - text_encoder: T5EncoderModel, - vae: AutoencoderKL, - transformer: Transformer3DModel, - scheduler: DPMSolverMultistepScheduler, + vae: AutoencoderKLMagvit, + text_encoder: Union[Qwen2VLForConditionalGeneration, BertModel], + tokenizer: Union[Qwen2Tokenizer, BertTokenizer], + text_encoder_2: Optional[Union[T5EncoderModel, Qwen2VLForConditionalGeneration]], + tokenizer_2: Optional[Union[T5Tokenizer, Qwen2Tokenizer]], + transformer: EasyAnimateTransformer3DModel, + scheduler: FlowMatchEulerDiscreteScheduler, ): super().__init__() self.register_modules( - tokenizer=tokenizer, text_encoder=text_encoder, vae=vae, transformer=transformer, scheduler=scheduler + vae=vae, + text_encoder=text_encoder, + text_encoder_2=text_encoder_2, + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + transformer=transformer, + scheduler=scheduler, ) self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1) - self.image_processor = VaeImageProcessor(vae_scale_factor=self.vae_scale_factor) - - # Adapted from https://github.com/PixArt-alpha/PixArt-alpha/blob/master/diffusion/model/utils.py - def mask_text_embeddings(self, emb, mask): - if emb.shape[0] == 1: - keep_index = mask.sum().item() - return emb[:, :, :keep_index, :], keep_index - else: - masked_feature = emb * mask[:, None, :, None] - return masked_feature, emb.shape[2] - # Adapted from diffusers.pipelines.deepfloyd_if.pipeline_if.encode_prompt + def enable_sequential_cpu_offload(self, *args, **kwargs): + super().enable_sequential_cpu_offload(*args, **kwargs) + if hasattr(self.transformer, "clip_projection") and self.transformer.clip_projection is not None: + import accelerate + accelerate.hooks.remove_hook_from_module(self.transformer.clip_projection, recurse=True) + self.transformer.clip_projection = self.transformer.clip_projection.to("cuda") + def encode_prompt( self, - prompt: Union[str, List[str]], - do_classifier_free_guidance: bool = True, - negative_prompt: str = "", + prompt: str, + device: torch.device, + dtype: torch.dtype, num_images_per_prompt: int = 1, - device: Optional[torch.device] = None, - prompt_embeds: Optional[torch.FloatTensor] = None, - negative_prompt_embeds: Optional[torch.FloatTensor] = None, - prompt_attention_mask: Optional[torch.FloatTensor] = None, - negative_prompt_attention_mask: Optional[torch.FloatTensor] = None, - clean_caption: bool = False, - max_sequence_length: int = 120, - **kwargs, + do_classifier_free_guidance: bool = True, + negative_prompt: Optional[str] = None, + prompt_embeds: Optional[torch.Tensor] = None, + negative_prompt_embeds: Optional[torch.Tensor] = None, + prompt_attention_mask: Optional[torch.Tensor] = None, + negative_prompt_attention_mask: Optional[torch.Tensor] = None, + max_sequence_length: Optional[int] = None, + text_encoder_index: int = 0, + actual_max_sequence_length: int = 256 ): r""" Encodes the prompt into text encoder hidden states. @@ -186,33 +270,46 @@ class EasyAnimatePipeline(DiffusionPipeline): Args: prompt (`str` or `List[str]`, *optional*): prompt to be encoded - negative_prompt (`str` or `List[str]`, *optional*): - The prompt not to guide the image generation. If not defined, one has to pass `negative_prompt_embeds` - instead. Ignored when not using guidance (i.e., ignored if `guidance_scale` is less than `1`). For - PixArt-Alpha, this should be "". - do_classifier_free_guidance (`bool`, *optional*, defaults to `True`): - whether to use classifier free guidance or not - num_images_per_prompt (`int`, *optional*, defaults to 1): + device: (`torch.device`): + torch device + dtype (`torch.dtype`): + torch dtype + num_images_per_prompt (`int`): number of images that should be generated per prompt - device: (`torch.device`, *optional*): - torch device to place the resulting embeddings on - prompt_embeds (`torch.FloatTensor`, *optional*): + do_classifier_free_guidance (`bool`): + whether to use classifier free guidance or not + negative_prompt (`str` or `List[str]`, *optional*): + The prompt or prompts not to guide the image generation. If not defined, one has to pass + `negative_prompt_embeds` instead. Ignored when not using guidance (i.e., ignored if `guidance_scale` is + less than `1`). + prompt_embeds (`torch.Tensor`, *optional*): Pre-generated text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting. If not provided, text embeddings will be generated from `prompt` input argument. - negative_prompt_embeds (`torch.FloatTensor`, *optional*): - Pre-generated negative text embeddings. For PixArt-Alpha, it's should be the embeddings of the "" - string. - clean_caption (`bool`, defaults to `False`): - If `True`, the function will preprocess and clean the provided caption before encoding. - max_sequence_length (`int`, defaults to 120): Maximum sequence length to use for the prompt. + negative_prompt_embeds (`torch.Tensor`, *optional*): + Pre-generated negative text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt + weighting. If not provided, negative_prompt_embeds will be generated from `negative_prompt` input + argument. + prompt_attention_mask (`torch.Tensor`, *optional*): + Attention mask for the prompt. Required when `prompt_embeds` is passed directly. + negative_prompt_attention_mask (`torch.Tensor`, *optional*): + Attention mask for the negative prompt. Required when `negative_prompt_embeds` is passed directly. + max_sequence_length (`int`, *optional*): maximum sequence length to use for the prompt. + text_encoder_index (`int`, *optional*): + Index of the text encoder to use. `0` for clip and `1` for T5. """ + tokenizers = [self.tokenizer, self.tokenizer_2] + text_encoders = [self.text_encoder, self.text_encoder_2] - if "mask_feature" in kwargs: - deprecation_message = "The use of `mask_feature` is deprecated. It is no longer used in any computation and that doesn't affect the end results. It will be removed in a future version." - deprecate("mask_feature", "1.0.0", deprecation_message, standard_warn=False) + tokenizer = tokenizers[text_encoder_index] + text_encoder = text_encoders[text_encoder_index] - if device is None: - device = self._execution_device + if max_sequence_length is None: + if text_encoder_index == 0: + max_length = min(self.tokenizer.model_max_length, actual_max_sequence_length) + if text_encoder_index == 1: + max_length = min(self.tokenizer_2.model_max_length, actual_max_sequence_length) + else: + max_length = max_sequence_length if prompt is not None and isinstance(prompt, str): batch_size = 1 @@ -221,74 +318,199 @@ class EasyAnimatePipeline(DiffusionPipeline): else: batch_size = prompt_embeds.shape[0] - # See Section 3.1. of the paper. - max_length = max_sequence_length - if prompt_embeds is None: - prompt = self._text_preprocessing(prompt, clean_caption=clean_caption) - text_inputs = self.tokenizer( - prompt, - padding="max_length", - max_length=max_length, - truncation=True, - add_special_tokens=True, - return_tensors="pt", - ) - text_input_ids = text_inputs.input_ids - untruncated_ids = self.tokenizer(prompt, padding="longest", return_tensors="pt").input_ids + if type(tokenizer) in [BertTokenizer, T5Tokenizer]: + text_inputs = tokenizer( + prompt, + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + return_tensors="pt", + ) + text_input_ids = text_inputs.input_ids + if text_input_ids.shape[-1] > actual_max_sequence_length: + reprompt = tokenizer.batch_decode(text_input_ids[:, :actual_max_sequence_length], skip_special_tokens=True) + text_inputs = tokenizer( + reprompt, + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + return_tensors="pt", + ) + text_input_ids = text_inputs.input_ids + untruncated_ids = tokenizer(prompt, padding="longest", return_tensors="pt").input_ids - if untruncated_ids.shape[-1] >= text_input_ids.shape[-1] and not torch.equal( - text_input_ids, untruncated_ids - ): - removed_text = self.tokenizer.batch_decode(untruncated_ids[:, max_length - 1 : -1]) - logger.warning( - "The following part of your input was truncated because CLIP can only handle sequences up to" - f" {max_length} tokens: {removed_text}" + if untruncated_ids.shape[-1] >= text_input_ids.shape[-1] and not torch.equal( + text_input_ids, untruncated_ids + ): + _actual_max_sequence_length = min(tokenizer.model_max_length, actual_max_sequence_length) + removed_text = tokenizer.batch_decode(untruncated_ids[:, _actual_max_sequence_length - 1 : -1]) + logger.warning( + "The following part of your input was truncated because CLIP can only handle sequences up to" + f" {_actual_max_sequence_length} tokens: {removed_text}" + ) + + prompt_attention_mask = text_inputs.attention_mask.to(device) + + if self.transformer.config.enable_text_attention_mask: + prompt_embeds = text_encoder( + text_input_ids.to(device), + attention_mask=prompt_attention_mask, + ) + else: + prompt_embeds = text_encoder( + text_input_ids.to(device) + ) + prompt_embeds = prompt_embeds[0] + prompt_attention_mask = prompt_attention_mask.repeat(num_images_per_prompt, 1) + else: + if prompt is not None and isinstance(prompt, str): + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": prompt}], + } + ] + else: + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": _prompt}], + } for _prompt in prompt + ] + text = tokenizer.apply_chat_template( + messages, tokenize=False, add_generation_prompt=True ) - prompt_attention_mask = text_inputs.attention_mask - prompt_attention_mask = prompt_attention_mask.to(device) - - prompt_embeds = self.text_encoder(text_input_ids.to(device), attention_mask=prompt_attention_mask) - prompt_embeds = prompt_embeds[0] - - if self.text_encoder is not None: - dtype = self.text_encoder.dtype - elif self.transformer is not None: - dtype = self.transformer.dtype - else: - dtype = None + text_inputs = tokenizer( + text=[text], + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + padding_side="right", + return_tensors="pt", + ) + text_inputs = text_inputs.to(text_encoder.device) + text_input_ids = text_inputs.input_ids + prompt_attention_mask = text_inputs.attention_mask + if self.transformer.config.enable_text_attention_mask: + # Inference: Generation of the output + prompt_embeds = text_encoder( + input_ids=text_input_ids, + attention_mask=prompt_attention_mask, + output_hidden_states=True).hidden_states[-2] + else: + raise ValueError("LLM needs attention_mask") + prompt_attention_mask = prompt_attention_mask.repeat(num_images_per_prompt, 1) + prompt_embeds = prompt_embeds.to(dtype=dtype, device=device) bs_embed, seq_len, _ = prompt_embeds.shape - # duplicate text embeddings and attention mask for each generation per prompt, using mps friendly method + # duplicate text embeddings for each generation per prompt, using mps friendly method prompt_embeds = prompt_embeds.repeat(1, num_images_per_prompt, 1) prompt_embeds = prompt_embeds.view(bs_embed * num_images_per_prompt, seq_len, -1) - prompt_attention_mask = prompt_attention_mask.view(bs_embed, -1) - prompt_attention_mask = prompt_attention_mask.repeat(num_images_per_prompt, 1) + prompt_attention_mask = prompt_attention_mask.to(device=device) # get unconditional embeddings for classifier free guidance if do_classifier_free_guidance and negative_prompt_embeds is None: - uncond_tokens = [negative_prompt] * batch_size - uncond_tokens = self._text_preprocessing(uncond_tokens, clean_caption=clean_caption) - max_length = prompt_embeds.shape[1] - uncond_input = self.tokenizer( - uncond_tokens, - padding="max_length", - max_length=max_length, - truncation=True, - return_attention_mask=True, - add_special_tokens=True, - return_tensors="pt", - ) - negative_prompt_attention_mask = uncond_input.attention_mask - negative_prompt_attention_mask = negative_prompt_attention_mask.to(device) + if type(tokenizer) in [BertTokenizer, T5Tokenizer]: + uncond_tokens: List[str] + if negative_prompt is None: + uncond_tokens = [""] * batch_size + elif prompt is not None and type(prompt) is not type(negative_prompt): + raise TypeError( + f"`negative_prompt` should be the same type to `prompt`, but got {type(negative_prompt)} !=" + f" {type(prompt)}." + ) + elif isinstance(negative_prompt, str): + uncond_tokens = [negative_prompt] + elif batch_size != len(negative_prompt): + raise ValueError( + f"`negative_prompt`: {negative_prompt} has batch size {len(negative_prompt)}, but `prompt`:" + f" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches" + " the batch size of `prompt`." + ) + else: + uncond_tokens = negative_prompt - negative_prompt_embeds = self.text_encoder( - uncond_input.input_ids.to(device), attention_mask=negative_prompt_attention_mask - ) - negative_prompt_embeds = negative_prompt_embeds[0] + max_length = prompt_embeds.shape[1] + uncond_input = tokenizer( + uncond_tokens, + padding="max_length", + max_length=max_length, + truncation=True, + return_tensors="pt", + ) + uncond_input_ids = uncond_input.input_ids + if uncond_input_ids.shape[-1] > actual_max_sequence_length: + reuncond_tokens = tokenizer.batch_decode(uncond_input_ids[:, :actual_max_sequence_length], skip_special_tokens=True) + uncond_input = tokenizer( + reuncond_tokens, + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + return_tensors="pt", + ) + uncond_input_ids = uncond_input.input_ids + + negative_prompt_attention_mask = uncond_input.attention_mask.to(device) + if self.transformer.config.enable_text_attention_mask: + negative_prompt_embeds = text_encoder( + uncond_input.input_ids.to(device), + attention_mask=negative_prompt_attention_mask, + ) + else: + negative_prompt_embeds = text_encoder( + uncond_input.input_ids.to(device) + ) + negative_prompt_embeds = negative_prompt_embeds[0] + negative_prompt_attention_mask = negative_prompt_attention_mask.repeat(num_images_per_prompt, 1) + else: + if negative_prompt is not None and isinstance(negative_prompt, str): + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": negative_prompt}], + } + ] + else: + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": _negative_prompt}], + } for _negative_prompt in negative_prompt + ] + text = tokenizer.apply_chat_template( + messages, tokenize=False, add_generation_prompt=True + ) + + text_inputs = tokenizer( + text=[text], + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + padding_side="right", + return_tensors="pt", + ) + text_inputs = text_inputs.to(text_encoder.device) + + text_input_ids = text_inputs.input_ids + negative_prompt_attention_mask = text_inputs.attention_mask + if self.transformer.config.enable_text_attention_mask: + # Inference: Generation of the output + negative_prompt_embeds = text_encoder( + input_ids=text_input_ids, + attention_mask=negative_prompt_attention_mask, + output_hidden_states=True).hidden_states[-2] + else: + raise ValueError("LLM needs attention_mask") + negative_prompt_attention_mask = negative_prompt_attention_mask.repeat(num_images_per_prompt, 1) if do_classifier_free_guidance: # duplicate unconditional embeddings for each generation per prompt, using mps friendly method @@ -298,14 +520,9 @@ class EasyAnimatePipeline(DiffusionPipeline): negative_prompt_embeds = negative_prompt_embeds.repeat(1, num_images_per_prompt, 1) negative_prompt_embeds = negative_prompt_embeds.view(batch_size * num_images_per_prompt, seq_len, -1) - - negative_prompt_attention_mask = negative_prompt_attention_mask.view(bs_embed, -1) - negative_prompt_attention_mask = negative_prompt_attention_mask.repeat(num_images_per_prompt, 1) - else: - negative_prompt_embeds = None - negative_prompt_attention_mask = None - - return prompt_embeds, prompt_attention_mask, negative_prompt_embeds, negative_prompt_attention_mask + negative_prompt_attention_mask = negative_prompt_attention_mask.to(device=device) + + return prompt_embeds, negative_prompt_embeds, prompt_attention_mask, negative_prompt_attention_mask # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.prepare_extra_step_kwargs def prepare_extra_step_kwargs(self, generator, eta): @@ -330,20 +547,25 @@ class EasyAnimatePipeline(DiffusionPipeline): prompt, height, width, - negative_prompt, - callback_steps, + negative_prompt=None, prompt_embeds=None, negative_prompt_embeds=None, + prompt_attention_mask=None, + negative_prompt_attention_mask=None, + prompt_embeds_2=None, + negative_prompt_embeds_2=None, + prompt_attention_mask_2=None, + negative_prompt_attention_mask_2=None, + callback_on_step_end_tensor_inputs=None, ): - if height % 8 != 0 or width % 8 != 0: + if height % 16 != 0 or width % 16 != 0: raise ValueError(f"`height` and `width` have to be divisible by 8 but are {height} and {width}.") - if (callback_steps is None) or ( - callback_steps is not None and (not isinstance(callback_steps, int) or callback_steps <= 0) + if callback_on_step_end_tensor_inputs is not None and not all( + k in self._callback_tensor_inputs for k in callback_on_step_end_tensor_inputs ): raise ValueError( - f"`callback_steps` has to be a positive integer but is {callback_steps} of type" - f" {type(callback_steps)}." + f"`callback_on_step_end_tensor_inputs` has to be in {self._callback_tensor_inputs}, but found {[k for k in callback_on_step_end_tensor_inputs if k not in self._callback_tensor_inputs]}" ) if prompt is not None and prompt_embeds is not None: @@ -355,14 +577,18 @@ class EasyAnimatePipeline(DiffusionPipeline): raise ValueError( "Provide either `prompt` or `prompt_embeds`. Cannot leave both `prompt` and `prompt_embeds` undefined." ) + elif prompt is None and prompt_embeds_2 is None: + raise ValueError( + "Provide either `prompt` or `prompt_embeds_2`. Cannot leave both `prompt` and `prompt_embeds_2` undefined." + ) elif prompt is not None and (not isinstance(prompt, str) and not isinstance(prompt, list)): raise ValueError(f"`prompt` has to be of type `str` or `list` but is {type(prompt)}") - if prompt is not None and negative_prompt_embeds is not None: - raise ValueError( - f"Cannot forward both `prompt`: {prompt} and `negative_prompt_embeds`:" - f" {negative_prompt_embeds}. Please make sure to only forward one of the two." - ) + if prompt_embeds is not None and prompt_attention_mask is None: + raise ValueError("Must provide `prompt_attention_mask` when specifying `prompt_embeds`.") + + if prompt_embeds_2 is not None and prompt_attention_mask_2 is None: + raise ValueError("Must provide `prompt_attention_mask_2` when specifying `prompt_embeds_2`.") if negative_prompt is not None and negative_prompt_embeds is not None: raise ValueError( @@ -370,6 +596,13 @@ class EasyAnimatePipeline(DiffusionPipeline): f" {negative_prompt_embeds}. Please make sure to only forward one of the two." ) + if negative_prompt_embeds is not None and negative_prompt_attention_mask is None: + raise ValueError("Must provide `negative_prompt_attention_mask` when specifying `negative_prompt_embeds`.") + + if negative_prompt_embeds_2 is not None and negative_prompt_attention_mask_2 is None: + raise ValueError( + "Must provide `negative_prompt_attention_mask_2` when specifying `negative_prompt_embeds_2`." + ) if prompt_embeds is not None and negative_prompt_embeds is not None: if prompt_embeds.shape != negative_prompt_embeds.shape: raise ValueError( @@ -377,153 +610,25 @@ class EasyAnimatePipeline(DiffusionPipeline): f" got: `prompt_embeds` {prompt_embeds.shape} != `negative_prompt_embeds`" f" {negative_prompt_embeds.shape}." ) - - # Copied from diffusers.pipelines.deepfloyd_if.pipeline_if.IFPipeline._text_preprocessing - def _text_preprocessing(self, text, clean_caption=False): - if clean_caption and not is_bs4_available(): - logger.warn(BACKENDS_MAPPING["bs4"][-1].format("Setting `clean_caption=True`")) - logger.warn("Setting `clean_caption` to False...") - clean_caption = False - - if clean_caption and not is_ftfy_available(): - logger.warn(BACKENDS_MAPPING["ftfy"][-1].format("Setting `clean_caption=True`")) - logger.warn("Setting `clean_caption` to False...") - clean_caption = False - - if not isinstance(text, (tuple, list)): - text = [text] - - def process(text: str): - if clean_caption: - text = self._clean_caption(text) - text = self._clean_caption(text) - else: - text = text.lower().strip() - return text - - return [process(t) for t in text] - - # Copied from diffusers.pipelines.deepfloyd_if.pipeline_if.IFPipeline._clean_caption - def _clean_caption(self, caption): - caption = str(caption) - caption = ul.unquote_plus(caption) - caption = caption.strip().lower() - caption = re.sub("<person>", "person", caption) - # urls: - caption = re.sub( - r"\b((?:https?:(?:\/{1,3}|[a-zA-Z0-9%])|[a-zA-Z0-9.\-]+[.](?:com|co|ru|net|org|edu|gov|it)[\w/-]*\b\/?(?!@)))", # noqa - "", - caption, - ) # regex for urls - caption = re.sub( - r"\b((?:www:(?:\/{1,3}|[a-zA-Z0-9%])|[a-zA-Z0-9.\-]+[.](?:com|co|ru|net|org|edu|gov|it)[\w/-]*\b\/?(?!@)))", # noqa - "", - caption, - ) # regex for urls - # html: - caption = BeautifulSoup(caption, features="html.parser").text - - # @<nickname> - caption = re.sub(r"@[\w\d]+\b", "", caption) - - # 31C0—31EF CJK Strokes - # 31F0—31FF Katakana Phonetic Extensions - # 3200—32FF Enclosed CJK Letters and Months - # 3300—33FF CJK Compatibility - # 3400—4DBF CJK Unified Ideographs Extension A - # 4DC0—4DFF Yijing Hexagram Symbols - # 4E00—9FFF CJK Unified Ideographs - caption = re.sub(r"[\u31c0-\u31ef]+", "", caption) - caption = re.sub(r"[\u31f0-\u31ff]+", "", caption) - caption = re.sub(r"[\u3200-\u32ff]+", "", caption) - caption = re.sub(r"[\u3300-\u33ff]+", "", caption) - caption = re.sub(r"[\u3400-\u4dbf]+", "", caption) - caption = re.sub(r"[\u4dc0-\u4dff]+", "", caption) - caption = re.sub(r"[\u4e00-\u9fff]+", "", caption) - ####################################################### - - # все виды тире / all types of dash --> "-" - caption = re.sub( - r"[\u002D\u058A\u05BE\u1400\u1806\u2010-\u2015\u2E17\u2E1A\u2E3A\u2E3B\u2E40\u301C\u3030\u30A0\uFE31\uFE32\uFE58\uFE63\uFF0D]+", # noqa - "-", - caption, - ) - - # кавычки к одному стандарту - caption = re.sub(r"[`´«»“”¨]", '"', caption) - caption = re.sub(r"[‘’]", "'", caption) - - # &quot; - caption = re.sub(r"&quot;?", "", caption) - # &amp - caption = re.sub(r"&amp", "", caption) - - # ip adresses: - caption = re.sub(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", " ", caption) - - # article ids: - caption = re.sub(r"\d:\d\d\s+$", "", caption) - - # \n - caption = re.sub(r"\\n", " ", caption) - - # "#123" - caption = re.sub(r"#\d{1,3}\b", "", caption) - # "#12345.." - caption = re.sub(r"#\d{5,}\b", "", caption) - # "123456.." - caption = re.sub(r"\b\d{6,}\b", "", caption) - # filenames: - caption = re.sub(r"[\S]+\.(?:png|jpg|jpeg|bmp|webp|eps|pdf|apk|mp4)", "", caption) - - # - caption = re.sub(r"[\"\']{2,}", r'"', caption) # """AUSVERKAUFT""" - caption = re.sub(r"[\.]{2,}", r" ", caption) # """AUSVERKAUFT""" - - caption = re.sub(self.bad_punct_regex, r" ", caption) # ***AUSVERKAUFT***, #AUSVERKAUFT - caption = re.sub(r"\s+\.\s+", r" ", caption) # " . " - - # this-is-my-cute-cat / this_is_my_cute_cat - regex2 = re.compile(r"(?:\-|\_)") - if len(re.findall(regex2, caption)) > 3: - caption = re.sub(regex2, " ", caption) - - caption = ftfy.fix_text(caption) - caption = html.unescape(html.unescape(caption)) - - caption = re.sub(r"\b[a-zA-Z]{1,3}\d{3,15}\b", "", caption) # jc6640 - caption = re.sub(r"\b[a-zA-Z]+\d+[a-zA-Z]+\b", "", caption) # jc6640vc - caption = re.sub(r"\b\d+[a-zA-Z]+\d+\b", "", caption) # 6640vc231 - - caption = re.sub(r"(worldwide\s+)?(free\s+)?shipping", "", caption) - caption = re.sub(r"(free\s)?download(\sfree)?", "", caption) - caption = re.sub(r"\bclick\b\s(?:for|on)\s\w+", "", caption) - caption = re.sub(r"\b(?:png|jpg|jpeg|bmp|webp|eps|pdf|apk|mp4)(\simage[s]?)?", "", caption) - caption = re.sub(r"\bpage\s+\d+\b", "", caption) - - caption = re.sub(r"\b\d*[a-zA-Z]+\d+[a-zA-Z]+\d+[a-zA-Z\d]*\b", r" ", caption) # j2d1a2a... - - caption = re.sub(r"\b\d+\.?\d*[xх×]\d+\.?\d*\b", "", caption) - - caption = re.sub(r"\b\s+\:\s+", r": ", caption) - caption = re.sub(r"(\D[,\./])\b", r"\1 ", caption) - caption = re.sub(r"\s+", " ", caption) - - caption.strip() - - caption = re.sub(r"^[\"\']([\w\W]+)[\"\']$", r"\1", caption) - caption = re.sub(r"^[\'\_,\-\:;]", r"", caption) - caption = re.sub(r"[\'\_,\-\:\-\+]$", r"", caption) - caption = re.sub(r"^\.\S+$", "", caption) - - return caption.strip() + if prompt_embeds_2 is not None and negative_prompt_embeds_2 is not None: + if prompt_embeds_2.shape != negative_prompt_embeds_2.shape: + raise ValueError( + "`prompt_embeds_2` and `negative_prompt_embeds_2` must have the same shape when passed directly, but" + f" got: `prompt_embeds_2` {prompt_embeds_2.shape} != `negative_prompt_embeds_2`" + f" {negative_prompt_embeds_2.shape}." + ) # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.prepare_latents def prepare_latents(self, batch_size, num_channels_latents, video_length, height, width, dtype, device, generator, latents=None): - if self.vae.quant_conv.weight.ndim==5: - mini_batch_encoder = self.vae.mini_batch_encoder - mini_batch_decoder = self.vae.mini_batch_decoder - shape = (batch_size, num_channels_latents, int(video_length // mini_batch_encoder * mini_batch_decoder) if video_length != 1 else 1, height // self.vae_scale_factor, width // self.vae_scale_factor) + if self.vae.quant_conv is None or self.vae.quant_conv.weight.ndim==5: + if self.vae.cache_mag_vae: + mini_batch_encoder = self.vae.mini_batch_encoder + mini_batch_decoder = self.vae.mini_batch_decoder + shape = (batch_size, num_channels_latents, int((video_length - 1) // mini_batch_encoder * mini_batch_decoder + 1) if video_length != 1 else 1, height // self.vae_scale_factor, width // self.vae_scale_factor) + else: + mini_batch_encoder = self.vae.mini_batch_encoder + mini_batch_decoder = self.vae.mini_batch_decoder + shape = (batch_size, num_channels_latents, int(video_length // mini_batch_encoder * mini_batch_decoder) if video_length != 1 else 1, height // self.vae_scale_factor, width // self.vae_scale_factor) else: shape = (batch_size, num_channels_latents, video_length, height // self.vae_scale_factor, width // self.vae_scale_factor) @@ -537,11 +642,12 @@ class EasyAnimatePipeline(DiffusionPipeline): latents = randn_tensor(shape, generator=generator, device=device, dtype=dtype) else: latents = latents.to(device) - + # scale the initial noise by the standard deviation required by the scheduler - latents = latents * self.scheduler.init_noise_sigma + if hasattr(self.scheduler, "init_noise_sigma"): + latents = latents * self.scheduler.init_noise_sigma return latents - + def smooth_output(self, video, mini_batch_encoder, mini_batch_decoder): if video.size()[2] <= mini_batch_encoder: return video @@ -557,16 +663,17 @@ class EasyAnimatePipeline(DiffusionPipeline): video[:, :, prefix_index_before:-prefix_index_after] = (video[:, :, prefix_index_before:-prefix_index_after] + middle_video) / 2 return video - + def decode_latents(self, latents): video_length = latents.shape[2] latents = 1 / self.vae.config.scaling_factor * latents - if self.vae.quant_conv.weight.ndim==5: + if self.vae.quant_conv is None or self.vae.quant_conv.weight.ndim==5: mini_batch_encoder = self.vae.mini_batch_encoder mini_batch_decoder = self.vae.mini_batch_decoder video = self.vae.decode(latents)[0] video = video.clamp(-1, 1) - video = self.smooth_output(video, mini_batch_encoder, mini_batch_decoder).cpu().clamp(-1, 1) + if not self.vae.cache_compression_vae and not self.vae.cache_mag_vae: + video = self.smooth_output(video, mini_batch_encoder, mini_batch_decoder).cpu().clamp(-1, 1) else: latents = rearrange(latents, "b c f h w -> (b f) c h w") video = [] @@ -579,109 +686,160 @@ class EasyAnimatePipeline(DiffusionPipeline): video = video.cpu().float().numpy() return video + @property + def guidance_scale(self): + return self._guidance_scale + + @property + def guidance_rescale(self): + return self._guidance_rescale + + # here `guidance_scale` is defined analog to the guidance weight `w` of equation (2) + # of the Imagen paper: https://arxiv.org/pdf/2205.11487.pdf . `guidance_scale = 1` + # corresponds to doing no classifier free guidance. + @property + def do_classifier_free_guidance(self): + return self._guidance_scale > 1 + + @property + def num_timesteps(self): + return self._num_timesteps + + @property + def interrupt(self): + return self._interrupt + @torch.no_grad() @replace_example_docstring(EXAMPLE_DOC_STRING) def __call__( self, prompt: Union[str, List[str]] = None, video_length: Optional[int] = None, - negative_prompt: str = "", - num_inference_steps: int = 20, - timesteps: List[int] = None, - guidance_scale: float = 4.5, - num_images_per_prompt: Optional[int] = 1, height: Optional[int] = None, width: Optional[int] = None, - eta: float = 0.0, + num_inference_steps: Optional[int] = 50, + guidance_scale: Optional[float] = 5.0, + negative_prompt: Optional[Union[str, List[str]]] = None, + num_images_per_prompt: Optional[int] = 1, + eta: Optional[float] = 0.0, generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None, - latents: Optional[torch.FloatTensor] = None, - prompt_embeds: Optional[torch.FloatTensor] = None, - prompt_attention_mask: Optional[torch.FloatTensor] = None, - negative_prompt_embeds: Optional[torch.FloatTensor] = None, - negative_prompt_attention_mask: Optional[torch.FloatTensor] = None, + latents: Optional[torch.Tensor] = None, + prompt_embeds: Optional[torch.Tensor] = None, + prompt_embeds_2: Optional[torch.Tensor] = None, + negative_prompt_embeds: Optional[torch.Tensor] = None, + negative_prompt_embeds_2: Optional[torch.Tensor] = None, + prompt_attention_mask: Optional[torch.Tensor] = None, + prompt_attention_mask_2: Optional[torch.Tensor] = None, + negative_prompt_attention_mask: Optional[torch.Tensor] = None, + negative_prompt_attention_mask_2: Optional[torch.Tensor] = None, output_type: Optional[str] = "latent", return_dict: bool = True, - callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None, - callback_steps: int = 1, - clean_caption: bool = True, - max_sequence_length: int = 120, + callback_on_step_end: Optional[ + Union[Callable[[int, int, Dict], None], PipelineCallback, MultiPipelineCallbacks] + ] = None, + callback_on_step_end_tensor_inputs: List[str] = ["latents"], + guidance_rescale: float = 0.0, + original_size: Optional[Tuple[int, int]] = (1024, 1024), + target_size: Optional[Tuple[int, int]] = None, + crops_coords_top_left: Tuple[int, int] = (0, 0), comfyui_progressbar: bool = False, - **kwargs, - ) -> Union[EasyAnimatePipelineOutput, Tuple]: - """ - Function invoked when calling the pipeline for generation. - - Args: - prompt (`str` or `List[str]`, *optional*): - The prompt or prompts to guide the image generation. If not defined, one has to pass `prompt_embeds`. - instead. - negative_prompt (`str` or `List[str]`, *optional*): - The prompt or prompts not to guide the image generation. If not defined, one has to pass - `negative_prompt_embeds` instead. Ignored when not using guidance (i.e., ignored if `guidance_scale` is - less than `1`). - num_inference_steps (`int`, *optional*, defaults to 100): - The number of denoising steps. More denoising steps usually lead to a higher quality image at the - expense of slower inference. - timesteps (`List[int]`, *optional*): - Custom timesteps to use for the denoising process. If not defined, equal spaced `num_inference_steps` - timesteps are used. Must be in descending order. - guidance_scale (`float`, *optional*, defaults to 7.0): - Guidance scale as defined in [Classifier-Free Diffusion Guidance](https://arxiv.org/abs/2207.12598). - `guidance_scale` is defined as `w` of equation 2. of [Imagen - Paper](https://arxiv.org/pdf/2205.11487.pdf). Guidance scale is enabled by setting `guidance_scale > - 1`. Higher guidance scale encourages to generate images that are closely linked to the text `prompt`, - usually at the expense of lower image quality. - num_images_per_prompt (`int`, *optional*, defaults to 1): - The number of images to generate per prompt. - height (`int`, *optional*, defaults to self.unet.config.sample_size): - The height in pixels of the generated image. - width (`int`, *optional*, defaults to self.unet.config.sample_size): - The width in pixels of the generated image. - eta (`float`, *optional*, defaults to 0.0): - Corresponds to parameter eta (η) in the DDIM paper: https://arxiv.org/abs/2010.02502. Only applies to - [`schedulers.DDIMScheduler`], will be ignored for others. - generator (`torch.Generator` or `List[torch.Generator]`, *optional*): - One or a list of [torch generator(s)](https://pytorch.org/docs/stable/generated/torch.Generator.html) - to make generation deterministic. - latents (`torch.FloatTensor`, *optional*): - Pre-generated noisy latents, sampled from a Gaussian distribution, to be used as inputs for image - generation. Can be used to tweak the same generation with different prompts. If not provided, a latents - tensor will ge generated by sampling using the supplied random `generator`. - prompt_embeds (`torch.FloatTensor`, *optional*): - Pre-generated text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting. If not - provided, text embeddings will be generated from `prompt` input argument. - negative_prompt_embeds (`torch.FloatTensor`, *optional*): - Pre-generated negative text embeddings. For PixArt-Alpha this negative prompt should be "". If not - provided, negative_prompt_embeds will be generated from `negative_prompt` input argument. - output_type (`str`, *optional*, defaults to `"pil"`): - The output format of the generate image. Choose between - [PIL](https://pillow.readthedocs.io/en/stable/): `PIL.Image.Image` or `np.array`. - return_dict (`bool`, *optional*, defaults to `True`): - Whether or not to return a [`~pipelines.stable_diffusion.IFPipelineOutput`] instead of a plain tuple. - callback (`Callable`, *optional*): - A function that will be called every `callback_steps` steps during inference. The function will be - called with the following arguments: `callback(step: int, timestep: int, latents: torch.FloatTensor)`. - callback_steps (`int`, *optional*, defaults to 1): - The frequency at which the `callback` function will be called. If not specified, the callback will be - called at every step. - clean_caption (`bool`, *optional*, defaults to `True`): - Whether or not to clean the caption before creating embeddings. Requires `beautifulsoup4` and `ftfy` to - be installed. If the dependencies are not installed, the embeddings will be created from the raw - prompt. - mask_feature (`bool` defaults to `True`): If set to `True`, the text embeddings will be masked. + timesteps: Optional[List[int]] = None, + ): + r""" + Generates images or video using the EasyAnimate pipeline based on the provided prompts. Examples: + prompt (`str` or `List[str]`, *optional*): + Text prompts to guide the image or video generation. If not provided, use `prompt_embeds` instead. + video_length (`int`, *optional*): + Length of the generated video (in frames). + height (`int`, *optional*): + Height of the generated image in pixels. + width (`int`, *optional*): + Width of the generated image in pixels. + num_inference_steps (`int`, *optional*, defaults to 50): + Number of denoising steps during generation. More steps generally yield higher quality images but slow down inference. + guidance_scale (`float`, *optional*, defaults to 5.0): + Encourages the model to align outputs with prompts. A higher value may decrease image quality. + negative_prompt (`str` or `List[str]`, *optional*): + Prompts indicating what to exclude in generation. If not specified, use `negative_prompt_embeds`. + num_images_per_prompt (`int`, *optional*, defaults to 1): + Number of images to generate for each prompt. + eta (`float`, *optional*, defaults to 0.0): + Applies to DDIM scheduling. Controlled by the eta parameter from the related literature. + generator (`torch.Generator` or `List[torch.Generator]`, *optional*): + A generator to ensure reproducibility in image generation. + latents (`torch.Tensor`, *optional*): + Predefined latent tensors to condition generation. + prompt_embeds (`torch.Tensor`, *optional*): + Text embeddings for the prompts. Overrides prompt string inputs for more flexibility. + prompt_embeds_2 (`torch.Tensor`, *optional*): + Secondary text embeddings to supplement or replace the initial prompt embeddings. + negative_prompt_embeds (`torch.Tensor`, *optional*): + Embeddings for negative prompts. Overrides string inputs if defined. + negative_prompt_embeds_2 (`torch.Tensor`, *optional*): + Secondary embeddings for negative prompts, similar to `negative_prompt_embeds`. + prompt_attention_mask (`torch.Tensor`, *optional*): + Attention mask for the primary prompt embeddings. + prompt_attention_mask_2 (`torch.Tensor`, *optional*): + Attention mask for the secondary prompt embeddings. + negative_prompt_attention_mask (`torch.Tensor`, *optional*): + Attention mask for negative prompt embeddings. + negative_prompt_attention_mask_2 (`torch.Tensor`, *optional*): + Attention mask for secondary negative prompt embeddings. + output_type (`str`, *optional*, defaults to "latent"): + Format of the generated output, either as a PIL image or as a NumPy array. + return_dict (`bool`, *optional*, defaults to `True`): + If `True`, returns a structured output. Otherwise returns a simple tuple. + callback_on_step_end (`Callable`, *optional*): + Functions called at the end of each denoising step. + callback_on_step_end_tensor_inputs (`List[str]`, *optional*): + Tensor names to be included in callback function calls. + guidance_rescale (`float`, *optional*, defaults to 0.0): + Adjusts noise levels based on guidance scale. + original_size (`Tuple[int, int]`, *optional*, defaults to `(1024, 1024)`): + Original dimensions of the output. + target_size (`Tuple[int, int]`, *optional*): + Desired output dimensions for calculations. + crops_coords_top_left (`Tuple[int, int]`, *optional*, defaults to `(0, 0)`): + Coordinates for cropping. Returns: - [`~pipelines.ImagePipelineOutput`] or `tuple`: - If `return_dict` is `True`, [`~pipelines.ImagePipelineOutput`] is returned, otherwise a `tuple` is - returned where the first element is a list with the generated images + [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] or `tuple`: + If `return_dict` is `True`, [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] is returned, + otherwise a `tuple` is returned where the first element is a list with the generated images and the + second element is a list of `bool`s indicating whether the corresponding generated image contains + "not-safe-for-work" (nsfw) content. """ - # 1. Check inputs. Raise error if not correct - height = height or self.transformer.config.sample_size * self.vae_scale_factor - width = width or self.transformer.config.sample_size * self.vae_scale_factor - # 2. Default height and width to transformer + if isinstance(callback_on_step_end, (PipelineCallback, MultiPipelineCallbacks)): + callback_on_step_end_tensor_inputs = callback_on_step_end.tensor_inputs + + # 0. default height and width + height = int((height // 16) * 16) + width = int((width // 16) * 16) + + # 1. Check inputs. Raise error if not correct + self.check_inputs( + prompt, + height, + width, + negative_prompt, + prompt_embeds, + negative_prompt_embeds, + prompt_attention_mask, + negative_prompt_attention_mask, + prompt_embeds_2, + negative_prompt_embeds_2, + prompt_attention_mask_2, + negative_prompt_attention_mask_2, + callback_on_step_end_tensor_inputs, + ) + self._guidance_scale = guidance_scale + self._guidance_rescale = guidance_rescale + self._interrupt = False + + # 2. Define call parameters if prompt is not None and isinstance(prompt, str): batch_size = 1 elif prompt is not None and isinstance(prompt, list): @@ -697,42 +855,64 @@ class EasyAnimatePipeline(DiffusionPipeline): else: dtype = self.transformer.dtype - # here `guidance_scale` is defined analog to the guidance weight `w` of equation (2) - # of the Imagen paper: https://arxiv.org/pdf/2205.11487.pdf . `guidance_scale = 1` - # corresponds to doing no classifier free guidance. - do_classifier_free_guidance = guidance_scale > 1.0 - # 3. Encode input prompt ( prompt_embeds, - prompt_attention_mask, negative_prompt_embeds, + prompt_attention_mask, negative_prompt_attention_mask, ) = self.encode_prompt( - prompt, - do_classifier_free_guidance, - negative_prompt=negative_prompt, - num_images_per_prompt=num_images_per_prompt, + prompt=prompt, device=device, + dtype=dtype, + num_images_per_prompt=num_images_per_prompt, + do_classifier_free_guidance=self.do_classifier_free_guidance, + negative_prompt=negative_prompt, prompt_embeds=prompt_embeds, negative_prompt_embeds=negative_prompt_embeds, prompt_attention_mask=prompt_attention_mask, negative_prompt_attention_mask=negative_prompt_attention_mask, - clean_caption=clean_caption, - max_sequence_length=max_sequence_length, + text_encoder_index=0, ) - if do_classifier_free_guidance: - prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds], dim=0) - prompt_attention_mask = torch.cat([negative_prompt_attention_mask, prompt_attention_mask], dim=0) + if self.tokenizer_2 is not None: + ( + prompt_embeds_2, + negative_prompt_embeds_2, + prompt_attention_mask_2, + negative_prompt_attention_mask_2, + ) = self.encode_prompt( + prompt=prompt, + device=device, + dtype=dtype, + num_images_per_prompt=num_images_per_prompt, + do_classifier_free_guidance=self.do_classifier_free_guidance, + negative_prompt=negative_prompt, + prompt_embeds=prompt_embeds_2, + negative_prompt_embeds=negative_prompt_embeds_2, + prompt_attention_mask=prompt_attention_mask_2, + negative_prompt_attention_mask=negative_prompt_attention_mask_2, + text_encoder_index=1, + ) + else: + prompt_embeds_2 = None + negative_prompt_embeds_2 = None + prompt_attention_mask_2 = None + negative_prompt_attention_mask_2 = None # 4. Prepare timesteps - timesteps, num_inference_steps = retrieve_timesteps(self.scheduler, num_inference_steps, device, timesteps) + if isinstance(self.scheduler, FlowMatchEulerDiscreteScheduler): + timesteps, num_inference_steps = retrieve_timesteps(self.scheduler, num_inference_steps, device, timesteps, mu=1) + else: + timesteps, num_inference_steps = retrieve_timesteps(self.scheduler, num_inference_steps, device, timesteps) + if comfyui_progressbar: + from comfy.utils import ProgressBar + pbar = ProgressBar(num_inference_steps + 1) - # 5. Prepare latents. - latent_channels = self.transformer.config.in_channels + # 5. Prepare latent variables + num_channels_latents = self.transformer.config.in_channels latents = self.prepare_latents( batch_size * num_images_per_prompt, - latent_channels, + num_channels_latents, video_length, height, width, @@ -741,79 +921,146 @@ class EasyAnimatePipeline(DiffusionPipeline): generator, latents, ) + if comfyui_progressbar: + pbar.update(1) # 6. Prepare extra step kwargs. TODO: Logic should ideally just be moved out of the pipeline extra_step_kwargs = self.prepare_extra_step_kwargs(generator, eta) - # 6.1 Prepare micro-conditions. + # 7 create image_rotary_emb, style embedding & time ids + grid_height = height // 8 // self.transformer.config.patch_size + grid_width = width // 8 // self.transformer.config.patch_size + if self.transformer.config.get("time_position_encoding_type", "2d_rope") == "3d_rope": + base_size_width = 720 // 8 // self.transformer.config.patch_size + base_size_height = 480 // 8 // self.transformer.config.patch_size + + grid_crops_coords = get_resize_crop_region_for_grid( + (grid_height, grid_width), base_size_width, base_size_height + ) + image_rotary_emb = get_3d_rotary_pos_embed( + self.transformer.config.attention_head_dim, grid_crops_coords, grid_size=(grid_height, grid_width), + temporal_size=latents.size(2), use_real=True, + ) + else: + base_size = 512 // 8 // self.transformer.config.patch_size + grid_crops_coords = get_resize_crop_region_for_grid( + (grid_height, grid_width), base_size, base_size + ) + image_rotary_emb = get_2d_rotary_pos_embed( + self.transformer.config.attention_head_dim, grid_crops_coords, (grid_height, grid_width) + ) + + # Get other hunyuan params + target_size = target_size or (height, width) + add_time_ids = list(original_size + target_size + crops_coords_top_left) + add_time_ids = torch.tensor([add_time_ids], dtype=dtype) + style = torch.tensor([0], device=device) + + if self.do_classifier_free_guidance: + add_time_ids = torch.cat([add_time_ids] * 2, dim=0) + style = torch.cat([style] * 2, dim=0) + + # To latents.device + add_time_ids = add_time_ids.to(dtype=dtype, device=device).repeat( + batch_size * num_images_per_prompt, 1 + ) + style = style.to(device=device).repeat(batch_size * num_images_per_prompt) + + # Get other pixart params added_cond_kwargs = {"resolution": None, "aspect_ratio": None} - if self.transformer.config.sample_size == 128: + if self.transformer.config.get("sample_size", 64) == 128: resolution = torch.tensor([height, width]).repeat(batch_size * num_images_per_prompt, 1) aspect_ratio = torch.tensor([float(height / width)]).repeat(batch_size * num_images_per_prompt, 1) resolution = resolution.to(dtype=dtype, device=device) aspect_ratio = aspect_ratio.to(dtype=dtype, device=device) - if do_classifier_free_guidance: + if self.do_classifier_free_guidance: resolution = torch.cat([resolution, resolution], dim=0) aspect_ratio = torch.cat([aspect_ratio, aspect_ratio], dim=0) added_cond_kwargs = {"resolution": resolution, "aspect_ratio": aspect_ratio} - # 7. Denoising loop - num_warmup_steps = max(len(timesteps) - num_inference_steps * self.scheduler.order, 0) - if comfyui_progressbar: - from comfy.utils import ProgressBar - pbar = ProgressBar(num_inference_steps) + if self.do_classifier_free_guidance: + prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds]) + prompt_attention_mask = torch.cat([negative_prompt_attention_mask, prompt_attention_mask]) + if prompt_embeds_2 is not None: + prompt_embeds_2 = torch.cat([negative_prompt_embeds_2, prompt_embeds_2]) + prompt_attention_mask_2 = torch.cat([negative_prompt_attention_mask_2, prompt_attention_mask_2]) + + # To latents.device + prompt_embeds = prompt_embeds.to(device=device) + prompt_attention_mask = prompt_attention_mask.to(device=device) + if prompt_embeds_2 is not None: + prompt_embeds_2 = prompt_embeds_2.to(device=device) + prompt_attention_mask_2 = prompt_attention_mask_2.to(device=device) + + # 8. Denoising loop + num_warmup_steps = len(timesteps) - num_inference_steps * self.scheduler.order + self._num_timesteps = len(timesteps) with self.progress_bar(total=num_inference_steps) as progress_bar: for i, t in enumerate(timesteps): - latent_model_input = torch.cat([latents] * 2) if do_classifier_free_guidance else latents - latent_model_input = self.scheduler.scale_model_input(latent_model_input, t) + if self.interrupt: + continue - current_timestep = t - if not torch.is_tensor(current_timestep): - # TODO: this requires sync between CPU and GPU. So try to pass timesteps as tensors if you can - # This would be a good case for the `match` statement (Python 3.10+) - is_mps = latent_model_input.device.type == "mps" - if isinstance(current_timestep, float): - dtype = torch.float32 if is_mps else torch.float64 - else: - dtype = torch.int32 if is_mps else torch.int64 - current_timestep = torch.tensor([current_timestep], dtype=dtype, device=latent_model_input.device) - elif len(current_timestep.shape) == 0: - current_timestep = current_timestep[None].to(latent_model_input.device) - # broadcast to batch dimension in a way that's compatible with ONNX/Core ML - current_timestep = current_timestep.expand(latent_model_input.shape[0]) + # expand the latents if we are doing classifier free guidance + latent_model_input = torch.cat([latents] * 2) if self.do_classifier_free_guidance else latents + if hasattr(self.scheduler, "scale_model_input"): + latent_model_input = self.scheduler.scale_model_input(latent_model_input, t) - # predict noise model_output + # expand scalar t to 1-D tensor to match the 1st dim of latent_model_input + t_expand = torch.tensor([t] * latent_model_input.shape[0], device=device).to( + dtype=latent_model_input.dtype + ) + + # predict the noise residual noise_pred = self.transformer( latent_model_input, + t_expand, encoder_hidden_states=prompt_embeds, - encoder_attention_mask=prompt_attention_mask, - timestep=current_timestep, + text_embedding_mask=prompt_attention_mask, + encoder_hidden_states_t5=prompt_embeds_2, + text_embedding_mask_t5=prompt_attention_mask_2, + image_meta_size=add_time_ids, + style=style, + image_rotary_emb=image_rotary_emb, added_cond_kwargs=added_cond_kwargs, return_dict=False, )[0] + + if noise_pred.size()[1] != self.vae.config.latent_channels: + noise_pred, _ = noise_pred.chunk(2, dim=1) # perform guidance - if do_classifier_free_guidance: + if self.do_classifier_free_guidance: noise_pred_uncond, noise_pred_text = noise_pred.chunk(2) noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond) - # learned sigma - if self.transformer.config.out_channels // 2 == latent_channels: - noise_pred = noise_pred.chunk(2, dim=1)[0] - else: - noise_pred = noise_pred + if self.do_classifier_free_guidance and guidance_rescale > 0.0: + # Based on 3.4. in https://arxiv.org/pdf/2305.08891.pdf + noise_pred = rescale_noise_cfg(noise_pred, noise_pred_text, guidance_rescale=guidance_rescale) - # compute previous image: x_t -> x_t-1 + # compute the previous noisy sample x_t -> x_t-1 latents = self.scheduler.step(noise_pred, t, latents, **extra_step_kwargs, return_dict=False)[0] - # call the callback, if provided + if callback_on_step_end is not None: + callback_kwargs = {} + for k in callback_on_step_end_tensor_inputs: + callback_kwargs[k] = locals()[k] + callback_outputs = callback_on_step_end(self, i, t, callback_kwargs) + + latents = callback_outputs.pop("latents", latents) + prompt_embeds = callback_outputs.pop("prompt_embeds", prompt_embeds) + negative_prompt_embeds = callback_outputs.pop("negative_prompt_embeds", negative_prompt_embeds) + prompt_embeds_2 = callback_outputs.pop("prompt_embeds_2", prompt_embeds_2) + negative_prompt_embeds_2 = callback_outputs.pop( + "negative_prompt_embeds_2", negative_prompt_embeds_2 + ) + if i == len(timesteps) - 1 or ((i + 1) > num_warmup_steps and (i + 1) % self.scheduler.order == 0): progress_bar.update() - if callback is not None and i % callback_steps == 0: - step_idx = i // getattr(self.scheduler, "order", 1) - callback(step_idx, t, latents) + + if XLA_AVAILABLE: + xm.mark_step() if comfyui_progressbar: pbar.update(1) @@ -825,7 +1072,10 @@ class EasyAnimatePipeline(DiffusionPipeline): if output_type == "latent": video = torch.from_numpy(video) + # Offload all models + self.maybe_free_model_hooks() + if not return_dict: return video - return EasyAnimatePipelineOutput(videos=video) \ No newline at end of file + return EasyAnimatePipelineOutput(frames=video) \ No newline at end of file diff --git a/easyanimate/pipeline/pipeline_easyanimate_multi_text_encoder_control.py b/easyanimate/pipeline/pipeline_easyanimate_control.py similarity index 63% rename from easyanimate/pipeline/pipeline_easyanimate_multi_text_encoder_control.py rename to easyanimate/pipeline/pipeline_easyanimate_control.py index cb7dcca..f5ab704 100644 --- a/easyanimate/pipeline/pipeline_easyanimate_multi_text_encoder_control.py +++ b/easyanimate/pipeline/pipeline_easyanimate_control.py @@ -31,7 +31,8 @@ from diffusers.pipelines.pipeline_utils import DiffusionPipeline from diffusers.pipelines.stable_diffusion import StableDiffusionPipelineOutput from diffusers.pipelines.stable_diffusion.safety_checker import \ StableDiffusionSafetyChecker -from diffusers.schedulers import DDIMScheduler, DPMSolverMultistepScheduler +from diffusers.schedulers import (DDIMScheduler, DPMSolverMultistepScheduler, + FlowMatchEulerDiscreteScheduler) from diffusers.utils import (BACKENDS_MAPPING, BaseOutput, deprecate, is_bs4_available, is_ftfy_available, is_torch_xla_available, logging, @@ -41,11 +42,12 @@ from einops import rearrange from PIL import Image from tqdm import tqdm from transformers import (BertModel, BertTokenizer, CLIPImageProcessor, - CLIPVisionModelWithProjection, - T5EncoderModel, T5Tokenizer) + CLIPVisionModelWithProjection, Qwen2Tokenizer, + Qwen2VLForConditionalGeneration, T5EncoderModel, + T5Tokenizer) from ..models import AutoencoderKLMagvit, EasyAnimateTransformer3DModel -from .pipeline_easyanimate import EasyAnimatePipelineOutput +from .pipeline_easyanimate_inpaint import EasyAnimatePipelineOutput if is_torch_xla_available(): import torch_xla.core.xla_model as xm @@ -64,6 +66,7 @@ EXAMPLE_DOC_STRING = """ ``` """ +# Similar to diffusers.pipelines.hunyuandit.pipeline_hunyuandit.get_resize_crop_region_for_grid def get_resize_crop_region_for_grid(src, tgt_width, tgt_height): tw = tgt_width th = tgt_height @@ -97,44 +100,140 @@ def rescale_noise_cfg(noise_cfg, noise_pred_text, guidance_rescale=0.0): return noise_cfg -class EasyAnimatePipeline_Multi_Text_Encoder_Control(DiffusionPipeline): +# Resize mask information in magvit +def resize_mask(mask, latent, process_first_frame_only=True): + latent_size = latent.size() + + if process_first_frame_only: + target_size = list(latent_size[2:]) + target_size[0] = 1 + first_frame_resized = F.interpolate( + mask[:, :, 0:1, :, :], + size=target_size, + mode='trilinear', + align_corners=False + ) + + target_size = list(latent_size[2:]) + target_size[0] = target_size[0] - 1 + if target_size[0] != 0: + remaining_frames_resized = F.interpolate( + mask[:, :, 1:, :, :], + size=target_size, + mode='trilinear', + align_corners=False + ) + resized_mask = torch.cat([first_frame_resized, remaining_frames_resized], dim=2) + else: + resized_mask = first_frame_resized + else: + target_size = list(latent_size[2:]) + resized_mask = F.interpolate( + mask, + size=target_size, + mode='trilinear', + align_corners=False + ) + return resized_mask + + +# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.retrieve_timesteps +def retrieve_timesteps( + scheduler, + num_inference_steps: Optional[int] = None, + device: Optional[Union[str, torch.device]] = None, + timesteps: Optional[List[int]] = None, + sigmas: Optional[List[float]] = None, + **kwargs, +): + """ + Calls the scheduler's `set_timesteps` method and retrieves timesteps from the scheduler after the call. Handles + custom timesteps. Any kwargs will be supplied to `scheduler.set_timesteps`. + + Args: + scheduler (`SchedulerMixin`): + The scheduler to get timesteps from. + num_inference_steps (`int`): + The number of diffusion steps used when generating samples with a pre-trained model. If used, `timesteps` + must be `None`. + device (`str` or `torch.device`, *optional*): + The device to which the timesteps should be moved to. If `None`, the timesteps are not moved. + timesteps (`List[int]`, *optional*): + Custom timesteps used to override the timestep spacing strategy of the scheduler. If `timesteps` is passed, + `num_inference_steps` and `sigmas` must be `None`. + sigmas (`List[float]`, *optional*): + Custom sigmas used to override the timestep spacing strategy of the scheduler. If `sigmas` is passed, + `num_inference_steps` and `timesteps` must be `None`. + + Returns: + `Tuple[torch.Tensor, int]`: A tuple where the first element is the timestep schedule from the scheduler and the + second element is the number of inference steps. + """ + if timesteps is not None and sigmas is not None: + raise ValueError("Only one of `timesteps` or `sigmas` can be passed. Please choose one to set custom values") + if timesteps is not None: + accepts_timesteps = "timesteps" in set(inspect.signature(scheduler.set_timesteps).parameters.keys()) + if not accepts_timesteps: + raise ValueError( + f"The current scheduler class {scheduler.__class__}'s `set_timesteps` does not support custom" + f" timestep schedules. Please check whether you are using the correct scheduler." + ) + scheduler.set_timesteps(timesteps=timesteps, device=device, **kwargs) + timesteps = scheduler.timesteps + num_inference_steps = len(timesteps) + elif sigmas is not None: + accept_sigmas = "sigmas" in set(inspect.signature(scheduler.set_timesteps).parameters.keys()) + if not accept_sigmas: + raise ValueError( + f"The current scheduler class {scheduler.__class__}'s `set_timesteps` does not support custom" + f" sigmas schedules. Please check whether you are using the correct scheduler." + ) + scheduler.set_timesteps(sigmas=sigmas, device=device, **kwargs) + timesteps = scheduler.timesteps + num_inference_steps = len(timesteps) + else: + scheduler.set_timesteps(num_inference_steps, device=device, **kwargs) + timesteps = scheduler.timesteps + return timesteps, num_inference_steps + + +class EasyAnimateControlPipeline(DiffusionPipeline): r""" Pipeline for text-to-video generation using EasyAnimate. This model inherits from [`DiffusionPipeline`]. Check the superclass documentation for the generic methods the library implements for all the pipelines (such as downloading or saving, running on a particular device, etc.) + EasyAnimate uses one text encoder [qwen2 vl](https://huggingface.co/Qwen/Qwen2-VL-7B-Instruct) in V5.1. EasyAnimate uses two text encoders: [mT5](https://huggingface.co/google/mt5-base) and [bilingual CLIP](fine-tuned by - HunyuanDiT team) + HunyuanDiT team) in V5. Args: vae ([`AutoencoderKLMagvit`]): Variational Auto-Encoder (VAE) Model to encode and decode video to and from latent representations. - text_encoder (Optional[`~transformers.BertModel`, `~transformers.CLIPTextModel`]): - Frozen text-encoder ([clip-vit-large-patch14](https://huggingface.co/openai/clip-vit-large-patch14)). - EasyAnimate uses a fine-tuned [bilingual CLIP]. - tokenizer (Optional[`~transformers.BertTokenizer`, `~transformers.CLIPTokenizer`]): - A `BertTokenizer` or `CLIPTokenizer` to tokenize text. + text_encoder (Optional[`~transformers.Qwen2VLForConditionalGeneration`, `~transformers.BertModel`]): + EasyAnimate uses [qwen2 vl](https://huggingface.co/Qwen/Qwen2-VL-7B-Instruct) in V5.1. + EasyAnimate uses [bilingual CLIP](https://huggingface.co/Tencent-Hunyuan/HunyuanDiT-v1.2-Diffusers) in V5. + tokenizer (Optional[`~transformers.Qwen2Tokenizer`, `~transformers.BertTokenizer`]): + A `Qwen2Tokenizer` or `BertTokenizer` to tokenize text. transformer ([`EasyAnimateTransformer3DModel`]): - The EasyAnimate model designed by Tencent Hunyuan. + The EasyAnimate model designed by EasyAnimate Team. text_encoder_2 (`T5EncoderModel`): - The mT5 embedder. + EasyAnimate does not use text_encoder_2 in V5.1. + EasyAnimate uses [mT5](https://huggingface.co/google/mt5-base) embedder in V5. tokenizer_2 (`T5Tokenizer`): The tokenizer for the mT5 embedder. - scheduler ([`DDIMScheduler`]): + scheduler ([`FlowMatchEulerDiscreteScheduler`]): A scheduler to be used in combination with EasyAnimate to denoise the encoded image latents. """ model_cpu_offload_seq = "text_encoder->text_encoder_2->transformer->vae" _optional_components = [ - "safety_checker", - "feature_extractor", "text_encoder_2", "tokenizer_2", "text_encoder", "tokenizer", ] - _exclude_from_cpu_offload = ["safety_checker"] _callback_tensor_inputs = [ "latents", "prompt_embeds", @@ -146,52 +245,30 @@ class EasyAnimatePipeline_Multi_Text_Encoder_Control(DiffusionPipeline): def __init__( self, vae: AutoencoderKLMagvit, - text_encoder: BertModel, - tokenizer: BertTokenizer, - text_encoder_2: T5EncoderModel, - tokenizer_2: T5Tokenizer, + text_encoder: Union[Qwen2VLForConditionalGeneration, BertModel], + tokenizer: Union[Qwen2Tokenizer, BertTokenizer], + text_encoder_2: Optional[Union[T5EncoderModel, Qwen2VLForConditionalGeneration]], + tokenizer_2: Optional[Union[T5Tokenizer, Qwen2Tokenizer]], transformer: EasyAnimateTransformer3DModel, - scheduler: DDIMScheduler, - safety_checker: StableDiffusionSafetyChecker, - feature_extractor: CLIPImageProcessor, - requires_safety_checker: bool = True + scheduler: FlowMatchEulerDiscreteScheduler, ): super().__init__() self.register_modules( vae=vae, text_encoder=text_encoder, + text_encoder_2=text_encoder_2, tokenizer=tokenizer, tokenizer_2=tokenizer_2, transformer=transformer, scheduler=scheduler, - safety_checker=safety_checker, - feature_extractor=feature_extractor, - text_encoder_2=text_encoder_2 ) - if safety_checker is None and requires_safety_checker: - logger.warning( - f"You have disabled the safety checker for {self.__class__} by passing `safety_checker=None`. Ensure" - " that you abide to the conditions of the Stable Diffusion license and do not expose unfiltered" - " results in services or applications open to the public. Both the diffusers team and Hugging Face" - " strongly recommend to keep the safety filter enabled in all public facing circumstances, disabling" - " it only for use-cases that involve analyzing network behavior or auditing its results. For more" - " information, please have a look at https://github.com/huggingface/diffusers/pull/254 ." - ) - - if safety_checker is not None and feature_extractor is None: - raise ValueError( - "Make sure to define a feature extractor when loading {self.__class__} if you want to use the safety" - " checker. If you do not want to use the safety checker, you can pass `'safety_checker=None'` instead." - ) - self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1) self.image_processor = VaeImageProcessor(vae_scale_factor=self.vae_scale_factor) self.mask_processor = VaeImageProcessor( vae_scale_factor=self.vae_scale_factor, do_normalize=False, do_binarize=True, do_convert_grayscale=True ) - self.register_to_config(requires_safety_checker=requires_safety_checker) def enable_sequential_cpu_offload(self, *args, **kwargs): super().enable_sequential_cpu_offload(*args, **kwargs) @@ -271,19 +348,9 @@ class EasyAnimatePipeline_Multi_Text_Encoder_Control(DiffusionPipeline): batch_size = prompt_embeds.shape[0] if prompt_embeds is None: - text_inputs = tokenizer( - prompt, - padding="max_length", - max_length=max_length, - truncation=True, - return_attention_mask=True, - return_tensors="pt", - ) - text_input_ids = text_inputs.input_ids - if text_input_ids.shape[-1] > actual_max_sequence_length: - reprompt = tokenizer.batch_decode(text_input_ids[:, :actual_max_sequence_length], skip_special_tokens=True) + if type(tokenizer) in [BertTokenizer, T5Tokenizer]: text_inputs = tokenizer( - reprompt, + prompt, padding="max_length", max_length=max_length, truncation=True, @@ -291,91 +358,188 @@ class EasyAnimatePipeline_Multi_Text_Encoder_Control(DiffusionPipeline): return_tensors="pt", ) text_input_ids = text_inputs.input_ids - untruncated_ids = tokenizer(prompt, padding="longest", return_tensors="pt").input_ids + if text_input_ids.shape[-1] > actual_max_sequence_length: + reprompt = tokenizer.batch_decode(text_input_ids[:, :actual_max_sequence_length], skip_special_tokens=True) + text_inputs = tokenizer( + reprompt, + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + return_tensors="pt", + ) + text_input_ids = text_inputs.input_ids + untruncated_ids = tokenizer(prompt, padding="longest", return_tensors="pt").input_ids - if untruncated_ids.shape[-1] >= text_input_ids.shape[-1] and not torch.equal( - text_input_ids, untruncated_ids - ): - _actual_max_sequence_length = min(tokenizer.model_max_length, actual_max_sequence_length) - removed_text = tokenizer.batch_decode(untruncated_ids[:, _actual_max_sequence_length - 1 : -1]) - logger.warning( - "The following part of your input was truncated because CLIP can only handle sequences up to" - f" {_actual_max_sequence_length} tokens: {removed_text}" - ) - prompt_attention_mask = text_inputs.attention_mask.to(device) - if self.transformer.config.enable_text_attention_mask: - prompt_embeds = text_encoder( - text_input_ids.to(device), - attention_mask=prompt_attention_mask, - ) + if untruncated_ids.shape[-1] >= text_input_ids.shape[-1] and not torch.equal( + text_input_ids, untruncated_ids + ): + _actual_max_sequence_length = min(tokenizer.model_max_length, actual_max_sequence_length) + removed_text = tokenizer.batch_decode(untruncated_ids[:, _actual_max_sequence_length - 1 : -1]) + logger.warning( + "The following part of your input was truncated because CLIP can only handle sequences up to" + f" {_actual_max_sequence_length} tokens: {removed_text}" + ) + + prompt_attention_mask = text_inputs.attention_mask.to(device) + + if self.transformer.config.enable_text_attention_mask: + prompt_embeds = text_encoder( + text_input_ids.to(device), + attention_mask=prompt_attention_mask, + ) + else: + prompt_embeds = text_encoder( + text_input_ids.to(device) + ) + prompt_embeds = prompt_embeds[0] + prompt_attention_mask = prompt_attention_mask.repeat(num_images_per_prompt, 1) else: - prompt_embeds = text_encoder( - text_input_ids.to(device) + if prompt is not None and isinstance(prompt, str): + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": prompt}], + } + ] + else: + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": _prompt}], + } for _prompt in prompt + ] + text = tokenizer.apply_chat_template( + messages, tokenize=False, add_generation_prompt=True ) - prompt_embeds = prompt_embeds[0] - prompt_attention_mask = prompt_attention_mask.repeat(num_images_per_prompt, 1) + text_inputs = tokenizer( + text=[text], + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + padding_side="right", + return_tensors="pt", + ) + text_inputs = text_inputs.to(text_encoder.device) + + text_input_ids = text_inputs.input_ids + prompt_attention_mask = text_inputs.attention_mask + if self.transformer.config.enable_text_attention_mask: + # Inference: Generation of the output + prompt_embeds = text_encoder( + input_ids=text_input_ids, + attention_mask=prompt_attention_mask, + output_hidden_states=True).hidden_states[-2] + else: + raise ValueError("LLM needs attention_mask") + prompt_attention_mask = prompt_attention_mask.repeat(num_images_per_prompt, 1) + prompt_embeds = prompt_embeds.to(dtype=dtype, device=device) bs_embed, seq_len, _ = prompt_embeds.shape # duplicate text embeddings for each generation per prompt, using mps friendly method prompt_embeds = prompt_embeds.repeat(1, num_images_per_prompt, 1) prompt_embeds = prompt_embeds.view(bs_embed * num_images_per_prompt, seq_len, -1) + prompt_attention_mask = prompt_attention_mask.to(device=device) # get unconditional embeddings for classifier free guidance if do_classifier_free_guidance and negative_prompt_embeds is None: - uncond_tokens: List[str] - if negative_prompt is None: - uncond_tokens = [""] * batch_size - elif prompt is not None and type(prompt) is not type(negative_prompt): - raise TypeError( - f"`negative_prompt` should be the same type to `prompt`, but got {type(negative_prompt)} !=" - f" {type(prompt)}." - ) - elif isinstance(negative_prompt, str): - uncond_tokens = [negative_prompt] - elif batch_size != len(negative_prompt): - raise ValueError( - f"`negative_prompt`: {negative_prompt} has batch size {len(negative_prompt)}, but `prompt`:" - f" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches" - " the batch size of `prompt`." - ) - else: - uncond_tokens = negative_prompt + if type(tokenizer) in [BertTokenizer, T5Tokenizer]: + uncond_tokens: List[str] + if negative_prompt is None: + uncond_tokens = [""] * batch_size + elif prompt is not None and type(prompt) is not type(negative_prompt): + raise TypeError( + f"`negative_prompt` should be the same type to `prompt`, but got {type(negative_prompt)} !=" + f" {type(prompt)}." + ) + elif isinstance(negative_prompt, str): + uncond_tokens = [negative_prompt] + elif batch_size != len(negative_prompt): + raise ValueError( + f"`negative_prompt`: {negative_prompt} has batch size {len(negative_prompt)}, but `prompt`:" + f" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches" + " the batch size of `prompt`." + ) + else: + uncond_tokens = negative_prompt - max_length = prompt_embeds.shape[1] - uncond_input = tokenizer( - uncond_tokens, - padding="max_length", - max_length=max_length, - truncation=True, - return_tensors="pt", - ) - uncond_input_ids = uncond_input.input_ids - if uncond_input_ids.shape[-1] > actual_max_sequence_length: - reuncond_tokens = tokenizer.batch_decode(uncond_input_ids[:, :actual_max_sequence_length], skip_special_tokens=True) + max_length = prompt_embeds.shape[1] uncond_input = tokenizer( - reuncond_tokens, + uncond_tokens, + padding="max_length", + max_length=max_length, + truncation=True, + return_tensors="pt", + ) + uncond_input_ids = uncond_input.input_ids + if uncond_input_ids.shape[-1] > actual_max_sequence_length: + reuncond_tokens = tokenizer.batch_decode(uncond_input_ids[:, :actual_max_sequence_length], skip_special_tokens=True) + uncond_input = tokenizer( + reuncond_tokens, + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + return_tensors="pt", + ) + uncond_input_ids = uncond_input.input_ids + + negative_prompt_attention_mask = uncond_input.attention_mask.to(device) + if self.transformer.config.enable_text_attention_mask: + negative_prompt_embeds = text_encoder( + uncond_input.input_ids.to(device), + attention_mask=negative_prompt_attention_mask, + ) + else: + negative_prompt_embeds = text_encoder( + uncond_input.input_ids.to(device) + ) + negative_prompt_embeds = negative_prompt_embeds[0] + negative_prompt_attention_mask = negative_prompt_attention_mask.repeat(num_images_per_prompt, 1) + else: + if negative_prompt is not None and isinstance(negative_prompt, str): + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": negative_prompt}], + } + ] + else: + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": _negative_prompt}], + } for _negative_prompt in negative_prompt + ] + text = tokenizer.apply_chat_template( + messages, tokenize=False, add_generation_prompt=True + ) + + text_inputs = tokenizer( + text=[text], padding="max_length", max_length=max_length, truncation=True, return_attention_mask=True, + padding_side="right", return_tensors="pt", ) - uncond_input_ids = uncond_input.input_ids + text_inputs = text_inputs.to(text_encoder.device) - negative_prompt_attention_mask = uncond_input.attention_mask.to(device) - if self.transformer.config.enable_text_attention_mask: - negative_prompt_embeds = text_encoder( - uncond_input.input_ids.to(device), - attention_mask=negative_prompt_attention_mask, - ) - else: - negative_prompt_embeds = text_encoder( - uncond_input.input_ids.to(device) - ) - negative_prompt_embeds = negative_prompt_embeds[0] - negative_prompt_attention_mask = negative_prompt_attention_mask.repeat(num_images_per_prompt, 1) + text_input_ids = text_inputs.input_ids + negative_prompt_attention_mask = text_inputs.attention_mask + if self.transformer.config.enable_text_attention_mask: + # Inference: Generation of the output + negative_prompt_embeds = text_encoder( + input_ids=text_input_ids, + attention_mask=negative_prompt_attention_mask, + output_hidden_states=True).hidden_states[-2] + else: + raise ValueError("LLM needs attention_mask") + negative_prompt_attention_mask = negative_prompt_attention_mask.repeat(num_images_per_prompt, 1) if do_classifier_free_guidance: # duplicate unconditional embeddings for each generation per prompt, using mps friendly method @@ -385,24 +549,10 @@ class EasyAnimatePipeline_Multi_Text_Encoder_Control(DiffusionPipeline): negative_prompt_embeds = negative_prompt_embeds.repeat(1, num_images_per_prompt, 1) negative_prompt_embeds = negative_prompt_embeds.view(batch_size * num_images_per_prompt, seq_len, -1) - + negative_prompt_attention_mask = negative_prompt_attention_mask.to(device=device) + return prompt_embeds, negative_prompt_embeds, prompt_attention_mask, negative_prompt_attention_mask - # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.run_safety_checker - def run_safety_checker(self, image, device, dtype): - if self.safety_checker is None: - has_nsfw_concept = None - else: - if torch.is_tensor(image): - feature_extractor_input = self.image_processor.postprocess(image, output_type="pil") - else: - feature_extractor_input = self.image_processor.numpy_to_pil(image) - safety_checker_input = self.feature_extractor(feature_extractor_input, return_tensors="pt").to(device) - image, has_nsfw_concept = self.safety_checker( - images=image, clip_input=safety_checker_input.pixel_values.to(dtype) - ) - return image, has_nsfw_concept - # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.prepare_extra_step_kwargs def prepare_extra_step_kwargs(self, generator, eta): # prepare extra kwargs for the scheduler step, since not all schedulers have the same signature @@ -437,8 +587,8 @@ class EasyAnimatePipeline_Multi_Text_Encoder_Control(DiffusionPipeline): negative_prompt_attention_mask_2=None, callback_on_step_end_tensor_inputs=None, ): - if height % 8 != 0 or width % 8 != 0: - raise ValueError(f"`height` and `width` have to be divisible by 8 but are {height} and {width}.") + if height % 16 != 0 or width % 16 != 0: + raise ValueError(f"`height` and `width` have to be divisible by 16 but are {height} and {width}.") if callback_on_step_end_tensor_inputs is not None and not all( k in self._callback_tensor_inputs for k in callback_on_step_end_tensor_inputs @@ -523,43 +673,44 @@ class EasyAnimatePipeline_Multi_Text_Encoder_Control(DiffusionPipeline): latents = latents.to(device) # scale the initial noise by the standard deviation required by the scheduler - latents = latents * self.scheduler.init_noise_sigma + if hasattr(self.scheduler, "init_noise_sigma"): + latents = latents * self.scheduler.init_noise_sigma return latents def prepare_control_latents( - self, mask, masked_image, batch_size, height, width, dtype, device, generator, do_classifier_free_guidance + self, control, control_image, batch_size, height, width, dtype, device, generator, do_classifier_free_guidance ): - # resize the mask to latents shape as we concatenate the mask to the latents + # resize the control to latents shape as we concatenate the control to the latents # we do that before converting to dtype to avoid breaking in case we're using cpu_offload # and half precision - if mask is not None: - mask = mask.to(device=device, dtype=dtype) + if control is not None: + control = control.to(device=device, dtype=dtype) bs = 1 - new_mask = [] - for i in range(0, mask.shape[0], bs): - mask_bs = mask[i : i + bs] - mask_bs = self.vae.encode(mask_bs)[0] - mask_bs = mask_bs.mode() - new_mask.append(mask_bs) - mask = torch.cat(new_mask, dim = 0) - mask = mask * self.vae.config.scaling_factor + new_control = [] + for i in range(0, control.shape[0], bs): + control_bs = control[i : i + bs] + control_bs = self.vae.encode(control_bs)[0] + control_bs = control_bs.mode() + new_control.append(control_bs) + control = torch.cat(new_control, dim = 0) + control = control * self.vae.config.scaling_factor - if masked_image is not None: - masked_image = masked_image.to(device=device, dtype=dtype) + if control_image is not None: + control_image = control_image.to(device=device, dtype=dtype) bs = 1 - new_mask_pixel_values = [] - for i in range(0, masked_image.shape[0], bs): - mask_pixel_values_bs = masked_image[i : i + bs] - mask_pixel_values_bs = self.vae.encode(mask_pixel_values_bs)[0] - mask_pixel_values_bs = mask_pixel_values_bs.mode() - new_mask_pixel_values.append(mask_pixel_values_bs) - masked_image_latents = torch.cat(new_mask_pixel_values, dim = 0) - masked_image_latents = masked_image_latents * self.vae.config.scaling_factor + new_control_pixel_values = [] + for i in range(0, control_image.shape[0], bs): + control_pixel_values_bs = control_image[i : i + bs] + control_pixel_values_bs = self.vae.encode(control_pixel_values_bs)[0] + control_pixel_values_bs = control_pixel_values_bs.mode() + new_control_pixel_values.append(control_pixel_values_bs) + control_image_latents = torch.cat(new_control_pixel_values, dim = 0) + control_image_latents = control_image_latents * self.vae.config.scaling_factor else: - masked_image_latents = None + control_image_latents = None - return mask, masked_image_latents + return control, control_image_latents def smooth_output(self, video, mini_batch_encoder, mini_batch_decoder): if video.size()[2] <= mini_batch_encoder: @@ -631,6 +782,8 @@ class EasyAnimatePipeline_Multi_Text_Encoder_Control(DiffusionPipeline): height: Optional[int] = None, width: Optional[int] = None, control_video: Union[torch.FloatTensor] = None, + control_camera_video: Union[torch.FloatTensor] = None, + ref_image: Union[torch.FloatTensor] = None, num_inference_steps: Optional[int] = 50, guidance_scale: Optional[float] = 5.0, negative_prompt: Optional[Union[str, List[str]]] = None, @@ -657,6 +810,7 @@ class EasyAnimatePipeline_Multi_Text_Encoder_Control(DiffusionPipeline): target_size: Optional[Tuple[int, int]] = None, crops_coords_top_left: Tuple[int, int] = (0, 0), comfyui_progressbar: bool = False, + timesteps: Optional[List[int]] = None, ): r""" Generates images or video using the EasyAnimate pipeline based on the provided prompts. @@ -787,27 +941,36 @@ class EasyAnimatePipeline_Multi_Text_Encoder_Control(DiffusionPipeline): negative_prompt_attention_mask=negative_prompt_attention_mask, text_encoder_index=0, ) - ( - prompt_embeds_2, - negative_prompt_embeds_2, - prompt_attention_mask_2, - negative_prompt_attention_mask_2, - ) = self.encode_prompt( - prompt=prompt, - device=device, - dtype=dtype, - num_images_per_prompt=num_images_per_prompt, - do_classifier_free_guidance=self.do_classifier_free_guidance, - negative_prompt=negative_prompt, - prompt_embeds=prompt_embeds_2, - negative_prompt_embeds=negative_prompt_embeds_2, - prompt_attention_mask=prompt_attention_mask_2, - negative_prompt_attention_mask=negative_prompt_attention_mask_2, - text_encoder_index=1, - ) + if self.tokenizer_2 is not None: + ( + prompt_embeds_2, + negative_prompt_embeds_2, + prompt_attention_mask_2, + negative_prompt_attention_mask_2, + ) = self.encode_prompt( + prompt=prompt, + device=device, + dtype=dtype, + num_images_per_prompt=num_images_per_prompt, + do_classifier_free_guidance=self.do_classifier_free_guidance, + negative_prompt=negative_prompt, + prompt_embeds=prompt_embeds_2, + negative_prompt_embeds=negative_prompt_embeds_2, + prompt_attention_mask=prompt_attention_mask_2, + negative_prompt_attention_mask=negative_prompt_attention_mask_2, + text_encoder_index=1, + ) + else: + prompt_embeds_2 = None + negative_prompt_embeds_2 = None + prompt_attention_mask_2 = None + negative_prompt_attention_mask_2 = None # 4. Prepare timesteps - self.scheduler.set_timesteps(num_inference_steps, device=device) + if isinstance(self.scheduler, FlowMatchEulerDiscreteScheduler): + timesteps, num_inference_steps = retrieve_timesteps(self.scheduler, num_inference_steps, device, timesteps, mu=1) + else: + timesteps, num_inference_steps = retrieve_timesteps(self.scheduler, num_inference_steps, device, timesteps) timesteps = self.scheduler.timesteps if comfyui_progressbar: from comfy.utils import ProgressBar @@ -829,27 +992,69 @@ class EasyAnimatePipeline_Multi_Text_Encoder_Control(DiffusionPipeline): if comfyui_progressbar: pbar.update(1) - if control_video is not None: + if control_camera_video is not None: + control_video_latents = resize_mask(control_camera_video, latents, process_first_frame_only=True) + control_video_latents = control_video_latents * 6 + control_latents = ( + torch.cat([control_video_latents] * 2) if self.do_classifier_free_guidance else control_video_latents + ).to(device, dtype) + elif control_video is not None: video_length = control_video.shape[2] control_video = self.image_processor.preprocess(rearrange(control_video, "b c f h w -> (b f) c h w"), height=height, width=width) control_video = control_video.to(dtype=torch.float32) control_video = rearrange(control_video, "(b f) c h w -> b c f h w", f=video_length) + control_video_latents = self.prepare_control_latents( + None, + control_video, + batch_size, + height, + width, + dtype, + device, + generator, + self.do_classifier_free_guidance + )[1] + control_latents = ( + torch.cat([control_video_latents] * 2) if self.do_classifier_free_guidance else control_video_latents + ).to(device, dtype) else: - control_video = None - control_video_latents = self.prepare_control_latents( - None, - control_video, - batch_size, - height, - width, - dtype, - device, - generator, - self.do_classifier_free_guidance - )[1] - control_latents = ( - torch.cat([control_video_latents] * 2) if self.do_classifier_free_guidance else control_video_latents - ) + control_video_latents = torch.zeros_like(latents).to(device, dtype) + control_latents = ( + torch.cat([control_video_latents] * 2) if self.do_classifier_free_guidance else control_video_latents + ).to(device, dtype) + + if ref_image is not None: + video_length = ref_image.shape[2] + ref_image = self.image_processor.preprocess(rearrange(ref_image, "b c f h w -> (b f) c h w"), height=height, width=width) + ref_image = ref_image.to(dtype=torch.float32) + ref_image = rearrange(ref_image, "(b f) c h w -> b c f h w", f=video_length) + + ref_image_latentes = self.prepare_control_latents( + None, + ref_image, + batch_size, + height, + width, + prompt_embeds.dtype, + device, + generator, + self.do_classifier_free_guidance + )[1] + + ref_image_latentes_conv_in = torch.zeros_like(latents) + if latents.size()[2] != 1: + ref_image_latentes_conv_in[:, :, :1] = ref_image_latentes + ref_image_latentes_conv_in = ( + torch.cat([ref_image_latentes_conv_in] * 2) if self.do_classifier_free_guidance else ref_image_latentes_conv_in + ).to(device, dtype) + control_latents = torch.cat([control_latents, ref_image_latentes_conv_in], dim = 1) + else: + if self.transformer.config.get("add_ref_latent_in_control_model", False): + ref_image_latentes_conv_in = torch.zeros_like(latents) + ref_image_latentes_conv_in = ( + torch.cat([ref_image_latentes_conv_in] * 2) if self.do_classifier_free_guidance else ref_image_latentes_conv_in + ).to(device, dtype) + control_latents = torch.cat([control_latents, ref_image_latentes_conv_in], dim = 1) if comfyui_progressbar: pbar.update(1) @@ -881,30 +1086,49 @@ class EasyAnimatePipeline_Multi_Text_Encoder_Control(DiffusionPipeline): ) # Get other hunyuan params - style = torch.tensor([0], device=device) - target_size = target_size or (height, width) add_time_ids = list(original_size + target_size + crops_coords_top_left) add_time_ids = torch.tensor([add_time_ids], dtype=dtype) + style = torch.tensor([0], device=device) if self.do_classifier_free_guidance: - prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds]) - prompt_attention_mask = torch.cat([negative_prompt_attention_mask, prompt_attention_mask]) - prompt_embeds_2 = torch.cat([negative_prompt_embeds_2, prompt_embeds_2]) - prompt_attention_mask_2 = torch.cat([negative_prompt_attention_mask_2, prompt_attention_mask_2]) add_time_ids = torch.cat([add_time_ids] * 2, dim=0) style = torch.cat([style] * 2, dim=0) # To latents.device - prompt_embeds = prompt_embeds.to(device=device) - prompt_attention_mask = prompt_attention_mask.to(device=device) - prompt_embeds_2 = prompt_embeds_2.to(device=device) - prompt_attention_mask_2 = prompt_attention_mask_2.to(device=device) add_time_ids = add_time_ids.to(dtype=dtype, device=device).repeat( batch_size * num_images_per_prompt, 1 ) style = style.to(device=device).repeat(batch_size * num_images_per_prompt) + # Get other pixart params + added_cond_kwargs = {"resolution": None, "aspect_ratio": None} + if self.transformer.config.get("sample_size", 64) == 128: + resolution = torch.tensor([height, width]).repeat(batch_size * num_images_per_prompt, 1) + aspect_ratio = torch.tensor([float(height / width)]).repeat(batch_size * num_images_per_prompt, 1) + resolution = resolution.to(dtype=dtype, device=device) + aspect_ratio = aspect_ratio.to(dtype=dtype, device=device) + + if self.do_classifier_free_guidance: + resolution = torch.cat([resolution, resolution], dim=0) + aspect_ratio = torch.cat([aspect_ratio, aspect_ratio], dim=0) + + added_cond_kwargs = {"resolution": resolution, "aspect_ratio": aspect_ratio} + + if self.do_classifier_free_guidance: + prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds]) + prompt_attention_mask = torch.cat([negative_prompt_attention_mask, prompt_attention_mask]) + if prompt_embeds_2 is not None: + prompt_embeds_2 = torch.cat([negative_prompt_embeds_2, prompt_embeds_2]) + prompt_attention_mask_2 = torch.cat([negative_prompt_attention_mask_2, prompt_attention_mask_2]) + + # To latents.device + prompt_embeds = prompt_embeds.to(device=device) + prompt_attention_mask = prompt_attention_mask.to(device=device) + if prompt_embeds_2 is not None: + prompt_embeds_2 = prompt_embeds_2.to(device=device) + prompt_attention_mask_2 = prompt_attention_mask_2.to(device=device) + # 8. Denoising loop num_warmup_steps = len(timesteps) - num_inference_steps * self.scheduler.order self._num_timesteps = len(timesteps) @@ -915,7 +1139,8 @@ class EasyAnimatePipeline_Multi_Text_Encoder_Control(DiffusionPipeline): # expand the latents if we are doing classifier free guidance latent_model_input = torch.cat([latents] * 2) if self.do_classifier_free_guidance else latents - latent_model_input = self.scheduler.scale_model_input(latent_model_input, t) + if hasattr(self.scheduler, "scale_model_input"): + latent_model_input = self.scheduler.scale_model_input(latent_model_input, t) # expand scalar t to 1-D tensor to match the 1st dim of latent_model_input t_expand = torch.tensor([t] * latent_model_input.shape[0], device=device).to( @@ -932,8 +1157,9 @@ class EasyAnimatePipeline_Multi_Text_Encoder_Control(DiffusionPipeline): image_meta_size=add_time_ids, style=style, image_rotary_emb=image_rotary_emb, - return_dict=False, + added_cond_kwargs=added_cond_kwargs, control_latents=control_latents, + return_dict=False, )[0] if noise_pred.size()[1] != self.vae.config.latent_channels: noise_pred, _ = noise_pred.chunk(2, dim=1) @@ -986,4 +1212,4 @@ class EasyAnimatePipeline_Multi_Text_Encoder_Control(DiffusionPipeline): if not return_dict: return video - return EasyAnimatePipelineOutput(videos=video) \ No newline at end of file + return EasyAnimatePipelineOutput(frames=video) \ No newline at end of file diff --git a/easyanimate/pipeline/pipeline_easyanimate_inpaint.py b/easyanimate/pipeline/pipeline_easyanimate_inpaint.py index 26d50bf..ffc5c45 100644 --- a/easyanimate/pipeline/pipeline_easyanimate_inpaint.py +++ b/easyanimate/pipeline/pipeline_easyanimate_inpaint.py @@ -1,4 +1,4 @@ -# Copyright 2023 PixArt-Alpha Authors and The HuggingFace Team. All rights reserved. +# Copyright 2024 EasyAnimate Authors and The HuggingFace Team. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,148 +12,336 @@ # See the License for the specific language governing permissions and # limitations under the License. -import copy -import gc -import html import inspect -import re -import urllib.parse as ul -from dataclasses import dataclass -from typing import Callable, List, Optional, Tuple, Union +from typing import Callable, Dict, List, Optional, Tuple, Union import numpy as np import torch import torch.nn.functional as F -from diffusers import DiffusionPipeline, ImagePipelineOutput +from dataclasses import dataclass +from diffusers import DiffusionPipeline +from diffusers.callbacks import MultiPipelineCallbacks, PipelineCallback from diffusers.image_processor import VaeImageProcessor -from diffusers.models import AutoencoderKL -from diffusers.schedulers import DPMSolverMultistepScheduler +from diffusers.models import AutoencoderKL, HunyuanDiT2DModel +from diffusers.models.embeddings import (get_2d_rotary_pos_embed, + get_3d_rotary_pos_embed) +from diffusers.pipelines.pipeline_utils import DiffusionPipeline +from diffusers.pipelines.stable_diffusion.safety_checker import \ + StableDiffusionSafetyChecker +from diffusers.schedulers import DDIMScheduler, FlowMatchEulerDiscreteScheduler from diffusers.utils import (BACKENDS_MAPPING, BaseOutput, deprecate, - is_bs4_available, is_ftfy_available, logging, + is_bs4_available, is_ftfy_available, + is_torch_xla_available, logging, replace_example_docstring) from diffusers.utils.torch_utils import randn_tensor from einops import rearrange from PIL import Image from tqdm import tqdm -from transformers import (CLIPImageProcessor, CLIPVisionModelWithProjection, +from transformers import (BertModel, BertTokenizer, CLIPImageProcessor, + Qwen2Tokenizer, Qwen2VLForConditionalGeneration, CLIPVisionModelWithProjection, T5EncoderModel, T5Tokenizer) -from ..models.transformer3d import Transformer3DModel +from ..models import AutoencoderKLMagvit, EasyAnimateTransformer3DModel + +if is_torch_xla_available(): + import torch_xla.core.xla_model as xm + + XLA_AVAILABLE = True +else: + XLA_AVAILABLE = False + logger = logging.get_logger(__name__) # pylint: disable=invalid-name -if is_bs4_available(): - from bs4 import BeautifulSoup - -if is_ftfy_available(): - import ftfy - - EXAMPLE_DOC_STRING = """ Examples: ```py >>> import torch - >>> from diffusers import EasyAnimatePipeline + >>> from diffusers import EasyAnimateInpaintPipeline + >>> from diffusers.easyanimate.pipeline_easyanimate_inpaint import get_image_to_video_latent + >>> from diffusers.utils import export_to_video, load_image - >>> # You can replace the checkpoint id with "PixArt-alpha/PixArt-XL-2-512x512" too. - >>> pipe = EasyAnimatePipeline.from_pretrained("PixArt-alpha/PixArt-XL-2-1024-MS", torch_dtype=torch.float16) - >>> # Enable memory optimizations. - >>> pipe.enable_model_cpu_offload() + >>> pipe = EasyAnimateInpaintPipeline.from_pretrained("alibaba-pai/EasyAnimateV5.1-12b-zh-InP", torch_dtype=torch.bfloat16) + >>> pipe.to("cuda") - >>> prompt = "A small cactus with a happy face in the Sahara desert." - >>> image = pipe(prompt).images[0] + >>> prompt = "An astronaut hatching from an egg, on the surface of the moon, the darkness and depth of space realised in the background. High quality, ultrarealistic detail and breath-taking movie-like camera shot." + >>> validation_image_start = load_image( + ... "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/astronaut.jpg" + ... ) + >>> validation_image_end = None + >>> sample_size = (576, 448) + >>> video_length = 49 + >>> input_video, input_video_mask, _ = get_image_to_video_latent(validation_image_start, validation_image_end, video_length, sample_size) + >>> video = pipe(prompt, video_length=video_length, negative_prompt="bad detailed", height=sample_size[0], width=sample_size[1], input_video=input_video, mask_video=input_video_mask) + >>> export_to_video(video.sample[0], "output.mp4", fps=8) ``` """ -# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion_img2img.retrieve_latents -def retrieve_latents(encoder_output, generator): - if hasattr(encoder_output, "latent_dist"): - return encoder_output.latent_dist.sample(generator) - elif hasattr(encoder_output, "latents"): - return encoder_output.latents + + +# Similar to diffusers.pipelines.hunyuandit.pipeline_hunyuandit.get_resize_crop_region_for_grid +def get_resize_crop_region_for_grid(src, tgt_width, tgt_height): + tw = tgt_width + th = tgt_height + h, w = src + r = h / w + if r > (th / tw): + resize_height = th + resize_width = int(round(th / h * w)) else: - raise AttributeError("Could not access latents of provided encoder_output") + resize_width = tw + resize_height = int(round(tw / w * h)) + + crop_top = int(round((th - resize_height) / 2.0)) + crop_left = int(round((tw - resize_width) / 2.0)) + + return (crop_top, crop_left), (crop_top + resize_height, crop_left + resize_width) + + +# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.rescale_noise_cfg +def rescale_noise_cfg(noise_cfg, noise_pred_text, guidance_rescale=0.0): + """ + Rescale `noise_cfg` according to `guidance_rescale`. Based on findings of [Common Diffusion Noise Schedules and + Sample Steps are Flawed](https://arxiv.org/pdf/2305.08891.pdf). See Section 3.4 + """ + std_text = noise_pred_text.std(dim=list(range(1, noise_pred_text.ndim)), keepdim=True) + std_cfg = noise_cfg.std(dim=list(range(1, noise_cfg.ndim)), keepdim=True) + # rescale the results from guidance (fixes overexposure) + noise_pred_rescaled = noise_cfg * (std_text / std_cfg) + # mix with the original results from guidance by factor guidance_rescale to avoid "plain looking" images + noise_cfg = guidance_rescale * noise_pred_rescaled + (1 - guidance_rescale) * noise_cfg + return noise_cfg + + +# Resize mask information in magvit +def resize_mask(mask, latent, process_first_frame_only=True): + latent_size = latent.size() + + if process_first_frame_only: + target_size = list(latent_size[2:]) + target_size[0] = 1 + first_frame_resized = F.interpolate( + mask[:, :, 0:1, :, :], + size=target_size, + mode='trilinear', + align_corners=False + ) + + target_size = list(latent_size[2:]) + target_size[0] = target_size[0] - 1 + if target_size[0] != 0: + remaining_frames_resized = F.interpolate( + mask[:, :, 1:, :, :], + size=target_size, + mode='trilinear', + align_corners=False + ) + resized_mask = torch.cat([first_frame_resized, remaining_frames_resized], dim=2) + else: + resized_mask = first_frame_resized + else: + target_size = list(latent_size[2:]) + resized_mask = F.interpolate( + mask, + size=target_size, + mode='trilinear', + align_corners=False + ) + return resized_mask + + +## Add noise to reference video +def add_noise_to_reference_video(image, ratio=None): + if ratio is None: + sigma = torch.normal(mean=-3.0, std=0.5, size=(image.shape[0],)).to(image.device) + sigma = torch.exp(sigma).to(image.dtype) + else: + sigma = torch.ones((image.shape[0],)).to(image.device, image.dtype) * ratio + image_noise = torch.randn_like(image) * sigma[:, None, None, None, None] + image_noise = torch.where(image==-1, torch.zeros_like(image), image_noise) + image = image + image_noise + return image + + +# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.retrieve_timesteps +def retrieve_timesteps( + scheduler, + num_inference_steps: Optional[int] = None, + device: Optional[Union[str, torch.device]] = None, + timesteps: Optional[List[int]] = None, + sigmas: Optional[List[float]] = None, + **kwargs, +): + """ + Calls the scheduler's `set_timesteps` method and retrieves timesteps from the scheduler after the call. Handles + custom timesteps. Any kwargs will be supplied to `scheduler.set_timesteps`. + + Args: + scheduler (`SchedulerMixin`): + The scheduler to get timesteps from. + num_inference_steps (`int`): + The number of diffusion steps used when generating samples with a pre-trained model. If used, `timesteps` + must be `None`. + device (`str` or `torch.device`, *optional*): + The device to which the timesteps should be moved to. If `None`, the timesteps are not moved. + timesteps (`List[int]`, *optional*): + Custom timesteps used to override the timestep spacing strategy of the scheduler. If `timesteps` is passed, + `num_inference_steps` and `sigmas` must be `None`. + sigmas (`List[float]`, *optional*): + Custom sigmas used to override the timestep spacing strategy of the scheduler. If `sigmas` is passed, + `num_inference_steps` and `timesteps` must be `None`. + + Returns: + `Tuple[torch.Tensor, int]`: A tuple where the first element is the timestep schedule from the scheduler and the + second element is the number of inference steps. + """ + if timesteps is not None and sigmas is not None: + raise ValueError("Only one of `timesteps` or `sigmas` can be passed. Please choose one to set custom values") + if timesteps is not None: + accepts_timesteps = "timesteps" in set(inspect.signature(scheduler.set_timesteps).parameters.keys()) + if not accepts_timesteps: + raise ValueError( + f"The current scheduler class {scheduler.__class__}'s `set_timesteps` does not support custom" + f" timestep schedules. Please check whether you are using the correct scheduler." + ) + scheduler.set_timesteps(timesteps=timesteps, device=device, **kwargs) + timesteps = scheduler.timesteps + num_inference_steps = len(timesteps) + elif sigmas is not None: + accept_sigmas = "sigmas" in set(inspect.signature(scheduler.set_timesteps).parameters.keys()) + if not accept_sigmas: + raise ValueError( + f"The current scheduler class {scheduler.__class__}'s `set_timesteps` does not support custom" + f" sigmas schedules. Please check whether you are using the correct scheduler." + ) + scheduler.set_timesteps(sigmas=sigmas, device=device, **kwargs) + timesteps = scheduler.timesteps + num_inference_steps = len(timesteps) + else: + scheduler.set_timesteps(num_inference_steps, device=device, **kwargs) + timesteps = scheduler.timesteps + return timesteps, num_inference_steps + + @dataclass class EasyAnimatePipelineOutput(BaseOutput): - videos: Union[torch.Tensor, np.ndarray] + r""" + Output class for EasyAnimate pipelines. + + Args: + frames (`torch.Tensor`, `np.ndarray`, or List[List[PIL.Image.Image]]): + List of video outputs - It can be a nested list of length `batch_size,` with each sub-list containing + denoised PIL image sequences of length `num_frames.` It can also be a NumPy array or Torch tensor of shape + `(batch_size, num_frames, channels, height, width)`. + """ + + frames: torch.Tensor + class EasyAnimateInpaintPipeline(DiffusionPipeline): r""" - Pipeline for text-to-image generation using PixArt-Alpha. + Pipeline for text-to-video generation using EasyAnimate. This model inherits from [`DiffusionPipeline`]. Check the superclass documentation for the generic methods the library implements for all the pipelines (such as downloading or saving, running on a particular device, etc.) - Args: - vae ([`AutoencoderKL`]): - Variational Auto-Encoder (VAE) Model to encode and decode images to and from latent representations. - text_encoder ([`T5EncoderModel`]): - Frozen text-encoder. PixArt-Alpha uses - [T5](https://huggingface.co/docs/transformers/model_doc/t5#transformers.T5EncoderModel), specifically the - [t5-v1_1-xxl](https://huggingface.co/PixArt-alpha/PixArt-alpha/tree/main/t5-v1_1-xxl) variant. - tokenizer (`T5Tokenizer`): - Tokenizer of class - [T5Tokenizer](https://huggingface.co/docs/transformers/model_doc/t5#transformers.T5Tokenizer). - transformer ([`Transformer3DModel`]): - A text conditioned `Transformer3DModel` to denoise the encoded image latents. - scheduler ([`SchedulerMixin`]): - A scheduler to be used in combination with `transformer` to denoise the encoded image latents. - """ - bad_punct_regex = re.compile( - r"[" + "#®•©™&@·º½¾¿¡§~" + "\)" + "\(" + "\]" + "\[" + "\}" + "\{" + "\|" + "\\" + "\/" + "\*" + r"]{1,}" - ) # noqa + EasyAnimate uses one text encoder [qwen2 vl](https://huggingface.co/Qwen/Qwen2-VL-7B-Instruct) in V5.1. + EasyAnimate uses two text encoders: [mT5](https://huggingface.co/google/mt5-base) and [bilingual CLIP](fine-tuned by + HunyuanDiT team) in V5. - _optional_components = ["tokenizer", "text_encoder"] - model_cpu_offload_seq = "text_encoder->transformer->vae" + Args: + vae ([`AutoencoderKLMagvit`]): + Variational Auto-Encoder (VAE) Model to encode and decode video to and from latent representations. + text_encoder (Optional[`~transformers.Qwen2VLForConditionalGeneration`, `~transformers.BertModel`]): + EasyAnimate uses [qwen2 vl](https://huggingface.co/Qwen/Qwen2-VL-7B-Instruct) in V5.1. + EasyAnimate uses [bilingual CLIP](https://huggingface.co/Tencent-Hunyuan/HunyuanDiT-v1.2-Diffusers) in V5. + tokenizer (Optional[`~transformers.Qwen2Tokenizer`, `~transformers.BertTokenizer`]): + A `Qwen2Tokenizer` or `BertTokenizer` to tokenize text. + transformer ([`EasyAnimateTransformer3DModel`]): + The EasyAnimate model designed by EasyAnimate Team. + text_encoder_2 (`T5EncoderModel`): + EasyAnimate does not use text_encoder_2 in V5.1. + EasyAnimate uses [mT5](https://huggingface.co/google/mt5-base) embedder in V5. + tokenizer_2 (`T5Tokenizer`): + The tokenizer for the mT5 embedder. + scheduler ([`FlowMatchEulerDiscreteScheduler`]): + A scheduler to be used in combination with EasyAnimate to denoise the encoded image latents. + clip_image_processor (`CLIPImageProcessor`): + The CLIP image embedder. + clip_image_encoder (`CLIPVisionModelWithProjection`): + The image processor for the CLIP image embedder. + """ + + model_cpu_offload_seq = "text_encoder->text_encoder_2->clip_image_encoder->transformer->vae" + _optional_components = [ + "text_encoder_2", + "tokenizer_2", + "text_encoder", + "tokenizer", + "clip_image_encoder", + ] + _callback_tensor_inputs = [ + "latents", + "prompt_embeds", + "negative_prompt_embeds", + "prompt_embeds_2", + "negative_prompt_embeds_2", + ] def __init__( self, - tokenizer: T5Tokenizer, - text_encoder: T5EncoderModel, - vae: AutoencoderKL, - transformer: Transformer3DModel, - scheduler: DPMSolverMultistepScheduler, - clip_image_processor:CLIPImageProcessor = None, - clip_image_encoder:CLIPVisionModelWithProjection = None, + vae: AutoencoderKLMagvit, + text_encoder: Union[Qwen2VLForConditionalGeneration, BertModel], + tokenizer: Union[Qwen2Tokenizer, BertTokenizer], + text_encoder_2: Optional[Union[T5EncoderModel, Qwen2VLForConditionalGeneration]], + tokenizer_2: Optional[Union[T5Tokenizer, Qwen2Tokenizer]], + transformer: EasyAnimateTransformer3DModel, + scheduler: FlowMatchEulerDiscreteScheduler, + clip_image_processor: CLIPImageProcessor = None, + clip_image_encoder: CLIPVisionModelWithProjection = None, ): super().__init__() self.register_modules( - tokenizer=tokenizer, text_encoder=text_encoder, vae=vae, transformer=transformer, + vae=vae, + text_encoder=text_encoder, + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + transformer=transformer, scheduler=scheduler, - clip_image_processor=clip_image_processor, clip_image_encoder=clip_image_encoder, + text_encoder_2=text_encoder_2, + clip_image_processor=clip_image_processor, + clip_image_encoder=clip_image_encoder, ) self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1) - self.image_processor = VaeImageProcessor(vae_scale_factor=self.vae_scale_factor, do_normalize=True) + self.image_processor = VaeImageProcessor(vae_scale_factor=self.vae_scale_factor) self.mask_processor = VaeImageProcessor( vae_scale_factor=self.vae_scale_factor, do_normalize=False, do_binarize=True, do_convert_grayscale=True ) - # Adapted from https://github.com/PixArt-alpha/PixArt-alpha/blob/master/diffusion/model/utils.py - def mask_text_embeddings(self, emb, mask): - if emb.shape[0] == 1: - keep_index = mask.sum().item() - return emb[:, :, :keep_index, :], keep_index - else: - masked_feature = emb * mask[:, None, :, None] - return masked_feature, emb.shape[2] + def enable_sequential_cpu_offload(self, *args, **kwargs): + super().enable_sequential_cpu_offload(*args, **kwargs) + if hasattr(self.transformer, "clip_projection") and self.transformer.clip_projection is not None: + import accelerate + accelerate.hooks.remove_hook_from_module(self.transformer.clip_projection, recurse=True) + self.transformer.clip_projection = self.transformer.clip_projection.to("cuda") - # Adapted from diffusers.pipelines.deepfloyd_if.pipeline_if.encode_prompt def encode_prompt( self, - prompt: Union[str, List[str]], - do_classifier_free_guidance: bool = True, - negative_prompt: str = "", + prompt: str, + device: torch.device, + dtype: torch.dtype, num_images_per_prompt: int = 1, - device: Optional[torch.device] = None, - prompt_embeds: Optional[torch.FloatTensor] = None, - negative_prompt_embeds: Optional[torch.FloatTensor] = None, - prompt_attention_mask: Optional[torch.FloatTensor] = None, - negative_prompt_attention_mask: Optional[torch.FloatTensor] = None, - clean_caption: bool = False, - max_sequence_length: int = 120, - **kwargs, + do_classifier_free_guidance: bool = True, + negative_prompt: Optional[str] = None, + prompt_embeds: Optional[torch.Tensor] = None, + negative_prompt_embeds: Optional[torch.Tensor] = None, + prompt_attention_mask: Optional[torch.Tensor] = None, + negative_prompt_attention_mask: Optional[torch.Tensor] = None, + max_sequence_length: Optional[int] = None, + text_encoder_index: int = 0, + actual_max_sequence_length: int = 256 ): r""" Encodes the prompt into text encoder hidden states. @@ -161,33 +349,46 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): Args: prompt (`str` or `List[str]`, *optional*): prompt to be encoded - negative_prompt (`str` or `List[str]`, *optional*): - The prompt not to guide the image generation. If not defined, one has to pass `negative_prompt_embeds` - instead. Ignored when not using guidance (i.e., ignored if `guidance_scale` is less than `1`). For - PixArt-Alpha, this should be "". - do_classifier_free_guidance (`bool`, *optional*, defaults to `True`): - whether to use classifier free guidance or not - num_images_per_prompt (`int`, *optional*, defaults to 1): + device: (`torch.device`): + torch device + dtype (`torch.dtype`): + torch dtype + num_images_per_prompt (`int`): number of images that should be generated per prompt - device: (`torch.device`, *optional*): - torch device to place the resulting embeddings on - prompt_embeds (`torch.FloatTensor`, *optional*): + do_classifier_free_guidance (`bool`): + whether to use classifier free guidance or not + negative_prompt (`str` or `List[str]`, *optional*): + The prompt or prompts not to guide the image generation. If not defined, one has to pass + `negative_prompt_embeds` instead. Ignored when not using guidance (i.e., ignored if `guidance_scale` is + less than `1`). + prompt_embeds (`torch.Tensor`, *optional*): Pre-generated text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting. If not provided, text embeddings will be generated from `prompt` input argument. - negative_prompt_embeds (`torch.FloatTensor`, *optional*): - Pre-generated negative text embeddings. For PixArt-Alpha, it's should be the embeddings of the "" - string. - clean_caption (`bool`, defaults to `False`): - If `True`, the function will preprocess and clean the provided caption before encoding. - max_sequence_length (`int`, defaults to 120): Maximum sequence length to use for the prompt. + negative_prompt_embeds (`torch.Tensor`, *optional*): + Pre-generated negative text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt + weighting. If not provided, negative_prompt_embeds will be generated from `negative_prompt` input + argument. + prompt_attention_mask (`torch.Tensor`, *optional*): + Attention mask for the prompt. Required when `prompt_embeds` is passed directly. + negative_prompt_attention_mask (`torch.Tensor`, *optional*): + Attention mask for the negative prompt. Required when `negative_prompt_embeds` is passed directly. + max_sequence_length (`int`, *optional*): maximum sequence length to use for the prompt. + text_encoder_index (`int`, *optional*): + Index of the text encoder to use. `0` for clip and `1` for T5. """ + tokenizers = [self.tokenizer, self.tokenizer_2] + text_encoders = [self.text_encoder, self.text_encoder_2] - if "mask_feature" in kwargs: - deprecation_message = "The use of `mask_feature` is deprecated. It is no longer used in any computation and that doesn't affect the end results. It will be removed in a future version." - deprecate("mask_feature", "1.0.0", deprecation_message, standard_warn=False) + tokenizer = tokenizers[text_encoder_index] + text_encoder = text_encoders[text_encoder_index] - if device is None: - device = self._execution_device + if max_sequence_length is None: + if text_encoder_index == 0: + max_length = min(self.tokenizer.model_max_length, actual_max_sequence_length) + if text_encoder_index == 1: + max_length = min(self.tokenizer_2.model_max_length, actual_max_sequence_length) + else: + max_length = max_sequence_length if prompt is not None and isinstance(prompt, str): batch_size = 1 @@ -196,74 +397,199 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): else: batch_size = prompt_embeds.shape[0] - # See Section 3.1. of the paper. - max_length = max_sequence_length - if prompt_embeds is None: - prompt = self._text_preprocessing(prompt, clean_caption=clean_caption) - text_inputs = self.tokenizer( - prompt, - padding="max_length", - max_length=max_length, - truncation=True, - add_special_tokens=True, - return_tensors="pt", - ) - text_input_ids = text_inputs.input_ids - untruncated_ids = self.tokenizer(prompt, padding="longest", return_tensors="pt").input_ids + if type(tokenizer) in [BertTokenizer, T5Tokenizer]: + text_inputs = tokenizer( + prompt, + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + return_tensors="pt", + ) + text_input_ids = text_inputs.input_ids + if text_input_ids.shape[-1] > actual_max_sequence_length: + reprompt = tokenizer.batch_decode(text_input_ids[:, :actual_max_sequence_length], skip_special_tokens=True) + text_inputs = tokenizer( + reprompt, + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + return_tensors="pt", + ) + text_input_ids = text_inputs.input_ids + untruncated_ids = tokenizer(prompt, padding="longest", return_tensors="pt").input_ids - if untruncated_ids.shape[-1] >= text_input_ids.shape[-1] and not torch.equal( - text_input_ids, untruncated_ids - ): - removed_text = self.tokenizer.batch_decode(untruncated_ids[:, max_length - 1 : -1]) - logger.warning( - "The following part of your input was truncated because CLIP can only handle sequences up to" - f" {max_length} tokens: {removed_text}" + if untruncated_ids.shape[-1] >= text_input_ids.shape[-1] and not torch.equal( + text_input_ids, untruncated_ids + ): + _actual_max_sequence_length = min(tokenizer.model_max_length, actual_max_sequence_length) + removed_text = tokenizer.batch_decode(untruncated_ids[:, _actual_max_sequence_length - 1 : -1]) + logger.warning( + "The following part of your input was truncated because CLIP can only handle sequences up to" + f" {_actual_max_sequence_length} tokens: {removed_text}" + ) + + prompt_attention_mask = text_inputs.attention_mask.to(device) + + if self.transformer.config.enable_text_attention_mask: + prompt_embeds = text_encoder( + text_input_ids.to(device), + attention_mask=prompt_attention_mask, + ) + else: + prompt_embeds = text_encoder( + text_input_ids.to(device) + ) + prompt_embeds = prompt_embeds[0] + prompt_attention_mask = prompt_attention_mask.repeat(num_images_per_prompt, 1) + else: + if prompt is not None and isinstance(prompt, str): + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": prompt}], + } + ] + else: + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": _prompt}], + } for _prompt in prompt + ] + text = tokenizer.apply_chat_template( + messages, tokenize=False, add_generation_prompt=True ) - prompt_attention_mask = text_inputs.attention_mask - prompt_attention_mask = prompt_attention_mask.to(device) - - prompt_embeds = self.text_encoder(text_input_ids.to(device), attention_mask=prompt_attention_mask) - prompt_embeds = prompt_embeds[0] - - if self.text_encoder is not None: - dtype = self.text_encoder.dtype - elif self.transformer is not None: - dtype = self.transformer.dtype - else: - dtype = None + text_inputs = tokenizer( + text=[text], + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + padding_side="right", + return_tensors="pt", + ) + text_inputs = text_inputs.to(text_encoder.device) + text_input_ids = text_inputs.input_ids + prompt_attention_mask = text_inputs.attention_mask + if self.transformer.config.enable_text_attention_mask: + # Inference: Generation of the output + prompt_embeds = text_encoder( + input_ids=text_input_ids, + attention_mask=prompt_attention_mask, + output_hidden_states=True).hidden_states[-2] + else: + raise ValueError("LLM needs attention_mask") + prompt_attention_mask = prompt_attention_mask.repeat(num_images_per_prompt, 1) + prompt_embeds = prompt_embeds.to(dtype=dtype, device=device) bs_embed, seq_len, _ = prompt_embeds.shape - # duplicate text embeddings and attention mask for each generation per prompt, using mps friendly method + # duplicate text embeddings for each generation per prompt, using mps friendly method prompt_embeds = prompt_embeds.repeat(1, num_images_per_prompt, 1) prompt_embeds = prompt_embeds.view(bs_embed * num_images_per_prompt, seq_len, -1) - prompt_attention_mask = prompt_attention_mask.view(bs_embed, -1) - prompt_attention_mask = prompt_attention_mask.repeat(num_images_per_prompt, 1) + prompt_attention_mask = prompt_attention_mask.to(device=device) # get unconditional embeddings for classifier free guidance if do_classifier_free_guidance and negative_prompt_embeds is None: - uncond_tokens = [negative_prompt] * batch_size - uncond_tokens = self._text_preprocessing(uncond_tokens, clean_caption=clean_caption) - max_length = prompt_embeds.shape[1] - uncond_input = self.tokenizer( - uncond_tokens, - padding="max_length", - max_length=max_length, - truncation=True, - return_attention_mask=True, - add_special_tokens=True, - return_tensors="pt", - ) - negative_prompt_attention_mask = uncond_input.attention_mask - negative_prompt_attention_mask = negative_prompt_attention_mask.to(device) + if type(tokenizer) in [BertTokenizer, T5Tokenizer]: + uncond_tokens: List[str] + if negative_prompt is None: + uncond_tokens = [""] * batch_size + elif prompt is not None and type(prompt) is not type(negative_prompt): + raise TypeError( + f"`negative_prompt` should be the same type to `prompt`, but got {type(negative_prompt)} !=" + f" {type(prompt)}." + ) + elif isinstance(negative_prompt, str): + uncond_tokens = [negative_prompt] + elif batch_size != len(negative_prompt): + raise ValueError( + f"`negative_prompt`: {negative_prompt} has batch size {len(negative_prompt)}, but `prompt`:" + f" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches" + " the batch size of `prompt`." + ) + else: + uncond_tokens = negative_prompt - negative_prompt_embeds = self.text_encoder( - uncond_input.input_ids.to(device), attention_mask=negative_prompt_attention_mask - ) - negative_prompt_embeds = negative_prompt_embeds[0] + max_length = prompt_embeds.shape[1] + uncond_input = tokenizer( + uncond_tokens, + padding="max_length", + max_length=max_length, + truncation=True, + return_tensors="pt", + ) + uncond_input_ids = uncond_input.input_ids + if uncond_input_ids.shape[-1] > actual_max_sequence_length: + reuncond_tokens = tokenizer.batch_decode(uncond_input_ids[:, :actual_max_sequence_length], skip_special_tokens=True) + uncond_input = tokenizer( + reuncond_tokens, + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + return_tensors="pt", + ) + uncond_input_ids = uncond_input.input_ids + + negative_prompt_attention_mask = uncond_input.attention_mask.to(device) + if self.transformer.config.enable_text_attention_mask: + negative_prompt_embeds = text_encoder( + uncond_input.input_ids.to(device), + attention_mask=negative_prompt_attention_mask, + ) + else: + negative_prompt_embeds = text_encoder( + uncond_input.input_ids.to(device) + ) + negative_prompt_embeds = negative_prompt_embeds[0] + negative_prompt_attention_mask = negative_prompt_attention_mask.repeat(num_images_per_prompt, 1) + else: + if negative_prompt is not None and isinstance(negative_prompt, str): + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": negative_prompt}], + } + ] + else: + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": _negative_prompt}], + } for _negative_prompt in negative_prompt + ] + text = tokenizer.apply_chat_template( + messages, tokenize=False, add_generation_prompt=True + ) + + text_inputs = tokenizer( + text=[text], + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + padding_side="right", + return_tensors="pt", + ) + text_inputs = text_inputs.to(text_encoder.device) + + text_input_ids = text_inputs.input_ids + negative_prompt_attention_mask = text_inputs.attention_mask + if self.transformer.config.enable_text_attention_mask: + # Inference: Generation of the output + negative_prompt_embeds = text_encoder( + input_ids=text_input_ids, + attention_mask=negative_prompt_attention_mask, + output_hidden_states=True).hidden_states[-2] + else: + raise ValueError("LLM needs attention_mask") + negative_prompt_attention_mask = negative_prompt_attention_mask.repeat(num_images_per_prompt, 1) if do_classifier_free_guidance: # duplicate unconditional embeddings for each generation per prompt, using mps friendly method @@ -273,14 +599,9 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): negative_prompt_embeds = negative_prompt_embeds.repeat(1, num_images_per_prompt, 1) negative_prompt_embeds = negative_prompt_embeds.view(batch_size * num_images_per_prompt, seq_len, -1) - - negative_prompt_attention_mask = negative_prompt_attention_mask.view(bs_embed, -1) - negative_prompt_attention_mask = negative_prompt_attention_mask.repeat(num_images_per_prompt, 1) - else: - negative_prompt_embeds = None - negative_prompt_attention_mask = None - - return prompt_embeds, prompt_attention_mask, negative_prompt_embeds, negative_prompt_attention_mask + negative_prompt_attention_mask = negative_prompt_attention_mask.to(device=device) + + return prompt_embeds, negative_prompt_embeds, prompt_attention_mask, negative_prompt_attention_mask # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.prepare_extra_step_kwargs def prepare_extra_step_kwargs(self, generator, eta): @@ -305,20 +626,25 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): prompt, height, width, - negative_prompt, - callback_steps, + negative_prompt=None, prompt_embeds=None, negative_prompt_embeds=None, + prompt_attention_mask=None, + negative_prompt_attention_mask=None, + prompt_embeds_2=None, + negative_prompt_embeds_2=None, + prompt_attention_mask_2=None, + negative_prompt_attention_mask_2=None, + callback_on_step_end_tensor_inputs=None, ): - if height % 8 != 0 or width % 8 != 0: - raise ValueError(f"`height` and `width` have to be divisible by 8 but are {height} and {width}.") + if height % 16 != 0 or width % 16 != 0: + raise ValueError(f"`height` and `width` have to be divisible by 16 but are {height} and {width}.") - if (callback_steps is None) or ( - callback_steps is not None and (not isinstance(callback_steps, int) or callback_steps <= 0) + if callback_on_step_end_tensor_inputs is not None and not all( + k in self._callback_tensor_inputs for k in callback_on_step_end_tensor_inputs ): raise ValueError( - f"`callback_steps` has to be a positive integer but is {callback_steps} of type" - f" {type(callback_steps)}." + f"`callback_on_step_end_tensor_inputs` has to be in {self._callback_tensor_inputs}, but found {[k for k in callback_on_step_end_tensor_inputs if k not in self._callback_tensor_inputs]}" ) if prompt is not None and prompt_embeds is not None: @@ -330,14 +656,18 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): raise ValueError( "Provide either `prompt` or `prompt_embeds`. Cannot leave both `prompt` and `prompt_embeds` undefined." ) + elif prompt is None and prompt_embeds_2 is None: + raise ValueError( + "Provide either `prompt` or `prompt_embeds_2`. Cannot leave both `prompt` and `prompt_embeds_2` undefined." + ) elif prompt is not None and (not isinstance(prompt, str) and not isinstance(prompt, list)): raise ValueError(f"`prompt` has to be of type `str` or `list` but is {type(prompt)}") - if prompt is not None and negative_prompt_embeds is not None: - raise ValueError( - f"Cannot forward both `prompt`: {prompt} and `negative_prompt_embeds`:" - f" {negative_prompt_embeds}. Please make sure to only forward one of the two." - ) + if prompt_embeds is not None and prompt_attention_mask is None: + raise ValueError("Must provide `prompt_attention_mask` when specifying `prompt_embeds`.") + + if prompt_embeds_2 is not None and prompt_attention_mask_2 is None: + raise ValueError("Must provide `prompt_attention_mask_2` when specifying `prompt_embeds_2`.") if negative_prompt is not None and negative_prompt_embeds is not None: raise ValueError( @@ -345,6 +675,13 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): f" {negative_prompt_embeds}. Please make sure to only forward one of the two." ) + if negative_prompt_embeds is not None and negative_prompt_attention_mask is None: + raise ValueError("Must provide `negative_prompt_attention_mask` when specifying `negative_prompt_embeds`.") + + if negative_prompt_embeds_2 is not None and negative_prompt_attention_mask_2 is None: + raise ValueError( + "Must provide `negative_prompt_attention_mask_2` when specifying `negative_prompt_embeds_2`." + ) if prompt_embeds is not None and negative_prompt_embeds is not None: if prompt_embeds.shape != negative_prompt_embeds.shape: raise ValueError( @@ -352,201 +689,83 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): f" got: `prompt_embeds` {prompt_embeds.shape} != `negative_prompt_embeds`" f" {negative_prompt_embeds.shape}." ) + if prompt_embeds_2 is not None and negative_prompt_embeds_2 is not None: + if prompt_embeds_2.shape != negative_prompt_embeds_2.shape: + raise ValueError( + "`prompt_embeds_2` and `negative_prompt_embeds_2` must have the same shape when passed directly, but" + f" got: `prompt_embeds_2` {prompt_embeds_2.shape} != `negative_prompt_embeds_2`" + f" {negative_prompt_embeds_2.shape}." + ) - # Copied from diffusers.pipelines.deepfloyd_if.pipeline_if.IFPipeline._text_preprocessing - def _text_preprocessing(self, text, clean_caption=False): - if clean_caption and not is_bs4_available(): - logger.warn(BACKENDS_MAPPING["bs4"][-1].format("Setting `clean_caption=True`")) - logger.warn("Setting `clean_caption` to False...") - clean_caption = False + # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion_img2img.StableDiffusionImg2ImgPipeline.get_timesteps + def get_timesteps(self, num_inference_steps, strength, device): + # get the original timestep using init_timestep + init_timestep = min(int(num_inference_steps * strength), num_inference_steps) - if clean_caption and not is_ftfy_available(): - logger.warn(BACKENDS_MAPPING["ftfy"][-1].format("Setting `clean_caption=True`")) - logger.warn("Setting `clean_caption` to False...") - clean_caption = False + t_start = max(num_inference_steps - init_timestep, 0) + timesteps = self.scheduler.timesteps[t_start * self.scheduler.order :] - if not isinstance(text, (tuple, list)): - text = [text] - - def process(text: str): - if clean_caption: - text = self._clean_caption(text) - text = self._clean_caption(text) - else: - text = text.lower().strip() - return text - - return [process(t) for t in text] - - # Copied from diffusers.pipelines.deepfloyd_if.pipeline_if.IFPipeline._clean_caption - def _clean_caption(self, caption): - caption = str(caption) - caption = ul.unquote_plus(caption) - caption = caption.strip().lower() - caption = re.sub("<person>", "person", caption) - # urls: - caption = re.sub( - r"\b((?:https?:(?:\/{1,3}|[a-zA-Z0-9%])|[a-zA-Z0-9.\-]+[.](?:com|co|ru|net|org|edu|gov|it)[\w/-]*\b\/?(?!@)))", # noqa - "", - caption, - ) # regex for urls - caption = re.sub( - r"\b((?:www:(?:\/{1,3}|[a-zA-Z0-9%])|[a-zA-Z0-9.\-]+[.](?:com|co|ru|net|org|edu|gov|it)[\w/-]*\b\/?(?!@)))", # noqa - "", - caption, - ) # regex for urls - # html: - caption = BeautifulSoup(caption, features="html.parser").text - - # @<nickname> - caption = re.sub(r"@[\w\d]+\b", "", caption) - - # 31C0—31EF CJK Strokes - # 31F0—31FF Katakana Phonetic Extensions - # 3200—32FF Enclosed CJK Letters and Months - # 3300—33FF CJK Compatibility - # 3400—4DBF CJK Unified Ideographs Extension A - # 4DC0—4DFF Yijing Hexagram Symbols - # 4E00—9FFF CJK Unified Ideographs - caption = re.sub(r"[\u31c0-\u31ef]+", "", caption) - caption = re.sub(r"[\u31f0-\u31ff]+", "", caption) - caption = re.sub(r"[\u3200-\u32ff]+", "", caption) - caption = re.sub(r"[\u3300-\u33ff]+", "", caption) - caption = re.sub(r"[\u3400-\u4dbf]+", "", caption) - caption = re.sub(r"[\u4dc0-\u4dff]+", "", caption) - caption = re.sub(r"[\u4e00-\u9fff]+", "", caption) - ####################################################### - - # все виды тире / all types of dash --> "-" - caption = re.sub( - r"[\u002D\u058A\u05BE\u1400\u1806\u2010-\u2015\u2E17\u2E1A\u2E3A\u2E3B\u2E40\u301C\u3030\u30A0\uFE31\uFE32\uFE58\uFE63\uFF0D]+", # noqa - "-", - caption, - ) - - # кавычки к одному стандарту - caption = re.sub(r"[`´«»“”¨]", '"', caption) - caption = re.sub(r"[‘’]", "'", caption) - - # &quot; - caption = re.sub(r"&quot;?", "", caption) - # &amp - caption = re.sub(r"&amp", "", caption) - - # ip adresses: - caption = re.sub(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", " ", caption) - - # article ids: - caption = re.sub(r"\d:\d\d\s+$", "", caption) - - # \n - caption = re.sub(r"\\n", " ", caption) - - # "#123" - caption = re.sub(r"#\d{1,3}\b", "", caption) - # "#12345.." - caption = re.sub(r"#\d{5,}\b", "", caption) - # "123456.." - caption = re.sub(r"\b\d{6,}\b", "", caption) - # filenames: - caption = re.sub(r"[\S]+\.(?:png|jpg|jpeg|bmp|webp|eps|pdf|apk|mp4)", "", caption) - - # - caption = re.sub(r"[\"\']{2,}", r'"', caption) # """AUSVERKAUFT""" - caption = re.sub(r"[\.]{2,}", r" ", caption) # """AUSVERKAUFT""" - - caption = re.sub(self.bad_punct_regex, r" ", caption) # ***AUSVERKAUFT***, #AUSVERKAUFT - caption = re.sub(r"\s+\.\s+", r" ", caption) # " . " - - # this-is-my-cute-cat / this_is_my_cute_cat - regex2 = re.compile(r"(?:\-|\_)") - if len(re.findall(regex2, caption)) > 3: - caption = re.sub(regex2, " ", caption) - - caption = ftfy.fix_text(caption) - caption = html.unescape(html.unescape(caption)) - - caption = re.sub(r"\b[a-zA-Z]{1,3}\d{3,15}\b", "", caption) # jc6640 - caption = re.sub(r"\b[a-zA-Z]+\d+[a-zA-Z]+\b", "", caption) # jc6640vc - caption = re.sub(r"\b\d+[a-zA-Z]+\d+\b", "", caption) # 6640vc231 - - caption = re.sub(r"(worldwide\s+)?(free\s+)?shipping", "", caption) - caption = re.sub(r"(free\s)?download(\sfree)?", "", caption) - caption = re.sub(r"\bclick\b\s(?:for|on)\s\w+", "", caption) - caption = re.sub(r"\b(?:png|jpg|jpeg|bmp|webp|eps|pdf|apk|mp4)(\simage[s]?)?", "", caption) - caption = re.sub(r"\bpage\s+\d+\b", "", caption) - - caption = re.sub(r"\b\d*[a-zA-Z]+\d+[a-zA-Z]+\d+[a-zA-Z\d]*\b", r" ", caption) # j2d1a2a... - - caption = re.sub(r"\b\d+\.?\d*[xх×]\d+\.?\d*\b", "", caption) - - caption = re.sub(r"\b\s+\:\s+", r": ", caption) - caption = re.sub(r"(\D[,\./])\b", r"\1 ", caption) - caption = re.sub(r"\s+", " ", caption) - - caption.strip() - - caption = re.sub(r"^[\"\']([\w\W]+)[\"\']$", r"\1", caption) - caption = re.sub(r"^[\'\_,\-\:;]", r"", caption) - caption = re.sub(r"[\'\_,\-\:\-\+]$", r"", caption) - caption = re.sub(r"^\.\S+$", "", caption) - - return caption.strip() + return timesteps, num_inference_steps - t_start def prepare_mask_latents( - self, mask, masked_image, batch_size, height, width, dtype, device, generator, do_classifier_free_guidance + self, mask, masked_image, batch_size, height, width, dtype, device, generator, do_classifier_free_guidance, noise_aug_strength ): # resize the mask to latents shape as we concatenate the mask to the latents # we do that before converting to dtype to avoid breaking in case we're using cpu_offload # and half precision - video_length = mask.shape[2] + if mask is not None: + mask = mask.to(device=device, dtype=dtype) + if self.vae.quant_conv is None or self.vae.quant_conv.weight.ndim==5: + bs = 1 + new_mask = [] + for i in range(0, mask.shape[0], bs): + mask_bs = mask[i : i + bs] + mask_bs = self.vae.encode(mask_bs)[0] + mask_bs = mask_bs.mode() + new_mask.append(mask_bs) + mask = torch.cat(new_mask, dim = 0) + mask = mask * self.vae.config.scaling_factor - mask = mask.to(device=device, dtype=self.vae.dtype) - if self.vae.quant_conv.weight.ndim==5: - bs = 1 - new_mask = [] - for i in range(0, mask.shape[0], bs): - mask_bs = mask[i : i + bs] - mask_bs = self.vae.encode(mask_bs)[0] - mask_bs = mask_bs.sample() - new_mask.append(mask_bs) - mask = torch.cat(new_mask, dim = 0) - mask = mask * self.vae.config.scaling_factor - - else: - if mask.shape[1] == 4: - mask = mask else: - video_length = mask.shape[2] - mask = rearrange(mask, "b c f h w -> (b f) c h w") - mask = self._encode_vae_image(mask, generator=generator) - mask = rearrange(mask, "(b f) c h w -> b c f h w", f=video_length) + if mask.shape[1] == 4: + mask = mask + else: + video_length = mask.shape[2] + mask = rearrange(mask, "b c f h w -> (b f) c h w") + mask = self._encode_vae_image(mask, generator=generator) + mask = rearrange(mask, "(b f) c h w -> b c f h w", f=video_length) - masked_image = masked_image.to(device=device, dtype=self.vae.dtype) - if self.vae.quant_conv.weight.ndim==5: - bs = 1 - new_mask_pixel_values = [] - for i in range(0, masked_image.shape[0], bs): - mask_pixel_values_bs = masked_image[i : i + bs] - mask_pixel_values_bs = self.vae.encode(mask_pixel_values_bs)[0] - mask_pixel_values_bs = mask_pixel_values_bs.sample() - new_mask_pixel_values.append(mask_pixel_values_bs) - masked_image_latents = torch.cat(new_mask_pixel_values, dim = 0) - masked_image_latents = masked_image_latents * self.vae.config.scaling_factor + if masked_image is not None: + masked_image = masked_image.to(device=device, dtype=dtype) + if self.transformer.config.add_noise_in_inpaint_model: + masked_image = add_noise_to_reference_video(masked_image, ratio=noise_aug_strength) + if self.vae.quant_conv is None or self.vae.quant_conv.weight.ndim==5: + bs = 1 + new_mask_pixel_values = [] + for i in range(0, masked_image.shape[0], bs): + mask_pixel_values_bs = masked_image[i : i + bs] + mask_pixel_values_bs = self.vae.encode(mask_pixel_values_bs)[0] + mask_pixel_values_bs = mask_pixel_values_bs.mode() + new_mask_pixel_values.append(mask_pixel_values_bs) + masked_image_latents = torch.cat(new_mask_pixel_values, dim = 0) + masked_image_latents = masked_image_latents * self.vae.config.scaling_factor - else: - if masked_image.shape[1] == 4: - masked_image_latents = masked_image else: - video_length = mask.shape[2] - masked_image = rearrange(masked_image, "b c f h w -> (b f) c h w") - masked_image_latents = self._encode_vae_image(masked_image, generator=generator) - masked_image_latents = rearrange(masked_image_latents, "(b f) c h w -> b c f h w", f=video_length) + if masked_image.shape[1] == 4: + masked_image_latents = masked_image + else: + video_length = masked_image.shape[2] + masked_image = rearrange(masked_image, "b c f h w -> (b f) c h w") + masked_image_latents = self._encode_vae_image(masked_image, generator=generator) + masked_image_latents = rearrange(masked_image_latents, "(b f) c h w -> b c f h w", f=video_length) + + # aligning device to prevent device errors when concating it with the latent model input + masked_image_latents = masked_image_latents.to(device=device, dtype=dtype) + else: + masked_image_latents = None - # aligning device to prevent device errors when concating it with the latent model input - masked_image_latents = masked_image_latents.to(device=device, dtype=dtype) return mask, masked_image_latents - + def prepare_latents( self, batch_size, @@ -564,10 +783,15 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): return_noise=False, return_video_latents=False, ): - if self.vae.quant_conv.weight.ndim==5: - mini_batch_encoder = self.vae.mini_batch_encoder - mini_batch_decoder = self.vae.mini_batch_decoder - shape = (batch_size, num_channels_latents, int(video_length // mini_batch_encoder * mini_batch_decoder) if video_length != 1 else 1, height // self.vae_scale_factor, width // self.vae_scale_factor) + if self.vae.quant_conv is None or self.vae.quant_conv.weight.ndim==5: + if self.vae.cache_mag_vae: + mini_batch_encoder = self.vae.mini_batch_encoder + mini_batch_decoder = self.vae.mini_batch_decoder + shape = (batch_size, num_channels_latents, int((video_length - 1) // mini_batch_encoder * mini_batch_decoder + 1) if video_length != 1 else 1, height // self.vae_scale_factor, width // self.vae_scale_factor) + else: + mini_batch_encoder = self.vae.mini_batch_encoder + mini_batch_decoder = self.vae.mini_batch_decoder + shape = (batch_size, num_channels_latents, int(video_length // mini_batch_encoder * mini_batch_decoder) if video_length != 1 else 1, height // self.vae_scale_factor, width // self.vae_scale_factor) else: shape = (batch_size, num_channels_latents, video_length, height // self.vae_scale_factor, width // self.vae_scale_factor) @@ -578,10 +802,9 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): ) if return_video_latents or (latents is None and not is_strength_max): - video = video.to(device=device, dtype=self.vae.dtype) - if self.vae.quant_conv.weight.ndim==5: + video = video.to(device=device, dtype=dtype) + if self.vae.quant_conv is None or self.vae.quant_conv.weight.ndim==5: bs = 1 - mini_batch_encoder = self.vae.mini_batch_encoder new_video = [] for i in range(0, video.shape[0], bs): video_bs = video[i : i + bs] @@ -600,16 +823,24 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): video = self._encode_vae_image(video, generator=generator) video = rearrange(video, "(b f) c h w -> b c f h w", f=video_length) video_latents = video.repeat(batch_size // video.shape[0], 1, 1, 1, 1) + video_latents = video_latents.to(device=device, dtype=dtype) if latents is None: noise = randn_tensor(shape, generator=generator, device=device, dtype=dtype) # if strength is 1. then initialise the latents to noise, else initial to image + noise - latents = noise if is_strength_max else self.scheduler.add_noise(video_latents, noise, timestep) + if isinstance(self.scheduler, FlowMatchEulerDiscreteScheduler): + latents = noise if is_strength_max else self.scheduler.scale_noise(video_latents, timestep, noise) + else: + latents = noise if is_strength_max else self.scheduler.add_noise(video_latents, noise, timestep) # if pure noise then scale the initial latents by the Scheduler's init sigma - latents = latents * self.scheduler.init_noise_sigma if is_strength_max else latents + if hasattr(self.scheduler, "init_noise_sigma"): + latents = latents * self.scheduler.init_noise_sigma if is_strength_max else latents else: - noise = latents.to(device) - latents = noise * self.scheduler.init_noise_sigma + if hasattr(self.scheduler, "init_noise_sigma"): + noise = latents.to(device) + latents = noise * self.scheduler.init_noise_sigma + else: + latents = latents.to(device) # scale the initial noise by the standard deviation required by the scheduler outputs = (latents,) @@ -631,22 +862,23 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): # Encode middle videos latents = self.vae.encode(pixel_values)[0] - latents = latents.sample() + latents = latents.mode() # Decode middle videos middle_video = self.vae.decode(latents)[0] video[:, :, prefix_index_before:-prefix_index_after] = (video[:, :, prefix_index_before:-prefix_index_after] + middle_video) / 2 return video - + def decode_latents(self, latents): video_length = latents.shape[2] latents = 1 / self.vae.config.scaling_factor * latents - if self.vae.quant_conv.weight.ndim==5: + if self.vae.quant_conv is None or self.vae.quant_conv.weight.ndim==5: mini_batch_encoder = self.vae.mini_batch_encoder mini_batch_decoder = self.vae.mini_batch_decoder video = self.vae.decode(latents)[0] video = video.clamp(-1, 1) - video = self.smooth_output(video, mini_batch_encoder, mini_batch_decoder).cpu().clamp(-1, 1) + if not self.vae.cache_compression_vae and not self.vae.cache_mag_vae: + video = self.smooth_output(video, mini_batch_encoder, mini_batch_decoder).cpu().clamp(-1, 1) else: latents = rearrange(latents, "b c f h w -> (b f) c h w") video = [] @@ -659,29 +891,28 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): video = video.cpu().float().numpy() return video - def _encode_vae_image(self, image: torch.Tensor, generator: torch.Generator): - if isinstance(generator, list): - image_latents = [ - retrieve_latents(self.vae.encode(image[i : i + 1]), generator=generator[i]) - for i in range(image.shape[0]) - ] - image_latents = torch.cat(image_latents, dim=0) - else: - image_latents = retrieve_latents(self.vae.encode(image), generator=generator) + @property + def guidance_scale(self): + return self._guidance_scale - image_latents = self.vae.config.scaling_factor * image_latents + @property + def guidance_rescale(self): + return self._guidance_rescale - return image_latents + # here `guidance_scale` is defined analog to the guidance weight `w` of equation (2) + # of the Imagen paper: https://arxiv.org/pdf/2205.11487.pdf . `guidance_scale = 1` + # corresponds to doing no classifier free guidance. + @property + def do_classifier_free_guidance(self): + return self._guidance_scale > 1 - # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion_img2img.StableDiffusionImg2ImgPipeline.get_timesteps - def get_timesteps(self, num_inference_steps, strength, device): - # get the original timestep using init_timestep - init_timestep = min(int(num_inference_steps * strength), num_inference_steps) + @property + def num_timesteps(self): + return self._num_timesteps - t_start = max(num_inference_steps - init_timestep, 0) - timesteps = self.scheduler.timesteps[t_start * self.scheduler.order :] - - return timesteps, num_inference_steps - t_start + @property + def interrupt(self): + return self._interrupt @torch.no_grad() @replace_example_docstring(EXAMPLE_DOC_STRING) @@ -692,109 +923,167 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): video: Union[torch.FloatTensor] = None, mask_video: Union[torch.FloatTensor] = None, masked_video_latents: Union[torch.FloatTensor] = None, - negative_prompt: str = "", - num_inference_steps: int = 20, - timesteps: List[int] = None, - guidance_scale: float = 4.5, - num_images_per_prompt: Optional[int] = 1, height: Optional[int] = None, width: Optional[int] = None, - strength: float = 1.0, - eta: float = 0.0, + num_inference_steps: Optional[int] = 50, + guidance_scale: Optional[float] = 5.0, + negative_prompt: Optional[Union[str, List[str]]] = None, + num_images_per_prompt: Optional[int] = 1, + eta: Optional[float] = 0.0, generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None, - latents: Optional[torch.FloatTensor] = None, - prompt_embeds: Optional[torch.FloatTensor] = None, - prompt_attention_mask: Optional[torch.FloatTensor] = None, - negative_prompt_embeds: Optional[torch.FloatTensor] = None, - negative_prompt_attention_mask: Optional[torch.FloatTensor] = None, + latents: Optional[torch.Tensor] = None, + prompt_embeds: Optional[torch.Tensor] = None, + prompt_embeds_2: Optional[torch.Tensor] = None, + negative_prompt_embeds: Optional[torch.Tensor] = None, + negative_prompt_embeds_2: Optional[torch.Tensor] = None, + prompt_attention_mask: Optional[torch.Tensor] = None, + prompt_attention_mask_2: Optional[torch.Tensor] = None, + negative_prompt_attention_mask: Optional[torch.Tensor] = None, + negative_prompt_attention_mask_2: Optional[torch.Tensor] = None, output_type: Optional[str] = "latent", return_dict: bool = True, - callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None, - callback_steps: int = 1, - clean_caption: bool = True, - mask_feature: bool = True, - max_sequence_length: int = 120, + callback_on_step_end: Optional[ + Union[Callable[[int, int, Dict], None], PipelineCallback, MultiPipelineCallbacks] + ] = None, + callback_on_step_end_tensor_inputs: List[str] = ["latents"], + guidance_rescale: float = 0.0, + original_size: Optional[Tuple[int, int]] = (1024, 1024), + target_size: Optional[Tuple[int, int]] = None, + crops_coords_top_left: Tuple[int, int] = (0, 0), clip_image: Image = None, - clip_apply_ratio: float = 0.50, + clip_apply_ratio: float = 0.40, + strength: float = 1.0, + noise_aug_strength: float = 0.0563, comfyui_progressbar: bool = False, - **kwargs, - ) -> Union[EasyAnimatePipelineOutput, Tuple]: - """ - Function invoked when calling the pipeline for generation. - - Args: - prompt (`str` or `List[str]`, *optional*): - The prompt or prompts to guide the image generation. If not defined, one has to pass `prompt_embeds`. - instead. - negative_prompt (`str` or `List[str]`, *optional*): - The prompt or prompts not to guide the image generation. If not defined, one has to pass - `negative_prompt_embeds` instead. Ignored when not using guidance (i.e., ignored if `guidance_scale` is - less than `1`). - num_inference_steps (`int`, *optional*, defaults to 100): - The number of denoising steps. More denoising steps usually lead to a higher quality image at the - expense of slower inference. - timesteps (`List[int]`, *optional*): - Custom timesteps to use for the denoising process. If not defined, equal spaced `num_inference_steps` - timesteps are used. Must be in descending order. - guidance_scale (`float`, *optional*, defaults to 7.0): - Guidance scale as defined in [Classifier-Free Diffusion Guidance](https://arxiv.org/abs/2207.12598). - `guidance_scale` is defined as `w` of equation 2. of [Imagen - Paper](https://arxiv.org/pdf/2205.11487.pdf). Guidance scale is enabled by setting `guidance_scale > - 1`. Higher guidance scale encourages to generate images that are closely linked to the text `prompt`, - usually at the expense of lower image quality. - num_images_per_prompt (`int`, *optional*, defaults to 1): - The number of images to generate per prompt. - height (`int`, *optional*, defaults to self.unet.config.sample_size): - The height in pixels of the generated image. - width (`int`, *optional*, defaults to self.unet.config.sample_size): - The width in pixels of the generated image. - eta (`float`, *optional*, defaults to 0.0): - Corresponds to parameter eta (η) in the DDIM paper: https://arxiv.org/abs/2010.02502. Only applies to - [`schedulers.DDIMScheduler`], will be ignored for others. - generator (`torch.Generator` or `List[torch.Generator]`, *optional*): - One or a list of [torch generator(s)](https://pytorch.org/docs/stable/generated/torch.Generator.html) - to make generation deterministic. - latents (`torch.FloatTensor`, *optional*): - Pre-generated noisy latents, sampled from a Gaussian distribution, to be used as inputs for image - generation. Can be used to tweak the same generation with different prompts. If not provided, a latents - tensor will ge generated by sampling using the supplied random `generator`. - prompt_embeds (`torch.FloatTensor`, *optional*): - Pre-generated text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting. If not - provided, text embeddings will be generated from `prompt` input argument. - negative_prompt_embeds (`torch.FloatTensor`, *optional*): - Pre-generated negative text embeddings. For PixArt-Alpha this negative prompt should be "". If not - provided, negative_prompt_embeds will be generated from `negative_prompt` input argument. - output_type (`str`, *optional*, defaults to `"pil"`): - The output format of the generate image. Choose between - [PIL](https://pillow.readthedocs.io/en/stable/): `PIL.Image.Image` or `np.array`. - return_dict (`bool`, *optional*, defaults to `True`): - Whether or not to return a [`~pipelines.stable_diffusion.IFPipelineOutput`] instead of a plain tuple. - callback (`Callable`, *optional*): - A function that will be called every `callback_steps` steps during inference. The function will be - called with the following arguments: `callback(step: int, timestep: int, latents: torch.FloatTensor)`. - callback_steps (`int`, *optional*, defaults to 1): - The frequency at which the `callback` function will be called. If not specified, the callback will be - called at every step. - clean_caption (`bool`, *optional*, defaults to `True`): - Whether or not to clean the caption before creating embeddings. Requires `beautifulsoup4` and `ftfy` to - be installed. If the dependencies are not installed, the embeddings will be created from the raw - prompt. - mask_feature (`bool` defaults to `True`): If set to `True`, the text embeddings will be masked. + timesteps: Optional[List[int]] = None, + ): + r""" + The call function to the pipeline for generation with HunyuanDiT. Examples: + prompt (`str` or `List[str]`, *optional*): + The prompt or prompts to guide image generation. If not defined, you need to pass `prompt_embeds`. + video_length (`int`, *optional*): + Length of the video to be generated in seconds. This parameter influences the number of frames and + continuity of generated content. + video (`torch.FloatTensor`, *optional*): + A tensor representing an input video, which can be modified depending on the prompts provided. + mask_video (`torch.FloatTensor`, *optional*): + A tensor to specify areas of the video to be masked (omitted from generation). + masked_video_latents (`torch.FloatTensor`, *optional*): + Latents from masked portions of the video, utilized during image generation. + height (`int`, *optional*): + The height in pixels of the generated image or video frames. + width (`int`, *optional*): + The width in pixels of the generated image or video frames. + num_inference_steps (`int`, *optional*, defaults to 50): + The number of denoising steps. More denoising steps usually lead to a higher quality image but slower + inference time. This parameter is modulated by `strength`. + guidance_scale (`float`, *optional*, defaults to 5.0): + A higher guidance scale value encourages the model to generate images closely linked to the text + `prompt` at the expense of lower image quality. Guidance scale is effective when `guidance_scale > 1`. + negative_prompt (`str` or `List[str]`, *optional*): + The prompt or prompts to guide what to exclude in image generation. If not defined, you need to + provide `negative_prompt_embeds`. This parameter is ignored when not using guidance (`guidance_scale < 1`). + num_images_per_prompt (`int`, *optional*, defaults to 1): + The number of images to generate per prompt. + eta (`float`, *optional*, defaults to 0.0): + A parameter defined in the [DDIM](https://arxiv.org/abs/2010.02502) paper. Only applies to the + [`~schedulers.DDIMScheduler`] and is ignored in other schedulers. It adjusts noise level during the + inference process. + generator (`torch.Generator` or `List[torch.Generator]`, *optional*): + A [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html) for setting + random seeds which helps in making generation deterministic. + latents (`torch.Tensor`, *optional*): + A pre-computed latent representation which can be used to guide the generation process. + prompt_embeds (`torch.Tensor`, *optional*): + Pre-generated text embeddings. Can be used to easily tweak text inputs (prompt weighting). If not + provided, embeddings are generated from the `prompt` input argument. + prompt_embeds_2 (`torch.Tensor`, *optional*): + Secondary set of pre-generated text embeddings, useful for advanced prompt weighting. + negative_prompt_embeds (`torch.Tensor`, *optional*): + Pre-generated negative text embeddings, aiding in fine-tuning what should not be represented in the outputs. + If not provided, embeddings are generated from the `negative_prompt` argument. + negative_prompt_embeds_2 (`torch.Tensor`, *optional*): + Secondary set of pre-generated negative text embeddings for further control. + prompt_attention_mask (`torch.Tensor`, *optional*): + Attention mask guiding the focus of the model on specific parts of the prompt text. Required when using + `prompt_embeds`. + prompt_attention_mask_2 (`torch.Tensor`, *optional*): + Attention mask for the secondary prompt embedding. + negative_prompt_attention_mask (`torch.Tensor`, *optional*): + Attention mask for the negative prompt, needed when `negative_prompt_embeds` are used. + negative_prompt_attention_mask_2 (`torch.Tensor`, *optional*): + Attention mask for the secondary negative prompt embedding. + output_type (`str`, *optional*, defaults to `"latent"`): + The output format of the generated image. Choose between `PIL.Image` and `np.array` to define + how you want the results to be formatted. + return_dict (`bool`, *optional*, defaults to `True`): + If set to `True`, a [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] will be returned; + otherwise, a tuple containing the generated images and safety flags will be returned. + callback_on_step_end (`Callable[[int, int, Dict], None]`, `PipelineCallback`, `MultiPipelineCallbacks`, *optional*): + A callback function (or a list of them) that will be executed at the end of each denoising step, + allowing for custom processing during generation. + callback_on_step_end_tensor_inputs (`List[str]`, *optional*): + Specifies which tensor inputs should be included in the callback function. If not defined, all tensor + inputs will be passed, facilitating enhanced logging or monitoring of the generation process. + guidance_rescale (`float`, *optional*, defaults to 0.0): + Rescale parameter for adjusting noise configuration based on guidance rescale. Based on findings from + [Common Diffusion Noise Schedules and Sample Steps are Flawed](https://arxiv.org/pdf/2305.08891.pdf). + original_size (`Tuple[int, int]`, *optional*, defaults to `(1024, 1024)`): + The original dimensions of the image. Used to compute time ids during the generation process. + target_size (`Tuple[int, int]`, *optional*): + The targeted dimensions of the generated image, also utilized in the time id calculations. + crops_coords_top_left (`Tuple[int, int]`, *optional*, defaults to `(0, 0)`): + Coordinates defining the top left corner of any cropping, utilized while calculating the time ids. + clip_image (`Image`, *optional*): + An optional image to assist in the generation process. It may be used as an additional visual cue. + clip_apply_ratio (`float`, *optional*, defaults to 0.40): + Ratio indicating how much influence the clip image should exert over the generated content. + strength (`float`, *optional*, defaults to 1.0): + Affects the overall styling or quality of the generated output. Values closer to 1 usually provide direct + adherence to prompts. + comfyui_progressbar (`bool`, *optional*, defaults to `False`): + Enables a progress bar in ComfyUI, providing visual feedback during the generation process. + Examples: + # Example usage of the function for generating images based on prompts. + Returns: - [`~pipelines.ImagePipelineOutput`] or `tuple`: - If `return_dict` is `True`, [`~pipelines.ImagePipelineOutput`] is returned, otherwise a `tuple` is - returned where the first element is a list with the generated images + [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] or `tuple`: + Returns either a structured output containing generated images and their metadata when `return_dict` is + `True`, or a simpler tuple, where the first element is a list of generated images and the second + element indicates if any of them contain "not-safe-for-work" (NSFW) content. """ - # 1. Check inputs. Raise error if not correct - height = height or self.transformer.config.sample_size * self.vae_scale_factor - width = width or self.transformer.config.sample_size * self.vae_scale_factor + + if isinstance(callback_on_step_end, (PipelineCallback, MultiPipelineCallbacks)): + callback_on_step_end_tensor_inputs = callback_on_step_end.tensor_inputs + + # 0. default height and width height = int(height // 16 * 16) width = int(width // 16 * 16) - # 2. Default height and width to transformer + # 1. Check inputs. Raise error if not correct + self.check_inputs( + prompt, + height, + width, + negative_prompt, + prompt_embeds, + negative_prompt_embeds, + prompt_attention_mask, + negative_prompt_attention_mask, + prompt_embeds_2, + negative_prompt_embeds_2, + prompt_attention_mask_2, + negative_prompt_attention_mask_2, + callback_on_step_end_tensor_inputs, + ) + self._guidance_scale = guidance_scale + self._guidance_rescale = guidance_rescale + self._interrupt = False + + # 2. Define call parameters if prompt is not None and isinstance(prompt, str): batch_size = 1 elif prompt is not None and isinstance(prompt, list): @@ -809,40 +1098,62 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): dtype = self.text_encoder_2.dtype else: dtype = self.transformer.dtype - - # here `guidance_scale` is defined analog to the guidance weight `w` of equation (2) - # of the Imagen paper: https://arxiv.org/pdf/2205.11487.pdf . `guidance_scale = 1` - # corresponds to doing no classifier free guidance. - do_classifier_free_guidance = guidance_scale > 1.0 - + # 3. Encode input prompt ( prompt_embeds, - prompt_attention_mask, negative_prompt_embeds, + prompt_attention_mask, negative_prompt_attention_mask, ) = self.encode_prompt( - prompt, - do_classifier_free_guidance, - negative_prompt=negative_prompt, - num_images_per_prompt=num_images_per_prompt, + prompt=prompt, device=device, + dtype=dtype, + num_images_per_prompt=num_images_per_prompt, + do_classifier_free_guidance=self.do_classifier_free_guidance, + negative_prompt=negative_prompt, prompt_embeds=prompt_embeds, negative_prompt_embeds=negative_prompt_embeds, prompt_attention_mask=prompt_attention_mask, negative_prompt_attention_mask=negative_prompt_attention_mask, - clean_caption=clean_caption, - max_sequence_length=max_sequence_length, + text_encoder_index=0, ) - if do_classifier_free_guidance: - prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds], dim=0) - prompt_attention_mask = torch.cat([negative_prompt_attention_mask, prompt_attention_mask], dim=0) + if self.tokenizer_2 is not None: + ( + prompt_embeds_2, + negative_prompt_embeds_2, + prompt_attention_mask_2, + negative_prompt_attention_mask_2, + ) = self.encode_prompt( + prompt=prompt, + device=device, + dtype=dtype, + num_images_per_prompt=num_images_per_prompt, + do_classifier_free_guidance=self.do_classifier_free_guidance, + negative_prompt=negative_prompt, + prompt_embeds=prompt_embeds_2, + negative_prompt_embeds=negative_prompt_embeds_2, + prompt_attention_mask=prompt_attention_mask_2, + negative_prompt_attention_mask=negative_prompt_attention_mask_2, + text_encoder_index=1, + ) + else: + prompt_embeds_2 = None + negative_prompt_embeds_2 = None + prompt_attention_mask_2 = None + negative_prompt_attention_mask_2 = None # 4. set timesteps - self.scheduler.set_timesteps(num_inference_steps, device=device) + if isinstance(self.scheduler, FlowMatchEulerDiscreteScheduler): + timesteps, num_inference_steps = retrieve_timesteps(self.scheduler, num_inference_steps, device, timesteps, mu=1) + else: + timesteps, num_inference_steps = retrieve_timesteps(self.scheduler, num_inference_steps, device, timesteps) timesteps, num_inference_steps = self.get_timesteps( num_inference_steps=num_inference_steps, strength=strength, device=device ) + if comfyui_progressbar: + from comfy.utils import ProgressBar + pbar = ProgressBar(num_inference_steps + 3) # at which timestep to set the initial noise (n.b. 50% if strength is 0.5) latent_timestep = timesteps[:1].repeat(batch_size * num_images_per_prompt) # create a boolean to check if the strength is set to 1. if so then initialise the latents with pure noise @@ -859,7 +1170,7 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): # Prepare latent variables num_channels_latents = self.vae.config.latent_channels num_channels_transformer = self.transformer.config.in_channels - return_image_latents = True # num_channels_transformer == 4 + return_image_latents = num_channels_transformer == num_channels_latents # 5. Prepare latents. latents_outputs = self.prepare_latents( @@ -882,91 +1193,153 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): latents, noise, image_latents = latents_outputs else: latents, noise = latents_outputs - latents_dtype = dtype - if mask_video is not None: - # Prepare mask latent variables - video_length = video.shape[2] - mask_condition = self.mask_processor.preprocess(rearrange(mask_video, "b c f h w -> (b f) c h w"), height=height, width=width) - mask_condition = mask_condition.to(dtype=torch.float32) - mask_condition = rearrange(mask_condition, "(b f) c h w -> b c f h w", f=video_length) + if comfyui_progressbar: + pbar.update(1) - if num_channels_transformer == 12: - mask_condition_tile = torch.tile(mask_condition, [1, 3, 1, 1, 1]) - if masked_video_latents is None: - masked_video = init_video * (mask_condition_tile < 0.5) + torch.ones_like(init_video) * (mask_condition_tile > 0.5) * -1 - else: - masked_video = masked_video_latents - - mask_latents, masked_video_latents = self.prepare_mask_latents( - mask_condition_tile, - masked_video, - batch_size, - height, - width, - dtype, - device, - generator, - do_classifier_free_guidance, - ) - mask = torch.tile(mask_condition, [1, num_channels_transformer // 3, 1, 1, 1]) - mask = F.interpolate(mask, size=latents.size()[-3:], mode='trilinear', align_corners=True).to(device, dtype) - - mask_input = torch.cat([mask_latents] * 2) if do_classifier_free_guidance else mask_latents - masked_video_latents_input = ( - torch.cat([masked_video_latents] * 2) if do_classifier_free_guidance else masked_video_latents - ) - inpaint_latents = torch.cat([mask_input, masked_video_latents_input], dim=1).to(dtype) - else: - mask = torch.tile(mask_condition, [1, num_channels_transformer, 1, 1, 1]) - mask = F.interpolate(mask, size=latents.size()[-3:], mode='trilinear', align_corners=True).to(device, dtype) - - inpaint_latents = None - else: - if num_channels_transformer == 12: - mask = torch.zeros_like(latents).to(device, dtype) - masked_video_latents = torch.zeros_like(latents).to(device, dtype) - - mask_input = torch.cat([mask] * 2) if do_classifier_free_guidance else mask - masked_video_latents_input = ( - torch.cat([masked_video_latents] * 2) if do_classifier_free_guidance else masked_video_latents - ) - inpaint_latents = torch.cat([mask_input, masked_video_latents_input], dim=1).to(dtype) - else: - mask = torch.zeros_like(init_video[:, :1]) - mask = torch.tile(mask, [1, num_channels_transformer, 1, 1, 1]) - mask = F.interpolate(mask, size=latents.size()[-3:], mode='trilinear', align_corners=True).to(device, dtype) - - inpaint_latents = None - - if clip_image is not None: + # 6. Prepare clip latents if it needs. + if clip_image is not None and self.transformer.enable_clip_in_inpaint: inputs = self.clip_image_processor(images=clip_image, return_tensors="pt") inputs["pixel_values"] = inputs["pixel_values"].to(device, dtype=dtype) - clip_encoder_hidden_states = self.clip_image_encoder(**inputs).image_embeds - clip_encoder_hidden_states_neg = torch.zeros([batch_size, 768]).to(device, dtype=dtype) + if self.transformer.config.get("position_of_clip_embedding", "full") == "full": + clip_encoder_hidden_states = self.clip_image_encoder(**inputs).last_hidden_state[:, 1:] + clip_encoder_hidden_states_neg = torch.zeros( + [ + batch_size, + int(self.clip_image_encoder.config.image_size / self.clip_image_encoder.config.patch_size) ** 2, + int(self.clip_image_encoder.config.hidden_size) + ] + ).to(device, dtype=dtype) - clip_attention_mask = torch.ones([batch_size, 8]).to(device, dtype=dtype) - clip_attention_mask_neg = torch.zeros([batch_size, 8]).to(device, dtype=dtype) + else: + clip_encoder_hidden_states = self.clip_image_encoder(**inputs).image_embeds + clip_encoder_hidden_states_neg = torch.zeros([batch_size, 768]).to(device, dtype=dtype) - clip_encoder_hidden_states_input = torch.cat([clip_encoder_hidden_states_neg, clip_encoder_hidden_states]) if do_classifier_free_guidance else clip_encoder_hidden_states - clip_attention_mask_input = torch.cat([clip_attention_mask_neg, clip_attention_mask]) if do_classifier_free_guidance else clip_attention_mask + clip_attention_mask = torch.ones([batch_size, self.transformer.n_query]).to(device, dtype=dtype) + clip_attention_mask_neg = torch.zeros([batch_size, self.transformer.n_query]).to(device, dtype=dtype) - elif clip_image is None and num_channels_transformer == 12: - clip_encoder_hidden_states = torch.zeros([batch_size, 768]).to(device, dtype=dtype) + clip_encoder_hidden_states_input = torch.cat([clip_encoder_hidden_states_neg, clip_encoder_hidden_states]) if self.do_classifier_free_guidance else clip_encoder_hidden_states + clip_attention_mask_input = torch.cat([clip_attention_mask_neg, clip_attention_mask]) if self.do_classifier_free_guidance else clip_attention_mask - clip_attention_mask = torch.zeros([batch_size, 8]) + elif clip_image is None and num_channels_transformer != num_channels_latents and self.transformer.enable_clip_in_inpaint: + if self.transformer.config.get("position_of_clip_embedding", "full") == "full": + clip_encoder_hidden_states = torch.zeros( + [ + batch_size, + int(self.clip_image_encoder.config.image_size / self.clip_image_encoder.config.patch_size) ** 2, + int(self.clip_image_encoder.config.hidden_size) + ] + ).to(device, dtype=dtype) + else: + clip_encoder_hidden_states = torch.zeros([batch_size, 768]).to(device, dtype=dtype) + + clip_attention_mask = torch.zeros([batch_size, self.transformer.n_query]) clip_attention_mask = clip_attention_mask.to(device, dtype=dtype) - clip_encoder_hidden_states_input = torch.cat([clip_encoder_hidden_states] * 2) if do_classifier_free_guidance else clip_encoder_hidden_states - clip_attention_mask_input = torch.cat([clip_attention_mask] * 2) if do_classifier_free_guidance else clip_attention_mask + clip_encoder_hidden_states_input = torch.cat([clip_encoder_hidden_states] * 2) if self.do_classifier_free_guidance else clip_encoder_hidden_states + clip_attention_mask_input = torch.cat([clip_attention_mask] * 2) if self.do_classifier_free_guidance else clip_attention_mask else: clip_encoder_hidden_states_input = None clip_attention_mask_input = None + if comfyui_progressbar: + pbar.update(1) + + # 7. Prepare inpaint latents if it needs. + if mask_video is not None: + if self.transformer.config.get("enable_zero_in_inpaint", True) and (mask_video == 255).all(): + # Use zero latents if we want to t2v. + mask = torch.zeros_like(latents).to(device, dtype) + if self.transformer.resize_inpaint_mask_directly: + mask_latents = torch.zeros_like(latents)[:, :1].to(device, dtype) + else: + mask_latents = torch.zeros_like(latents).to(device, dtype) + masked_video_latents = torch.zeros_like(latents).to(device, dtype) + + mask_input = torch.cat([mask_latents] * 2) if self.do_classifier_free_guidance else mask_latents + masked_video_latents_input = ( + torch.cat([masked_video_latents] * 2) if self.do_classifier_free_guidance else masked_video_latents + ) + inpaint_latents = torch.cat([mask_input, masked_video_latents_input], dim=1).to(dtype) + else: + # Prepare mask latent variables + video_length = video.shape[2] + mask_condition = self.mask_processor.preprocess(rearrange(mask_video, "b c f h w -> (b f) c h w"), height=height, width=width) + mask_condition = mask_condition.to(dtype=torch.float32) + mask_condition = rearrange(mask_condition, "(b f) c h w -> b c f h w", f=video_length) + + if num_channels_transformer != num_channels_latents: + mask_condition_tile = torch.tile(mask_condition, [1, 3, 1, 1, 1]) + if masked_video_latents is None: + masked_video = init_video * (mask_condition_tile < 0.5) + torch.ones_like(init_video) * (mask_condition_tile > 0.5) * -1 + else: + masked_video = masked_video_latents + + if self.transformer.resize_inpaint_mask_directly: + _, masked_video_latents = self.prepare_mask_latents( + None, + masked_video, + batch_size, + height, + width, + dtype, + device, + generator, + self.do_classifier_free_guidance, + noise_aug_strength=noise_aug_strength, + ) + mask_latents = resize_mask(1 - mask_condition, masked_video_latents, self.vae.cache_mag_vae) + mask_latents = mask_latents.to(device, dtype) * self.vae.config.scaling_factor + else: + mask_latents, masked_video_latents = self.prepare_mask_latents( + mask_condition_tile, + masked_video, + batch_size, + height, + width, + dtype, + device, + generator, + self.do_classifier_free_guidance, + noise_aug_strength=noise_aug_strength, + ) + + mask_input = torch.cat([mask_latents] * 2) if self.do_classifier_free_guidance else mask_latents + masked_video_latents_input = ( + torch.cat([masked_video_latents] * 2) if self.do_classifier_free_guidance else masked_video_latents + ) + inpaint_latents = torch.cat([mask_input, masked_video_latents_input], dim=1).to(dtype) + else: + inpaint_latents = None + + mask = torch.tile(mask_condition, [1, num_channels_latents, 1, 1, 1]) + mask = F.interpolate(mask, size=latents.size()[-3:], mode='trilinear', align_corners=True).to(device, dtype) + else: + if num_channels_transformer != num_channels_latents: + mask = torch.zeros_like(latents).to(device, dtype) + if self.transformer.resize_inpaint_mask_directly: + mask_latents = torch.zeros_like(latents)[:, :1].to(device, dtype) + else: + mask_latents = torch.zeros_like(latents).to(device, dtype) + masked_video_latents = torch.zeros_like(latents).to(device, dtype) + + mask_input = torch.cat([mask_latents] * 2) if self.do_classifier_free_guidance else mask_latents + masked_video_latents_input = ( + torch.cat([masked_video_latents] * 2) if self.do_classifier_free_guidance else masked_video_latents + ) + inpaint_latents = torch.cat([mask_input, masked_video_latents_input], dim=1).to(dtype) + else: + mask = torch.zeros_like(init_video[:, :1]) + mask = torch.tile(mask, [1, num_channels_latents, 1, 1, 1]) + mask = F.interpolate(mask, size=latents.size()[-3:], mode='trilinear', align_corners=True).to(device, dtype) + + inpaint_latents = None + + if comfyui_progressbar: + pbar.update(1) # Check that sizes of mask, masked image and latents match - if num_channels_transformer == 12: - # default case for runwayml/stable-diffusion-inpainting + if num_channels_transformer != num_channels_latents: num_channels_mask = mask_latents.shape[1] num_channels_masked_image = masked_video_latents.shape[1] if num_channels_latents + num_channels_mask + num_channels_masked_image != self.transformer.config.in_channels: @@ -977,38 +1350,89 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): f" = {num_channels_latents+num_channels_masked_image+num_channels_mask}. Please verify the config of" " `pipeline.transformer` or your `mask_image` or `image` input." ) - elif num_channels_transformer != 4: - raise ValueError( - f"The transformer {self.transformer.__class__} should have 9 input channels, not {self.transformer.config.in_channels}." - ) - - # 9. Prepare extra step kwargs. TODO: Logic should ideally just be moved out of the pipeline + + # 8. Prepare extra step kwargs. TODO: Logic should ideally just be moved out of the pipeline extra_step_kwargs = self.prepare_extra_step_kwargs(generator, eta) - # 6.1 Prepare micro-conditions. + # 9 create image_rotary_emb, style embedding & time ids + grid_height = height // 8 // self.transformer.config.patch_size + grid_width = width // 8 // self.transformer.config.patch_size + if self.transformer.config.get("time_position_encoding_type", "2d_rope") == "3d_rope": + base_size_width = 720 // 8 // self.transformer.config.patch_size + base_size_height = 480 // 8 // self.transformer.config.patch_size + + grid_crops_coords = get_resize_crop_region_for_grid( + (grid_height, grid_width), base_size_width, base_size_height + ) + image_rotary_emb = get_3d_rotary_pos_embed( + self.transformer.config.attention_head_dim, grid_crops_coords, grid_size=(grid_height, grid_width), + temporal_size=latents.size(2), use_real=True, + ) + else: + base_size = 512 // 8 // self.transformer.config.patch_size + grid_crops_coords = get_resize_crop_region_for_grid( + (grid_height, grid_width), base_size, base_size + ) + image_rotary_emb = get_2d_rotary_pos_embed( + self.transformer.config.attention_head_dim, grid_crops_coords, (grid_height, grid_width) + ) + + # Get other hunyuan params + target_size = target_size or (height, width) + add_time_ids = list(original_size + target_size + crops_coords_top_left) + add_time_ids = torch.tensor([add_time_ids], dtype=dtype) + style = torch.tensor([0], device=device) + + if self.do_classifier_free_guidance: + add_time_ids = torch.cat([add_time_ids] * 2, dim=0) + style = torch.cat([style] * 2, dim=0) + + # To latents.device + add_time_ids = add_time_ids.to(dtype=dtype, device=device).repeat( + batch_size * num_images_per_prompt, 1 + ) + style = style.to(device=device).repeat(batch_size * num_images_per_prompt) + + # Get other pixart params added_cond_kwargs = {"resolution": None, "aspect_ratio": None} - if self.transformer.config.sample_size == 128: + if self.transformer.config.get("sample_size", 64) == 128: resolution = torch.tensor([height, width]).repeat(batch_size * num_images_per_prompt, 1) aspect_ratio = torch.tensor([float(height / width)]).repeat(batch_size * num_images_per_prompt, 1) resolution = resolution.to(dtype=dtype, device=device) aspect_ratio = aspect_ratio.to(dtype=dtype, device=device) - if do_classifier_free_guidance: + if self.do_classifier_free_guidance: resolution = torch.cat([resolution, resolution], dim=0) aspect_ratio = torch.cat([aspect_ratio, aspect_ratio], dim=0) - + added_cond_kwargs = {"resolution": resolution, "aspect_ratio": aspect_ratio} + if self.do_classifier_free_guidance: + prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds]) + prompt_attention_mask = torch.cat([negative_prompt_attention_mask, prompt_attention_mask]) + if prompt_embeds_2 is not None: + prompt_embeds_2 = torch.cat([negative_prompt_embeds_2, prompt_embeds_2]) + prompt_attention_mask_2 = torch.cat([negative_prompt_attention_mask_2, prompt_attention_mask_2]) + + # To latents.device + prompt_embeds = prompt_embeds.to(device=device) + prompt_attention_mask = prompt_attention_mask.to(device=device) + if prompt_embeds_2 is not None: + prompt_embeds_2 = prompt_embeds_2.to(device=device) + prompt_attention_mask_2 = prompt_attention_mask_2.to(device=device) + # 10. Denoising loop num_warmup_steps = len(timesteps) - num_inference_steps * self.scheduler.order self._num_timesteps = len(timesteps) - if comfyui_progressbar: - from comfy.utils import ProgressBar - pbar = ProgressBar(num_inference_steps) with self.progress_bar(total=num_inference_steps) as progress_bar: for i, t in enumerate(timesteps): - latent_model_input = torch.cat([latents] * 2) if do_classifier_free_guidance else latents - latent_model_input = self.scheduler.scale_model_input(latent_model_input, t) + if self.interrupt: + continue + + # expand the latents if we are doing classifier free guidance + latent_model_input = torch.cat([latents] * 2) if self.do_classifier_free_guidance else latents + if hasattr(self.scheduler, "scale_model_input"): + latent_model_input = self.scheduler.scale_model_input(latent_model_input, t) if i < len(timesteps) * (1 - clip_apply_ratio) and clip_encoder_hidden_states_input is not None: clip_encoder_hidden_states_actual_input = torch.zeros_like(clip_encoder_hidden_states_input) @@ -1016,63 +1440,79 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): else: clip_encoder_hidden_states_actual_input = clip_encoder_hidden_states_input clip_attention_mask_actual_input = clip_attention_mask_input + + # expand scalar t to 1-D tensor to match the 1st dim of latent_model_input + t_expand = torch.tensor([t] * latent_model_input.shape[0], device=device).to( + dtype=latent_model_input.dtype + ) - current_timestep = t - if not torch.is_tensor(current_timestep): - # TODO: this requires sync between CPU and GPU. So try to pass timesteps as tensors if you can - # This would be a good case for the `match` statement (Python 3.10+) - is_mps = latent_model_input.device.type == "mps" - if isinstance(current_timestep, float): - dtype = torch.float32 if is_mps else torch.float64 - else: - dtype = torch.int32 if is_mps else torch.int64 - current_timestep = torch.tensor([current_timestep], dtype=dtype, device=latent_model_input.device) - elif len(current_timestep.shape) == 0: - current_timestep = current_timestep[None].to(latent_model_input.device) - # broadcast to batch dimension in a way that's compatible with ONNX/Core ML - current_timestep = current_timestep.expand(latent_model_input.shape[0]) - - # predict noise model_output + # predict the noise residual noise_pred = self.transformer( latent_model_input, + t_expand, encoder_hidden_states=prompt_embeds, - encoder_attention_mask=prompt_attention_mask, - timestep=current_timestep, - added_cond_kwargs=added_cond_kwargs, + text_embedding_mask=prompt_attention_mask, + encoder_hidden_states_t5=prompt_embeds_2, + text_embedding_mask_t5=prompt_attention_mask_2, + image_meta_size=add_time_ids, + style=style, + image_rotary_emb=image_rotary_emb, inpaint_latents=inpaint_latents, clip_encoder_hidden_states=clip_encoder_hidden_states_actual_input, clip_attention_mask=clip_attention_mask_actual_input, + added_cond_kwargs=added_cond_kwargs, return_dict=False, )[0] + if noise_pred.size()[1] != self.vae.config.latent_channels: + noise_pred, _ = noise_pred.chunk(2, dim=1) # perform guidance - if do_classifier_free_guidance: + if self.do_classifier_free_guidance: noise_pred_uncond, noise_pred_text = noise_pred.chunk(2) noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond) - # learned sigma - noise_pred = noise_pred.chunk(2, dim=1)[0] + if self.do_classifier_free_guidance and guidance_rescale > 0.0: + # Based on 3.4. in https://arxiv.org/pdf/2305.08891.pdf + noise_pred = rescale_noise_cfg(noise_pred, noise_pred_text, guidance_rescale=guidance_rescale) - # compute previous image: x_t -> x_t-1 + # compute the previous noisy sample x_t -> x_t-1 latents = self.scheduler.step(noise_pred, t, latents, **extra_step_kwargs, return_dict=False)[0] - if num_channels_transformer == 4: + if num_channels_transformer == num_channels_latents: init_latents_proper = image_latents init_mask = mask if i < len(timesteps) - 1: noise_timestep = timesteps[i + 1] - init_latents_proper = self.scheduler.add_noise( - init_latents_proper, noise, torch.tensor([noise_timestep]) - ) - + if isinstance(self.scheduler, FlowMatchEulerDiscreteScheduler): + init_latents_proper = self.scheduler.scale_noise( + init_latents_proper, torch.tensor([noise_timestep], noise) + ) + else: + init_latents_proper = self.scheduler.add_noise( + init_latents_proper, noise, torch.tensor([noise_timestep]) + ) + latents = (1 - init_mask) * init_latents_proper + init_mask * latents - # call the callback, if provided + if callback_on_step_end is not None: + callback_kwargs = {} + for k in callback_on_step_end_tensor_inputs: + callback_kwargs[k] = locals()[k] + callback_outputs = callback_on_step_end(self, i, t, callback_kwargs) + + latents = callback_outputs.pop("latents", latents) + prompt_embeds = callback_outputs.pop("prompt_embeds", prompt_embeds) + negative_prompt_embeds = callback_outputs.pop("negative_prompt_embeds", negative_prompt_embeds) + prompt_embeds_2 = callback_outputs.pop("prompt_embeds_2", prompt_embeds_2) + negative_prompt_embeds_2 = callback_outputs.pop( + "negative_prompt_embeds_2", negative_prompt_embeds_2 + ) + if i == len(timesteps) - 1 or ((i + 1) > num_warmup_steps and (i + 1) % self.scheduler.order == 0): progress_bar.update() - if callback is not None and i % callback_steps == 0: - step_idx = i // getattr(self.scheduler, "order", 1) - callback(step_idx, t, latents) + + if XLA_AVAILABLE: + xm.mark_step() if comfyui_progressbar: pbar.update(1) @@ -1084,7 +1524,10 @@ class EasyAnimateInpaintPipeline(DiffusionPipeline): if output_type == "latent": video = torch.from_numpy(video) + # Offload all models + self.maybe_free_model_hooks() + if not return_dict: return video - return EasyAnimatePipelineOutput(videos=video) \ No newline at end of file + return EasyAnimatePipelineOutput(frames=video) \ No newline at end of file diff --git a/easyanimate/pipeline/pipeline_easyanimate_multi_text_encoder.py b/easyanimate/pipeline/pipeline_easyanimate_multi_text_encoder.py deleted file mode 100644 index edd35ad..0000000 --- a/easyanimate/pipeline/pipeline_easyanimate_multi_text_encoder.py +++ /dev/null @@ -1,918 +0,0 @@ -# Copyright 2024 EasyAnimate Authors and The HuggingFace Team. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import inspect -from typing import Callable, Dict, List, Optional, Tuple, Union - -import numpy as np -import torch -from diffusers.callbacks import MultiPipelineCallbacks, PipelineCallback -from diffusers.image_processor import VaeImageProcessor -from diffusers.models.embeddings import (get_2d_rotary_pos_embed, - get_3d_rotary_pos_embed) -from diffusers.pipelines.pipeline_utils import DiffusionPipeline -from diffusers.pipelines.stable_diffusion import StableDiffusionPipelineOutput -from diffusers.pipelines.stable_diffusion.safety_checker import \ - StableDiffusionSafetyChecker -from diffusers.schedulers import DDIMScheduler -from diffusers.utils import (is_torch_xla_available, logging, - replace_example_docstring) -from diffusers.utils.torch_utils import randn_tensor -from einops import rearrange -from tqdm import tqdm -from transformers import (BertModel, BertTokenizer, CLIPImageProcessor, - T5Tokenizer, T5EncoderModel) - -from .pipeline_easyanimate import EasyAnimatePipelineOutput -from ..models import AutoencoderKLMagvit, EasyAnimateTransformer3DModel - -if is_torch_xla_available(): - import torch_xla.core.xla_model as xm - - XLA_AVAILABLE = True -else: - XLA_AVAILABLE = False - - -logger = logging.get_logger(__name__) # pylint: disable=invalid-name - -EXAMPLE_DOC_STRING = """ - Examples: - ```py - >>> pass - ``` -""" - - -def get_resize_crop_region_for_grid(src, tgt_width, tgt_height): - tw = tgt_width - th = tgt_height - h, w = src - r = h / w - if r > (th / tw): - resize_height = th - resize_width = int(round(th / h * w)) - else: - resize_width = tw - resize_height = int(round(tw / w * h)) - - crop_top = int(round((th - resize_height) / 2.0)) - crop_left = int(round((tw - resize_width) / 2.0)) - - return (crop_top, crop_left), (crop_top + resize_height, crop_left + resize_width) - - -# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.rescale_noise_cfg -def rescale_noise_cfg(noise_cfg, noise_pred_text, guidance_rescale=0.0): - """ - Rescale `noise_cfg` according to `guidance_rescale`. Based on findings of [Common Diffusion Noise Schedules and - Sample Steps are Flawed](https://arxiv.org/pdf/2305.08891.pdf). See Section 3.4 - """ - std_text = noise_pred_text.std(dim=list(range(1, noise_pred_text.ndim)), keepdim=True) - std_cfg = noise_cfg.std(dim=list(range(1, noise_cfg.ndim)), keepdim=True) - # rescale the results from guidance (fixes overexposure) - noise_pred_rescaled = noise_cfg * (std_text / std_cfg) - # mix with the original results from guidance by factor guidance_rescale to avoid "plain looking" images - noise_cfg = guidance_rescale * noise_pred_rescaled + (1 - guidance_rescale) * noise_cfg - return noise_cfg - - -class EasyAnimatePipeline_Multi_Text_Encoder(DiffusionPipeline): - r""" - Pipeline for text-to-video generation using EasyAnimate. - - This model inherits from [`DiffusionPipeline`]. Check the superclass documentation for the generic methods the - library implements for all the pipelines (such as downloading or saving, running on a particular device, etc.) - - EasyAnimate uses two text encoders: [mT5](https://huggingface.co/google/mt5-base) and [bilingual CLIP](fine-tuned by - HunyuanDiT team) - - Args: - vae ([`AutoencoderKLMagvit`]): - Variational Auto-Encoder (VAE) Model to encode and decode video to and from latent representations. - text_encoder (Optional[`~transformers.BertModel`, `~transformers.CLIPTextModel`]): - Frozen text-encoder ([clip-vit-large-patch14](https://huggingface.co/openai/clip-vit-large-patch14)). - EasyAnimate uses a fine-tuned [bilingual CLIP]. - tokenizer (Optional[`~transformers.BertTokenizer`, `~transformers.CLIPTokenizer`]): - A `BertTokenizer` or `CLIPTokenizer` to tokenize text. - transformer ([`EasyAnimateTransformer3DModel`]): - The EasyAnimate model designed by Tencent Hunyuan. - text_encoder_2 (`T5EncoderModel`): - The mT5 embedder. - tokenizer_2 (`T5Tokenizer`): - The tokenizer for the mT5 embedder. - scheduler ([`DDIMScheduler`]): - A scheduler to be used in combination with EasyAnimate to denoise the encoded image latents. - """ - - model_cpu_offload_seq = "text_encoder->text_encoder_2->transformer->vae" - _optional_components = [ - "safety_checker", - "feature_extractor", - "text_encoder_2", - "tokenizer_2", - "text_encoder", - "tokenizer", - ] - _exclude_from_cpu_offload = ["safety_checker"] - _callback_tensor_inputs = [ - "latents", - "prompt_embeds", - "negative_prompt_embeds", - "prompt_embeds_2", - "negative_prompt_embeds_2", - ] - - def __init__( - self, - vae: AutoencoderKLMagvit, - text_encoder: BertModel, - tokenizer: BertTokenizer, - text_encoder_2: T5EncoderModel, - tokenizer_2: T5Tokenizer, - transformer: EasyAnimateTransformer3DModel, - scheduler: DDIMScheduler, - safety_checker: StableDiffusionSafetyChecker, - feature_extractor: CLIPImageProcessor, - requires_safety_checker: bool = True, - ): - super().__init__() - - self.register_modules( - vae=vae, - text_encoder=text_encoder, - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - transformer=transformer, - scheduler=scheduler, - safety_checker=safety_checker, - feature_extractor=feature_extractor, - text_encoder_2=text_encoder_2, - ) - - if safety_checker is None and requires_safety_checker: - logger.warning( - f"You have disabled the safety checker for {self.__class__} by passing `safety_checker=None`. Ensure" - " that you abide to the conditions of the Stable Diffusion license and do not expose unfiltered" - " results in services or applications open to the public. Both the diffusers team and Hugging Face" - " strongly recommend to keep the safety filter enabled in all public facing circumstances, disabling" - " it only for use-cases that involve analyzing network behavior or auditing its results. For more" - " information, please have a look at https://github.com/huggingface/diffusers/pull/254 ." - ) - - if safety_checker is not None and feature_extractor is None: - raise ValueError( - "Make sure to define a feature extractor when loading {self.__class__} if you want to use the safety" - " checker. If you do not want to use the safety checker, you can pass `'safety_checker=None'` instead." - ) - - self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1) - self.image_processor = VaeImageProcessor(vae_scale_factor=self.vae_scale_factor) - self.register_to_config(requires_safety_checker=requires_safety_checker) - - def enable_sequential_cpu_offload(self, *args, **kwargs): - super().enable_sequential_cpu_offload(*args, **kwargs) - if hasattr(self.transformer, "clip_projection") and self.transformer.clip_projection is not None: - import accelerate - accelerate.hooks.remove_hook_from_module(self.transformer.clip_projection, recurse=True) - self.transformer.clip_projection = self.transformer.clip_projection.to("cuda") - - def encode_prompt( - self, - prompt: str, - device: torch.device, - dtype: torch.dtype, - num_images_per_prompt: int = 1, - do_classifier_free_guidance: bool = True, - negative_prompt: Optional[str] = None, - prompt_embeds: Optional[torch.Tensor] = None, - negative_prompt_embeds: Optional[torch.Tensor] = None, - prompt_attention_mask: Optional[torch.Tensor] = None, - negative_prompt_attention_mask: Optional[torch.Tensor] = None, - max_sequence_length: Optional[int] = None, - text_encoder_index: int = 0, - actual_max_sequence_length: int = 256 - ): - r""" - Encodes the prompt into text encoder hidden states. - - Args: - prompt (`str` or `List[str]`, *optional*): - prompt to be encoded - device: (`torch.device`): - torch device - dtype (`torch.dtype`): - torch dtype - num_images_per_prompt (`int`): - number of images that should be generated per prompt - do_classifier_free_guidance (`bool`): - whether to use classifier free guidance or not - negative_prompt (`str` or `List[str]`, *optional*): - The prompt or prompts not to guide the image generation. If not defined, one has to pass - `negative_prompt_embeds` instead. Ignored when not using guidance (i.e., ignored if `guidance_scale` is - less than `1`). - prompt_embeds (`torch.Tensor`, *optional*): - Pre-generated text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting. If not - provided, text embeddings will be generated from `prompt` input argument. - negative_prompt_embeds (`torch.Tensor`, *optional*): - Pre-generated negative text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt - weighting. If not provided, negative_prompt_embeds will be generated from `negative_prompt` input - argument. - prompt_attention_mask (`torch.Tensor`, *optional*): - Attention mask for the prompt. Required when `prompt_embeds` is passed directly. - negative_prompt_attention_mask (`torch.Tensor`, *optional*): - Attention mask for the negative prompt. Required when `negative_prompt_embeds` is passed directly. - max_sequence_length (`int`, *optional*): maximum sequence length to use for the prompt. - text_encoder_index (`int`, *optional*): - Index of the text encoder to use. `0` for clip and `1` for T5. - """ - tokenizers = [self.tokenizer, self.tokenizer_2] - text_encoders = [self.text_encoder, self.text_encoder_2] - - tokenizer = tokenizers[text_encoder_index] - text_encoder = text_encoders[text_encoder_index] - - if max_sequence_length is None: - if text_encoder_index == 0: - max_length = min(self.tokenizer.model_max_length, actual_max_sequence_length) - if text_encoder_index == 1: - max_length = min(self.tokenizer_2.model_max_length, actual_max_sequence_length) - else: - max_length = max_sequence_length - - if prompt is not None and isinstance(prompt, str): - batch_size = 1 - elif prompt is not None and isinstance(prompt, list): - batch_size = len(prompt) - else: - batch_size = prompt_embeds.shape[0] - - if prompt_embeds is None: - text_inputs = tokenizer( - prompt, - padding="max_length", - max_length=max_length, - truncation=True, - return_attention_mask=True, - return_tensors="pt", - ) - text_input_ids = text_inputs.input_ids - if text_input_ids.shape[-1] > actual_max_sequence_length: - reprompt = tokenizer.batch_decode(text_input_ids[:, :actual_max_sequence_length], skip_special_tokens=True) - text_inputs = tokenizer( - reprompt, - padding="max_length", - max_length=max_length, - truncation=True, - return_attention_mask=True, - return_tensors="pt", - ) - text_input_ids = text_inputs.input_ids - untruncated_ids = tokenizer(prompt, padding="longest", return_tensors="pt").input_ids - - if untruncated_ids.shape[-1] >= text_input_ids.shape[-1] and not torch.equal( - text_input_ids, untruncated_ids - ): - _actual_max_sequence_length = min(tokenizer.model_max_length, actual_max_sequence_length) - removed_text = tokenizer.batch_decode(untruncated_ids[:, _actual_max_sequence_length - 1 : -1]) - logger.warning( - "The following part of your input was truncated because CLIP can only handle sequences up to" - f" {_actual_max_sequence_length} tokens: {removed_text}" - ) - prompt_attention_mask = text_inputs.attention_mask.to(device) - - if self.transformer.config.enable_text_attention_mask: - prompt_embeds = text_encoder( - text_input_ids.to(device), - attention_mask=prompt_attention_mask, - ) - else: - prompt_embeds = text_encoder( - text_input_ids.to(device) - ) - prompt_embeds = prompt_embeds[0] - prompt_attention_mask = prompt_attention_mask.repeat(num_images_per_prompt, 1) - - prompt_embeds = prompt_embeds.to(dtype=dtype, device=device) - - bs_embed, seq_len, _ = prompt_embeds.shape - # duplicate text embeddings for each generation per prompt, using mps friendly method - prompt_embeds = prompt_embeds.repeat(1, num_images_per_prompt, 1) - prompt_embeds = prompt_embeds.view(bs_embed * num_images_per_prompt, seq_len, -1) - - # get unconditional embeddings for classifier free guidance - if do_classifier_free_guidance and negative_prompt_embeds is None: - uncond_tokens: List[str] - if negative_prompt is None: - uncond_tokens = [""] * batch_size - elif prompt is not None and type(prompt) is not type(negative_prompt): - raise TypeError( - f"`negative_prompt` should be the same type to `prompt`, but got {type(negative_prompt)} !=" - f" {type(prompt)}." - ) - elif isinstance(negative_prompt, str): - uncond_tokens = [negative_prompt] - elif batch_size != len(negative_prompt): - raise ValueError( - f"`negative_prompt`: {negative_prompt} has batch size {len(negative_prompt)}, but `prompt`:" - f" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches" - " the batch size of `prompt`." - ) - else: - uncond_tokens = negative_prompt - - max_length = prompt_embeds.shape[1] - uncond_input = tokenizer( - uncond_tokens, - padding="max_length", - max_length=max_length, - truncation=True, - return_tensors="pt", - ) - uncond_input_ids = uncond_input.input_ids - if uncond_input_ids.shape[-1] > actual_max_sequence_length: - reuncond_tokens = tokenizer.batch_decode(uncond_input_ids[:, :actual_max_sequence_length], skip_special_tokens=True) - uncond_input = tokenizer( - reuncond_tokens, - padding="max_length", - max_length=max_length, - truncation=True, - return_attention_mask=True, - return_tensors="pt", - ) - uncond_input_ids = uncond_input.input_ids - - negative_prompt_attention_mask = uncond_input.attention_mask.to(device) - if self.transformer.config.enable_text_attention_mask: - negative_prompt_embeds = text_encoder( - uncond_input.input_ids.to(device), - attention_mask=negative_prompt_attention_mask, - ) - else: - negative_prompt_embeds = text_encoder( - uncond_input.input_ids.to(device) - ) - negative_prompt_embeds = negative_prompt_embeds[0] - negative_prompt_attention_mask = negative_prompt_attention_mask.repeat(num_images_per_prompt, 1) - - if do_classifier_free_guidance: - # duplicate unconditional embeddings for each generation per prompt, using mps friendly method - seq_len = negative_prompt_embeds.shape[1] - - negative_prompt_embeds = negative_prompt_embeds.to(dtype=dtype, device=device) - - negative_prompt_embeds = negative_prompt_embeds.repeat(1, num_images_per_prompt, 1) - negative_prompt_embeds = negative_prompt_embeds.view(batch_size * num_images_per_prompt, seq_len, -1) - - return prompt_embeds, negative_prompt_embeds, prompt_attention_mask, negative_prompt_attention_mask - - # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.run_safety_checker - def run_safety_checker(self, image, device, dtype): - if self.safety_checker is None: - has_nsfw_concept = None - else: - if torch.is_tensor(image): - feature_extractor_input = self.image_processor.postprocess(image, output_type="pil") - else: - feature_extractor_input = self.image_processor.numpy_to_pil(image) - safety_checker_input = self.feature_extractor(feature_extractor_input, return_tensors="pt").to(device) - image, has_nsfw_concept = self.safety_checker( - images=image, clip_input=safety_checker_input.pixel_values.to(dtype) - ) - return image, has_nsfw_concept - - # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.prepare_extra_step_kwargs - def prepare_extra_step_kwargs(self, generator, eta): - # prepare extra kwargs for the scheduler step, since not all schedulers have the same signature - # eta (η) is only used with the DDIMScheduler, it will be ignored for other schedulers. - # eta corresponds to η in DDIM paper: https://arxiv.org/abs/2010.02502 - # and should be between [0, 1] - - accepts_eta = "eta" in set(inspect.signature(self.scheduler.step).parameters.keys()) - extra_step_kwargs = {} - if accepts_eta: - extra_step_kwargs["eta"] = eta - - # check if the scheduler accepts generator - accepts_generator = "generator" in set(inspect.signature(self.scheduler.step).parameters.keys()) - if accepts_generator: - extra_step_kwargs["generator"] = generator - return extra_step_kwargs - - def check_inputs( - self, - prompt, - height, - width, - negative_prompt=None, - prompt_embeds=None, - negative_prompt_embeds=None, - prompt_attention_mask=None, - negative_prompt_attention_mask=None, - prompt_embeds_2=None, - negative_prompt_embeds_2=None, - prompt_attention_mask_2=None, - negative_prompt_attention_mask_2=None, - callback_on_step_end_tensor_inputs=None, - ): - if height % 8 != 0 or width % 8 != 0: - raise ValueError(f"`height` and `width` have to be divisible by 8 but are {height} and {width}.") - - if callback_on_step_end_tensor_inputs is not None and not all( - k in self._callback_tensor_inputs for k in callback_on_step_end_tensor_inputs - ): - raise ValueError( - f"`callback_on_step_end_tensor_inputs` has to be in {self._callback_tensor_inputs}, but found {[k for k in callback_on_step_end_tensor_inputs if k not in self._callback_tensor_inputs]}" - ) - - if prompt is not None and prompt_embeds is not None: - raise ValueError( - f"Cannot forward both `prompt`: {prompt} and `prompt_embeds`: {prompt_embeds}. Please make sure to" - " only forward one of the two." - ) - elif prompt is None and prompt_embeds is None: - raise ValueError( - "Provide either `prompt` or `prompt_embeds`. Cannot leave both `prompt` and `prompt_embeds` undefined." - ) - elif prompt is None and prompt_embeds_2 is None: - raise ValueError( - "Provide either `prompt` or `prompt_embeds_2`. Cannot leave both `prompt` and `prompt_embeds_2` undefined." - ) - elif prompt is not None and (not isinstance(prompt, str) and not isinstance(prompt, list)): - raise ValueError(f"`prompt` has to be of type `str` or `list` but is {type(prompt)}") - - if prompt_embeds is not None and prompt_attention_mask is None: - raise ValueError("Must provide `prompt_attention_mask` when specifying `prompt_embeds`.") - - if prompt_embeds_2 is not None and prompt_attention_mask_2 is None: - raise ValueError("Must provide `prompt_attention_mask_2` when specifying `prompt_embeds_2`.") - - if negative_prompt is not None and negative_prompt_embeds is not None: - raise ValueError( - f"Cannot forward both `negative_prompt`: {negative_prompt} and `negative_prompt_embeds`:" - f" {negative_prompt_embeds}. Please make sure to only forward one of the two." - ) - - if negative_prompt_embeds is not None and negative_prompt_attention_mask is None: - raise ValueError("Must provide `negative_prompt_attention_mask` when specifying `negative_prompt_embeds`.") - - if negative_prompt_embeds_2 is not None and negative_prompt_attention_mask_2 is None: - raise ValueError( - "Must provide `negative_prompt_attention_mask_2` when specifying `negative_prompt_embeds_2`." - ) - if prompt_embeds is not None and negative_prompt_embeds is not None: - if prompt_embeds.shape != negative_prompt_embeds.shape: - raise ValueError( - "`prompt_embeds` and `negative_prompt_embeds` must have the same shape when passed directly, but" - f" got: `prompt_embeds` {prompt_embeds.shape} != `negative_prompt_embeds`" - f" {negative_prompt_embeds.shape}." - ) - if prompt_embeds_2 is not None and negative_prompt_embeds_2 is not None: - if prompt_embeds_2.shape != negative_prompt_embeds_2.shape: - raise ValueError( - "`prompt_embeds_2` and `negative_prompt_embeds_2` must have the same shape when passed directly, but" - f" got: `prompt_embeds_2` {prompt_embeds_2.shape} != `negative_prompt_embeds_2`" - f" {negative_prompt_embeds_2.shape}." - ) - - # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.prepare_latents - def prepare_latents(self, batch_size, num_channels_latents, video_length, height, width, dtype, device, generator, latents=None): - if self.vae.quant_conv is None or self.vae.quant_conv.weight.ndim==5: - if self.vae.cache_mag_vae: - mini_batch_encoder = self.vae.mini_batch_encoder - mini_batch_decoder = self.vae.mini_batch_decoder - shape = (batch_size, num_channels_latents, int((video_length - 1) // mini_batch_encoder * mini_batch_decoder + 1) if video_length != 1 else 1, height // self.vae_scale_factor, width // self.vae_scale_factor) - else: - mini_batch_encoder = self.vae.mini_batch_encoder - mini_batch_decoder = self.vae.mini_batch_decoder - shape = (batch_size, num_channels_latents, int(video_length // mini_batch_encoder * mini_batch_decoder) if video_length != 1 else 1, height // self.vae_scale_factor, width // self.vae_scale_factor) - else: - shape = (batch_size, num_channels_latents, video_length, height // self.vae_scale_factor, width // self.vae_scale_factor) - - if isinstance(generator, list) and len(generator) != batch_size: - raise ValueError( - f"You have passed a list of generators of length {len(generator)}, but requested an effective batch" - f" size of {batch_size}. Make sure the batch size matches the length of the generators." - ) - - if latents is None: - latents = randn_tensor(shape, generator=generator, device=device, dtype=dtype) - else: - latents = latents.to(device) - - # scale the initial noise by the standard deviation required by the scheduler - latents = latents * self.scheduler.init_noise_sigma - return latents - - def smooth_output(self, video, mini_batch_encoder, mini_batch_decoder): - if video.size()[2] <= mini_batch_encoder: - return video - prefix_index_before = mini_batch_encoder // 2 - prefix_index_after = mini_batch_encoder - prefix_index_before - pixel_values = video[:, :, prefix_index_before:-prefix_index_after] - - # Encode middle videos - latents = self.vae.encode(pixel_values)[0] - latents = latents.mode() - # Decode middle videos - middle_video = self.vae.decode(latents)[0] - - video[:, :, prefix_index_before:-prefix_index_after] = (video[:, :, prefix_index_before:-prefix_index_after] + middle_video) / 2 - return video - - def decode_latents(self, latents): - video_length = latents.shape[2] - latents = 1 / self.vae.config.scaling_factor * latents - if self.vae.quant_conv is None or self.vae.quant_conv.weight.ndim==5: - mini_batch_encoder = self.vae.mini_batch_encoder - mini_batch_decoder = self.vae.mini_batch_decoder - video = self.vae.decode(latents)[0] - video = video.clamp(-1, 1) - if not self.vae.cache_compression_vae and not self.vae.cache_mag_vae: - video = self.smooth_output(video, mini_batch_encoder, mini_batch_decoder).cpu().clamp(-1, 1) - else: - latents = rearrange(latents, "b c f h w -> (b f) c h w") - video = [] - for frame_idx in tqdm(range(latents.shape[0])): - video.append(self.vae.decode(latents[frame_idx:frame_idx+1]).sample) - video = torch.cat(video) - video = rearrange(video, "(b f) c h w -> b c f h w", f=video_length) - video = (video / 2 + 0.5).clamp(0, 1) - # we always cast to float32 as this does not cause significant overhead and is compatible with bfloa16 - video = video.cpu().float().numpy() - return video - - @property - def guidance_scale(self): - return self._guidance_scale - - @property - def guidance_rescale(self): - return self._guidance_rescale - - # here `guidance_scale` is defined analog to the guidance weight `w` of equation (2) - # of the Imagen paper: https://arxiv.org/pdf/2205.11487.pdf . `guidance_scale = 1` - # corresponds to doing no classifier free guidance. - @property - def do_classifier_free_guidance(self): - return self._guidance_scale > 1 - - @property - def num_timesteps(self): - return self._num_timesteps - - @property - def interrupt(self): - return self._interrupt - - @torch.no_grad() - @replace_example_docstring(EXAMPLE_DOC_STRING) - def __call__( - self, - prompt: Union[str, List[str]] = None, - video_length: Optional[int] = None, - height: Optional[int] = None, - width: Optional[int] = None, - num_inference_steps: Optional[int] = 50, - guidance_scale: Optional[float] = 5.0, - negative_prompt: Optional[Union[str, List[str]]] = None, - num_images_per_prompt: Optional[int] = 1, - eta: Optional[float] = 0.0, - generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None, - latents: Optional[torch.Tensor] = None, - prompt_embeds: Optional[torch.Tensor] = None, - prompt_embeds_2: Optional[torch.Tensor] = None, - negative_prompt_embeds: Optional[torch.Tensor] = None, - negative_prompt_embeds_2: Optional[torch.Tensor] = None, - prompt_attention_mask: Optional[torch.Tensor] = None, - prompt_attention_mask_2: Optional[torch.Tensor] = None, - negative_prompt_attention_mask: Optional[torch.Tensor] = None, - negative_prompt_attention_mask_2: Optional[torch.Tensor] = None, - output_type: Optional[str] = "latent", - return_dict: bool = True, - callback_on_step_end: Optional[ - Union[Callable[[int, int, Dict], None], PipelineCallback, MultiPipelineCallbacks] - ] = None, - callback_on_step_end_tensor_inputs: List[str] = ["latents"], - guidance_rescale: float = 0.0, - original_size: Optional[Tuple[int, int]] = (1024, 1024), - target_size: Optional[Tuple[int, int]] = None, - crops_coords_top_left: Tuple[int, int] = (0, 0), - comfyui_progressbar: bool = False, - ): - r""" - Generates images or video using the EasyAnimate pipeline based on the provided prompts. - - Examples: - prompt (`str` or `List[str]`, *optional*): - Text prompts to guide the image or video generation. If not provided, use `prompt_embeds` instead. - video_length (`int`, *optional*): - Length of the generated video (in frames). - height (`int`, *optional*): - Height of the generated image in pixels. - width (`int`, *optional*): - Width of the generated image in pixels. - num_inference_steps (`int`, *optional*, defaults to 50): - Number of denoising steps during generation. More steps generally yield higher quality images but slow down inference. - guidance_scale (`float`, *optional*, defaults to 5.0): - Encourages the model to align outputs with prompts. A higher value may decrease image quality. - negative_prompt (`str` or `List[str]`, *optional*): - Prompts indicating what to exclude in generation. If not specified, use `negative_prompt_embeds`. - num_images_per_prompt (`int`, *optional*, defaults to 1): - Number of images to generate for each prompt. - eta (`float`, *optional*, defaults to 0.0): - Applies to DDIM scheduling. Controlled by the eta parameter from the related literature. - generator (`torch.Generator` or `List[torch.Generator]`, *optional*): - A generator to ensure reproducibility in image generation. - latents (`torch.Tensor`, *optional*): - Predefined latent tensors to condition generation. - prompt_embeds (`torch.Tensor`, *optional*): - Text embeddings for the prompts. Overrides prompt string inputs for more flexibility. - prompt_embeds_2 (`torch.Tensor`, *optional*): - Secondary text embeddings to supplement or replace the initial prompt embeddings. - negative_prompt_embeds (`torch.Tensor`, *optional*): - Embeddings for negative prompts. Overrides string inputs if defined. - negative_prompt_embeds_2 (`torch.Tensor`, *optional*): - Secondary embeddings for negative prompts, similar to `negative_prompt_embeds`. - prompt_attention_mask (`torch.Tensor`, *optional*): - Attention mask for the primary prompt embeddings. - prompt_attention_mask_2 (`torch.Tensor`, *optional*): - Attention mask for the secondary prompt embeddings. - negative_prompt_attention_mask (`torch.Tensor`, *optional*): - Attention mask for negative prompt embeddings. - negative_prompt_attention_mask_2 (`torch.Tensor`, *optional*): - Attention mask for secondary negative prompt embeddings. - output_type (`str`, *optional*, defaults to "latent"): - Format of the generated output, either as a PIL image or as a NumPy array. - return_dict (`bool`, *optional*, defaults to `True`): - If `True`, returns a structured output. Otherwise returns a simple tuple. - callback_on_step_end (`Callable`, *optional*): - Functions called at the end of each denoising step. - callback_on_step_end_tensor_inputs (`List[str]`, *optional*): - Tensor names to be included in callback function calls. - guidance_rescale (`float`, *optional*, defaults to 0.0): - Adjusts noise levels based on guidance scale. - original_size (`Tuple[int, int]`, *optional*, defaults to `(1024, 1024)`): - Original dimensions of the output. - target_size (`Tuple[int, int]`, *optional*): - Desired output dimensions for calculations. - crops_coords_top_left (`Tuple[int, int]`, *optional*, defaults to `(0, 0)`): - Coordinates for cropping. - - Returns: - [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] or `tuple`: - If `return_dict` is `True`, [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] is returned, - otherwise a `tuple` is returned where the first element is a list with the generated images and the - second element is a list of `bool`s indicating whether the corresponding generated image contains - "not-safe-for-work" (nsfw) content. - """ - - if isinstance(callback_on_step_end, (PipelineCallback, MultiPipelineCallbacks)): - callback_on_step_end_tensor_inputs = callback_on_step_end.tensor_inputs - - # 0. default height and width - height = int((height // 16) * 16) - width = int((width // 16) * 16) - - # 1. Check inputs. Raise error if not correct - self.check_inputs( - prompt, - height, - width, - negative_prompt, - prompt_embeds, - negative_prompt_embeds, - prompt_attention_mask, - negative_prompt_attention_mask, - prompt_embeds_2, - negative_prompt_embeds_2, - prompt_attention_mask_2, - negative_prompt_attention_mask_2, - callback_on_step_end_tensor_inputs, - ) - self._guidance_scale = guidance_scale - self._guidance_rescale = guidance_rescale - self._interrupt = False - - # 2. Define call parameters - if prompt is not None and isinstance(prompt, str): - batch_size = 1 - elif prompt is not None and isinstance(prompt, list): - batch_size = len(prompt) - else: - batch_size = prompt_embeds.shape[0] - - device = self._execution_device - if self.text_encoder is not None: - dtype = self.text_encoder.dtype - elif self.text_encoder_2 is not None: - dtype = self.text_encoder_2.dtype - else: - dtype = self.transformer.dtype - - # 3. Encode input prompt - ( - prompt_embeds, - negative_prompt_embeds, - prompt_attention_mask, - negative_prompt_attention_mask, - ) = self.encode_prompt( - prompt=prompt, - device=device, - dtype=dtype, - num_images_per_prompt=num_images_per_prompt, - do_classifier_free_guidance=self.do_classifier_free_guidance, - negative_prompt=negative_prompt, - prompt_embeds=prompt_embeds, - negative_prompt_embeds=negative_prompt_embeds, - prompt_attention_mask=prompt_attention_mask, - negative_prompt_attention_mask=negative_prompt_attention_mask, - text_encoder_index=0, - ) - ( - prompt_embeds_2, - negative_prompt_embeds_2, - prompt_attention_mask_2, - negative_prompt_attention_mask_2, - ) = self.encode_prompt( - prompt=prompt, - device=device, - dtype=dtype, - num_images_per_prompt=num_images_per_prompt, - do_classifier_free_guidance=self.do_classifier_free_guidance, - negative_prompt=negative_prompt, - prompt_embeds=prompt_embeds_2, - negative_prompt_embeds=negative_prompt_embeds_2, - prompt_attention_mask=prompt_attention_mask_2, - negative_prompt_attention_mask=negative_prompt_attention_mask_2, - text_encoder_index=1, - ) - - # 4. Prepare timesteps - self.scheduler.set_timesteps(num_inference_steps, device=device) - timesteps = self.scheduler.timesteps - if comfyui_progressbar: - from comfy.utils import ProgressBar - pbar = ProgressBar(num_inference_steps + 1) - - # 5. Prepare latent variables - num_channels_latents = self.transformer.config.in_channels - latents = self.prepare_latents( - batch_size * num_images_per_prompt, - num_channels_latents, - video_length, - height, - width, - dtype, - device, - generator, - latents, - ) - if comfyui_progressbar: - pbar.update(1) - - # 6. Prepare extra step kwargs. TODO: Logic should ideally just be moved out of the pipeline - extra_step_kwargs = self.prepare_extra_step_kwargs(generator, eta) - - # 7 create image_rotary_emb, style embedding & time ids - grid_height = height // 8 // self.transformer.config.patch_size - grid_width = width // 8 // self.transformer.config.patch_size - if self.transformer.config.get("time_position_encoding_type", "2d_rope") == "3d_rope": - base_size_width = 720 // 8 // self.transformer.config.patch_size - base_size_height = 480 // 8 // self.transformer.config.patch_size - - grid_crops_coords = get_resize_crop_region_for_grid( - (grid_height, grid_width), base_size_width, base_size_height - ) - image_rotary_emb = get_3d_rotary_pos_embed( - self.transformer.config.attention_head_dim, grid_crops_coords, grid_size=(grid_height, grid_width), - temporal_size=latents.size(2), use_real=True, - ) - else: - base_size = 512 // 8 // self.transformer.config.patch_size - grid_crops_coords = get_resize_crop_region_for_grid( - (grid_height, grid_width), base_size, base_size - ) - image_rotary_emb = get_2d_rotary_pos_embed( - self.transformer.config.attention_head_dim, grid_crops_coords, (grid_height, grid_width) - ) - - # Get other hunyuan params - style = torch.tensor([0], device=device) - - target_size = target_size or (height, width) - add_time_ids = list(original_size + target_size + crops_coords_top_left) - add_time_ids = torch.tensor([add_time_ids], dtype=dtype) - - if self.do_classifier_free_guidance: - prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds]) - prompt_attention_mask = torch.cat([negative_prompt_attention_mask, prompt_attention_mask]) - prompt_embeds_2 = torch.cat([negative_prompt_embeds_2, prompt_embeds_2]) - prompt_attention_mask_2 = torch.cat([negative_prompt_attention_mask_2, prompt_attention_mask_2]) - add_time_ids = torch.cat([add_time_ids] * 2, dim=0) - style = torch.cat([style] * 2, dim=0) - - # To latents.device - prompt_embeds = prompt_embeds.to(device=device) - prompt_attention_mask = prompt_attention_mask.to(device=device) - prompt_embeds_2 = prompt_embeds_2.to(device=device) - prompt_attention_mask_2 = prompt_attention_mask_2.to(device=device) - add_time_ids = add_time_ids.to(dtype=dtype, device=device).repeat( - batch_size * num_images_per_prompt, 1 - ) - style = style.to(device=device).repeat(batch_size * num_images_per_prompt) - - # 8. Denoising loop - num_warmup_steps = len(timesteps) - num_inference_steps * self.scheduler.order - self._num_timesteps = len(timesteps) - with self.progress_bar(total=num_inference_steps) as progress_bar: - for i, t in enumerate(timesteps): - if self.interrupt: - continue - - # expand the latents if we are doing classifier free guidance - latent_model_input = torch.cat([latents] * 2) if self.do_classifier_free_guidance else latents - latent_model_input = self.scheduler.scale_model_input(latent_model_input, t) - - # expand scalar t to 1-D tensor to match the 1st dim of latent_model_input - t_expand = torch.tensor([t] * latent_model_input.shape[0], device=device).to( - dtype=latent_model_input.dtype - ) - - # predict the noise residual - noise_pred = self.transformer( - latent_model_input, - t_expand, - encoder_hidden_states=prompt_embeds, - text_embedding_mask=prompt_attention_mask, - encoder_hidden_states_t5=prompt_embeds_2, - text_embedding_mask_t5=prompt_attention_mask_2, - image_meta_size=add_time_ids, - style=style, - image_rotary_emb=image_rotary_emb, - return_dict=False, - )[0] - - if noise_pred.size()[1] != self.vae.config.latent_channels: - noise_pred, _ = noise_pred.chunk(2, dim=1) - - # perform guidance - if self.do_classifier_free_guidance: - noise_pred_uncond, noise_pred_text = noise_pred.chunk(2) - noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond) - - if self.do_classifier_free_guidance and guidance_rescale > 0.0: - # Based on 3.4. in https://arxiv.org/pdf/2305.08891.pdf - noise_pred = rescale_noise_cfg(noise_pred, noise_pred_text, guidance_rescale=guidance_rescale) - - # compute the previous noisy sample x_t -> x_t-1 - latents = self.scheduler.step(noise_pred, t, latents, **extra_step_kwargs, return_dict=False)[0] - - if callback_on_step_end is not None: - callback_kwargs = {} - for k in callback_on_step_end_tensor_inputs: - callback_kwargs[k] = locals()[k] - callback_outputs = callback_on_step_end(self, i, t, callback_kwargs) - - latents = callback_outputs.pop("latents", latents) - prompt_embeds = callback_outputs.pop("prompt_embeds", prompt_embeds) - negative_prompt_embeds = callback_outputs.pop("negative_prompt_embeds", negative_prompt_embeds) - prompt_embeds_2 = callback_outputs.pop("prompt_embeds_2", prompt_embeds_2) - negative_prompt_embeds_2 = callback_outputs.pop( - "negative_prompt_embeds_2", negative_prompt_embeds_2 - ) - - if i == len(timesteps) - 1 or ((i + 1) > num_warmup_steps and (i + 1) % self.scheduler.order == 0): - progress_bar.update() - - if XLA_AVAILABLE: - xm.mark_step() - - if comfyui_progressbar: - pbar.update(1) - - # Post-processing - video = self.decode_latents(latents) - - # Convert to tensor - if output_type == "latent": - video = torch.from_numpy(video) - - # Offload all models - self.maybe_free_model_hooks() - - if not return_dict: - return video - - return EasyAnimatePipelineOutput(videos=video) \ No newline at end of file diff --git a/easyanimate/pipeline/pipeline_easyanimate_multi_text_encoder_inpaint.py b/easyanimate/pipeline/pipeline_easyanimate_multi_text_encoder_inpaint.py deleted file mode 100644 index 5e55af9..0000000 --- a/easyanimate/pipeline/pipeline_easyanimate_multi_text_encoder_inpaint.py +++ /dev/null @@ -1,1327 +0,0 @@ -# Copyright 2024 EasyAnimate Authors and The HuggingFace Team. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import inspect -from typing import Callable, Dict, List, Optional, Tuple, Union - -import torch -import torch.nn.functional as F -from diffusers import DiffusionPipeline -from diffusers.callbacks import MultiPipelineCallbacks, PipelineCallback -from diffusers.image_processor import VaeImageProcessor -from diffusers.models import AutoencoderKL, HunyuanDiT2DModel -from diffusers.models.embeddings import (get_2d_rotary_pos_embed, - get_3d_rotary_pos_embed) -from diffusers.pipelines.pipeline_utils import DiffusionPipeline -from diffusers.pipelines.stable_diffusion.safety_checker import \ - StableDiffusionSafetyChecker -from diffusers.schedulers import DDIMScheduler -from diffusers.utils import (is_torch_xla_available, logging, - replace_example_docstring) -from diffusers.utils.torch_utils import randn_tensor -from einops import rearrange -from PIL import Image -from tqdm import tqdm -from transformers import (BertModel, BertTokenizer, CLIPImageProcessor, - CLIPVisionModelWithProjection, T5Tokenizer, - T5EncoderModel) - -from .pipeline_easyanimate import EasyAnimatePipelineOutput -from ..models import AutoencoderKLMagvit, EasyAnimateTransformer3DModel - -if is_torch_xla_available(): - import torch_xla.core.xla_model as xm - - XLA_AVAILABLE = True -else: - XLA_AVAILABLE = False - - -logger = logging.get_logger(__name__) # pylint: disable=invalid-name - -EXAMPLE_DOC_STRING = """ - Examples: - ```py - >>> pass - ``` -""" - - -def get_resize_crop_region_for_grid(src, tgt_width, tgt_height): - tw = tgt_width - th = tgt_height - h, w = src - r = h / w - if r > (th / tw): - resize_height = th - resize_width = int(round(th / h * w)) - else: - resize_width = tw - resize_height = int(round(tw / w * h)) - - crop_top = int(round((th - resize_height) / 2.0)) - crop_left = int(round((tw - resize_width) / 2.0)) - - return (crop_top, crop_left), (crop_top + resize_height, crop_left + resize_width) - - -# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.rescale_noise_cfg -def rescale_noise_cfg(noise_cfg, noise_pred_text, guidance_rescale=0.0): - """ - Rescale `noise_cfg` according to `guidance_rescale`. Based on findings of [Common Diffusion Noise Schedules and - Sample Steps are Flawed](https://arxiv.org/pdf/2305.08891.pdf). See Section 3.4 - """ - std_text = noise_pred_text.std(dim=list(range(1, noise_pred_text.ndim)), keepdim=True) - std_cfg = noise_cfg.std(dim=list(range(1, noise_cfg.ndim)), keepdim=True) - # rescale the results from guidance (fixes overexposure) - noise_pred_rescaled = noise_cfg * (std_text / std_cfg) - # mix with the original results from guidance by factor guidance_rescale to avoid "plain looking" images - noise_cfg = guidance_rescale * noise_pred_rescaled + (1 - guidance_rescale) * noise_cfg - return noise_cfg - - -def resize_mask(mask, latent, process_first_frame_only=True): - latent_size = latent.size() - - if process_first_frame_only: - target_size = list(latent_size[2:]) - target_size[0] = 1 - first_frame_resized = F.interpolate( - mask[:, :, 0:1, :, :], - size=target_size, - mode='trilinear', - align_corners=False - ) - - target_size = list(latent_size[2:]) - target_size[0] = target_size[0] - 1 - if target_size[0] != 0: - remaining_frames_resized = F.interpolate( - mask[:, :, 1:, :, :], - size=target_size, - mode='trilinear', - align_corners=False - ) - resized_mask = torch.cat([first_frame_resized, remaining_frames_resized], dim=2) - else: - resized_mask = first_frame_resized - else: - target_size = list(latent_size[2:]) - resized_mask = F.interpolate( - mask, - size=target_size, - mode='trilinear', - align_corners=False - ) - return resized_mask - - -def add_noise_to_reference_video(image, ratio=None): - if ratio is None: - sigma = torch.normal(mean=-3.0, std=0.5, size=(image.shape[0],)).to(image.device) - sigma = torch.exp(sigma).to(image.dtype) - else: - sigma = torch.ones((image.shape[0],)).to(image.device, image.dtype) * ratio - - image_noise = torch.randn_like(image) * sigma[:, None, None, None, None] - image_noise = torch.where(image==-1, torch.zeros_like(image), image_noise) - image = image + image_noise - return image - - -class EasyAnimatePipeline_Multi_Text_Encoder_Inpaint(DiffusionPipeline): - r""" - Pipeline for text-to-video generation using EasyAnimate. - - This model inherits from [`DiffusionPipeline`]. Check the superclass documentation for the generic methods the - library implements for all the pipelines (such as downloading or saving, running on a particular device, etc.) - - EasyAnimate uses two text encoders: [mT5](https://huggingface.co/google/mt5-base) and [bilingual CLIP](fine-tuned by - HunyuanDiT team) - - Args: - vae ([`AutoencoderKLMagvit`]): - Variational Auto-Encoder (VAE) Model to encode and decode video to and from latent representations. - text_encoder (Optional[`~transformers.BertModel`, `~transformers.CLIPTextModel`]): - Frozen text-encoder ([clip-vit-large-patch14](https://huggingface.co/openai/clip-vit-large-patch14)). - EasyAnimate uses a fine-tuned [bilingual CLIP]. - tokenizer (Optional[`~transformers.BertTokenizer`, `~transformers.CLIPTokenizer`]): - A `BertTokenizer` or `CLIPTokenizer` to tokenize text. - transformer ([`EasyAnimateTransformer3DModel`]): - The EasyAnimate model designed by Tencent Hunyuan. - text_encoder_2 (`T5EncoderModel`): - The mT5 embedder. - tokenizer_2 (`T5Tokenizer`): - The tokenizer for the mT5 embedder. - scheduler ([`DDIMScheduler`]): - A scheduler to be used in combination with EasyAnimate to denoise the encoded image latents. - clip_image_processor (`CLIPImageProcessor`): - The CLIP image embedder. - clip_image_encoder (`CLIPVisionModelWithProjection`): - The image processor for the CLIP image embedder. - """ - - model_cpu_offload_seq = "text_encoder->text_encoder_2->transformer->vae" - _optional_components = [ - "safety_checker", - "feature_extractor", - "text_encoder_2", - "tokenizer_2", - "text_encoder", - "tokenizer", - "clip_image_encoder", - ] - _exclude_from_cpu_offload = ["safety_checker"] - _callback_tensor_inputs = [ - "latents", - "prompt_embeds", - "negative_prompt_embeds", - "prompt_embeds_2", - "negative_prompt_embeds_2", - ] - - def __init__( - self, - vae: AutoencoderKLMagvit, - text_encoder: BertModel, - tokenizer: BertTokenizer, - text_encoder_2: T5EncoderModel, - tokenizer_2: T5Tokenizer, - transformer: EasyAnimateTransformer3DModel, - scheduler: DDIMScheduler, - safety_checker: StableDiffusionSafetyChecker, - feature_extractor: CLIPImageProcessor, - requires_safety_checker: bool = True, - clip_image_processor: CLIPImageProcessor = None, - clip_image_encoder: CLIPVisionModelWithProjection = None, - ): - super().__init__() - - self.register_modules( - vae=vae, - text_encoder=text_encoder, - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - transformer=transformer, - scheduler=scheduler, - safety_checker=safety_checker, - feature_extractor=feature_extractor, - text_encoder_2=text_encoder_2, - clip_image_processor=clip_image_processor, - clip_image_encoder=clip_image_encoder, - ) - - if safety_checker is None and requires_safety_checker: - logger.warning( - f"You have disabled the safety checker for {self.__class__} by passing `safety_checker=None`. Ensure" - " that you abide to the conditions of the Stable Diffusion license and do not expose unfiltered" - " results in services or applications open to the public. Both the diffusers team and Hugging Face" - " strongly recommend to keep the safety filter enabled in all public facing circumstances, disabling" - " it only for use-cases that involve analyzing network behavior or auditing its results. For more" - " information, please have a look at https://github.com/huggingface/diffusers/pull/254 ." - ) - - if safety_checker is not None and feature_extractor is None: - raise ValueError( - "Make sure to define a feature extractor when loading {self.__class__} if you want to use the safety" - " checker. If you do not want to use the safety checker, you can pass `'safety_checker=None'` instead." - ) - - self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1) - self.image_processor = VaeImageProcessor(vae_scale_factor=self.vae_scale_factor) - self.mask_processor = VaeImageProcessor( - vae_scale_factor=self.vae_scale_factor, do_normalize=False, do_binarize=True, do_convert_grayscale=True - ) - self.register_to_config(requires_safety_checker=requires_safety_checker) - - def enable_sequential_cpu_offload(self, *args, **kwargs): - super().enable_sequential_cpu_offload(*args, **kwargs) - if hasattr(self.transformer, "clip_projection") and self.transformer.clip_projection is not None: - import accelerate - accelerate.hooks.remove_hook_from_module(self.transformer.clip_projection, recurse=True) - self.transformer.clip_projection = self.transformer.clip_projection.to("cuda") - - def encode_prompt( - self, - prompt: str, - device: torch.device, - dtype: torch.dtype, - num_images_per_prompt: int = 1, - do_classifier_free_guidance: bool = True, - negative_prompt: Optional[str] = None, - prompt_embeds: Optional[torch.Tensor] = None, - negative_prompt_embeds: Optional[torch.Tensor] = None, - prompt_attention_mask: Optional[torch.Tensor] = None, - negative_prompt_attention_mask: Optional[torch.Tensor] = None, - max_sequence_length: Optional[int] = None, - text_encoder_index: int = 0, - actual_max_sequence_length: int = 256 - ): - r""" - Encodes the prompt into text encoder hidden states. - - Args: - prompt (`str` or `List[str]`, *optional*): - prompt to be encoded - device: (`torch.device`): - torch device - dtype (`torch.dtype`): - torch dtype - num_images_per_prompt (`int`): - number of images that should be generated per prompt - do_classifier_free_guidance (`bool`): - whether to use classifier free guidance or not - negative_prompt (`str` or `List[str]`, *optional*): - The prompt or prompts not to guide the image generation. If not defined, one has to pass - `negative_prompt_embeds` instead. Ignored when not using guidance (i.e., ignored if `guidance_scale` is - less than `1`). - prompt_embeds (`torch.Tensor`, *optional*): - Pre-generated text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting. If not - provided, text embeddings will be generated from `prompt` input argument. - negative_prompt_embeds (`torch.Tensor`, *optional*): - Pre-generated negative text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt - weighting. If not provided, negative_prompt_embeds will be generated from `negative_prompt` input - argument. - prompt_attention_mask (`torch.Tensor`, *optional*): - Attention mask for the prompt. Required when `prompt_embeds` is passed directly. - negative_prompt_attention_mask (`torch.Tensor`, *optional*): - Attention mask for the negative prompt. Required when `negative_prompt_embeds` is passed directly. - max_sequence_length (`int`, *optional*): maximum sequence length to use for the prompt. - text_encoder_index (`int`, *optional*): - Index of the text encoder to use. `0` for clip and `1` for T5. - """ - tokenizers = [self.tokenizer, self.tokenizer_2] - text_encoders = [self.text_encoder, self.text_encoder_2] - - tokenizer = tokenizers[text_encoder_index] - text_encoder = text_encoders[text_encoder_index] - - if max_sequence_length is None: - if text_encoder_index == 0: - max_length = min(self.tokenizer.model_max_length, actual_max_sequence_length) - if text_encoder_index == 1: - max_length = min(self.tokenizer_2.model_max_length, actual_max_sequence_length) - else: - max_length = max_sequence_length - - if prompt is not None and isinstance(prompt, str): - batch_size = 1 - elif prompt is not None and isinstance(prompt, list): - batch_size = len(prompt) - else: - batch_size = prompt_embeds.shape[0] - - if prompt_embeds is None: - text_inputs = tokenizer( - prompt, - padding="max_length", - max_length=max_length, - truncation=True, - return_attention_mask=True, - return_tensors="pt", - ) - text_input_ids = text_inputs.input_ids - if text_input_ids.shape[-1] > actual_max_sequence_length: - reprompt = tokenizer.batch_decode(text_input_ids[:, :actual_max_sequence_length], skip_special_tokens=True) - text_inputs = tokenizer( - reprompt, - padding="max_length", - max_length=max_length, - truncation=True, - return_attention_mask=True, - return_tensors="pt", - ) - text_input_ids = text_inputs.input_ids - untruncated_ids = tokenizer(prompt, padding="longest", return_tensors="pt").input_ids - - if untruncated_ids.shape[-1] >= text_input_ids.shape[-1] and not torch.equal( - text_input_ids, untruncated_ids - ): - _actual_max_sequence_length = min(tokenizer.model_max_length, actual_max_sequence_length) - removed_text = tokenizer.batch_decode(untruncated_ids[:, _actual_max_sequence_length - 1 : -1]) - logger.warning( - "The following part of your input was truncated because CLIP can only handle sequences up to" - f" {_actual_max_sequence_length} tokens: {removed_text}" - ) - prompt_attention_mask = text_inputs.attention_mask.to(device) - if self.transformer.config.enable_text_attention_mask: - prompt_embeds = text_encoder( - text_input_ids.to(device), - attention_mask=prompt_attention_mask, - ) - else: - prompt_embeds = text_encoder( - text_input_ids.to(device) - ) - prompt_embeds = prompt_embeds[0] - prompt_attention_mask = prompt_attention_mask.repeat(num_images_per_prompt, 1) - - prompt_embeds = prompt_embeds.to(dtype=dtype, device=device) - - bs_embed, seq_len, _ = prompt_embeds.shape - # duplicate text embeddings for each generation per prompt, using mps friendly method - prompt_embeds = prompt_embeds.repeat(1, num_images_per_prompt, 1) - prompt_embeds = prompt_embeds.view(bs_embed * num_images_per_prompt, seq_len, -1) - - # get unconditional embeddings for classifier free guidance - if do_classifier_free_guidance and negative_prompt_embeds is None: - uncond_tokens: List[str] - if negative_prompt is None: - uncond_tokens = [""] * batch_size - elif prompt is not None and type(prompt) is not type(negative_prompt): - raise TypeError( - f"`negative_prompt` should be the same type to `prompt`, but got {type(negative_prompt)} !=" - f" {type(prompt)}." - ) - elif isinstance(negative_prompt, str): - uncond_tokens = [negative_prompt] - elif batch_size != len(negative_prompt): - raise ValueError( - f"`negative_prompt`: {negative_prompt} has batch size {len(negative_prompt)}, but `prompt`:" - f" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches" - " the batch size of `prompt`." - ) - else: - uncond_tokens = negative_prompt - - max_length = prompt_embeds.shape[1] - uncond_input = tokenizer( - uncond_tokens, - padding="max_length", - max_length=max_length, - truncation=True, - return_tensors="pt", - ) - uncond_input_ids = uncond_input.input_ids - if uncond_input_ids.shape[-1] > actual_max_sequence_length: - reuncond_tokens = tokenizer.batch_decode(uncond_input_ids[:, :actual_max_sequence_length], skip_special_tokens=True) - uncond_input = tokenizer( - reuncond_tokens, - padding="max_length", - max_length=max_length, - truncation=True, - return_attention_mask=True, - return_tensors="pt", - ) - uncond_input_ids = uncond_input.input_ids - - negative_prompt_attention_mask = uncond_input.attention_mask.to(device) - if self.transformer.config.enable_text_attention_mask: - negative_prompt_embeds = text_encoder( - uncond_input.input_ids.to(device), - attention_mask=negative_prompt_attention_mask, - ) - else: - negative_prompt_embeds = text_encoder( - uncond_input.input_ids.to(device) - ) - negative_prompt_embeds = negative_prompt_embeds[0] - negative_prompt_attention_mask = negative_prompt_attention_mask.repeat(num_images_per_prompt, 1) - - if do_classifier_free_guidance: - # duplicate unconditional embeddings for each generation per prompt, using mps friendly method - seq_len = negative_prompt_embeds.shape[1] - - negative_prompt_embeds = negative_prompt_embeds.to(dtype=dtype, device=device) - - negative_prompt_embeds = negative_prompt_embeds.repeat(1, num_images_per_prompt, 1) - negative_prompt_embeds = negative_prompt_embeds.view(batch_size * num_images_per_prompt, seq_len, -1) - - return prompt_embeds, negative_prompt_embeds, prompt_attention_mask, negative_prompt_attention_mask - - # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.run_safety_checker - def run_safety_checker(self, image, device, dtype): - if self.safety_checker is None: - has_nsfw_concept = None - else: - if torch.is_tensor(image): - feature_extractor_input = self.image_processor.postprocess(image, output_type="pil") - else: - feature_extractor_input = self.image_processor.numpy_to_pil(image) - safety_checker_input = self.feature_extractor(feature_extractor_input, return_tensors="pt").to(device) - image, has_nsfw_concept = self.safety_checker( - images=image, clip_input=safety_checker_input.pixel_values.to(dtype) - ) - return image, has_nsfw_concept - - # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.prepare_extra_step_kwargs - def prepare_extra_step_kwargs(self, generator, eta): - # prepare extra kwargs for the scheduler step, since not all schedulers have the same signature - # eta (η) is only used with the DDIMScheduler, it will be ignored for other schedulers. - # eta corresponds to η in DDIM paper: https://arxiv.org/abs/2010.02502 - # and should be between [0, 1] - - accepts_eta = "eta" in set(inspect.signature(self.scheduler.step).parameters.keys()) - extra_step_kwargs = {} - if accepts_eta: - extra_step_kwargs["eta"] = eta - - # check if the scheduler accepts generator - accepts_generator = "generator" in set(inspect.signature(self.scheduler.step).parameters.keys()) - if accepts_generator: - extra_step_kwargs["generator"] = generator - return extra_step_kwargs - - def check_inputs( - self, - prompt, - height, - width, - negative_prompt=None, - prompt_embeds=None, - negative_prompt_embeds=None, - prompt_attention_mask=None, - negative_prompt_attention_mask=None, - prompt_embeds_2=None, - negative_prompt_embeds_2=None, - prompt_attention_mask_2=None, - negative_prompt_attention_mask_2=None, - callback_on_step_end_tensor_inputs=None, - ): - if height % 8 != 0 or width % 8 != 0: - raise ValueError(f"`height` and `width` have to be divisible by 8 but are {height} and {width}.") - - if callback_on_step_end_tensor_inputs is not None and not all( - k in self._callback_tensor_inputs for k in callback_on_step_end_tensor_inputs - ): - raise ValueError( - f"`callback_on_step_end_tensor_inputs` has to be in {self._callback_tensor_inputs}, but found {[k for k in callback_on_step_end_tensor_inputs if k not in self._callback_tensor_inputs]}" - ) - - if prompt is not None and prompt_embeds is not None: - raise ValueError( - f"Cannot forward both `prompt`: {prompt} and `prompt_embeds`: {prompt_embeds}. Please make sure to" - " only forward one of the two." - ) - elif prompt is None and prompt_embeds is None: - raise ValueError( - "Provide either `prompt` or `prompt_embeds`. Cannot leave both `prompt` and `prompt_embeds` undefined." - ) - elif prompt is None and prompt_embeds_2 is None: - raise ValueError( - "Provide either `prompt` or `prompt_embeds_2`. Cannot leave both `prompt` and `prompt_embeds_2` undefined." - ) - elif prompt is not None and (not isinstance(prompt, str) and not isinstance(prompt, list)): - raise ValueError(f"`prompt` has to be of type `str` or `list` but is {type(prompt)}") - - if prompt_embeds is not None and prompt_attention_mask is None: - raise ValueError("Must provide `prompt_attention_mask` when specifying `prompt_embeds`.") - - if prompt_embeds_2 is not None and prompt_attention_mask_2 is None: - raise ValueError("Must provide `prompt_attention_mask_2` when specifying `prompt_embeds_2`.") - - if negative_prompt is not None and negative_prompt_embeds is not None: - raise ValueError( - f"Cannot forward both `negative_prompt`: {negative_prompt} and `negative_prompt_embeds`:" - f" {negative_prompt_embeds}. Please make sure to only forward one of the two." - ) - - if negative_prompt_embeds is not None and negative_prompt_attention_mask is None: - raise ValueError("Must provide `negative_prompt_attention_mask` when specifying `negative_prompt_embeds`.") - - if negative_prompt_embeds_2 is not None and negative_prompt_attention_mask_2 is None: - raise ValueError( - "Must provide `negative_prompt_attention_mask_2` when specifying `negative_prompt_embeds_2`." - ) - if prompt_embeds is not None and negative_prompt_embeds is not None: - if prompt_embeds.shape != negative_prompt_embeds.shape: - raise ValueError( - "`prompt_embeds` and `negative_prompt_embeds` must have the same shape when passed directly, but" - f" got: `prompt_embeds` {prompt_embeds.shape} != `negative_prompt_embeds`" - f" {negative_prompt_embeds.shape}." - ) - if prompt_embeds_2 is not None and negative_prompt_embeds_2 is not None: - if prompt_embeds_2.shape != negative_prompt_embeds_2.shape: - raise ValueError( - "`prompt_embeds_2` and `negative_prompt_embeds_2` must have the same shape when passed directly, but" - f" got: `prompt_embeds_2` {prompt_embeds_2.shape} != `negative_prompt_embeds_2`" - f" {negative_prompt_embeds_2.shape}." - ) - - # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion_img2img.StableDiffusionImg2ImgPipeline.get_timesteps - def get_timesteps(self, num_inference_steps, strength, device): - # get the original timestep using init_timestep - init_timestep = min(int(num_inference_steps * strength), num_inference_steps) - - t_start = max(num_inference_steps - init_timestep, 0) - timesteps = self.scheduler.timesteps[t_start * self.scheduler.order :] - - return timesteps, num_inference_steps - t_start - - def prepare_mask_latents( - self, mask, masked_image, batch_size, height, width, dtype, device, generator, do_classifier_free_guidance, noise_aug_strength - ): - # resize the mask to latents shape as we concatenate the mask to the latents - # we do that before converting to dtype to avoid breaking in case we're using cpu_offload - # and half precision - if mask is not None: - mask = mask.to(device=device, dtype=dtype) - if self.vae.quant_conv is None or self.vae.quant_conv.weight.ndim==5: - bs = 1 - new_mask = [] - for i in range(0, mask.shape[0], bs): - mask_bs = mask[i : i + bs] - mask_bs = self.vae.encode(mask_bs)[0] - mask_bs = mask_bs.mode() - new_mask.append(mask_bs) - mask = torch.cat(new_mask, dim = 0) - mask = mask * self.vae.config.scaling_factor - - else: - if mask.shape[1] == 4: - mask = mask - else: - video_length = mask.shape[2] - mask = rearrange(mask, "b c f h w -> (b f) c h w") - mask = self._encode_vae_image(mask, generator=generator) - mask = rearrange(mask, "(b f) c h w -> b c f h w", f=video_length) - - if masked_image is not None: - masked_image = masked_image.to(device=device, dtype=dtype) - if self.transformer.config.add_noise_in_inpaint_model: - masked_image = add_noise_to_reference_video(masked_image, ratio=noise_aug_strength) - if self.vae.quant_conv is None or self.vae.quant_conv.weight.ndim==5: - bs = 1 - new_mask_pixel_values = [] - for i in range(0, masked_image.shape[0], bs): - mask_pixel_values_bs = masked_image[i : i + bs] - mask_pixel_values_bs = self.vae.encode(mask_pixel_values_bs)[0] - mask_pixel_values_bs = mask_pixel_values_bs.mode() - new_mask_pixel_values.append(mask_pixel_values_bs) - masked_image_latents = torch.cat(new_mask_pixel_values, dim = 0) - masked_image_latents = masked_image_latents * self.vae.config.scaling_factor - - else: - if masked_image.shape[1] == 4: - masked_image_latents = masked_image - else: - video_length = masked_image.shape[2] - masked_image = rearrange(masked_image, "b c f h w -> (b f) c h w") - masked_image_latents = self._encode_vae_image(masked_image, generator=generator) - masked_image_latents = rearrange(masked_image_latents, "(b f) c h w -> b c f h w", f=video_length) - - # aligning device to prevent device errors when concating it with the latent model input - masked_image_latents = masked_image_latents.to(device=device, dtype=dtype) - else: - masked_image_latents = None - - return mask, masked_image_latents - - def prepare_latents( - self, - batch_size, - num_channels_latents, - height, - width, - video_length, - dtype, - device, - generator, - latents=None, - video=None, - timestep=None, - is_strength_max=True, - return_noise=False, - return_video_latents=False, - ): - if self.vae.quant_conv is None or self.vae.quant_conv.weight.ndim==5: - if self.vae.cache_mag_vae: - mini_batch_encoder = self.vae.mini_batch_encoder - mini_batch_decoder = self.vae.mini_batch_decoder - shape = (batch_size, num_channels_latents, int((video_length - 1) // mini_batch_encoder * mini_batch_decoder + 1) if video_length != 1 else 1, height // self.vae_scale_factor, width // self.vae_scale_factor) - else: - mini_batch_encoder = self.vae.mini_batch_encoder - mini_batch_decoder = self.vae.mini_batch_decoder - shape = (batch_size, num_channels_latents, int(video_length // mini_batch_encoder * mini_batch_decoder) if video_length != 1 else 1, height // self.vae_scale_factor, width // self.vae_scale_factor) - else: - shape = (batch_size, num_channels_latents, video_length, height // self.vae_scale_factor, width // self.vae_scale_factor) - - if isinstance(generator, list) and len(generator) != batch_size: - raise ValueError( - f"You have passed a list of generators of length {len(generator)}, but requested an effective batch" - f" size of {batch_size}. Make sure the batch size matches the length of the generators." - ) - - if return_video_latents or (latents is None and not is_strength_max): - video = video.to(device=device, dtype=dtype) - if self.vae.quant_conv is None or self.vae.quant_conv.weight.ndim==5: - bs = 1 - new_video = [] - for i in range(0, video.shape[0], bs): - video_bs = video[i : i + bs] - video_bs = self.vae.encode(video_bs)[0] - video_bs = video_bs.sample() - new_video.append(video_bs) - video = torch.cat(new_video, dim = 0) - video = video * self.vae.config.scaling_factor - - else: - if video.shape[1] == 4: - video = video - else: - video_length = video.shape[2] - video = rearrange(video, "b c f h w -> (b f) c h w") - video = self._encode_vae_image(video, generator=generator) - video = rearrange(video, "(b f) c h w -> b c f h w", f=video_length) - video_latents = video.repeat(batch_size // video.shape[0], 1, 1, 1, 1) - video_latents = video_latents.to(device=device, dtype=dtype) - - if latents is None: - noise = randn_tensor(shape, generator=generator, device=device, dtype=dtype) - # if strength is 1. then initialise the latents to noise, else initial to image + noise - latents = noise if is_strength_max else self.scheduler.add_noise(video_latents, noise, timestep) - # if pure noise then scale the initial latents by the Scheduler's init sigma - latents = latents * self.scheduler.init_noise_sigma if is_strength_max else latents - else: - noise = latents.to(device) - latents = noise * self.scheduler.init_noise_sigma - - # scale the initial noise by the standard deviation required by the scheduler - outputs = (latents,) - - if return_noise: - outputs += (noise,) - - if return_video_latents: - outputs += (video_latents,) - - return outputs - - def smooth_output(self, video, mini_batch_encoder, mini_batch_decoder): - if video.size()[2] <= mini_batch_encoder: - return video - prefix_index_before = mini_batch_encoder // 2 - prefix_index_after = mini_batch_encoder - prefix_index_before - pixel_values = video[:, :, prefix_index_before:-prefix_index_after] - - # Encode middle videos - latents = self.vae.encode(pixel_values)[0] - latents = latents.mode() - # Decode middle videos - middle_video = self.vae.decode(latents)[0] - - video[:, :, prefix_index_before:-prefix_index_after] = (video[:, :, prefix_index_before:-prefix_index_after] + middle_video) / 2 - return video - - def decode_latents(self, latents): - video_length = latents.shape[2] - latents = 1 / self.vae.config.scaling_factor * latents - if self.vae.quant_conv is None or self.vae.quant_conv.weight.ndim==5: - mini_batch_encoder = self.vae.mini_batch_encoder - mini_batch_decoder = self.vae.mini_batch_decoder - video = self.vae.decode(latents)[0] - video = video.clamp(-1, 1) - if not self.vae.cache_compression_vae and not self.vae.cache_mag_vae: - video = self.smooth_output(video, mini_batch_encoder, mini_batch_decoder).cpu().clamp(-1, 1) - else: - latents = rearrange(latents, "b c f h w -> (b f) c h w") - video = [] - for frame_idx in tqdm(range(latents.shape[0])): - video.append(self.vae.decode(latents[frame_idx:frame_idx+1]).sample) - video = torch.cat(video) - video = rearrange(video, "(b f) c h w -> b c f h w", f=video_length) - video = (video / 2 + 0.5).clamp(0, 1) - # we always cast to float32 as this does not cause significant overhead and is compatible with bfloa16 - video = video.cpu().float().numpy() - return video - - @property - def guidance_scale(self): - return self._guidance_scale - - @property - def guidance_rescale(self): - return self._guidance_rescale - - # here `guidance_scale` is defined analog to the guidance weight `w` of equation (2) - # of the Imagen paper: https://arxiv.org/pdf/2205.11487.pdf . `guidance_scale = 1` - # corresponds to doing no classifier free guidance. - @property - def do_classifier_free_guidance(self): - return self._guidance_scale > 1 - - @property - def num_timesteps(self): - return self._num_timesteps - - @property - def interrupt(self): - return self._interrupt - - @torch.no_grad() - @replace_example_docstring(EXAMPLE_DOC_STRING) - def __call__( - self, - prompt: Union[str, List[str]] = None, - video_length: Optional[int] = None, - video: Union[torch.FloatTensor] = None, - mask_video: Union[torch.FloatTensor] = None, - masked_video_latents: Union[torch.FloatTensor] = None, - height: Optional[int] = None, - width: Optional[int] = None, - num_inference_steps: Optional[int] = 50, - guidance_scale: Optional[float] = 5.0, - negative_prompt: Optional[Union[str, List[str]]] = None, - num_images_per_prompt: Optional[int] = 1, - eta: Optional[float] = 0.0, - generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None, - latents: Optional[torch.Tensor] = None, - prompt_embeds: Optional[torch.Tensor] = None, - prompt_embeds_2: Optional[torch.Tensor] = None, - negative_prompt_embeds: Optional[torch.Tensor] = None, - negative_prompt_embeds_2: Optional[torch.Tensor] = None, - prompt_attention_mask: Optional[torch.Tensor] = None, - prompt_attention_mask_2: Optional[torch.Tensor] = None, - negative_prompt_attention_mask: Optional[torch.Tensor] = None, - negative_prompt_attention_mask_2: Optional[torch.Tensor] = None, - output_type: Optional[str] = "latent", - return_dict: bool = True, - callback_on_step_end: Optional[ - Union[Callable[[int, int, Dict], None], PipelineCallback, MultiPipelineCallbacks] - ] = None, - callback_on_step_end_tensor_inputs: List[str] = ["latents"], - guidance_rescale: float = 0.0, - original_size: Optional[Tuple[int, int]] = (1024, 1024), - target_size: Optional[Tuple[int, int]] = None, - crops_coords_top_left: Tuple[int, int] = (0, 0), - clip_image: Image = None, - clip_apply_ratio: float = 0.40, - strength: float = 1.0, - noise_aug_strength: float = 0.0563, - comfyui_progressbar: bool = False, - ): - r""" - The call function to the pipeline for generation with HunyuanDiT. - - Examples: - prompt (`str` or `List[str]`, *optional*): - The prompt or prompts to guide image generation. If not defined, you need to pass `prompt_embeds`. - video_length (`int`, *optional*): - Length of the video to be generated in seconds. This parameter influences the number of frames and - continuity of generated content. - video (`torch.FloatTensor`, *optional*): - A tensor representing an input video, which can be modified depending on the prompts provided. - mask_video (`torch.FloatTensor`, *optional*): - A tensor to specify areas of the video to be masked (omitted from generation). - masked_video_latents (`torch.FloatTensor`, *optional*): - Latents from masked portions of the video, utilized during image generation. - height (`int`, *optional*): - The height in pixels of the generated image or video frames. - width (`int`, *optional*): - The width in pixels of the generated image or video frames. - num_inference_steps (`int`, *optional*, defaults to 50): - The number of denoising steps. More denoising steps usually lead to a higher quality image but slower - inference time. This parameter is modulated by `strength`. - guidance_scale (`float`, *optional*, defaults to 5.0): - A higher guidance scale value encourages the model to generate images closely linked to the text - `prompt` at the expense of lower image quality. Guidance scale is effective when `guidance_scale > 1`. - negative_prompt (`str` or `List[str]`, *optional*): - The prompt or prompts to guide what to exclude in image generation. If not defined, you need to - provide `negative_prompt_embeds`. This parameter is ignored when not using guidance (`guidance_scale < 1`). - num_images_per_prompt (`int`, *optional*, defaults to 1): - The number of images to generate per prompt. - eta (`float`, *optional*, defaults to 0.0): - A parameter defined in the [DDIM](https://arxiv.org/abs/2010.02502) paper. Only applies to the - [`~schedulers.DDIMScheduler`] and is ignored in other schedulers. It adjusts noise level during the - inference process. - generator (`torch.Generator` or `List[torch.Generator]`, *optional*): - A [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html) for setting - random seeds which helps in making generation deterministic. - latents (`torch.Tensor`, *optional*): - A pre-computed latent representation which can be used to guide the generation process. - prompt_embeds (`torch.Tensor`, *optional*): - Pre-generated text embeddings. Can be used to easily tweak text inputs (prompt weighting). If not - provided, embeddings are generated from the `prompt` input argument. - prompt_embeds_2 (`torch.Tensor`, *optional*): - Secondary set of pre-generated text embeddings, useful for advanced prompt weighting. - negative_prompt_embeds (`torch.Tensor`, *optional*): - Pre-generated negative text embeddings, aiding in fine-tuning what should not be represented in the outputs. - If not provided, embeddings are generated from the `negative_prompt` argument. - negative_prompt_embeds_2 (`torch.Tensor`, *optional*): - Secondary set of pre-generated negative text embeddings for further control. - prompt_attention_mask (`torch.Tensor`, *optional*): - Attention mask guiding the focus of the model on specific parts of the prompt text. Required when using - `prompt_embeds`. - prompt_attention_mask_2 (`torch.Tensor`, *optional*): - Attention mask for the secondary prompt embedding. - negative_prompt_attention_mask (`torch.Tensor`, *optional*): - Attention mask for the negative prompt, needed when `negative_prompt_embeds` are used. - negative_prompt_attention_mask_2 (`torch.Tensor`, *optional*): - Attention mask for the secondary negative prompt embedding. - output_type (`str`, *optional*, defaults to `"latent"`): - The output format of the generated image. Choose between `PIL.Image` and `np.array` to define - how you want the results to be formatted. - return_dict (`bool`, *optional*, defaults to `True`): - If set to `True`, a [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] will be returned; - otherwise, a tuple containing the generated images and safety flags will be returned. - callback_on_step_end (`Callable[[int, int, Dict], None]`, `PipelineCallback`, `MultiPipelineCallbacks`, *optional*): - A callback function (or a list of them) that will be executed at the end of each denoising step, - allowing for custom processing during generation. - callback_on_step_end_tensor_inputs (`List[str]`, *optional*): - Specifies which tensor inputs should be included in the callback function. If not defined, all tensor - inputs will be passed, facilitating enhanced logging or monitoring of the generation process. - guidance_rescale (`float`, *optional*, defaults to 0.0): - Rescale parameter for adjusting noise configuration based on guidance rescale. Based on findings from - [Common Diffusion Noise Schedules and Sample Steps are Flawed](https://arxiv.org/pdf/2305.08891.pdf). - original_size (`Tuple[int, int]`, *optional*, defaults to `(1024, 1024)`): - The original dimensions of the image. Used to compute time ids during the generation process. - target_size (`Tuple[int, int]`, *optional*): - The targeted dimensions of the generated image, also utilized in the time id calculations. - crops_coords_top_left (`Tuple[int, int]`, *optional*, defaults to `(0, 0)`): - Coordinates defining the top left corner of any cropping, utilized while calculating the time ids. - clip_image (`Image`, *optional*): - An optional image to assist in the generation process. It may be used as an additional visual cue. - clip_apply_ratio (`float`, *optional*, defaults to 0.40): - Ratio indicating how much influence the clip image should exert over the generated content. - strength (`float`, *optional*, defaults to 1.0): - Affects the overall styling or quality of the generated output. Values closer to 1 usually provide direct - adherence to prompts. - comfyui_progressbar (`bool`, *optional*, defaults to `False`): - Enables a progress bar in ComfyUI, providing visual feedback during the generation process. - - Examples: - # Example usage of the function for generating images based on prompts. - - Returns: - [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] or `tuple`: - Returns either a structured output containing generated images and their metadata when `return_dict` is - `True`, or a simpler tuple, where the first element is a list of generated images and the second - element indicates if any of them contain "not-safe-for-work" (NSFW) content. - """ - - if isinstance(callback_on_step_end, (PipelineCallback, MultiPipelineCallbacks)): - callback_on_step_end_tensor_inputs = callback_on_step_end.tensor_inputs - - # 0. default height and width - height = int(height // 16 * 16) - width = int(width // 16 * 16) - - # 1. Check inputs. Raise error if not correct - self.check_inputs( - prompt, - height, - width, - negative_prompt, - prompt_embeds, - negative_prompt_embeds, - prompt_attention_mask, - negative_prompt_attention_mask, - prompt_embeds_2, - negative_prompt_embeds_2, - prompt_attention_mask_2, - negative_prompt_attention_mask_2, - callback_on_step_end_tensor_inputs, - ) - self._guidance_scale = guidance_scale - self._guidance_rescale = guidance_rescale - self._interrupt = False - - # 2. Define call parameters - if prompt is not None and isinstance(prompt, str): - batch_size = 1 - elif prompt is not None and isinstance(prompt, list): - batch_size = len(prompt) - else: - batch_size = prompt_embeds.shape[0] - - device = self._execution_device - if self.text_encoder is not None: - dtype = self.text_encoder.dtype - elif self.text_encoder_2 is not None: - dtype = self.text_encoder_2.dtype - else: - dtype = self.transformer.dtype - - # 3. Encode input prompt - ( - prompt_embeds, - negative_prompt_embeds, - prompt_attention_mask, - negative_prompt_attention_mask, - ) = self.encode_prompt( - prompt=prompt, - device=device, - dtype=dtype, - num_images_per_prompt=num_images_per_prompt, - do_classifier_free_guidance=self.do_classifier_free_guidance, - negative_prompt=negative_prompt, - prompt_embeds=prompt_embeds, - negative_prompt_embeds=negative_prompt_embeds, - prompt_attention_mask=prompt_attention_mask, - negative_prompt_attention_mask=negative_prompt_attention_mask, - text_encoder_index=0, - ) - ( - prompt_embeds_2, - negative_prompt_embeds_2, - prompt_attention_mask_2, - negative_prompt_attention_mask_2, - ) = self.encode_prompt( - prompt=prompt, - device=device, - dtype=dtype, - num_images_per_prompt=num_images_per_prompt, - do_classifier_free_guidance=self.do_classifier_free_guidance, - negative_prompt=negative_prompt, - prompt_embeds=prompt_embeds_2, - negative_prompt_embeds=negative_prompt_embeds_2, - prompt_attention_mask=prompt_attention_mask_2, - negative_prompt_attention_mask=negative_prompt_attention_mask_2, - text_encoder_index=1, - ) - - # 4. set timesteps - self.scheduler.set_timesteps(num_inference_steps, device=device) - timesteps, num_inference_steps = self.get_timesteps( - num_inference_steps=num_inference_steps, strength=strength, device=device - ) - if comfyui_progressbar: - from comfy.utils import ProgressBar - pbar = ProgressBar(num_inference_steps + 3) - # at which timestep to set the initial noise (n.b. 50% if strength is 0.5) - latent_timestep = timesteps[:1].repeat(batch_size * num_images_per_prompt) - # create a boolean to check if the strength is set to 1. if so then initialise the latents with pure noise - is_strength_max = strength == 1.0 - - if video is not None: - video_length = video.shape[2] - init_video = self.image_processor.preprocess(rearrange(video, "b c f h w -> (b f) c h w"), height=height, width=width) - init_video = init_video.to(dtype=torch.float32) - init_video = rearrange(init_video, "(b f) c h w -> b c f h w", f=video_length) - else: - init_video = None - - # Prepare latent variables - num_channels_latents = self.vae.config.latent_channels - num_channels_transformer = self.transformer.config.in_channels - return_image_latents = num_channels_transformer == num_channels_latents - - # 5. Prepare latents. - latents_outputs = self.prepare_latents( - batch_size * num_images_per_prompt, - num_channels_latents, - height, - width, - video_length, - dtype, - device, - generator, - latents, - video=init_video, - timestep=latent_timestep, - is_strength_max=is_strength_max, - return_noise=True, - return_video_latents=return_image_latents, - ) - if return_image_latents: - latents, noise, image_latents = latents_outputs - else: - latents, noise = latents_outputs - - if comfyui_progressbar: - pbar.update(1) - - # 6. Prepare clip latents if it needs. - if clip_image is not None and self.transformer.enable_clip_in_inpaint: - inputs = self.clip_image_processor(images=clip_image, return_tensors="pt") - inputs["pixel_values"] = inputs["pixel_values"].to(device, dtype=dtype) - clip_encoder_hidden_states = self.clip_image_encoder(**inputs).last_hidden_state[:, 1:] - clip_encoder_hidden_states_neg = torch.zeros( - [ - batch_size, - int(self.clip_image_encoder.config.image_size / self.clip_image_encoder.config.patch_size) ** 2, - int(self.clip_image_encoder.config.hidden_size) - ] - ).to(device, dtype=dtype) - - clip_attention_mask = torch.ones([batch_size, self.transformer.n_query]).to(device, dtype=dtype) - clip_attention_mask_neg = torch.zeros([batch_size, self.transformer.n_query]).to(device, dtype=dtype) - - clip_encoder_hidden_states_input = torch.cat([clip_encoder_hidden_states_neg, clip_encoder_hidden_states]) if self.do_classifier_free_guidance else clip_encoder_hidden_states - clip_attention_mask_input = torch.cat([clip_attention_mask_neg, clip_attention_mask]) if self.do_classifier_free_guidance else clip_attention_mask - - elif clip_image is None and num_channels_transformer != num_channels_latents and self.transformer.enable_clip_in_inpaint: - clip_encoder_hidden_states = torch.zeros( - [ - batch_size, - int(self.clip_image_encoder.config.image_size / self.clip_image_encoder.config.patch_size) ** 2, - int(self.clip_image_encoder.config.hidden_size) - ] - ).to(device, dtype=dtype) - - clip_attention_mask = torch.zeros([batch_size, self.transformer.n_query]) - clip_attention_mask = clip_attention_mask.to(device, dtype=dtype) - - clip_encoder_hidden_states_input = torch.cat([clip_encoder_hidden_states] * 2) if self.do_classifier_free_guidance else clip_encoder_hidden_states - clip_attention_mask_input = torch.cat([clip_attention_mask] * 2) if self.do_classifier_free_guidance else clip_attention_mask - - else: - clip_encoder_hidden_states_input = None - clip_attention_mask_input = None - if comfyui_progressbar: - pbar.update(1) - - # 7. Prepare inpaint latents if it needs. - if mask_video is not None: - if (mask_video == 255).all(): - # Use zero latents if we want to t2v. - if self.transformer.resize_inpaint_mask_directly: - mask_latents = torch.zeros_like(latents)[:, :1].to(device, dtype) - else: - mask_latents = torch.zeros_like(latents).to(device, dtype) - masked_video_latents = torch.zeros_like(latents).to(device, dtype) - - mask_input = torch.cat([mask_latents] * 2) if self.do_classifier_free_guidance else mask_latents - masked_video_latents_input = ( - torch.cat([masked_video_latents] * 2) if self.do_classifier_free_guidance else masked_video_latents - ) - inpaint_latents = torch.cat([mask_input, masked_video_latents_input], dim=1).to(dtype) - else: - # Prepare mask latent variables - video_length = video.shape[2] - mask_condition = self.mask_processor.preprocess(rearrange(mask_video, "b c f h w -> (b f) c h w"), height=height, width=width) - mask_condition = mask_condition.to(dtype=torch.float32) - mask_condition = rearrange(mask_condition, "(b f) c h w -> b c f h w", f=video_length) - - if num_channels_transformer != num_channels_latents: - mask_condition_tile = torch.tile(mask_condition, [1, 3, 1, 1, 1]) - if masked_video_latents is None: - masked_video = init_video * (mask_condition_tile < 0.5) + torch.ones_like(init_video) * (mask_condition_tile > 0.5) * -1 - else: - masked_video = masked_video_latents - - if self.transformer.resize_inpaint_mask_directly: - _, masked_video_latents = self.prepare_mask_latents( - None, - masked_video, - batch_size, - height, - width, - dtype, - device, - generator, - self.do_classifier_free_guidance, - noise_aug_strength=noise_aug_strength, - ) - mask_latents = resize_mask(1 - mask_condition, masked_video_latents, self.vae.cache_mag_vae) - mask_latents = mask_latents.to(device, dtype) * self.vae.config.scaling_factor - else: - mask_latents, masked_video_latents = self.prepare_mask_latents( - mask_condition_tile, - masked_video, - batch_size, - height, - width, - dtype, - device, - generator, - self.do_classifier_free_guidance, - noise_aug_strength=noise_aug_strength, - ) - - mask_input = torch.cat([mask_latents] * 2) if self.do_classifier_free_guidance else mask_latents - masked_video_latents_input = ( - torch.cat([masked_video_latents] * 2) if self.do_classifier_free_guidance else masked_video_latents - ) - inpaint_latents = torch.cat([mask_input, masked_video_latents_input], dim=1).to(dtype) - else: - inpaint_latents = None - - mask = torch.tile(mask_condition, [1, num_channels_latents, 1, 1, 1]) - mask = F.interpolate(mask, size=latents.size()[-3:], mode='trilinear', align_corners=True).to(device, dtype) - else: - if num_channels_transformer != num_channels_latents: - mask = torch.zeros_like(latents).to(device, dtype) - masked_video_latents = torch.zeros_like(latents).to(device, dtype) - - mask_input = torch.cat([mask] * 2) if self.do_classifier_free_guidance else mask - masked_video_latents_input = ( - torch.cat([masked_video_latents] * 2) if self.do_classifier_free_guidance else masked_video_latents - ) - inpaint_latents = torch.cat([mask_input, masked_video_latents_input], dim=1).to(dtype) - else: - mask = torch.zeros_like(init_video[:, :1]) - mask = torch.tile(mask, [1, num_channels_latents, 1, 1, 1]) - mask = F.interpolate(mask, size=latents.size()[-3:], mode='trilinear', align_corners=True).to(device, dtype) - - inpaint_latents = None - if comfyui_progressbar: - pbar.update(1) - - # Check that sizes of mask, masked image and latents match - if num_channels_transformer != num_channels_latents: - num_channels_mask = mask_latents.shape[1] - num_channels_masked_image = masked_video_latents.shape[1] - if num_channels_latents + num_channels_mask + num_channels_masked_image != self.transformer.config.in_channels: - raise ValueError( - f"Incorrect configuration settings! The config of `pipeline.transformer`: {self.transformer.config} expects" - f" {self.transformer.config.in_channels} but received `num_channels_latents`: {num_channels_latents} +" - f" `num_channels_mask`: {num_channels_mask} + `num_channels_masked_image`: {num_channels_masked_image}" - f" = {num_channels_latents+num_channels_masked_image+num_channels_mask}. Please verify the config of" - " `pipeline.transformer` or your `mask_image` or `image` input." - ) - - # 8. Prepare extra step kwargs. TODO: Logic should ideally just be moved out of the pipeline - extra_step_kwargs = self.prepare_extra_step_kwargs(generator, eta) - - # 9 create image_rotary_emb, style embedding & time ids - grid_height = height // 8 // self.transformer.config.patch_size - grid_width = width // 8 // self.transformer.config.patch_size - if self.transformer.config.get("time_position_encoding_type", "2d_rope") == "3d_rope": - base_size_width = 720 // 8 // self.transformer.config.patch_size - base_size_height = 480 // 8 // self.transformer.config.patch_size - - grid_crops_coords = get_resize_crop_region_for_grid( - (grid_height, grid_width), base_size_width, base_size_height - ) - image_rotary_emb = get_3d_rotary_pos_embed( - self.transformer.config.attention_head_dim, grid_crops_coords, grid_size=(grid_height, grid_width), - temporal_size=latents.size(2), use_real=True, - ) - else: - base_size = 512 // 8 // self.transformer.config.patch_size - grid_crops_coords = get_resize_crop_region_for_grid( - (grid_height, grid_width), base_size, base_size - ) - image_rotary_emb = get_2d_rotary_pos_embed( - self.transformer.config.attention_head_dim, grid_crops_coords, (grid_height, grid_width) - ) - - # Get other hunyuan params - style = torch.tensor([0], device=device) - - target_size = target_size or (height, width) - add_time_ids = list(original_size + target_size + crops_coords_top_left) - add_time_ids = torch.tensor([add_time_ids], dtype=dtype) - - if self.do_classifier_free_guidance: - prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds]) - prompt_attention_mask = torch.cat([negative_prompt_attention_mask, prompt_attention_mask]) - prompt_embeds_2 = torch.cat([negative_prompt_embeds_2, prompt_embeds_2]) - prompt_attention_mask_2 = torch.cat([negative_prompt_attention_mask_2, prompt_attention_mask_2]) - add_time_ids = torch.cat([add_time_ids] * 2, dim=0) - style = torch.cat([style] * 2, dim=0) - - prompt_embeds = prompt_embeds.to(device=device) - prompt_attention_mask = prompt_attention_mask.to(device=device) - prompt_embeds_2 = prompt_embeds_2.to(device=device) - prompt_attention_mask_2 = prompt_attention_mask_2.to(device=device) - add_time_ids = add_time_ids.to(dtype=dtype, device=device).repeat( - batch_size * num_images_per_prompt, 1 - ) - style = style.to(device=device).repeat(batch_size * num_images_per_prompt) - - # 10. Denoising loop - num_warmup_steps = len(timesteps) - num_inference_steps * self.scheduler.order - self._num_timesteps = len(timesteps) - with self.progress_bar(total=num_inference_steps) as progress_bar: - for i, t in enumerate(timesteps): - if self.interrupt: - continue - - # expand the latents if we are doing classifier free guidance - latent_model_input = torch.cat([latents] * 2) if self.do_classifier_free_guidance else latents - latent_model_input = self.scheduler.scale_model_input(latent_model_input, t) - - if i < len(timesteps) * (1 - clip_apply_ratio) and clip_encoder_hidden_states_input is not None: - clip_encoder_hidden_states_actual_input = torch.zeros_like(clip_encoder_hidden_states_input) - clip_attention_mask_actual_input = torch.zeros_like(clip_attention_mask_input) - else: - clip_encoder_hidden_states_actual_input = clip_encoder_hidden_states_input - clip_attention_mask_actual_input = clip_attention_mask_input - - # expand scalar t to 1-D tensor to match the 1st dim of latent_model_input - t_expand = torch.tensor([t] * latent_model_input.shape[0], device=device).to( - dtype=latent_model_input.dtype - ) - - # predict the noise residual - noise_pred = self.transformer( - latent_model_input, - t_expand, - encoder_hidden_states=prompt_embeds, - text_embedding_mask=prompt_attention_mask, - encoder_hidden_states_t5=prompt_embeds_2, - text_embedding_mask_t5=prompt_attention_mask_2, - image_meta_size=add_time_ids, - style=style, - image_rotary_emb=image_rotary_emb, - inpaint_latents=inpaint_latents, - clip_encoder_hidden_states=clip_encoder_hidden_states_actual_input, - clip_attention_mask=clip_attention_mask_actual_input, - return_dict=False, - )[0] - if noise_pred.size()[1] != self.vae.config.latent_channels: - noise_pred, _ = noise_pred.chunk(2, dim=1) - - # perform guidance - if self.do_classifier_free_guidance: - noise_pred_uncond, noise_pred_text = noise_pred.chunk(2) - noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond) - - if self.do_classifier_free_guidance and guidance_rescale > 0.0: - # Based on 3.4. in https://arxiv.org/pdf/2305.08891.pdf - noise_pred = rescale_noise_cfg(noise_pred, noise_pred_text, guidance_rescale=guidance_rescale) - - # compute the previous noisy sample x_t -> x_t-1 - latents = self.scheduler.step(noise_pred, t, latents, **extra_step_kwargs, return_dict=False)[0] - - if num_channels_transformer == 4: - init_latents_proper = image_latents - init_mask = mask - if i < len(timesteps) - 1: - noise_timestep = timesteps[i + 1] - init_latents_proper = self.scheduler.add_noise( - init_latents_proper, noise, torch.tensor([noise_timestep]) - ) - - latents = (1 - init_mask) * init_latents_proper + init_mask * latents - - if callback_on_step_end is not None: - callback_kwargs = {} - for k in callback_on_step_end_tensor_inputs: - callback_kwargs[k] = locals()[k] - callback_outputs = callback_on_step_end(self, i, t, callback_kwargs) - - latents = callback_outputs.pop("latents", latents) - prompt_embeds = callback_outputs.pop("prompt_embeds", prompt_embeds) - negative_prompt_embeds = callback_outputs.pop("negative_prompt_embeds", negative_prompt_embeds) - prompt_embeds_2 = callback_outputs.pop("prompt_embeds_2", prompt_embeds_2) - negative_prompt_embeds_2 = callback_outputs.pop( - "negative_prompt_embeds_2", negative_prompt_embeds_2 - ) - - if i == len(timesteps) - 1 or ((i + 1) > num_warmup_steps and (i + 1) % self.scheduler.order == 0): - progress_bar.update() - - if XLA_AVAILABLE: - xm.mark_step() - - if comfyui_progressbar: - pbar.update(1) - - # Post-processing - video = self.decode_latents(latents) - - # Convert to tensor - if output_type == "latent": - video = torch.from_numpy(video) - - # Offload all models - self.maybe_free_model_hooks() - - if not return_dict: - return video - - return EasyAnimatePipelineOutput(videos=video) \ No newline at end of file diff --git a/easyanimate/ui/ui.py b/easyanimate/ui/ui.py old mode 100644 new mode 100755 index d088a4f..85fe9b3 --- a/easyanimate/ui/ui.py +++ b/easyanimate/ui/ui.py @@ -17,43 +17,42 @@ import torch from diffusers import (AutoencoderKL, DDIMScheduler, DPMSolverMultistepScheduler, EulerAncestralDiscreteScheduler, EulerDiscreteScheduler, - PNDMScheduler) + FlowMatchEulerDiscreteScheduler, PNDMScheduler) from diffusers.utils.import_utils import is_xformers_available from omegaconf import OmegaConf from PIL import Image from safetensors import safe_open from transformers import (BertModel, BertTokenizer, CLIPImageProcessor, - CLIPVisionModelWithProjection, T5Tokenizer, - T5EncoderModel, T5Tokenizer) + CLIPVisionModelWithProjection, Qwen2Tokenizer, + Qwen2VLForConditionalGeneration, T5EncoderModel, + T5Tokenizer) -from easyanimate.data.bucket_sampler import ASPECT_RATIO_512, get_closest_ratio -from easyanimate.models import (name_to_autoencoder_magvit, +from ..data.bucket_sampler import ASPECT_RATIO_512, get_closest_ratio +from ..models import (name_to_autoencoder_magvit, name_to_transformer3d) -from easyanimate.models.autoencoder_magvit import AutoencoderKLMagvit -from easyanimate.models.transformer3d import (HunyuanTransformer3DModel, - Transformer3DModel) -from easyanimate.pipeline.pipeline_easyanimate import EasyAnimatePipeline -from easyanimate.pipeline.pipeline_easyanimate_inpaint import \ +from ..pipeline.pipeline_easyanimate import \ + EasyAnimatePipeline +from ..pipeline.pipeline_easyanimate_control import \ + EasyAnimateControlPipeline +from ..pipeline.pipeline_easyanimate_inpaint import \ EasyAnimateInpaintPipeline -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder import \ - EasyAnimatePipeline_Multi_Text_Encoder -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder_inpaint import \ - EasyAnimatePipeline_Multi_Text_Encoder_Inpaint -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder_control import \ - EasyAnimatePipeline_Multi_Text_Encoder_Control -from easyanimate.utils.lora_utils import merge_lora, unmerge_lora -from easyanimate.utils.utils import ( +from ..utils.fp8_optimization import convert_weight_dtype_wrapper +from ..utils.lora_utils import merge_lora, unmerge_lora +from ..utils.utils import ( get_image_to_video_latent, get_video_to_video_latent, get_width_and_height_from_image_and_base_resolution, save_videos_grid) -from easyanimate.utils.fp8_optimization import convert_weight_dtype_wrapper -scheduler_dict = { +ddpm_scheduler_dict = { "Euler": EulerDiscreteScheduler, "Euler A": EulerAncestralDiscreteScheduler, "DPM++": DPMSolverMultistepScheduler, "PNDM": PNDMScheduler, "DDIM": DDIMScheduler, } +flow_scheduler_dict = { + "Flow": FlowMatchEulerDiscreteScheduler, +} +all_cheduler_dict = {**ddpm_scheduler_dict, **flow_scheduler_dict} gradio_version = pkg_resources.get_distribution("gradio").version gradio_version_is_above_4 = True if int(gradio_version.split('.')[0]) >= 4 else False @@ -100,8 +99,8 @@ class EasyAnimateController: self.GPU_memory_mode = GPU_memory_mode self.weight_dtype = weight_dtype - self.edition = "v5" - self.inference_config = OmegaConf.load(os.path.join(self.config_dir, "easyanimate_video_v5_magvit_multi_text_encoder.yaml")) + self.edition = "v5.1" + self.inference_config = OmegaConf.load(os.path.join(self.config_dir, "easyanimate_video_v5.1_magvit_qwen.yaml")) def refresh_diffusion_transformer(self): self.diffusion_transformer_list = sorted(glob(os.path.join(self.diffusion_transformer_dir, "*/"))) @@ -123,26 +122,37 @@ class EasyAnimateController: if edition == "v1": self.inference_config = OmegaConf.load(os.path.join(self.config_dir, "easyanimate_video_v1_motion_module.yaml")) return gr.update(), gr.update(value="none"), gr.update(visible=True), gr.update(visible=True), \ + gr.update(choices=list(ddpm_scheduler_dict.keys()), value=list(ddpm_scheduler_dict.keys())[0]), \ gr.update(value=512, minimum=384, maximum=704, step=32), \ gr.update(value=512, minimum=384, maximum=704, step=32), gr.update(value=80, minimum=40, maximum=80, step=1) elif edition == "v2": self.inference_config = OmegaConf.load(os.path.join(self.config_dir, "easyanimate_video_v2_magvit_motion_module.yaml")) return gr.update(), gr.update(value="none"), gr.update(visible=False), gr.update(visible=False), \ + gr.update(choices=list(ddpm_scheduler_dict.keys()), value=list(ddpm_scheduler_dict.keys())[0]), \ gr.update(value=672, minimum=128, maximum=1344, step=16), \ gr.update(value=384, minimum=128, maximum=1344, step=16), gr.update(value=144, minimum=9, maximum=144, step=9) elif edition == "v3": self.inference_config = OmegaConf.load(os.path.join(self.config_dir, "easyanimate_video_v3_slicevae_motion_module.yaml")) return gr.update(), gr.update(value="none"), gr.update(visible=False), gr.update(visible=False), \ + gr.update(choices=list(ddpm_scheduler_dict.keys()), value=list(ddpm_scheduler_dict.keys())[0]), \ gr.update(value=672, minimum=128, maximum=1344, step=16), \ gr.update(value=384, minimum=128, maximum=1344, step=16), gr.update(value=144, minimum=8, maximum=144, step=8) elif edition == "v4": self.inference_config = OmegaConf.load(os.path.join(self.config_dir, "easyanimate_video_v4_slicevae_multi_text_encoder.yaml")) return gr.update(), gr.update(value="none"), gr.update(visible=False), gr.update(visible=False), \ + gr.update(choices=list(ddpm_scheduler_dict.keys()), value=list(ddpm_scheduler_dict.keys())[0]), \ gr.update(value=672, minimum=128, maximum=1344, step=16), \ gr.update(value=384, minimum=128, maximum=1344, step=16), gr.update(value=144, minimum=8, maximum=144, step=8) elif edition == "v5": self.inference_config = OmegaConf.load(os.path.join(self.config_dir, "easyanimate_video_v5_magvit_multi_text_encoder.yaml")) return gr.update(), gr.update(value="none"), gr.update(visible=False), gr.update(visible=False), \ + gr.update(choices=list(ddpm_scheduler_dict.keys()), value=list(ddpm_scheduler_dict.keys())[0]), \ + gr.update(value=672, minimum=128, maximum=1344, step=16), \ + gr.update(value=384, minimum=128, maximum=1344, step=16), gr.update(value=49, minimum=1, maximum=49, step=4) + elif edition == "v5.1": + self.inference_config = OmegaConf.load(os.path.join(self.config_dir, "easyanimate_video_v5.1_magvit_qwen.yaml")) + return gr.update(), gr.update(value="none"), gr.update(visible=False), gr.update(visible=False), \ + gr.update(choices=list(flow_scheduler_dict.keys()), value=list(flow_scheduler_dict.keys())[0]), \ gr.update(value=672, minimum=128, maximum=1344, step=16), \ gr.update(value=384, minimum=128, maximum=1344, step=16), gr.update(value=49, minimum=1, maximum=49, step=4) @@ -181,26 +191,48 @@ class EasyAnimateController: tokenizer = BertTokenizer.from_pretrained( diffusion_transformer_dropdown, subfolder="tokenizer" ) - tokenizer_2 = T5Tokenizer.from_pretrained( - diffusion_transformer_dropdown, subfolder="tokenizer_2" - ) + if self.inference_config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + tokenizer_2 = Qwen2Tokenizer.from_pretrained( + os.path.join(diffusion_transformer_dropdown, "tokenizer_2") + ) + else: + tokenizer_2 = T5Tokenizer.from_pretrained( + diffusion_transformer_dropdown, subfolder="tokenizer_2" + ) else: - tokenizer = T5Tokenizer.from_pretrained( - diffusion_transformer_dropdown, subfolder="tokenizer" - ) + if self.inference_config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + tokenizer = Qwen2Tokenizer.from_pretrained( + os.path.join(diffusion_transformer_dropdown, "tokenizer") + ) + else: + tokenizer = T5Tokenizer.from_pretrained( + diffusion_transformer_dropdown, subfolder="tokenizer" + ) tokenizer_2 = None if self.inference_config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): text_encoder = BertModel.from_pretrained( diffusion_transformer_dropdown, subfolder="text_encoder", torch_dtype=self.weight_dtype ) - text_encoder_2 = T5EncoderModel.from_pretrained( - diffusion_transformer_dropdown, subfolder="text_encoder_2", torch_dtype=self.weight_dtype - ) - else: - text_encoder = T5EncoderModel.from_pretrained( - diffusion_transformer_dropdown, subfolder="text_encoder", torch_dtype=self.weight_dtype - ) + if self.inference_config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder_2 = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(diffusion_transformer_dropdown, "text_encoder_2"), + torch_dtype=self.weight_dtype, + ) + else: + text_encoder_2 = T5EncoderModel.from_pretrained( + diffusion_transformer_dropdown, subfolder="text_encoder_2", torch_dtype=self.weight_dtype + ) + else: + if self.inference_config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(diffusion_transformer_dropdown, "text_encoder"), + torch_dtype=self.weight_dtype, + ) + else: + text_encoder = T5EncoderModel.from_pretrained( + diffusion_transformer_dropdown, subfolder="text_encoder", torch_dtype=self.weight_dtype + ) text_encoder_2 = None # Get pipeline @@ -216,73 +248,40 @@ class EasyAnimateController: clip_image_processor = None # Get Scheduler - Choosen_Scheduler = scheduler_dict = { - "Euler": EulerDiscreteScheduler, - "Euler A": EulerAncestralDiscreteScheduler, - "DPM++": DPMSolverMultistepScheduler, - "PNDM": PNDMScheduler, - "DDIM": DDIMScheduler, - }["Euler"] - + if self.edition in ["v5.1"]: + Choosen_Scheduler = all_cheduler_dict["Flow"] + else: + Choosen_Scheduler = all_cheduler_dict["Euler"] scheduler = Choosen_Scheduler.from_pretrained( diffusion_transformer_dropdown, subfolder="scheduler" ) if self.model_type == "Inpaint": - if self.inference_config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): - if self.transformer.config.in_channels != self.vae.config.latent_channels: - self.pipeline = EasyAnimatePipeline_Multi_Text_Encoder_Inpaint.from_pretrained( - diffusion_transformer_dropdown, - text_encoder=text_encoder, - text_encoder_2=text_encoder_2, - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - vae=self.vae, - transformer=self.transformer, - scheduler=scheduler, - torch_dtype=self.weight_dtype, - clip_image_encoder=clip_image_encoder, - clip_image_processor=clip_image_processor, - ) - else: - self.pipeline = EasyAnimatePipeline_Multi_Text_Encoder.from_pretrained( - diffusion_transformer_dropdown, - text_encoder=text_encoder, - text_encoder_2=text_encoder_2, - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - vae=self.vae, - transformer=self.transformer, - scheduler=scheduler, - torch_dtype=self.weight_dtype - ) + if self.transformer.config.in_channels != self.vae.config.latent_channels: + self.pipeline = EasyAnimateInpaintPipeline( + text_encoder=text_encoder, + text_encoder_2=text_encoder_2, + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + vae=self.vae, + transformer=self.transformer, + scheduler=scheduler, + clip_image_encoder=clip_image_encoder, + clip_image_processor=clip_image_processor, + ) else: - if self.transformer.config.in_channels != self.vae.config.latent_channels: - self.pipeline = EasyAnimateInpaintPipeline( - diffusion_transformer_dropdown, - text_encoder=text_encoder, - tokenizer=tokenizer, - vae=self.vae, - transformer=self.transformer, - scheduler=scheduler, - torch_dtype=self.weight_dtype, - clip_image_encoder=clip_image_encoder, - clip_image_processor=clip_image_processor, - ) - else: - self.pipeline = EasyAnimatePipeline( - diffusion_transformer_dropdown, - text_encoder=text_encoder, - tokenizer=tokenizer, - vae=self.vae, - transformer=self.transformer, - scheduler=scheduler, - torch_dtype=self.weight_dtype - ) + self.pipeline = EasyAnimatePipeline( + text_encoder=text_encoder, + text_encoder_2=text_encoder_2, + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + vae=self.vae, + transformer=self.transformer, + scheduler=scheduler, + ) else: - self.pipeline = EasyAnimatePipeline_Multi_Text_Encoder_Control.from_pretrained( - diffusion_transformer_dropdown, + self.pipeline = EasyAnimateControlPipeline( text_encoder=text_encoder, text_encoder_2=text_encoder_2, tokenizer=tokenizer, @@ -290,7 +289,6 @@ class EasyAnimateController: vae=self.vae, transformer=self.transformer, scheduler=scheduler, - torch_dtype=self.weight_dtype ) if self.GPU_memory_mode == "sequential_cpu_offload": @@ -394,8 +392,10 @@ class EasyAnimateController: if self.base_model_path != base_model_dropdown: self.update_base_model(base_model_dropdown) + if self.motion_module_path != motion_module_dropdown: + self.update_motion_module(motion_module_dropdown) + if self.lora_model_path != lora_model_dropdown: - print("Update lora model") self.update_lora_model(lora_model_dropdown) if control_video is not None and self.model_type == "Inpaint": @@ -446,19 +446,21 @@ class EasyAnimateController: else: raise gr.Error(f"If specifying the ending image of the video, please specify a starting image of the video.") - fps = {"v1": 12, "v2": 24, "v3": 24, "v4": 24, "v5": 8}[self.edition] + fps = {"v1": 12, "v2": 24, "v3": 24, "v4": 24, "v5": 8, "v5.1": 8}[self.edition] is_image = True if generation_method == "Image Generation" else False - if is_xformers_available() and not self.inference_config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): self.transformer.enable_xformers_memory_efficient_attention() - - self.pipeline.scheduler = scheduler_dict[sampler_dropdown].from_config(self.pipeline.scheduler.config) - if self.lora_model_path != "none": - # lora part - self.pipeline = merge_lora(self.pipeline, self.lora_model_path, multiplier=lora_alpha_slider, device="cuda", dtype=self.weight_dtype) - if int(seed_textbox) != -1 and seed_textbox != "": torch.manual_seed(int(seed_textbox)) else: seed_textbox = np.random.randint(0, 1e10) generator = torch.Generator(device="cuda").manual_seed(int(seed_textbox)) + + if is_xformers_available() \ + and self.inference_config['transformer_additional_kwargs'].get('transformer_type', 'Transformer3DModel') == 'Transformer3DModel': + self.transformer.enable_xformers_memory_efficient_attention() + + self.pipeline.scheduler = all_cheduler_dict[sampler_dropdown].from_config(self.pipeline.scheduler.config) + if self.lora_model_path != "none": + # lora part + self.pipeline = merge_lora(self.pipeline, self.lora_model_path, multiplier=lora_alpha_slider) try: if self.model_type == "Inpaint": @@ -500,7 +502,7 @@ class EasyAnimateController: video = input_video, mask_video = input_video_mask, strength = 1, - ).videos + ).frames if init_frames != 0: mix_ratio = torch.from_numpy( @@ -551,7 +553,7 @@ class EasyAnimateController: video = input_video, mask_video = input_video_mask, strength = strength, - ).videos + ).frames else: if self.vae.cache_mag_vae: length_slider = int((length_slider - 1) // self.vae.mini_batch_encoder * self.vae.mini_batch_encoder) + 1 @@ -567,7 +569,7 @@ class EasyAnimateController: height = height_slider, video_length = length_slider if not is_image else 1, generator = generator - ).videos + ).frames else: if self.vae.cache_mag_vae: length_slider = int((length_slider - 1) // self.vae.mini_batch_encoder * self.vae.mini_batch_encoder) + 1 @@ -586,7 +588,7 @@ class EasyAnimateController: generator = generator, control_video = input_video, - ).videos + ).frames except Exception as e: gc.collect() torch.cuda.empty_cache() @@ -696,8 +698,8 @@ def ui(GPU_memory_mode, weight_dtype): with gr.Row(): easyanimate_edition_dropdown = gr.Dropdown( label="The config of EasyAnimate Edition (EasyAnimate版本配置)", - choices=["v1", "v2", "v3", "v4", "v5"], - value="v5", + choices=["v1", "v2", "v3", "v4", "v5", "v5.1"], + value="v5.1", interactive=True, ) gr.Markdown( @@ -771,7 +773,7 @@ def ui(GPU_memory_mode, weight_dtype): """ ) - prompt_textbox = gr.Textbox(label="Prompt (正向提示词)", lines=2, value="A young woman with beautiful and clear eyes and blonde hair standing and white dress in a forest wearing a crown. She seems to be lost in thought, and the camera focuses on her face. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.") + prompt_textbox = gr.Textbox(label="Prompt (正向提示词)", lines=2, value="A young woman with beautiful, clear eyes and blonde hair stands in the forest, wearing a white dress and a crown. Her expression is serene, reminiscent of a movie star, with fair and youthful skin. Her brown long hair flows in the wind. The video quality is very high, with a clear view. High quality, masterpiece, best quality, high resolution, ultra-fine, fantastical.") gr.Markdown( """ Using longer neg prompt such as "Blurring, mutation, deformation, distortion, dark and solid, comics, text subtitles, line art." can increase stability. Adding words such as "quiet, solid" to the neg prompt can increase dynamism. @@ -783,7 +785,10 @@ def ui(GPU_memory_mode, weight_dtype): with gr.Row(): with gr.Column(): with gr.Row(): - sampler_dropdown = gr.Dropdown(label="Sampling method (采样器种类)", choices=list(scheduler_dict.keys()), value=list(scheduler_dict.keys())[0]) + sampler_dropdown = gr.Dropdown( + label="Sampling method (采样器种类)", + choices=list(flow_scheduler_dict.keys()), value=list(flow_scheduler_dict.keys())[0] + ) sample_step_slider = gr.Slider(label="Sampling steps (生成步数)", value=50, minimum=10, maximum=100, step=1) resize_method = gr.Radio( @@ -820,11 +825,11 @@ def ui(GPU_memory_mode, weight_dtype): template_gallery_path = ["asset/1.png", "asset/2.png", "asset/3.png", "asset/4.png", "asset/5.png"] def select_template(evt: gr.SelectData): text = { - "asset/1.png": "The dog is shaking head. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.", - "asset/2.png": "a sailboat sailing in rough seas with a dramatic sunset. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.", - "asset/3.png": "a beautiful woman with long hair and a dress blowing in the wind. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.", - "asset/4.png": "a man in an astronaut suit playing a guitar. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.", - "asset/5.png": "fireworks display over night city. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.", + "asset/1.png": "A brown dog is shaking its head and sitting on a light colored sofa in a comfortable room. Behind the dog, there is a framed painting on the shelf surrounded by pink flowers. The soft and warm lighting in the room creates a comfortable atmosphere.", + "asset/2.png": "A sailboat navigates through moderately rough seas, with waves and ocean spray visible. The sailboat features a white hull and sails, accompanied by an orange sail catching the wind. The sky above shows dramatic, cloudy formations with a sunset or sunrise backdrop, casting warm colors across the scene. The water reflects the golden light, enhancing the visual contrast between the dark ocean and the bright horizon. The camera captures the scene with a dynamic and immersive angle, showcasing the movement of the boat and the energy of the ocean.", + "asset/3.png": "A stunningly beautiful woman with flowing long hair stands gracefully, her elegant dress rippling and billowing in the gentle wind. Petals falling off. Her serene expression and the natural movement of her attire create an enchanting and captivating scene, full of ethereal charm.", + "asset/4.png": "An astronaut, clad in a full space suit with a helmet, plays an electric guitar while floating in a cosmic environment filled with glowing particles and rocky textures. The scene is illuminated by a warm light source, creating dramatic shadows and contrasts. The background features a complex geometry, similar to a space station or an alien landscape, indicating a futuristic or otherworldly setting.", + "asset/5.png": "Fireworks light up the evening sky over a sprawling cityscape with gothic-style buildings featuring pointed towers and clock faces. The city is lit by both artificial lights from the buildings and the colorful bursts of the fireworks. The scene is viewed from an elevated angle, showcasing a vibrant urban environment set against a backdrop of a dramatic, partially cloudy sky at dusk.", }[template_gallery_path[evt.index]] return template_gallery_path[evt.index], text @@ -864,6 +869,7 @@ def ui(GPU_memory_mode, weight_dtype): gr.Markdown( """ Demo pose control video can be downloaded here [URL](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1.1/pose.mp4). + Only normal controls are supported in app.py; trajectory control and camera control need ComfyUI, as shown in https://github.com/aigc-apps/EasyAnimate/tree/main/comfyui. """ ) control_video = gr.Video( @@ -953,6 +959,7 @@ def ui(GPU_memory_mode, weight_dtype): diffusion_transformer_dropdown, motion_module_dropdown, motion_module_refresh_button, + sampler_dropdown, width_slider, height_slider, length_slider, @@ -1038,26 +1045,46 @@ class EasyAnimateController_Modelscope: tokenizer = BertTokenizer.from_pretrained( model_name, subfolder="tokenizer" ) - tokenizer_2 = T5Tokenizer.from_pretrained( - model_name, subfolder="tokenizer_2" - ) + if self.inference_config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + tokenizer_2 = Qwen2Tokenizer.from_pretrained( + os.path.join(model_name, "tokenizer_2") + ) + else: + tokenizer_2 = T5Tokenizer.from_pretrained( + model_name, subfolder="tokenizer_2" + ) else: - tokenizer = T5Tokenizer.from_pretrained( - model_name, subfolder="tokenizer" - ) + if self.inference_config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + tokenizer = Qwen2Tokenizer.from_pretrained( + os.path.join(model_name, "tokenizer") + ) + else: + tokenizer = T5Tokenizer.from_pretrained( + model_name, subfolder="tokenizer" + ) tokenizer_2 = None if self.inference_config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): text_encoder = BertModel.from_pretrained( model_name, subfolder="text_encoder", torch_dtype=self.weight_dtype ) - text_encoder_2 = T5EncoderModel.from_pretrained( - model_name, subfolder="text_encoder_2", torch_dtype=self.weight_dtype - ) - else: - text_encoder = T5EncoderModel.from_pretrained( - model_name, subfolder="text_encoder", torch_dtype=self.weight_dtype - ) + if self.inference_config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder_2 = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(model_name, "text_encoder_2"), torch_dtype=self.weight_dtype + ) + else: + text_encoder_2 = T5EncoderModel.from_pretrained( + model_name, subfolder="text_encoder_2", torch_dtype=self.weight_dtype + ) + else: + if self.inference_config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(model_name, "text_encoder"), torch_dtype=self.weight_dtype + ) + else: + text_encoder = T5EncoderModel.from_pretrained( + model_name, subfolder="text_encoder", torch_dtype=self.weight_dtype + ) text_encoder_2 = None # Get pipeline @@ -1073,73 +1100,40 @@ class EasyAnimateController_Modelscope: clip_image_processor = None # Get Scheduler - Choosen_Scheduler = scheduler_dict = { - "Euler": EulerDiscreteScheduler, - "Euler A": EulerAncestralDiscreteScheduler, - "DPM++": DPMSolverMultistepScheduler, - "PNDM": PNDMScheduler, - "DDIM": DDIMScheduler, - }["Euler"] - + if self.edition in ["v5.1"]: + Choosen_Scheduler = all_cheduler_dict["Flow"] + else: + Choosen_Scheduler = all_cheduler_dict["Euler"] scheduler = Choosen_Scheduler.from_pretrained( model_name, subfolder="scheduler" ) if model_type == "Inpaint": - if self.inference_config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): - if self.transformer.config.in_channels != self.vae.config.latent_channels: - self.pipeline = EasyAnimatePipeline_Multi_Text_Encoder_Inpaint.from_pretrained( - model_name, - text_encoder=text_encoder, - text_encoder_2=text_encoder_2, - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - vae=self.vae, - transformer=self.transformer, - scheduler=scheduler, - torch_dtype=self.weight_dtype, - clip_image_encoder=clip_image_encoder, - clip_image_processor=clip_image_processor, - ) - else: - self.pipeline = EasyAnimatePipeline_Multi_Text_Encoder.from_pretrained( - model_name, - text_encoder=text_encoder, - text_encoder_2=text_encoder_2, - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - vae=self.vae, - transformer=self.transformer, - scheduler=scheduler, - torch_dtype=self.weight_dtype - ) + if self.transformer.config.in_channels != self.vae.config.latent_channels: + self.pipeline = EasyAnimateInpaintPipeline( + text_encoder=text_encoder, + text_encoder_2=text_encoder_2, + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + vae=self.vae, + transformer=self.transformer, + scheduler=scheduler, + clip_image_encoder=clip_image_encoder, + clip_image_processor=clip_image_processor, + ) else: - if self.transformer.config.in_channels != self.vae.config.latent_channels: - self.pipeline = EasyAnimateInpaintPipeline( - model_name, - text_encoder=text_encoder, - tokenizer=tokenizer, - vae=self.vae, - transformer=self.transformer, - scheduler=scheduler, - torch_dtype=self.weight_dtype, - clip_image_encoder=clip_image_encoder, - clip_image_processor=clip_image_processor, - ) - else: - self.pipeline = EasyAnimatePipeline( - model_name, - text_encoder=text_encoder, - tokenizer=tokenizer, - vae=self.vae, - transformer=self.transformer, - scheduler=scheduler, - torch_dtype=self.weight_dtype - ) + self.pipeline = EasyAnimatePipeline( + text_encoder=text_encoder, + text_encoder_2=text_encoder_2, + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + vae=self.vae, + transformer=self.transformer, + scheduler=scheduler + ) else: - pipeline = EasyAnimatePipeline_Multi_Text_Encoder_Control.from_pretrained( - model_name, + self.pipeline = EasyAnimateControlPipeline( text_encoder=text_encoder, text_encoder_2=text_encoder_2, tokenizer=tokenizer, @@ -1147,7 +1141,6 @@ class EasyAnimateController_Modelscope: vae=self.vae, transformer=self.transformer, scheduler=scheduler, - torch_dtype=weight_dtype ) if GPU_memory_mode == "sequential_cpu_offload": @@ -1254,17 +1247,17 @@ class EasyAnimateController_Modelscope: else: raise gr.Error(f"If specifying the ending image of the video, please specify a starting image of the video.") - fps = {"v1": 12, "v2": 24, "v3": 24, "v4": 24, "v5": 8}[self.edition] + fps = {"v1": 12, "v2": 24, "v3": 24, "v4": 24, "v5": 8, "v5.1": 8}[self.edition] is_image = True if generation_method == "Image Generation" else False - self.pipeline.scheduler = scheduler_dict[sampler_dropdown].from_config(self.pipeline.scheduler.config) - if self.lora_model_path != "none": - # lora part - self.pipeline = merge_lora(self.pipeline, self.lora_model_path, multiplier=lora_alpha_slider, device="cuda", dtype=self.weight_dtype) - if int(seed_textbox) != -1 and seed_textbox != "": torch.manual_seed(int(seed_textbox)) else: seed_textbox = np.random.randint(0, 1e10) generator = torch.Generator(device="cuda").manual_seed(int(seed_textbox)) + + self.pipeline.scheduler = all_cheduler_dict[sampler_dropdown].from_config(self.pipeline.scheduler.config) + if self.lora_model_path != "none": + # lora part + self.pipeline = merge_lora(self.pipeline, self.lora_model_path, multiplier=lora_alpha_slider) try: if self.model_type == "Inpaint": @@ -1294,7 +1287,7 @@ class EasyAnimateController_Modelscope: video = input_video, mask_video = input_video_mask, strength = strength, - ).videos + ).frames else: sample = self.pipeline( prompt_textbox, @@ -1305,7 +1298,7 @@ class EasyAnimateController_Modelscope: height = height_slider, video_length = length_slider if not is_image else 1, generator = generator - ).videos + ).frames else: if self.vae.cache_mag_vae: length_slider = int((length_slider - 1) // self.vae.mini_batch_encoder * self.vae.mini_batch_encoder) + 1 @@ -1325,7 +1318,7 @@ class EasyAnimateController_Modelscope: generator = generator, control_video = input_video, - ).videos + ).frames except Exception as e: gc.collect() torch.cuda.empty_cache() @@ -1446,7 +1439,7 @@ def ui_modelscope(model_type, edition, config_path, model_name, savedir_sample, """ ) - prompt_textbox = gr.Textbox(label="Prompt (正向提示词)", lines=2, value="A young woman with beautiful and clear eyes and blonde hair standing and white dress in a forest wearing a crown. She seems to be lost in thought, and the camera focuses on her face. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.") + prompt_textbox = gr.Textbox(label="Prompt (正向提示词)", lines=2, value="A young woman with beautiful, clear eyes and blonde hair stands in the forest, wearing a white dress and a crown. Her expression is serene, reminiscent of a movie star, with fair and youthful skin. Her brown long hair flows in the wind. The video quality is very high, with a clear view. High quality, masterpiece, best quality, high resolution, ultra-fine, fantastical.") gr.Markdown( """ Using longer neg prompt such as "Blurring, mutation, deformation, distortion, dark and solid, comics, text subtitles, line art." can increase stability. Adding words such as "quiet, solid" to the neg prompt can increase dynamism. @@ -1458,7 +1451,16 @@ def ui_modelscope(model_type, edition, config_path, model_name, savedir_sample, with gr.Row(): with gr.Column(): with gr.Row(): - sampler_dropdown = gr.Dropdown(label="Sampling method (采样器种类)", choices=list(scheduler_dict.keys()), value=list(scheduler_dict.keys())[0]) + if edition in ["v5.1"]: + sampler_dropdown = gr.Dropdown( + label="Sampling method (采样器种类)", + choices=list(flow_scheduler_dict.keys()), value=list(flow_scheduler_dict.keys())[0] + ) + else: + sampler_dropdown = gr.Dropdown( + label="Sampling method (采样器种类)", + choices=list(ddpm_scheduler_dict.keys()), value=list(ddpm_scheduler_dict.keys())[0] + ) sample_step_slider = gr.Slider(label="Sampling steps (生成步数)", value=50, minimum=10, maximum=50, step=1, interactive=False) if edition == "v1": @@ -1512,11 +1514,11 @@ def ui_modelscope(model_type, edition, config_path, model_name, savedir_sample, template_gallery_path = ["asset/1.png", "asset/2.png", "asset/3.png", "asset/4.png", "asset/5.png"] def select_template(evt: gr.SelectData): text = { - "asset/1.png": "The dog is shaking head. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.", - "asset/2.png": "a sailboat sailing in rough seas with a dramatic sunset. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.", - "asset/3.png": "a beautiful woman with long hair and a dress blowing in the wind. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.", - "asset/4.png": "a man in an astronaut suit playing a guitar. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.", - "asset/5.png": "fireworks display over night city. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.", + "asset/1.png": "A brown dog is shaking its head and sitting on a light colored sofa in a comfortable room. Behind the dog, there is a framed painting on the shelf surrounded by pink flowers. The soft and warm lighting in the room creates a comfortable atmosphere.", + "asset/2.png": "A sailboat navigates through moderately rough seas, with waves and ocean spray visible. The sailboat features a white hull and sails, accompanied by an orange sail catching the wind. The sky above shows dramatic, cloudy formations with a sunset or sunrise backdrop, casting warm colors across the scene. The water reflects the golden light, enhancing the visual contrast between the dark ocean and the bright horizon. The camera captures the scene with a dynamic and immersive angle, showcasing the movement of the boat and the energy of the ocean.", + "asset/3.png": "A stunningly beautiful woman with flowing long hair stands gracefully, her elegant dress rippling and billowing in the gentle wind. Petals falling off. Her serene expression and the natural movement of her attire create an enchanting and captivating scene, full of ethereal charm.", + "asset/4.png": "An astronaut, clad in a full space suit with a helmet, plays an electric guitar while floating in a cosmic environment filled with glowing particles and rocky textures. The scene is illuminated by a warm light source, creating dramatic shadows and contrasts. The background features a complex geometry, similar to a space station or an alien landscape, indicating a futuristic or otherworldly setting.", + "asset/5.png": "Fireworks light up the evening sky over a sprawling cityscape with gothic-style buildings featuring pointed towers and clock faces. The city is lit by both artificial lights from the buildings and the colorful bursts of the fireworks. The scene is viewed from an elevated angle, showcasing a vibrant urban environment set against a backdrop of a dramatic, partially cloudy sky at dusk.", }[template_gallery_path[evt.index]] return template_gallery_path[evt.index], text @@ -1556,6 +1558,7 @@ def ui_modelscope(model_type, edition, config_path, model_name, savedir_sample, gr.Markdown( """ Demo pose control video can be downloaded here [URL](https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/cogvideox_fun/asset/v1.1/pose.mp4). + Only normal controls are supported in app.py; trajectory control and camera control need ComfyUI, as shown in https://github.com/aigc-apps/EasyAnimate/tree/main/comfyui. """ ) control_video = gr.Video( @@ -1866,7 +1869,7 @@ def ui_eas(edition, config_path, model_name, savedir_sample): """ ) - prompt_textbox = gr.Textbox(label="Prompt", lines=2, value="A young woman with beautiful and clear eyes and blonde hair standing and white dress in a forest wearing a crown. She seems to be lost in thought, and the camera focuses on her face. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.") + prompt_textbox = gr.Textbox(label="Prompt", lines=2, value="A young woman with beautiful, clear eyes and blonde hair stands in the forest, wearing a white dress and a crown. Her expression is serene, reminiscent of a movie star, with fair and youthful skin. Her brown long hair flows in the wind. The video quality is very high, with a clear view. High quality, masterpiece, best quality, high resolution, ultra-fine, fantastical.") gr.Markdown( """ Using longer neg prompt such as "Blurring, mutation, deformation, distortion, dark and solid, comics, text subtitles, line art." can increase stability. Adding words such as "quiet, solid" to the neg prompt can increase dynamism. @@ -1878,7 +1881,16 @@ def ui_eas(edition, config_path, model_name, savedir_sample): with gr.Row(): with gr.Column(): with gr.Row(): - sampler_dropdown = gr.Dropdown(label="Sampling method", choices=list(scheduler_dict.keys()), value=list(scheduler_dict.keys())[0]) + if edition in ["v5.1"]: + sampler_dropdown = gr.Dropdown( + label="Sampling method (采样器种类)", + choices=list(flow_scheduler_dict.keys()), value=list(flow_scheduler_dict.keys())[0] + ) + else: + sampler_dropdown = gr.Dropdown( + label="Sampling method (采样器种类)", + choices=list(ddpm_scheduler_dict.keys()), value=list(ddpm_scheduler_dict.keys())[0] + ) sample_step_slider = gr.Slider(label="Sampling steps", value=50, minimum=10, maximum=50, step=1, interactive=False) if edition == "v1": @@ -1927,11 +1939,11 @@ def ui_eas(edition, config_path, model_name, savedir_sample): template_gallery_path = ["asset/1.png", "asset/2.png", "asset/3.png", "asset/4.png", "asset/5.png"] def select_template(evt: gr.SelectData): text = { - "asset/1.png": "The dog is shaking head. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.", - "asset/2.png": "a sailboat sailing in rough seas with a dramatic sunset. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.", - "asset/3.png": "a beautiful woman with long hair and a dress blowing in the wind. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.", - "asset/4.png": "a man in an astronaut suit playing a guitar. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.", - "asset/5.png": "fireworks display over night city. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic.", + "asset/1.png": "A brown dog is shaking its head and sitting on a light colored sofa in a comfortable room. Behind the dog, there is a framed painting on the shelf surrounded by pink flowers. The soft and warm lighting in the room creates a comfortable atmosphere.", + "asset/2.png": "A sailboat navigates through moderately rough seas, with waves and ocean spray visible. The sailboat features a white hull and sails, accompanied by an orange sail catching the wind. The sky above shows dramatic, cloudy formations with a sunset or sunrise backdrop, casting warm colors across the scene. The water reflects the golden light, enhancing the visual contrast between the dark ocean and the bright horizon. The camera captures the scene with a dynamic and immersive angle, showcasing the movement of the boat and the energy of the ocean.", + "asset/3.png": "A stunningly beautiful woman with flowing long hair stands gracefully, her elegant dress rippling and billowing in the gentle wind. Petals falling off. Her serene expression and the natural movement of her attire create an enchanting and captivating scene, full of ethereal charm.", + "asset/4.png": "An astronaut, clad in a full space suit with a helmet, plays an electric guitar while floating in a cosmic environment filled with glowing particles and rocky textures. The scene is illuminated by a warm light source, creating dramatic shadows and contrasts. The background features a complex geometry, similar to a space station or an alien landscape, indicating a futuristic or otherworldly setting.", + "asset/5.png": "Fireworks light up the evening sky over a sprawling cityscape with gothic-style buildings featuring pointed towers and clock faces. The city is lit by both artificial lights from the buildings and the colorful bursts of the fireworks. The scene is viewed from an elevated angle, showcasing a vibrant urban environment set against a backdrop of a dramatic, partially cloudy sky at dusk.", }[template_gallery_path[evt.index]] return template_gallery_path[evt.index], text diff --git a/easyanimate/utils/utils.py b/easyanimate/utils/utils.py index c1e2083..bcfedf0 100644 --- a/easyanimate/utils/utils.py +++ b/easyanimate/utils/utils.py @@ -169,47 +169,67 @@ def get_image_to_video_latent(validation_image_start, validation_image_end, vide return input_video, input_video_mask, clip_image def get_video_to_video_latent(input_video_path, video_length, sample_size, fps=None, validation_video_mask=None, ref_image=None): - if isinstance(input_video_path, str): - cap = cv2.VideoCapture(input_video_path) - input_video = [] + if input_video_path is not None: + if isinstance(input_video_path, str): + cap = cv2.VideoCapture(input_video_path) + input_video = [] - original_fps = cap.get(cv2.CAP_PROP_FPS) - frame_skip = 1 if fps is None else int(original_fps // fps) + original_fps = cap.get(cv2.CAP_PROP_FPS) + frame_skip = 1 if fps is None else int(original_fps // fps) - frame_count = 0 + frame_count = 0 - while True: - ret, frame = cap.read() - if not ret: - break + while True: + ret, frame = cap.read() + if not ret: + break - if frame_count % frame_skip == 0: - frame = cv2.resize(frame, (sample_size[1], sample_size[0])) - input_video.append(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) + if frame_count % frame_skip == 0: + frame = cv2.resize(frame, (sample_size[1], sample_size[0])) + input_video.append(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) - frame_count += 1 + frame_count += 1 - cap.release() + cap.release() + else: + input_video = input_video_path + + input_video = torch.from_numpy(np.array(input_video))[:video_length] + input_video = input_video.permute([3, 0, 1, 2]).unsqueeze(0) / 255 + + if validation_video_mask is not None: + validation_video_mask = Image.open(validation_video_mask).convert('L').resize((sample_size[1], sample_size[0])) + input_video_mask = np.where(np.array(validation_video_mask) < 240, 0, 255) + + input_video_mask = torch.from_numpy(np.array(input_video_mask)).unsqueeze(0).unsqueeze(-1).permute([3, 0, 1, 2]).unsqueeze(0) + input_video_mask = torch.tile(input_video_mask, [1, 1, input_video.size()[2], 1, 1]) + input_video_mask = input_video_mask.to(input_video.device, input_video.dtype) + else: + input_video_mask = torch.zeros_like(input_video[:, :1]) + input_video_mask[:, :, :] = 255 else: - input_video = input_video_path - - input_video = torch.from_numpy(np.array(input_video))[:video_length] - input_video = input_video.permute([3, 0, 1, 2]).unsqueeze(0) / 255 + input_video, input_video_mask = None, None if ref_image is not None: - ref_image = Image.open(ref_image) - ref_image = torch.from_numpy(np.array(ref_image)) - ref_image = ref_image.unsqueeze(0).permute([3, 0, 1, 2]).unsqueeze(0) / 255 + if isinstance(ref_image, str): + ref_image = Image.open(ref_image).convert("RGB") + ref_image = ref_image.resize((sample_size[1], sample_size[0])) + ref_image = torch.from_numpy(np.array(ref_image)) + ref_image = ref_image.unsqueeze(0).permute([3, 0, 1, 2]).unsqueeze(0) / 255 + else: + ref_image = torch.from_numpy(np.array(ref_image)) + ref_image = ref_image.unsqueeze(0).permute([3, 0, 1, 2]).unsqueeze(0) / 255 + return input_video, input_video_mask, ref_image - if validation_video_mask is not None: - validation_video_mask = Image.open(validation_video_mask).convert('L').resize((sample_size[1], sample_size[0])) - input_video_mask = np.where(np.array(validation_video_mask) < 240, 0, 255) - - input_video_mask = torch.from_numpy(np.array(input_video_mask)).unsqueeze(0).unsqueeze(-1).permute([3, 0, 1, 2]).unsqueeze(0) - input_video_mask = torch.tile(input_video_mask, [1, 1, input_video.size()[2], 1, 1]) - input_video_mask = input_video_mask.to(input_video.device, input_video.dtype) - else: - input_video_mask = torch.zeros_like(input_video[:, :1]) - input_video_mask[:, :, :] = 255 +def get_image_latent(ref_image=None, sample_size=None): + if ref_image is not None: + if isinstance(ref_image, str): + ref_image = Image.open(ref_image).convert("RGB") + ref_image = ref_image.resize((sample_size[1], sample_size[0])) + ref_image = torch.from_numpy(np.array(ref_image)) + ref_image = ref_image.unsqueeze(0).permute([3, 0, 1, 2]).unsqueeze(0) / 255 + else: + ref_image = torch.from_numpy(np.array(ref_image)) + ref_image = ref_image.unsqueeze(0).permute([3, 0, 1, 2]).unsqueeze(0) / 255 - return input_video, input_video_mask, ref_image \ No newline at end of file + return ref_image \ No newline at end of file diff --git a/easyanimate/vae/ldm/models/autoencoder.py b/easyanimate/vae/ldm/models/autoencoder.py index 7cc28ae..7d7854f 100644 --- a/easyanimate/vae/ldm/models/autoencoder.py +++ b/easyanimate/vae/ldm/models/autoencoder.py @@ -126,13 +126,13 @@ class AutoencoderKLMagvit(pl.LightningModule): def configure_optimizers(self): lr = self.learning_rate - opt_ae = torch.optim.Adam(list(self.encoder.parameters())+ + opt_ae = torch.optim.AdamW(list(self.encoder.parameters())+ list(self.decoder.parameters())+ list(self.quant_conv.parameters())+ list(self.post_quant_conv.parameters()), - lr=lr, betas=(0.5, 0.9)) - opt_disc = torch.optim.Adam(self.loss.discriminator.parameters(), - lr=lr, betas=(0.5, 0.9)) + lr=lr, betas=(0.9, 0.999), weight_decay=5e-2) + opt_disc = torch.optim.AdamW(self.loss.discriminator.parameters(), + lr=lr, betas=(0.9, 0.999), weight_decay=5e-2) return [opt_ae, opt_disc], [] def get_last_layer(self): diff --git a/easyanimate/vae/ldm/models/casual3dcnn.py b/easyanimate/vae/ldm/models/casual3dcnn.py index a1e4a60..0c99c9a 100644 --- a/easyanimate/vae/ldm/models/casual3dcnn.py +++ b/easyanimate/vae/ldm/models/casual3dcnn.py @@ -279,13 +279,13 @@ class AutoencoderKL(pl.LightningModule): def configure_optimizers(self): lr = self.learning_rate - opt_ae = torch.optim.Adam(list(self.encoder.parameters())+ + opt_ae = torch.optim.AdamW(list(self.encoder.parameters())+ list(self.decoder.parameters())+ list(self.quant_conv.parameters())+ - list(self.post_quant_conv.parameters()), - lr=lr, betas=(0.5, 0.9)) - opt_disc = torch.optim.Adam(self.loss.discriminator.parameters(), - lr=lr, betas=(0.5, 0.9)) + list(self.post_quant_conv.parameters()), \ + lr=lr, betas=(0.9, 0.999), weight_decay=5e-2) + opt_disc = torch.optim.AdamW(self.loss.discriminator.parameters(), + lr=lr, betas=(0.9, 0.999), weight_decay=5e-2) return [opt_ae, opt_disc], [] def get_last_layer(self): diff --git a/easyanimate/vae/ldm/models/cogvideox_casual3dcnn.py b/easyanimate/vae/ldm/models/cogvideox_casual3dcnn.py index a64c616..5a4db17 100644 --- a/easyanimate/vae/ldm/models/cogvideox_casual3dcnn.py +++ b/easyanimate/vae/ldm/models/cogvideox_casual3dcnn.py @@ -277,23 +277,23 @@ class AutoencoderKLMagvit_CogVideoX(pl.LightningModule): training_list = list(self.decoder.parameters()) + list(self.post_quant_conv.parameters()) else: training_list = list(self.decoder.parameters()) - opt_ae = torch.optim.Adam(training_list, lr=lr, betas=(0.5, 0.9)) + opt_ae = torch.optim.AdamW(training_list, lr=lr, betas=(0.9, 0.999), weight_decay=5e-2) elif self.train_encoder_only: if self.quant_conv is not None: training_list = list(self.encoder.parameters()) + list(self.quant_conv.parameters()) else: training_list = list(self.encoder.parameters()) - opt_ae = torch.optim.Adam(training_list, lr=lr, betas=(0.5, 0.9)) + opt_ae = torch.optim.AdamW(training_list, lr=lr, betas=(0.9, 0.999), weight_decay=5e-2) else: training_list = list(self.encoder.parameters()) + list(self.decoder.parameters()) if self.quant_conv is not None: training_list = training_list + list(self.quant_conv.parameters()) if self.post_quant_conv is not None: training_list = training_list + list(self.post_quant_conv.parameters()) - opt_ae = torch.optim.Adam(training_list, lr=lr, betas=(0.5, 0.9)) - opt_disc = torch.optim.Adam( + opt_ae = torch.optim.AdamW(training_list, lr=lr, betas=(0.9, 0.999), weight_decay=5e-2) + opt_disc = torch.optim.AdamW( list(self.loss.discriminator3d.parameters()) + list(self.loss.discriminator.parameters()), - lr=lr, betas=(0.5, 0.9) + lr=lr, betas=(0.9, 0.999), weight_decay=5e-2 ) return [opt_ae, opt_disc], [] diff --git a/easyanimate/vae/ldm/models/omnigen_casual3dcnn.py b/easyanimate/vae/ldm/models/omnigen_casual3dcnn.py index cba33e1..37fee0e 100644 --- a/easyanimate/vae/ldm/models/omnigen_casual3dcnn.py +++ b/easyanimate/vae/ldm/models/omnigen_casual3dcnn.py @@ -296,23 +296,23 @@ class AutoencoderKLMagvit_fromOmnigen(pl.LightningModule): training_list = list(self.decoder.parameters()) + list(self.post_quant_conv.parameters()) else: training_list = list(self.decoder.parameters()) - opt_ae = torch.optim.Adam(training_list, lr=lr, betas=(0.5, 0.9)) + opt_ae = torch.optim.AdamW(training_list, lr=lr, betas=(0.9, 0.999), weight_decay=5e-2) elif self.train_encoder_only: if self.quant_conv is not None: training_list = list(self.encoder.parameters()) + list(self.quant_conv.parameters()) else: training_list = list(self.encoder.parameters()) - opt_ae = torch.optim.Adam(training_list, lr=lr, betas=(0.5, 0.9)) + opt_ae = torch.optim.AdamW(training_list, lr=lr, betas=(0.9, 0.999), weight_decay=5e-2) else: training_list = list(self.encoder.parameters()) + list(self.decoder.parameters()) if self.quant_conv is not None: training_list = training_list + list(self.quant_conv.parameters()) if self.post_quant_conv is not None: training_list = training_list + list(self.post_quant_conv.parameters()) - opt_ae = torch.optim.Adam(training_list, lr=lr, betas=(0.5, 0.9)) - opt_disc = torch.optim.Adam( + opt_ae = torch.optim.AdamW(training_list, lr=lr, betas=(0.9, 0.999), weight_decay=5e-2) + opt_disc = torch.optim.AdamW( list(self.loss.discriminator3d.parameters()) + list(self.loss.discriminator.parameters()), - lr=lr, betas=(0.5, 0.9) + lr=lr, betas=(0.9, 0.999), weight_decay=5e-2 ) return [opt_ae, opt_disc], [] diff --git a/easyanimate/vae/ldm/models/omnigen_enc_dec.py b/easyanimate/vae/ldm/models/omnigen_enc_dec.py index 3c1f359..631b65d 100644 --- a/easyanimate/vae/ldm/models/omnigen_enc_dec.py +++ b/easyanimate/vae/ldm/models/omnigen_enc_dec.py @@ -51,6 +51,8 @@ class Encoder(nn.Module): Whether to double the number of output channels for the last block. """ + _supports_gradient_checkpointing = True + def __init__( self, in_channels: int = 3, @@ -146,6 +148,8 @@ class Encoder(nn.Module): self.spatial_group_norm = spatial_group_norm self.verbose = verbose + self.gradient_checkpointing = False + def set_padding_one_frame(self): def _set_padding_one_frame(name, module): if hasattr(module, 'padding_flag'): @@ -225,7 +229,7 @@ class Encoder(nn.Module): def single_forward(self, x: torch.Tensor, previous_features: torch.Tensor, after_features: torch.Tensor) -> torch.Tensor: # x: (B, C, T, H, W) - if self.training: + if torch.is_grad_enabled() and self.gradient_checkpointing: ckpt_kwargs: Dict[str, Any] = {"use_reentrant": False} if is_torch_version(">=", "1.11.0") else {} if previous_features is not None and after_features is None: x = torch.concat([previous_features, x], 2) @@ -234,7 +238,7 @@ class Encoder(nn.Module): elif previous_features is not None and after_features is not None: x = torch.concat([previous_features, x, after_features], 2) - if self.training: + if torch.is_grad_enabled() and self.gradient_checkpointing: x = torch.utils.checkpoint.checkpoint( create_custom_forward(self.conv_in), x, @@ -243,7 +247,7 @@ class Encoder(nn.Module): else: x = self.conv_in(x) for down_block in self.down_blocks: - if self.training: + if torch.is_grad_enabled() and self.gradient_checkpointing: x = torch.utils.checkpoint.checkpoint( create_custom_forward(down_block), x, @@ -359,6 +363,8 @@ class Decoder(nn.Module): The number of attention heads to use. """ + _supports_gradient_checkpointing = True + def __init__( self, in_channels: int = 8, @@ -456,6 +462,8 @@ class Decoder(nn.Module): self.spatial_group_norm = spatial_group_norm self.verbose = verbose + self.gradient_checkpointing = False + def set_padding_one_frame(self): def _set_padding_one_frame(name, module): if hasattr(module, 'padding_flag'): @@ -546,7 +554,7 @@ class Decoder(nn.Module): def single_forward(self, x: torch.Tensor, previous_features: torch.Tensor, after_features: torch.Tensor) -> torch.Tensor: # x: (B, C, T, H, W) - if self.training: + if torch.is_grad_enabled() and self.gradient_checkpointing: ckpt_kwargs: Dict[str, Any] = {"use_reentrant": False} if is_torch_version(">=", "1.11.0") else {} if previous_features is not None and after_features is None: b, c, t, h, w = x.size() @@ -568,7 +576,7 @@ class Decoder(nn.Module): x = self.mid_block(x) x = x[:, :, t_1:(t_1 + t_2)] else: - if self.training: + if torch.is_grad_enabled() and self.gradient_checkpointing: x = torch.utils.checkpoint.checkpoint( create_custom_forward(self.conv_in), x, @@ -584,7 +592,7 @@ class Decoder(nn.Module): x = self.mid_block(x) for up_block in self.up_blocks: - if self.training: + if torch.is_grad_enabled() and self.gradient_checkpointing: x = torch.utils.checkpoint.checkpoint( create_custom_forward(up_block), x, @@ -613,9 +621,9 @@ class Decoder(nn.Module): if self.cache_mag_vae: self.set_magvit_padding_one_frame() first_frames = self.single_forward(x[:, :, 0:1, :, :], None, None) - self.set_magvit_padding_more_frame() new_pixel_values = [first_frames] for i in range(1, x.shape[2], self.mini_batch_decoder): + self.set_magvit_padding_more_frame() next_frames = self.single_forward(x[:, :, i: i + self.mini_batch_decoder, :, :], None, None) new_pixel_values.append(next_frames) new_pixel_values = torch.cat(new_pixel_values, dim=2) diff --git a/easyanimate/vae/ldm/modules/vaemodules/__init__.py b/easyanimate/vae/ldm/modules/vaemodules/__init__.py old mode 100755 new mode 100644 diff --git a/easyanimate/vae/ldm/modules/vaemodules/activations.py b/easyanimate/vae/ldm/modules/vaemodules/activations.py old mode 100755 new mode 100644 diff --git a/easyanimate/vae/ldm/modules/vaemodules/common.py b/easyanimate/vae/ldm/modules/vaemodules/common.py old mode 100755 new mode 100644 diff --git a/easyanimate/vae/ldm/modules/vaemodules/down_blocks.py b/easyanimate/vae/ldm/modules/vaemodules/down_blocks.py old mode 100755 new mode 100644 diff --git a/easyanimate/vae/ldm/modules/vaemodules/mid_blocks.py b/easyanimate/vae/ldm/modules/vaemodules/mid_blocks.py old mode 100755 new mode 100644 diff --git a/easyanimate/vae/ldm/modules/vaemodules/up_blocks.py b/easyanimate/vae/ldm/modules/vaemodules/up_blocks.py old mode 100755 new mode 100644 diff --git a/easyanimate/video_caption/compute_semantic_consistency.py b/easyanimate/video_caption/compute_semantic_consistency.py index c12bf23..4599cfe 100644 --- a/easyanimate/video_caption/compute_semantic_consistency.py +++ b/easyanimate/video_caption/compute_semantic_consistency.py @@ -170,8 +170,18 @@ def main(): for idx, batch in enumerate(tqdm(video_loader)): if len(batch) > 0: - batch_video_path = batch["path"] - batch_frame = batch["sampled_frame"] + batch_video_path = [] + batch_frame = [] + batch_sampled_frame_idx = [] + # At least two frames are required to calculate cross-frame semantic consistency. + for path, frame, frame_idx in zip(batch["path"], batch["sampled_frame"], batch["sampled_frame_idx"]): + if len(frame) > 1: + batch_video_path.append(path) + batch_frame.append(frame) + batch_sampled_frame_idx.append(frame_idx) + else: + logger.warning(f"Skip {path} because it only has {len(frame)} frames.") + frame_num_list = [len(video_frames) for video_frames in batch_frame] # [B, T, H, W, C] => [(B * T), H, W, C] reshaped_batch_frame = [frame for video_frames in batch_frame for frame in video_frames] @@ -197,7 +207,7 @@ def main(): result_dict[args.video_path_column].extend(saved_video_path_list) result_dict["similarity_cross_frame"].extend(batch_simi_cross_frame) result_dict["similarity_mean"].extend(batch_similarity_mean) - result_dict["sample_frame_idx"].extend(batch["sampled_frame_idx"]) + result_dict["sample_frame_idx"].extend(batch_sampled_frame_idx) # Save the metadata in the main process every saved_freq. if (idx % args.saved_freq) == 0 or idx == len(video_loader) - 1: diff --git a/easyanimate/video_caption/internvl2_video_recaptioning.py b/easyanimate/video_caption/internvl2_video_recaptioning.py index f779731..9db8761 100644 --- a/easyanimate/video_caption/internvl2_video_recaptioning.py +++ b/easyanimate/video_caption/internvl2_video_recaptioning.py @@ -181,6 +181,7 @@ def main(): video_dataset = VideoDataset( dataset_inputs={args.video_path_column: video_path_list}, + video_path_column=args.video_path_column, video_folder=args.video_folder, sample_method=args.frame_sample_method, num_sampled_frames=args.num_sampled_frames @@ -192,6 +193,12 @@ def main(): tensor_parallel_size = torch.cuda.device_count() if CUDA_VISIBLE_DEVICES is None else len(CUDA_VISIBLE_DEVICES.split(",")) logger.info(f"Automatically set tensor_parallel_size={tensor_parallel_size} based on the available devices.") + max_dynamic_patch = 1 + if args.frame_sample_method == "image": + max_dynamic_patch = 12 + quantization = None + if "awq" in args.model_path.lower(): + quantization="awq" llm = LLM( model=args.model_path, trust_remote_code=True, @@ -199,14 +206,17 @@ def main(): limit_mm_per_prompt={"image": args.num_sampled_frames}, gpu_memory_utilization=0.9, tensor_parallel_size=tensor_parallel_size, - quantization="awq", + quantization=quantization, dtype="float16", - mm_processor_kwargs={"max_dynamic_patch": 1} + mm_processor_kwargs={"max_dynamic_patch": max_dynamic_patch} ) tokenizer = AutoTokenizer.from_pretrained(args.model_path, trust_remote_code=True) - placeholders = "".join(f"Frame{i}: <image>\n" for i in range(1, args.num_sampled_frames + 1)) - messages = [{'role': 'user', 'content': f"{placeholders}{args.input_prompt}"}] + if args.frame_sample_method == "image": + placeholders = "<image>\n" + else: + placeholders = "".join(f"Frame{i}: <image>\n" for i in range(1, args.num_sampled_frames + 1)) + messages = [{"role": "user", "content": f"{placeholders}{args.input_prompt}"}] prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True) # Stop tokens for InternVL diff --git a/easyanimate/video_caption/utils/video_utils.py b/easyanimate/video_caption/utils/video_utils.py index 2c7e12e..bc9cc6c 100644 --- a/easyanimate/video_caption/utils/video_utils.py +++ b/easyanimate/video_caption/utils/video_utils.py @@ -44,13 +44,16 @@ def get_keyframe_index(video_path): result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) keyframe_index_list = [] - for index, line in enumerate(result.stdout.split("\n")): + frame_index = 0 + for line in result.stdout.split("\n"): line = line.strip(",") pict_type = line.strip() if pict_type == "I": - keyframe_index_list.append(index) + keyframe_index_list.append(frame_index) + if pict_type == "I" or pict_type == "B" or pict_type == "P": + frame_index += 1 - return keyframe_index_list + return keyframe_index_list, frame_index def extract_frames( video_path: str, @@ -81,17 +84,22 @@ def extract_frames( elif sample_method == "last": sampled_frame_idx_list = [len(vr) - 1] elif sample_method == "keyframe": - sampled_frame_idx_list = get_keyframe_index(video_path) - elif sample_method == "keyframe+first": - sampled_frame_idx_list = get_keyframe_index(video_path) + sampled_frame_idx_list, final_frame_index = get_keyframe_index(video_path) + elif sample_method == "keyframe+first": # keyframe + the first second + sampled_frame_idx_list, final_frame_index = get_keyframe_index(video_path) if len(sampled_frame_idx_list) == 1 or sampled_frame_idx_list[1] > 1 * vr.get_avg_fps(): + if int(1 * vr.get_avg_fps()) > len(vr): + raise ValueError(f"The duration of {video_path} is less than 1s.") sampled_frame_idx_list.insert(1, int(1 * vr.get_avg_fps())) - elif sample_method == "keyframe+last": - sampled_frame_idx_list = get_keyframe_index(video_path) + elif sample_method == "keyframe+last": # keyframe + the last frame + sampled_frame_idx_list, final_frame_index = get_keyframe_index(video_path) if sampled_frame_idx_list[-1] != (len(vr) - 1): sampled_frame_idx_list.append(len(vr) - 1) else: raise ValueError(f"The sample_method must be within {ALL_FRAME_SAMPLE_METHODS}.") + if "keyframe" in sample_method: + if final_frame_index != len(vr): + raise ValueError(f"The keyframe index list is not accurate. Please check the video {video_path}.") sampled_frame_list = vr.get_batch(sampled_frame_idx_list).asnumpy() sampled_frame_list = [Image.fromarray(frame) for frame in sampled_frame_list] diff --git a/predict_i2v.py b/predict_i2v.py index c745459..61ec857 100644 --- a/predict_i2v.py +++ b/predict_i2v.py @@ -2,25 +2,23 @@ import os import numpy as np import torch -from diffusers import (DDIMScheduler, - DPMSolverMultistepScheduler, +from diffusers import (DDIMScheduler, DPMSolverMultistepScheduler, EulerAncestralDiscreteScheduler, EulerDiscreteScheduler, - PNDMScheduler) + FlowMatchEulerDiscreteScheduler, PNDMScheduler) from omegaconf import OmegaConf from PIL import Image from transformers import (BertModel, BertTokenizer, CLIPImageProcessor, - CLIPVisionModelWithProjection, - T5EncoderModel, T5Tokenizer) + CLIPVisionModelWithProjection, Qwen2Tokenizer, + Qwen2VLForConditionalGeneration, T5EncoderModel, + T5Tokenizer) from easyanimate.models import (name_to_autoencoder_magvit, name_to_transformer3d) from easyanimate.pipeline.pipeline_easyanimate_inpaint import \ EasyAnimateInpaintPipeline -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder_inpaint import \ - EasyAnimatePipeline_Multi_Text_Encoder_Inpaint +from easyanimate.utils.fp8_optimization import convert_weight_dtype_wrapper from easyanimate.utils.lora_utils import merge_lora, unmerge_lora from easyanimate.utils.utils import get_image_to_video_latent, save_videos_grid -from easyanimate.utils.fp8_optimization import convert_weight_dtype_wrapper # GPU memory mode, which can be choosen in [model_cpu_offload, model_cpu_offload_and_qfloat8, sequential_cpu_offload]. # model_cpu_offload means that the entire model will be moved to the CPU after use, which can save some GPU memory. @@ -30,16 +28,21 @@ from easyanimate.utils.fp8_optimization import convert_weight_dtype_wrapper # # sequential_cpu_offload means that each layer of the model will be moved to the CPU after use, # resulting in slower speeds but saving a large amount of GPU memory. -GPU_memory_mode = "model_cpu_offload" +# +# EasyAnimateV1, V2 and V3 support "model_cpu_offload" "sequential_cpu_offload" +# EasyAnimateV4, V5 support "model_cpu_offload" "model_cpu_offload_and_qfloat8" "sequential_cpu_offload" +# EasyAnimateV5.1 support "model_cpu_offload" "model_cpu_offload_and_qfloat8" +GPU_memory_mode = "model_cpu_offload_and_qfloat8" # Config and model path -config_path = "config/easyanimate_video_v5_magvit_multi_text_encoder.yaml" -model_name = "models/Diffusion_Transformer/EasyAnimateV5-12b-zh-InP" +config_path = "config/easyanimate_video_v5.1_magvit_qwen.yaml" +model_name = "models/Diffusion_Transformer/EasyAnimateV5.1-12b-zh-InP" -# Choose the sampler in "Euler" "Euler A" "DPM++" "PNDM" and "DDIM" -# EasyAnimateV1, V2 and V3 cannot use DDIM. -# EasyAnimateV4 and V5 support DDIM. -sampler_name = "DDIM" +# Choose the sampler in "Euler" "Euler A" "DPM++" "PNDM" "DDIM" "Flow" +# EasyAnimateV1, V2 and V3 support "Euler" "Euler A" "DPM++" "PNDM" +# EasyAnimateV4 and V5 support "Euler" "Euler A" "DPM++" "PNDM" "DDIM". +# EasyAnimateV5.1 supports Flow. +sampler_name = "Flow" # Load pretrained model if need transformer_path = None @@ -52,7 +55,7 @@ lora_path = None sample_size = [384, 672] # In EasyAnimateV1, the video_length of video is 40 ~ 80. # In EasyAnimateV2, V3, V4, the video_length of video is 1 ~ 144. -# In EasyAnimateV5, the video_length of video is 1 ~ 49. +# In EasyAnimateV5, V5.1, the video_length of video is 1 ~ 49. # If u want to generate a image, please set the video_length = 1. video_length = 49 fps = 8 @@ -69,10 +72,10 @@ validation_image_start = "asset/1.png" validation_image_end = None # EasyAnimateV1, V2 and V3 support English. -# EasyAnimateV4 and V5 support English and Chinese. +# EasyAnimateV4, V5 and V5.1 support English and Chinese. # 使用更长的neg prompt如"模糊,突变,变形,失真,画面暗,文本字幕,画面固定,连环画,漫画,线稿,没有主体。",可以增加稳定性 # 在neg prompt中添加"安静,固定"等词语可以增加动态性。 -prompt = "一条狗正在摇头。质量高、杰作、最佳品质、高分辨率、超精细、梦幻般。" +prompt = "一只棕褐色的狗在摇晃脑袋,坐在一个舒适的房间里的浅色沙发上。在狗的后面,架子上有一幅镶框的画,周围是粉红色的花朵。房间里的灯光柔和温暖,营造出舒适的氛围。" negative_prompt = "扭曲的身体,肢体残缺,文本字幕,漫画,静止,丑陋,错误,乱码。" # # Using longer neg prompt such as "Blurring, mutation, deformation, distortion, dark and solid, comics, text subtitles, line art." can increase stability @@ -156,26 +159,48 @@ if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): tokenizer = BertTokenizer.from_pretrained( model_name, subfolder="tokenizer" ) - tokenizer_2 = T5Tokenizer.from_pretrained( - model_name, subfolder="tokenizer_2" - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + tokenizer_2 = Qwen2Tokenizer.from_pretrained( + os.path.join(model_name, "tokenizer_2") + ) + else: + tokenizer_2 = T5Tokenizer.from_pretrained( + model_name, subfolder="tokenizer_2" + ) else: - tokenizer = T5Tokenizer.from_pretrained( - model_name, subfolder="tokenizer" - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + tokenizer = Qwen2Tokenizer.from_pretrained( + os.path.join(model_name, "tokenizer") + ) + else: + tokenizer = T5Tokenizer.from_pretrained( + model_name, subfolder="tokenizer" + ) tokenizer_2 = None if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): text_encoder = BertModel.from_pretrained( - model_name, subfolder="text_encoder", torch_dtype=weight_dtype - ) - text_encoder_2 = T5EncoderModel.from_pretrained( - model_name, subfolder="text_encoder_2", torch_dtype=weight_dtype - ) + model_name, subfolder="text_encoder" + ).to(weight_dtype) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder_2 = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(model_name, "text_encoder_2"), + torch_dtype=weight_dtype, + ) + else: + text_encoder_2 = T5EncoderModel.from_pretrained( + model_name, subfolder="text_encoder_2" + ).to(weight_dtype) else: - text_encoder = T5EncoderModel.from_pretrained( - model_name, subfolder="text_encoder", torch_dtype=weight_dtype - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(model_name, "text_encoder"), + torch_dtype=weight_dtype, + ) + else: + text_encoder = T5EncoderModel.from_pretrained( + model_name, subfolder="text_encoder" + ).to(weight_dtype) text_encoder_2 = None if transformer.config.in_channels != vae.config.latent_channels and config['transformer_additional_kwargs'].get('enable_clip_in_inpaint', True): @@ -196,38 +221,25 @@ Choosen_Scheduler = scheduler_dict = { "DPM++": DPMSolverMultistepScheduler, "PNDM": PNDMScheduler, "DDIM": DDIMScheduler, + "Flow": FlowMatchEulerDiscreteScheduler, }[sampler_name] scheduler = Choosen_Scheduler.from_pretrained( model_name, subfolder="scheduler" ) -if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): - pipeline = EasyAnimatePipeline_Multi_Text_Encoder_Inpaint.from_pretrained( - model_name, - text_encoder=text_encoder, - text_encoder_2=text_encoder_2, - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - vae=vae, - transformer=transformer, - scheduler=scheduler, - torch_dtype=weight_dtype, - clip_image_encoder=clip_image_encoder, - clip_image_processor=clip_image_processor, - ) -else: - pipeline = EasyAnimateInpaintPipeline.from_pretrained( - model_name, - text_encoder=text_encoder, - tokenizer=tokenizer, - vae=vae, - transformer=transformer, - scheduler=scheduler, - torch_dtype=weight_dtype, - clip_image_encoder=clip_image_encoder, - clip_image_processor=clip_image_processor, - ) +pipeline = EasyAnimateInpaintPipeline( + text_encoder=text_encoder, + text_encoder_2=text_encoder_2, + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + vae=vae, + transformer=transformer, + scheduler=scheduler, + clip_image_encoder=clip_image_encoder, + clip_image_processor=clip_image_processor, +) + if GPU_memory_mode == "sequential_cpu_offload": pipeline.enable_sequential_cpu_offload() elif GPU_memory_mode == "model_cpu_offload_and_qfloat8": @@ -261,7 +273,7 @@ if partial_video_length is not None: else: _partial_video_length = partial_video_length - input_video, input_video_mask, clip_image = get_image_to_video_latent(validation_image, None, video_length=_partial_video_length, sample_size=sample_size) + input_video, input_video_mask, clip_image = get_image_to_video_latent(validation_image_start, None, video_length=_partial_video_length, sample_size=sample_size) with torch.no_grad(): sample = pipeline( @@ -277,7 +289,7 @@ if partial_video_length is not None: video = input_video, mask_video = input_video_mask, clip_image = clip_image, - ).videos + ).frames if init_frames != 0: mix_ratio = torch.from_numpy( @@ -295,7 +307,7 @@ if partial_video_length is not None: if last_frames >= video_length: break - validation_image = [ + validation_image_start = [ Image.fromarray( (sample[0, :, _index].transpose(0, 1).transpose(1, 2) * 255).numpy().astype(np.uint8) ) for _index in range(-overlap_video_length, 0) @@ -324,7 +336,7 @@ else: video = input_video, mask_video = input_video_mask, clip_image = clip_image, - ).videos + ).frames if lora_path is not None: pipeline = unmerge_lora(pipeline, lora_path, lora_weight, device="cuda", dtype=weight_dtype) diff --git a/predict_t2v.py b/predict_t2v.py index 78db586..505345b 100644 --- a/predict_t2v.py +++ b/predict_t2v.py @@ -2,28 +2,25 @@ import os import numpy as np import torch -from diffusers import (DDIMScheduler, - DPMSolverMultistepScheduler, +from diffusers import (DDIMScheduler, DPMSolverMultistepScheduler, EulerAncestralDiscreteScheduler, EulerDiscreteScheduler, - PNDMScheduler) + FlowMatchEulerDiscreteScheduler, PNDMScheduler) from omegaconf import OmegaConf from PIL import Image -from transformers import (BertModel, BertTokenizer, CLIPImageProcessor, - CLIPVisionModelWithProjection, +from transformers import (BertModel, BertTokenizer, + CLIPImageProcessor, CLIPVisionModelWithProjection, + Qwen2Tokenizer, Qwen2VLForConditionalGeneration, T5EncoderModel, T5Tokenizer) from easyanimate.models import (name_to_autoencoder_magvit, name_to_transformer3d) -from easyanimate.pipeline.pipeline_easyanimate import EasyAnimatePipeline +from easyanimate.pipeline.pipeline_easyanimate import \ + EasyAnimatePipeline from easyanimate.pipeline.pipeline_easyanimate_inpaint import \ EasyAnimateInpaintPipeline -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder import \ - EasyAnimatePipeline_Multi_Text_Encoder -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder_inpaint import \ - EasyAnimatePipeline_Multi_Text_Encoder_Inpaint +from easyanimate.utils.fp8_optimization import convert_weight_dtype_wrapper from easyanimate.utils.lora_utils import merge_lora, unmerge_lora from easyanimate.utils.utils import get_image_to_video_latent, save_videos_grid -from easyanimate.utils.fp8_optimization import convert_weight_dtype_wrapper # GPU memory mode, which can be choosen in [model_cpu_offload, model_cpu_offload_and_qfloat8, sequential_cpu_offload]. # model_cpu_offload means that the entire model will be moved to the CPU after use, which can save some GPU memory. @@ -33,16 +30,21 @@ from easyanimate.utils.fp8_optimization import convert_weight_dtype_wrapper # # sequential_cpu_offload means that each layer of the model will be moved to the CPU after use, # resulting in slower speeds but saving a large amount of GPU memory. -GPU_memory_mode = "model_cpu_offload" +# +# EasyAnimateV1, V2 and V3 support "model_cpu_offload" "sequential_cpu_offload" +# EasyAnimateV4, V5 support "model_cpu_offload" "model_cpu_offload_and_qfloat8" "sequential_cpu_offload" +# EasyAnimateV5.1 support "model_cpu_offload" "model_cpu_offload_and_qfloat8" +GPU_memory_mode = "model_cpu_offload_and_qfloat8" # Config and model path -config_path = "config/easyanimate_video_v5_magvit_multi_text_encoder.yaml" -model_name = "models/Diffusion_Transformer/EasyAnimateV5-12b-zh-InP" +config_path = "config/easyanimate_video_v5.1_magvit_qwen.yaml" +model_name = "models/Diffusion_Transformer/EasyAnimateV5.1-12b-zh-InP" -# Choose the sampler in "Euler" "Euler A" "DPM++" "PNDM" and "DDIM" -# EasyAnimateV1, V2 and V3 cannot use DDIM. -# EasyAnimateV4 and V5 support DDIM. -sampler_name = "DDIM" +# Choose the sampler in "Euler" "Euler A" "DPM++" "PNDM" "DDIM" "Flow" +# EasyAnimateV1, V2 and V3 support "Euler" "Euler A" "DPM++" "PNDM" +# EasyAnimateV4 and V5 support "Euler" "Euler A" "DPM++" "PNDM" "DDIM". +# EasyAnimateV5.1 supports Flow. +sampler_name = "Flow" # Load pretrained model if need transformer_path = None @@ -55,7 +57,7 @@ lora_path = None sample_size = [384, 672] # In EasyAnimateV1, the video_length of video is 40 ~ 80. # In EasyAnimateV2, V3, V4, the video_length of video is 1 ~ 144. -# In EasyAnimateV5, the video_length of video is 1 ~ 49. +# In EasyAnimateV5, V5.1, the video_length of video is 1 ~ 49. # If u want to generate a image, please set the video_length = 1. video_length = 49 fps = 8 @@ -65,10 +67,10 @@ fps = 8 weight_dtype = torch.bfloat16 # EasyAnimateV1, V2 and V3 support English. -# EasyAnimateV4 and V5 support English and Chinese. +# EasyAnimateV4, V5 and V5.1 support English and Chinese. # 使用更长的neg prompt如"模糊,突变,变形,失真,画面暗,文本字幕,画面固定,连环画,漫画,线稿,没有主体。",可以增加稳定性 # 在neg prompt中添加"安静,固定"等词语可以增加动态性。 -prompt = "一条狗正在摇头。质量高、杰作、最佳品质、高分辨率、超精细、梦幻般。" +prompt = "一只棕褐色的狗在摇晃脑袋,坐在一个舒适的房间里的浅色沙发上。在狗的后面,架子上有一幅镶框的画,周围是粉红色的花朵。房间里的灯光柔和温暖,营造出舒适的氛围。" negative_prompt = "扭曲的身体,肢体残缺,文本字幕,漫画,静止,丑陋,错误,乱码。" # # Using longer neg prompt such as "Blurring, mutation, deformation, distortion, dark and solid, comics, text subtitles, line art." can increase stability @@ -152,26 +154,49 @@ if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): tokenizer = BertTokenizer.from_pretrained( model_name, subfolder="tokenizer" ) - tokenizer_2 = T5Tokenizer.from_pretrained( - model_name, subfolder="tokenizer_2" - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + tokenizer_2 = Qwen2Tokenizer.from_pretrained( + os.path.join(model_name, "tokenizer_2") + ) + else: + tokenizer_2 = T5Tokenizer.from_pretrained( + model_name, subfolder="tokenizer_2" + ) else: - tokenizer = T5Tokenizer.from_pretrained( - model_name, subfolder="tokenizer" - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + print(os.path.join(model_name, "tokenizer")) + tokenizer = Qwen2Tokenizer.from_pretrained( + os.path.join(model_name, "tokenizer") + ) + else: + tokenizer = T5Tokenizer.from_pretrained( + model_name, subfolder="tokenizer" + ) tokenizer_2 = None if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): text_encoder = BertModel.from_pretrained( model_name, subfolder="text_encoder" - ).to(torch.bfloat16) - text_encoder_2 = T5EncoderModel.from_pretrained( - model_name, subfolder="text_encoder_2" - ).to(torch.bfloat16) -else: - text_encoder = T5EncoderModel.from_pretrained( - model_name, subfolder="text_encoder" ).to(weight_dtype) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder_2 = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(model_name, "text_encoder_2"), + torch_dtype=weight_dtype, + ) + else: + text_encoder_2 = T5EncoderModel.from_pretrained( + model_name, subfolder="text_encoder_2" + ).to(weight_dtype) +else: + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(model_name, "text_encoder"), + torch_dtype=weight_dtype, + ) + else: + text_encoder = T5EncoderModel.from_pretrained( + model_name, subfolder="text_encoder" + ).to(weight_dtype) text_encoder_2 = None if transformer.config.in_channels != vae.config.latent_channels and config['transformer_additional_kwargs'].get('enable_clip_in_inpaint', True): @@ -192,62 +217,37 @@ Choosen_Scheduler = scheduler_dict = { "DPM++": DPMSolverMultistepScheduler, "PNDM": PNDMScheduler, "DDIM": DDIMScheduler, + "Flow": FlowMatchEulerDiscreteScheduler, }[sampler_name] scheduler = Choosen_Scheduler.from_pretrained( model_name, subfolder="scheduler" ) -if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): - if transformer.config.in_channels != vae.config.latent_channels: - pipeline = EasyAnimatePipeline_Multi_Text_Encoder_Inpaint.from_pretrained( - model_name, - text_encoder=text_encoder, - text_encoder_2=text_encoder_2, - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - vae=vae, - transformer=transformer, - scheduler=scheduler, - torch_dtype=weight_dtype, - clip_image_encoder=clip_image_encoder, - clip_image_processor=clip_image_processor, - ) - else: - pipeline = EasyAnimatePipeline_Multi_Text_Encoder.from_pretrained( - model_name, - text_encoder=text_encoder, - text_encoder_2=text_encoder_2, - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - vae=vae, - transformer=transformer, - scheduler=scheduler, - torch_dtype=weight_dtype - ) + +if transformer.config.in_channels != vae.config.latent_channels: + pipeline = EasyAnimateInpaintPipeline( + text_encoder=text_encoder, + text_encoder_2=text_encoder_2, + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + vae=vae, + transformer=transformer, + scheduler=scheduler, + clip_image_encoder=clip_image_encoder, + clip_image_processor=clip_image_processor, + ) else: - if transformer.config.in_channels != vae.config.latent_channels: - pipeline = EasyAnimateInpaintPipeline.from_pretrained( - model_name, - text_encoder=text_encoder, - tokenizer=tokenizer, - vae=vae, - transformer=transformer, - scheduler=scheduler, - torch_dtype=weight_dtype, - clip_image_encoder=clip_image_encoder, - clip_image_processor=clip_image_processor, - ) - else: - pipeline = EasyAnimatePipeline.from_pretrained( - model_name, - text_encoder=text_encoder, - tokenizer=tokenizer, - vae=vae, - transformer=transformer, - scheduler=scheduler, - torch_dtype=weight_dtype - ) + pipeline = EasyAnimatePipeline( + text_encoder=text_encoder, + text_encoder_2=text_encoder_2, + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + vae=vae, + transformer=transformer, + scheduler=scheduler, + ) + if GPU_memory_mode == "sequential_cpu_offload": pipeline.enable_sequential_cpu_offload() elif GPU_memory_mode == "model_cpu_offload_and_qfloat8": @@ -282,7 +282,7 @@ with torch.no_grad(): video = input_video, mask_video = input_video_mask, clip_image = clip_image, - ).videos + ).frames else: sample = pipeline( prompt, @@ -293,7 +293,7 @@ with torch.no_grad(): generator = generator, guidance_scale = guidance_scale, num_inference_steps = num_inference_steps, - ).videos + ).frames if lora_path is not None: pipeline = unmerge_lora(pipeline, lora_path, lora_weight, device="cuda", dtype=weight_dtype) diff --git a/predict_v2v.py b/predict_v2v.py index 2e9a22e..5e54876 100644 --- a/predict_v2v.py +++ b/predict_v2v.py @@ -2,26 +2,24 @@ import os import numpy as np import torch -from diffusers import (DDIMScheduler, - DPMSolverMultistepScheduler, +from diffusers import (DDIMScheduler, DPMSolverMultistepScheduler, EulerAncestralDiscreteScheduler, EulerDiscreteScheduler, - PNDMScheduler) + FlowMatchEulerDiscreteScheduler, PNDMScheduler) from omegaconf import OmegaConf from PIL import Image from transformers import (BertModel, BertTokenizer, CLIPImageProcessor, - CLIPVisionModelWithProjection, - T5EncoderModel, T5Tokenizer) + CLIPVisionModelWithProjection, Qwen2Tokenizer, + Qwen2VLForConditionalGeneration, T5EncoderModel, + T5Tokenizer) from easyanimate.models import (name_to_autoencoder_magvit, name_to_transformer3d) from easyanimate.pipeline.pipeline_easyanimate_inpaint import \ EasyAnimateInpaintPipeline -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder_inpaint import \ - EasyAnimatePipeline_Multi_Text_Encoder_Inpaint +from easyanimate.utils.fp8_optimization import convert_weight_dtype_wrapper from easyanimate.utils.lora_utils import merge_lora, unmerge_lora from easyanimate.utils.utils import (get_video_to_video_latent, save_videos_grid) -from easyanimate.utils.fp8_optimization import convert_weight_dtype_wrapper # GPU memory mode, which can be choosen in [model_cpu_offload, model_cpu_offload_and_qfloat8, sequential_cpu_offload]. # model_cpu_offload means that the entire model will be moved to the CPU after use, which can save some GPU memory. @@ -31,16 +29,21 @@ from easyanimate.utils.fp8_optimization import convert_weight_dtype_wrapper # # sequential_cpu_offload means that each layer of the model will be moved to the CPU after use, # resulting in slower speeds but saving a large amount of GPU memory. -GPU_memory_mode = "model_cpu_offload" +# +# EasyAnimateV3 support "model_cpu_offload" "sequential_cpu_offload" +# EasyAnimateV4, V5 support "model_cpu_offload" "model_cpu_offload_and_qfloat8" "sequential_cpu_offload" +# EasyAnimateV5.1 support "model_cpu_offload" "model_cpu_offload_and_qfloat8" +GPU_memory_mode = "model_cpu_offload_and_qfloat8" # Config and model path -config_path = "config/easyanimate_video_v5_magvit_multi_text_encoder.yaml" -model_name = "models/Diffusion_Transformer/EasyAnimateV5-12b-zh-InP" +config_path = "config/easyanimate_video_v5.1_magvit_qwen.yaml" +model_name = "models/Diffusion_Transformer/EasyAnimateV5.1-12b-zh-InP" -# Choose the sampler in "Euler" "Euler A" "DPM++" "PNDM" and "DDIM" -# EasyAnimateV1, V2 and V3 cannot use DDIM. -# EasyAnimateV4 and V5 support DDIM. -sampler_name = "DDIM" +# Choose the sampler in "Euler" "Euler A" "DPM++" "PNDM" "DDIM" "Flow" +# EasyAnimateV3 support "Euler" "Euler A" "DPM++" "PNDM" +# EasyAnimateV4 and V5 support "Euler" "Euler A" "DPM++" "PNDM" "DDIM". +# EasyAnimateV5.1 supports Flow. +sampler_name = "Flow" # Load pretrained model if need transformer_path = None @@ -51,9 +54,8 @@ lora_path = None # Other params sample_size = [384, 672] -# In EasyAnimateV1, the video_length of video is 40 ~ 80. -# In EasyAnimateV2, V3, V4, the video_length of video is 1 ~ 144. -# In EasyAnimateV5, the video_length of video is 1 ~ 49. +# In EasyAnimateV3, V4, the video_length of video is 1 ~ 144. +# In EasyAnimateV5, V5.1, the video_length of video is 1 ~ 49. # If u want to generate a image, please set the video_length = 1. video_length = 49 fps = 8 @@ -65,11 +67,9 @@ weight_dtype = torch.bfloat16 validation_video = "asset/1.mp4" denoise_strength = 0.70 -# EasyAnimateV1, V2 and V3 support English. -# EasyAnimateV4 and V5 support English and Chinese. # 使用更长的neg prompt如"模糊,突变,变形,失真,画面暗,文本字幕,画面固定,连环画,漫画,线稿,没有主体。",可以增加稳定性 # 在neg prompt中添加"安静,固定"等词语可以增加动态性。 -prompt = "一只猫正在弹吉他。" +prompt = "一只穿着小外套的猫咪正在花园秋千上安静地弹吉他。晚霞的余光洒在它柔软的毛皮上,和煦的微风轻轻拂过,周围斑驳的光影随着音乐的旋律轻轻摇曳。" negative_prompt = "扭曲的身体,肢体残缺,文本字幕,漫画,静止,丑陋,错误,乱码。" # # Using longer neg prompt such as "Blurring, mutation, deformation, distortion, dark and solid, comics, text subtitles, line art." can increase stability @@ -153,26 +153,48 @@ if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): tokenizer = BertTokenizer.from_pretrained( model_name, subfolder="tokenizer" ) - tokenizer_2 = T5Tokenizer.from_pretrained( - model_name, subfolder="tokenizer_2" - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + tokenizer_2 = Qwen2Tokenizer.from_pretrained( + os.path.join(model_name, "tokenizer_2") + ) + else: + tokenizer_2 = T5Tokenizer.from_pretrained( + model_name, subfolder="tokenizer_2" + ) else: - tokenizer = T5Tokenizer.from_pretrained( - model_name, subfolder="tokenizer" - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + tokenizer = Qwen2Tokenizer.from_pretrained( + os.path.join(model_name, "tokenizer") + ) + else: + tokenizer = T5Tokenizer.from_pretrained( + model_name, subfolder="tokenizer" + ) tokenizer_2 = None if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): text_encoder = BertModel.from_pretrained( - model_name, subfolder="text_encoder", torch_dtype=weight_dtype - ) - text_encoder_2 = T5EncoderModel.from_pretrained( - model_name, subfolder="text_encoder_2", torch_dtype=weight_dtype - ) + model_name, subfolder="text_encoder" + ).to(weight_dtype) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder_2 = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(model_name, "text_encoder_2"), + torch_dtype=weight_dtype, + ) + else: + text_encoder_2 = T5EncoderModel.from_pretrained( + model_name, subfolder="text_encoder_2" + ).to(weight_dtype) else: - text_encoder = T5EncoderModel.from_pretrained( - model_name, subfolder="text_encoder", torch_dtype=weight_dtype - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(model_name, "text_encoder"), + torch_dtype=weight_dtype, + ) + else: + text_encoder = T5EncoderModel.from_pretrained( + model_name, subfolder="text_encoder" + ).to(weight_dtype) text_encoder_2 = None if transformer.config.in_channels != vae.config.latent_channels and config['transformer_additional_kwargs'].get('enable_clip_in_inpaint', True): @@ -193,38 +215,25 @@ Choosen_Scheduler = scheduler_dict = { "DPM++": DPMSolverMultistepScheduler, "PNDM": PNDMScheduler, "DDIM": DDIMScheduler, + "Flow": FlowMatchEulerDiscreteScheduler, }[sampler_name] scheduler = Choosen_Scheduler.from_pretrained( model_name, subfolder="scheduler" ) -if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): - pipeline = EasyAnimatePipeline_Multi_Text_Encoder_Inpaint.from_pretrained( - model_name, - text_encoder=text_encoder, - text_encoder_2=text_encoder_2, - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - vae=vae, - transformer=transformer, - scheduler=scheduler, - torch_dtype=weight_dtype, - clip_image_encoder=clip_image_encoder, - clip_image_processor=clip_image_processor, - ) -else: - pipeline = EasyAnimateInpaintPipeline.from_pretrained( - model_name, - text_encoder=text_encoder, - tokenizer=tokenizer, - vae=vae, - transformer=transformer, - scheduler=scheduler, - torch_dtype=weight_dtype, - clip_image_encoder=clip_image_encoder, - clip_image_processor=clip_image_processor, - ) + +pipeline = EasyAnimateInpaintPipeline( + text_encoder=text_encoder, + text_encoder_2=text_encoder_2, + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + vae=vae, + transformer=transformer, + scheduler=scheduler, + clip_image_encoder=clip_image_encoder, + clip_image_processor=clip_image_processor, +) if GPU_memory_mode == "sequential_cpu_offload": pipeline.enable_sequential_cpu_offload() @@ -260,7 +269,7 @@ with torch.no_grad(): mask_video = input_video_mask, clip_image = clip_image, strength = denoise_strength - ).videos + ).frames if lora_path is not None: pipeline = unmerge_lora(pipeline, lora_path, lora_weight, device="cuda", dtype=weight_dtype) diff --git a/predict_v2v_control.py b/predict_v2v_control.py index 553658a..e1d2678 100644 --- a/predict_v2v_control.py +++ b/predict_v2v_control.py @@ -7,17 +7,20 @@ from diffusers import (DDIMScheduler, DPMSolverMultistepScheduler, PNDMScheduler) from omegaconf import OmegaConf from PIL import Image -from transformers import (BertModel, BertTokenizer, CLIPImageProcessor, - CLIPVisionModelWithProjection, +from transformers import (BertModel, BertTokenizer, + CLIPImageProcessor, CLIPVisionModelWithProjection, + Qwen2Tokenizer, Qwen2VLForConditionalGeneration, T5EncoderModel, T5Tokenizer) +from easyanimate.data.dataset_image_video import process_pose_file from easyanimate.models import (name_to_autoencoder_magvit, name_to_transformer3d) -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder_control import \ - EasyAnimatePipeline_Multi_Text_Encoder_Control +from easyanimate.pipeline.pipeline_easyanimate_control import \ + EasyAnimateControlPipeline from easyanimate.utils.lora_utils import merge_lora, unmerge_lora -from easyanimate.utils.utils import get_video_to_video_latent, save_videos_grid +from easyanimate.utils.utils import get_video_to_video_latent, save_videos_grid, get_image_latent from easyanimate.utils.fp8_optimization import convert_weight_dtype_wrapper +from diffusers import FlowMatchEulerDiscreteScheduler # GPU memory mode, which can be choosen in [model_cpu_offload, model_cpu_offload_and_qfloat8, sequential_cpu_offload]. # model_cpu_offload means that the entire model will be moved to the CPU after use, which can save some GPU memory. @@ -27,16 +30,19 @@ from easyanimate.utils.fp8_optimization import convert_weight_dtype_wrapper # # sequential_cpu_offload means that each layer of the model will be moved to the CPU after use, # resulting in slower speeds but saving a large amount of GPU memory. -GPU_memory_mode = "model_cpu_offload" +# +# EasyAnimateV5 support "model_cpu_offload" "model_cpu_offload_and_qfloat8" "sequential_cpu_offload" +# EasyAnimateV5.1 support "model_cpu_offload" "model_cpu_offload_and_qfloat8" +GPU_memory_mode = "model_cpu_offload_and_qfloat8" # Config and model path -config_path = "config/easyanimate_video_v5_magvit_multi_text_encoder.yaml" -model_name = "models/Diffusion_Transformer/EasyAnimateV5-12b-zh-Control" +config_path = "config/easyanimate_video_v5.1_magvit_qwen.yaml" +model_name = "models/Diffusion_Transformer/EasyAnimateV5.1-12b-zh-Control" -# Choose the sampler in "Euler" "Euler A" "DPM++" "PNDM" and "DDIM" -# EasyAnimateV1, V2 and V3 cannot use DDIM. -# EasyAnimateV4 and V5 support DDIM. -sampler_name = "DDIM" +# Choose the sampler in "Euler" "Euler A" "DPM++" "PNDM" "DDIM" "Flow" +# EasyAnimateV5 support "Euler" "Euler A" "DPM++" "PNDM" "DDIM". +# EasyAnimateV5.1 supports Flow. +sampler_name = "Flow" # Load pretrained model if need transformer_path = None @@ -47,7 +53,7 @@ lora_path = None # Other params sample_size = [672, 384] -# In EasyAnimateV5, the video_length of video is 1 ~ 49. +# In EasyAnimateV5, V5.1, the video_length of video is 1 ~ 49. # If u want to generate a image, please set the video_length = 1. video_length = 49 fps = 8 @@ -56,17 +62,17 @@ fps = 8 # ome graphics cards, such as v100, 2080ti, do not support torch.bfloat16 weight_dtype = torch.bfloat16 control_video = "asset/pose.mp4" +control_camera_txt = None +ref_image = None -# EasyAnimateV1, V2 and V3 support English. -# EasyAnimateV4 and V5 support English and Chinese. # 使用更长的neg prompt如"模糊,突变,变形,失真,画面暗,文本字幕,画面固定,连环画,漫画,线稿,没有主体。",可以增加稳定性 # 在neg prompt中添加"安静,固定"等词语可以增加动态性。 -prompt = "一位年轻女子,有着美丽清澈的眼睛和金发,穿着白色的衣服在扭动身体,相机聚焦在她的脸上。质量高、杰作、最佳品质、高分辨率、超精细、梦幻般。" +prompt = "一位穿着合身的白色连衣裙,带着细肩带的女人站在一个铺着木地板的房间里。她有一头深色的长发。背景是一个放着各种瓶子的架子。灯光温暖,背景似乎在室内。" negative_prompt = "扭曲的身体,肢体残缺,文本字幕,漫画,静止,丑陋,错误,乱码。" # # Using longer neg prompt such as "Blurring, mutation, deformation, distortion, dark and solid, comics, text subtitles, line art." can increase stability # Adding words such as "quiet, solid" to the neg prompt can increase dynamism. -# prompt = "A young woman with beautiful and clear eyes and blonde hair standing and white dress in a forest wearing a crown. She seems to be lost in thought, and the camera focuses on her face. The video is of high quality, and the view is very clear. High quality, masterpiece, best quality, highres, ultra-detailed, fantastic." +# prompt = "A young woman with beautiful, clear eyes and blonde hair stands in the forest, wearing a white dress and a crown. Her expression is serene, reminiscent of a movie star, with fair and youthful skin. Her brown long hair flows in the wind. The video quality is very high, with a clear view. High quality, masterpiece, best quality, high resolution, ultra-fine, fantastical." # negative_prompt = "Twisted body, limb deformities, text captions, comic, static, ugly, error, messy code." guidance_scale = 6.0 seed = 43 @@ -145,39 +151,50 @@ if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): tokenizer = BertTokenizer.from_pretrained( model_name, subfolder="tokenizer" ) - tokenizer_2 = T5Tokenizer.from_pretrained( - model_name, subfolder="tokenizer_2" - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + tokenizer_2 = Qwen2Tokenizer.from_pretrained( + os.path.join(model_name, "tokenizer_2") + ) + else: + tokenizer_2 = T5Tokenizer.from_pretrained( + model_name, subfolder="tokenizer_2" + ) else: - tokenizer = T5Tokenizer.from_pretrained( - model_name, subfolder="tokenizer" - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + tokenizer = Qwen2Tokenizer.from_pretrained( + os.path.join(model_name, "tokenizer") + ) + else: + tokenizer = T5Tokenizer.from_pretrained( + model_name, subfolder="tokenizer" + ) tokenizer_2 = None if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): text_encoder = BertModel.from_pretrained( - model_name, subfolder="text_encoder", torch_dtype=weight_dtype - ) - text_encoder_2 = T5EncoderModel.from_pretrained( - model_name, subfolder="text_encoder_2", torch_dtype=weight_dtype - ) + model_name, subfolder="text_encoder" + ).to(weight_dtype) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder_2 = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(model_name, "text_encoder_2"), + torch_dtype=weight_dtype, + ) + else: + text_encoder_2 = T5EncoderModel.from_pretrained( + model_name, subfolder="text_encoder_2" + ).to(weight_dtype) else: - text_encoder = T5EncoderModel.from_pretrained( - model_name, subfolder="text_encoder", torch_dtype=weight_dtype - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(model_name, "text_encoder"), + torch_dtype=weight_dtype, + ) + else: + text_encoder = T5EncoderModel.from_pretrained( + model_name, subfolder="text_encoder" + ).to(weight_dtype) text_encoder_2 = None -if transformer.config.ref_channels is not None: - clip_image_encoder = CLIPVisionModelWithProjection.from_pretrained( - model_name, subfolder="image_encoder" - ).to("cuda", weight_dtype) - clip_image_processor = CLIPImageProcessor.from_pretrained( - model_name, subfolder="image_encoder" - ) -else: - clip_image_encoder = None - clip_image_processor = None - # Get Scheduler Choosen_Scheduler = scheduler_dict = { "Euler": EulerDiscreteScheduler, @@ -185,28 +202,23 @@ Choosen_Scheduler = scheduler_dict = { "DPM++": DPMSolverMultistepScheduler, "PNDM": PNDMScheduler, "DDIM": DDIMScheduler, + "Flow": FlowMatchEulerDiscreteScheduler, }[sampler_name] scheduler = Choosen_Scheduler.from_pretrained( model_name, subfolder="scheduler" ) -if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): - pipeline = EasyAnimatePipeline_Multi_Text_Encoder_Control.from_pretrained( - model_name, - text_encoder=text_encoder, - text_encoder_2=text_encoder_2, - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - vae=vae, - transformer=transformer, - scheduler=scheduler, - torch_dtype=weight_dtype, - clip_image_encoder=clip_image_encoder, - clip_image_processor=clip_image_processor, - ) -else: - raise ValueError("enable_multi_text_encoder == False is not support now") + +pipeline = EasyAnimateControlPipeline( + text_encoder=text_encoder, + text_encoder_2=text_encoder_2, + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + vae=vae, + transformer=transformer, + scheduler=scheduler, +) if GPU_memory_mode == "sequential_cpu_offload": pipeline.enable_sequential_cpu_offload() @@ -226,7 +238,15 @@ with torch.no_grad(): video_length = int((video_length - 1) // vae.mini_batch_encoder * vae.mini_batch_encoder) + 1 if video_length != 1 else 1 else: video_length = int(video_length // vae.mini_batch_encoder * vae.mini_batch_encoder) if video_length != 1 else 1 - input_video, input_video_mask, _ = get_video_to_video_latent(control_video, video_length=video_length, sample_size=sample_size, fps=fps, ref_image=None) + + if control_camera_txt is not None: + ref_image = get_image_latent(sample_size=sample_size, ref_image=ref_image) + input_video, input_video_mask = None, None + control_camera_video = process_pose_file(control_camera_txt, sample_size[1], sample_size[0]) + control_camera_video = control_camera_video[::int(24 // fps)][:video_length].permute([3, 0, 1, 2]).unsqueeze(0) + else: + input_video, input_video_mask, ref_image = get_video_to_video_latent(control_video, video_length=video_length, sample_size=sample_size, fps=fps, ref_image=ref_image) + control_camera_video = None sample = pipeline( prompt, @@ -239,7 +259,9 @@ with torch.no_grad(): num_inference_steps = num_inference_steps, control_video = input_video, - ).videos + control_camera_video = control_camera_video, + ref_image = ref_image, + ).frames if lora_path is not None: pipeline = unmerge_lora(pipeline, lora_path, lora_weight, device="cuda", dtype=weight_dtype) diff --git a/reports/report_v5_1.md b/reports/report_v5_1.md new file mode 100644 index 0000000..5016ddf --- /dev/null +++ b/reports/report_v5_1.md @@ -0,0 +1,70 @@ +# EasyAnimateV5 Report + +In the EasyAnimateV5.1 version, we have replaced the original dual text encoders with Alibaba's recently released Qwen2 VL. Since Qwen2 VL is a multilingual model, EasyAnimateV5.1 supports multilingual predictions, and the language support range is linked to Qwen2 VL. In general, the experience is best with Chinese and English, while Japanese, Korean, and other languages are also supported. + +In addition to text-to-video, image-to-video, video-to-video, and general control, we now support trajectory control and camera lens control. With trajectory control, you can manage the specific movement direction of an object, and with camera lens control, you can control the movement of the video camera lens. By combining multiple camera movements, deviations such as left-up and left-down can be achieved. + +Compared to EasyAnimateV5, EasyAnimateV5.1 mainly highlights the following features: + +- Utilizes Qwen2 VL as the text encoder, supporting multilingual predictions; +- Supports new control methods, such as trajectory control and camera control; +- Optimizes performance using reward algorithms; +- Uses Flow as the sampling method; +- Trains with more data. + +## Utilizing Qwen2 VL as the Text Encoder +Based on the MMDiT structure, we replaced EasyAnimateV5's dual text encoders with Alibaba's recently released Qwen2 VL. Compared to CLIP and T5, [Qwen2 VL](https://huggingface.co/Qwen/Qwen2-VL-7B-Instruct) outperforms both as a generation and encoding model, offering more precise semantic understanding. Additionally, aligning with images allows Qwen2 VL to have a more accurate understanding of image content compared to Qwen2 itself. + +We extract the penultimate feature of Qwen2 VL's hidden_states and input it into MMDiT, performing self-attention with video embedding. Before self-attention, we apply an RMSNorm for value correction and then fully connect, as deep feature values of large language models are generally large (up to tens of thousands), + +<img src="https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/qwen2_vl_transformer.jpg" alt="ui" style="zoom:50%;" /> + +## Supporting New Control Methods such as Trajectory Control and Camera Control +Referring to [Drag Anything](https://github.com/showlab/DragAnything), we implemented 2D trajectory control, adding trajectory control points before Conv in to manage the movement direction of objects. The Gaussian blur is used to specify the movement direction of objects. + +Referring to [CameraCtrl](https://github.com/hehao13/CameraCtrl), we input the control trajectory of the camera lens before Conv in, which determines the direction of lens movement, achieving control of the video lens. + +We have implemented corresponding control schemes in [EasyAnimate ComfyUI](../comfyui/README.md), thanks to the node implementations from [KJ Nodes](https://github.com/kijai/ComfyUI-KJNodes) and [ComfyUI-CameraCtrl-Wrapper](https://github.com/chaojie/ComfyUI-CameraCtrl-Wrapper). + +## Optimizing Performance Using Reward Algorithms +To further enhance the quality of generated videos and better align them with human preferences, we applied reward backpropagation ([DRaFT](https://arxiv.org/abs/2309.17400) and [DRTune](https://arxiv.org/abs/2405.00760)) for further training the base model of EasyAnimateV5.1, using rewards to improve the model's text consistency and image detail. + +For details on using reward backpropagation, refer to [EasyAnimate ComfyUI](../scripts/README_TRAIN_REWARD.md). + +## Using Flow Matching as the Sampling Method +Beyond the architectural changes mentioned, EasyAnimateV5.1 also adopts the [flow-matching](https://arxiv.org/html/2403.03206v1#S3) approach for training. In this method, the forward noise process is defined as rectifying along a straight line connecting the data and noise distributions. + +The corrected flow-matching sampling process is simpler and performs well in reducing sampling steps. Our new scheduler (FlowMatchEulerDiscreteScheduler), consistent with [Stable Diffusion 3](https://huggingface.co/stabilityai/stable-diffusion-3-medium/), includes the corrected flow-matching formula and Euler method steps. + +## Training with More Data +Compared to EasyAnimateV5, EasyAnimateV5.1 added about 10M high-resolution data for training. + +EasyAnimateV5.1 training consists of multiple phases, with all phases being video training except for the image Adapt VAE phase, corresponding to different Token lengths. + +### 1. Image VAE Alignment +We used 10M [SAM](https://www.semanticscholar.org/paper/Segment-Anything-Kirillov-Mintun/7470a1702c8c86e6f28d32cfa315381150102f5b) to train the model from scratch for text-image alignment, training a total of about 120K steps. + +Upon completion, the model can generate corresponding images based on prompts, with the targets in the images generally matching the prompt descriptions. + +### 2. Video Training +Video training involves scaling videos according to different Token lengths. + +Video training is divided into multiple stages, with Token lengths of 3328 (corresponding to 256x256x49 videos), 13312 (corresponding to 512x512x49 videos), and 53248 (corresponding to 1024x1024x49 videos). + +Among them: +- 3328 stage + - Used all data (about 36.6M) to train text-to-video models, with a batch size of 1024, training about 100K steps. +- 13312 stage + - Used videos above 720P (about 27.9M) to train text-to-video models, with a batch size of 512, training about 60K steps. + - Used the highest quality videos (about 0.5M) to train image-to-video models, with a batch size of 256, training about 5K steps. +- 53248 stage + - Used the highest quality videos (about 0.5M) to train image-to-video models, with a batch size of 256, training about 5K steps. + +Combining high and low resolution training, the model supports generating videos at any resolution from 512 to 1024. + +For different resolutions at 13312 token length: +- At 512x512 resolution, the video frame count is 49; +- At 768x768 resolution, the video frame count is 21; +- At 1024x1024 resolution, the video frame count is 9; + +These resolutions and corresponding lengths are mixed during training, allowing the model to generate videos of varying sizes and resolutions. diff --git a/reports/report_v5_1_zh-CN.md b/reports/report_v5_1_zh-CN.md new file mode 100644 index 0000000..dc6a17b --- /dev/null +++ b/reports/report_v5_1_zh-CN.md @@ -0,0 +1,67 @@ +# EasyAnimateV5 Report + +在EasyAnimateV5.1版本中,我们将原来的双text encoders替换成alibaba近期发布的Qwen2 VL,由于Qwen2 VL是一个多语言模型,EasyAnimateV5.1支持多语言预测,语言支持范围与Qwen2 VL挂钩,综合体验下来是中文英文最佳,同时还支持日语、韩语等语言的预测。 + +另外在文生视频、图生视频、视频生视频和通用控制的基础上,我们支持了轨迹控制与相机镜头控制,通过轨迹控制可以实现控制某一物体的具体的运动方向,通过相机镜头控制可以控制视频镜头的运动方向,组合多个镜头运动后,还可以往左上、左下等方向进行偏转。 + +对比EasyAnimateV5,EasyAnimateV5.1主要突出了以下特点: + +- 应用Qwen2 VL作为文本编码器,支持多语言预测; +- 支持轨迹控制,相机控制等新控制方式; +- 使用奖励算法最终优化性能; +- 使用Flow作为采样方式; +- 使用更多数据训练。 + +## 应用Qwen2 VL作为文本编码器 +在MMDiT结构的基础上,我们将EasyAnimateV5的双text encoders替换成alibaba近期发布的Qwen2 VL;相比于CLIP与T5,无论是作为生成模型还是编码模型,[Qwen2 VL](https://huggingface.co/Qwen/Qwen2-VL-7B-Instruct)性能更加优越,对语义理解更加精准。而相比于Qwen2本身,Qwen2 VL由于和图像做过对齐,对图像内容的理解更为精确。 + +我们取出Qwen2 VL hidden_states的倒数第二个特征输入到MMDiT中,与视频Embedding一起做Self-Attention。在做Self-Attention前,由于大语言模型深层特征值一般较大(可以达到几万),我们为其做了一个RMSNorm进行数值的矫正再进行全链接, + +<img src="https://pai-aigc-photog.oss-cn-hangzhou.aliyuncs.com/easyanimate/asset/v5.1/qwen2_vl_transformer.jpg" alt="ui" style="zoom:50%;" /> + +## 支持轨迹控制,相机控制等新控制方式 +参考[Drag Anything](https://github.com/showlab/DragAnything),我们使用了2D的轨迹控制,在Conv in前添加轨迹控制点,通过轨迹控制点控制物体的运动方向。通过白色高斯图的方式,指定物体的运动方向。 + +参考[CameraCtrl](https://github.com/hehao13/CameraCtrl),我们在Conv in前输入了相机镜头的控制轨迹,该轨迹规定的镜头的运动方向,实现了视频镜头的控制。 + +我们在[EasyAnimate ComfyUI](../comfyui/README.md)中实现了对应的控制方案,感谢[KJ Nodes](https://github.com/kijai/ComfyUI-KJNodes)和[ComfyUI-CameraCtrl-Wrapper](https://github.com/chaojie/ComfyUI-CameraCtrl-Wrapper)中对控制节点的实现。 + +## 使用奖励算法最终优化性能 +为了进一步优化生成视频的质量以更好地对齐人类偏好,我们采用奖励反向传播([DRaFT](https://arxiv.org/abs/2309.17400) 和 [DRTune](https://arxiv.org/abs/2405.00760))对 EasyAnimateV5.1 基础模型进行后训练,使用奖励提升模型的文本一致性与画面的精细程度。 + +我们在[EasyAnimate ComfyUI](../scripts/README_TRAIN_REWARD.md)中详细说明了奖励反向传播的使用方案。 + +## 使用Flow matching作为采样方式 +除了上述的架构变化之外,EasyAnimateV5.1还应用[flow-matching](https://arxiv.org/html/2403.03206v1#S3)的方案来训练模型。在这种方法中,前向噪声过程被定义为在直线上连接数据和噪声分布的整流。 + +修正流匹配采样过程更简单,在减少采样步骤数时表现良好。与[Stable Diffusion 3](https://huggingface.co/stabilityai/stable-diffusion-3-medium/)一致,我们新的调度程序(FlowMatchEulerDiscreteScheduler)作为调度器,其中包含修正流匹配公式和欧拉方法步骤。 + +## 使用更多数据训练 +相比于EasyAnimateV5,EasyAnimateV5.1在训练时,我们添加了约10M的高分辨率数据。 + +EasyAnimateV5.1的训练分为多个阶段,除了图片Adapt VAE的阶段外,其它阶段均为视频训练,分别对应了不同的Token长度。 + +### 1. 图片VAE的对齐 +我们使用了10M的[SAM](https://www.semanticscholar.org/paper/Segment-Anything-Kirillov-Mintun/7470a1702c8c86e6f28d32cfa315381150102f5b)进行模型从0开始的文本图片对齐的训练,总共训练约120K步。 + +在训练完成后,模型已经有能力根据提示词去生成对应的图片,并且图片中的目标基本符合提示词描述。 + +### 2. 视频训练 +视频训练则根据不同Token长度,对视频进行缩放后进行训练。 + +视频训练分为多个阶段,每个阶段的Token长度分别是3328(对应256x256x49的视频),13312(对应512x512x49的视频),53248(对应1024x1024x49的视频)。 + +其中: +- 3328阶段 + - 使用了全部的数据(大约36.6M)训练文生视频模型,Batch size为1024,训练步数约为100k。 +- 13312阶段 + - 使用了720P以上的视频训练(大约27.9M)训练文生视频模型,Batch size为512,训练步数约为60k + - 使用了最高质量的视频训练(大约0.5M)训练图生视频模型 ,Batch size为256,训练步数为5k +- 53248阶段 + - 使用了最高质量的视频训练(大约0.5M)训练图生视频模型,Batch size为256,训练步数为5k。 + +训练时我们采用高低分辨率结合训练,因此模型支持从512到1024任意分辨率的视频生成,以13312 token长度为例: +- 在512x512分辨率下,视频帧数为49; +- 在768x768分辨率下,视频帧数为21; +- 在1024x1024分辨率下,视频帧数为9; +这些分辨率与对应长度混合训练,模型可以完成不同大小分辨率的视频生成。 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 96c58b2..c95e7d9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,5 +22,5 @@ ftfy func_timeout accelerate>=0.25.0 gradio>=3.41.2,<=3.48.0 -diffusers>=0.30.1 -transformers>=4.37.2 +diffusers>=0.30.1,<=0.31.0 +transformers>=4.46.2 diff --git a/scripts/README_TRAIN.md b/scripts/README_TRAIN.md old mode 100644 new mode 100755 index 286aecf..edecd5d --- a/scripts/README_TRAIN.md +++ b/scripts/README_TRAIN.md @@ -8,7 +8,7 @@ Some parameters in the sh file can be confusing, and they are explained in this - `enable_bucket` is used to enable bucket training. When enabled, the model does not crop the images and videos at the center, but instead, it trains the entire images and videos after grouping them into buckets based on resolution. - `random_frame_crop` is used for random cropping on video frames to simulate videos with different frame counts. -- `random_hw_adapt` is used to enable automatic height and width scaling for images and videos. When `random_hw_adapt` is enabled, the training images will have their height and width set to `image_sample_size` as the maximum and `min(video_sample_size, 512)` as the minimum. For training videos, the height and width will be set to `video_sample_size` as the maximum and `min(video_sample_size, 512)` as the minimum. +- `random_hw_adapt` is used to enable automatic height and width scaling for images and videos. When `random_hw_adapt` is enabled, the training images will have their height and width set to `image_sample_size` as the maximum and `min(video_sample_size, 512)` as the minimum. For training videos, the height and width will be set to `image_sample_size` as the maximum and `min(video_sample_size, 512)` as the minimum. - For example, when `random_hw_adapt` is enabled, with `video_sample_n_frames=49`, `video_sample_size=1024`, and `image_sample_size=1024`, the resolution of image inputs for training is `512x512` to `1024x1024`, and the shape of video inputs for training is `512x512x49` to `1024x1024x49`. - For example, when `random_hw_adapt` is enabled, with `video_sample_n_frames=49`, `video_sample_size=1024`, and `image_sample_size=256`, the resolution of image inputs for training is `256x256` to `1024x1024`, and the shape of video inputs for training is `256x256x49`. - `training_with_video_token_length` specifies training the model according to token length. For training images and videos, the height and width will be set to `image_sample_size` as the maximum and `video_sample_size` as the minimum. @@ -22,6 +22,100 @@ Some parameters in the sh file can be confusing, and they are explained in this - `train_mode` is used to specify the training mode, which can be either normal or inpaint. Since EasyAnimate uses the Inpaint model to achieve image-to-video generation, the default is set to inpaint mode. If you only wish to achieve text-to-video generation, you can remove this line, and it will default to the text-to-video mode. - `uniform_sampling` is used to ensure that each batch can be uniformly sampled from 0 to 1000. - The default parameter for training is the Inpaint model. If you only want to train the T2V model, please set train_made="normal" and use the EasyAnimateV5-12b-zh model. +- `loss_type`: The loss type for training. Currently, flow is used in v5.1, ddpm is used in v5 and v4, sigma is used in v3, v2 and v1. + +EasyAnimateV5.1-InP without deepspeed: +```sh +export MODEL_NAME="models/Diffusion_Transformer/EasyAnimateV5.1-12b-zh-InP" +export DATASET_NAME="datasets/internal_datasets/" +export DATASET_META_NAME="datasets/internal_datasets/metadata.json" +export NCCL_IB_DISABLE=1 +export NCCL_P2P_DISABLE=1 +NCCL_DEBUG=INFO + +# When train model with multi machines, use "--config_file accelerate.yaml" instead of "--mixed_precision='bf16'". +accelerate launch --mixed_precision="bf16" scripts/train.py \ + --pretrained_model_name_or_path=$MODEL_NAME \ + --train_data_dir=$DATASET_NAME \ + --train_data_meta=$DATASET_META_NAME \ + --config_path "config/easyanimate_video_v5.1_magvit_qwen.yaml" \ + --image_sample_size=1024 \ + --video_sample_size=256 \ + --token_sample_size=512 \ + --video_sample_stride=3 \ + --video_sample_n_frames=49 \ + --train_batch_size=1 \ + --video_repeat=1 \ + --gradient_accumulation_steps=1 \ + --dataloader_num_workers=8 \ + --num_train_epochs=100 \ + --checkpointing_steps=100 \ + --learning_rate=2e-05 \ + --lr_scheduler="constant_with_warmup" \ + --lr_warmup_steps=100 \ + --seed=42 \ + --output_dir="output_dir" \ + --gradient_checkpointing \ + --mixed_precision="bf16" \ + --adam_weight_decay=5e-3 \ + --adam_epsilon=1e-10 \ + --vae_mini_batch=1 \ + --max_grad_norm=0.05 \ + --random_hw_adapt \ + --training_with_video_token_length \ + --loss_type="flow" \ + --enable_bucket \ + --uniform_sampling \ + --train_mode="inpaint" \ + --trainable_modules "." +``` + +EasyAnimateV5.1-InP with deepspeed: +```sh +export MODEL_NAME="models/Diffusion_Transformer/EasyAnimateV5.1-12b-zh-InP" +export DATASET_NAME="datasets/internal_datasets/" +export DATASET_META_NAME="datasets/internal_datasets/metadata.json" +export NCCL_IB_DISABLE=1 +export NCCL_P2P_DISABLE=1 +NCCL_DEBUG=INFO + +# When train model with multi machines, use "--config_file accelerate.yaml" instead of "--mixed_precision='bf16'". +accelerate launch --use_deepspeed --deepspeed_config_file config/zero_stage2_config.json --deepspeed_multinode_launcher standard scripts/train.py \ + --pretrained_model_name_or_path=$MODEL_NAME \ + --train_data_dir=$DATASET_NAME \ + --train_data_meta=$DATASET_META_NAME \ + --config_path "config/easyanimate_video_v5.1_magvit_qwen.yaml" \ + --image_sample_size=1024 \ + --video_sample_size=256 \ + --token_sample_size=512 \ + --video_sample_stride=3 \ + --video_sample_n_frames=49 \ + --train_batch_size=1 \ + --video_repeat=1 \ + --gradient_accumulation_steps=1 \ + --dataloader_num_workers=8 \ + --num_train_epochs=100 \ + --checkpointing_steps=100 \ + --learning_rate=2e-05 \ + --lr_scheduler="constant_with_warmup" \ + --lr_warmup_steps=100 \ + --seed=42 \ + --output_dir="output_dir" \ + --gradient_checkpointing \ + --mixed_precision="bf16" \ + --adam_weight_decay=5e-3 \ + --adam_epsilon=1e-10 \ + --vae_mini_batch=1 \ + --max_grad_norm=0.05 \ + --random_hw_adapt \ + --training_with_video_token_length \ + --loss_type="flow" \ + --enable_bucket \ + --uniform_sampling \ + --use_deepspeed \ + --train_mode="inpaint" \ + --trainable_modules "." +``` EasyAnimateV5-InP without deepspeed: ```sh @@ -62,7 +156,7 @@ accelerate launch --mixed_precision="bf16" scripts/train.py \ --max_grad_norm=0.05 \ --random_hw_adapt \ --training_with_video_token_length \ - --not_sigma_loss \ + --loss_type="ddpm" \ --enable_bucket \ --uniform_sampling \ --train_mode="inpaint" \ @@ -108,7 +202,7 @@ accelerate launch --use_deepspeed --deepspeed_config_file config/zero_stage2_con --max_grad_norm=0.05 \ --random_hw_adapt \ --training_with_video_token_length \ - --not_sigma_loss \ + --loss_type="ddpm" \ --enable_bucket \ --uniform_sampling \ --use_deepspeed \ @@ -116,7 +210,6 @@ accelerate launch --use_deepspeed --deepspeed_config_file config/zero_stage2_con --trainable_modules "." ``` - <details> <summary>(Obsolete) EasyAnimateV4:</summary> @@ -161,7 +254,7 @@ accelerate launch --mixed_precision="bf16" scripts/train.py \ --random_hw_adapt \ --training_with_video_token_length \ --motion_sub_loss \ - --not_sigma_loss \ + --loss_type="ddpm" \ --random_frame_crop \ --enable_bucket \ --train_mode="inpaint" \ @@ -209,7 +302,7 @@ accelerate launch --use_deepspeed --deepspeed_config_file config/zero_stage2_con --random_hw_adapt \ --training_with_video_token_length \ --motion_sub_loss \ - --not_sigma_loss \ + --loss_type="ddpm" \ --random_frame_crop \ --enable_bucket \ --use_deepspeed \ diff --git a/scripts/README_TRAIN_CONTROL.md b/scripts/README_TRAIN_CONTROL.md old mode 100644 new mode 100755 index 83b3b72..ca4828c --- a/scripts/README_TRAIN_CONTROL.md +++ b/scripts/README_TRAIN_CONTROL.md @@ -28,7 +28,7 @@ Some parameters in the sh file can be confusing, and they are explained in this - `enable_bucket` is used to enable bucket training. When enabled, the model does not crop the images and videos at the center, but instead, it trains the entire images and videos after grouping them into buckets based on resolution. - `random_frame_crop` is used for random cropping on video frames to simulate videos with different frame counts. -- `random_hw_adapt` is used to enable automatic height and width scaling for images and videos. When `random_hw_adapt` is enabled, the training images will have their height and width set to `image_sample_size` as the maximum and `min(video_sample_size, 512)` as the minimum. For training videos, the height and width will be set to `video_sample_size` as the maximum and `min(video_sample_size, 512)` as the minimum. +- `random_hw_adapt` is used to enable automatic height and width scaling for images and videos. When `random_hw_adapt` is enabled, the training images will have their height and width set to `image_sample_size` as the maximum and `min(video_sample_size, 512)` as the minimum. For training videos, the height and width will be set to `image_sample_size` as the maximum and `min(video_sample_size, 512)` as the minimum. - For example, when `random_hw_adapt` is enabled, with `video_sample_n_frames=49`, `video_sample_size=1024`, and `image_sample_size=1024`, the resolution of image inputs for training is `512x512` to `1024x1024`, and the resolution of video inputs for training is `512x512x49` to `1024x1024x49`. - For example, when `random_hw_adapt` is enabled, with `video_sample_n_frames=49`, `video_sample_size=1024`, and `image_sample_size=256`, the resolution of image inputs for training is `256x256` to `1024x1024`, and the resolution of video inputs for training is `256x256x49`. - `training_with_video_token_length` specifies training the model according to token length. For training images and videos, the height and width will be set to `image_sample_size` as the maximum and `video_sample_size` as the minimum. @@ -39,6 +39,102 @@ Some parameters in the sh file can be confusing, and they are explained in this - At 768x768 resolution, the number of video frames is 21 (~= 512 * 512 * 49 / 768 / 768). - At 1024x1024 resolution, the number of video frames is 9 (~= 512 * 512 * 49 / 1024 / 1024). - These resolutions combined with their corresponding lengths allow the model to generate videos of different sizes. +- `loss_type`: The loss type for training. Currently, flow is used in v5.1, ddpm is used in v5 and v4, sigma is used in v3, v2 and v1. + +EasyAnimateV5.1 without deepspeed: +```sh +export MODEL_NAME="models/Diffusion_Transformer/EasyAnimateV5.1-12b-zh-Control" +export DATASET_NAME="datasets/internal_datasets/" +export DATASET_META_NAME="datasets/internal_datasets/metadata.json" +export NCCL_IB_DISABLE=1 +export NCCL_P2P_DISABLE=1 +NCCL_DEBUG=INFO + +# When train model with multi machines, use "--config_file accelerate.yaml" instead of "--mixed_precision='bf16'". +accelerate launch --mixed_precision="bf16" scripts/train_control.py \ + --pretrained_model_name_or_path=$MODEL_NAME \ + --train_data_dir=$DATASET_NAME \ + --train_data_meta=$DATASET_META_NAME \ + --config_path "config/easyanimate_video_v5.1_magvit_qwen.yaml" \ + --image_sample_size=1024 \ + --video_sample_size=256 \ + --token_sample_size=512 \ + --video_sample_stride=3 \ + --video_sample_n_frames=49 \ + --train_batch_size=1 \ + --video_repeat=1 \ + --gradient_accumulation_steps=1 \ + --dataloader_num_workers=8 \ + --num_train_epochs=100 \ + --checkpointing_steps=100 \ + --learning_rate=2e-05 \ + --lr_scheduler="constant_with_warmup" \ + --lr_warmup_steps=100 \ + --seed=42 \ + --output_dir="output_dir" \ + --gradient_checkpointing \ + --mixed_precision="bf16" \ + --adam_weight_decay=5e-3 \ + --adam_epsilon=1e-10 \ + --vae_mini_batch=1 \ + --max_grad_norm=0.05 \ + --random_hw_adapt \ + --training_with_video_token_length \ + --enable_bucket \ + --uniform_sampling \ + --loss_type="flow" \ + --train_mode="control_ref" \ + --control_ref_image="first_frame" \ + --trainable_modules "." +``` + +EasyAnimateV5.1 with deepspeed: +```sh +export MODEL_NAME="models/Diffusion_Transformer/EasyAnimateV5.1-12b-zh-Control" +export DATASET_NAME="datasets/internal_datasets/" +export DATASET_META_NAME="datasets/internal_datasets/metadata.json" +export NCCL_IB_DISABLE=1 +export NCCL_P2P_DISABLE=1 +NCCL_DEBUG=INFO + +# When train model with multi machines, use "--config_file accelerate.yaml" instead of "--mixed_precision='bf16'". +accelerate launch --use_deepspeed --deepspeed_config_file config/zero_stage2_config.json --deepspeed_multinode_launcher standard scripts/train_control.py \ + --pretrained_model_name_or_path=$MODEL_NAME \ + --train_data_dir=$DATASET_NAME \ + --train_data_meta=$DATASET_META_NAME \ + --config_path "config/easyanimate_video_v5.1_magvit_qwen.yaml" \ + --image_sample_size=1024 \ + --video_sample_size=256 \ + --token_sample_size=512 \ + --video_sample_stride=3 \ + --video_sample_n_frames=49 \ + --train_batch_size=1 \ + --video_repeat=1 \ + --gradient_accumulation_steps=1 \ + --dataloader_num_workers=8 \ + --num_train_epochs=100 \ + --checkpointing_steps=100 \ + --learning_rate=2e-05 \ + --lr_scheduler="constant_with_warmup" \ + --lr_warmup_steps=100 \ + --seed=42 \ + --output_dir="output_dir" \ + --gradient_checkpointing \ + --mixed_precision="bf16" \ + --adam_weight_decay=5e-3 \ + --adam_epsilon=1e-10 \ + --vae_mini_batch=1 \ + --max_grad_norm=0.05 \ + --random_hw_adapt \ + --training_with_video_token_length \ + --enable_bucket \ + --uniform_sampling \ + --loss_type="flow" \ + --train_mode="control_ref" \ + --control_ref_image="first_frame" \ + --use_deepspeed \ + --trainable_modules "." +``` EasyAnimateV5 without deepspeed: ```sh @@ -79,7 +175,7 @@ accelerate launch --mixed_precision="bf16" scripts/train_control.py \ --max_grad_norm=0.05 \ --random_hw_adapt \ --training_with_video_token_length \ - --not_sigma_loss \ + --loss_type="ddpm" \ --enable_bucket \ --uniform_sampling \ --trainable_modules "." @@ -124,7 +220,7 @@ accelerate launch --use_deepspeed --deepspeed_config_file config/zero_stage2_con --max_grad_norm=0.05 \ --random_hw_adapt \ --training_with_video_token_length \ - --not_sigma_loss \ + --loss_type="ddpm" \ --enable_bucket \ --uniform_sampling \ --use_deepspeed \ diff --git a/scripts/README_TRAIN_LORA.md b/scripts/README_TRAIN_LORA.md old mode 100644 new mode 100755 index c9a5711..c66ba80 --- a/scripts/README_TRAIN_LORA.md +++ b/scripts/README_TRAIN_LORA.md @@ -8,7 +8,7 @@ Some parameters in the sh file can be confusing, and they are explained in this - `enable_bucket` is used to enable bucket training. When enabled, the model does not crop the images and videos at the center, but instead, it trains the entire images and videos after grouping them into buckets based on resolution. - `random_frame_crop` is used for random cropping on video frames to simulate videos with different frame counts. -- `random_hw_adapt` is used to enable automatic height and width scaling for images and videos. When `random_hw_adapt` is enabled, the training images will have their height and width set to `image_sample_size` as the maximum and `min(video_sample_size, 512)` as the minimum. For training videos, the height and width will be set to `video_sample_size` as the maximum and `min(video_sample_size, 512)` as the minimum. +- `random_hw_adapt` is used to enable automatic height and width scaling for images and videos. When `random_hw_adapt` is enabled, the training images will have their height and width set to `image_sample_size` as the maximum and `min(video_sample_size, 512)` as the minimum. For training videos, the height and width will be set to `image_sample_size` as the maximum and `min(video_sample_size, 512)` as the minimum. - For example, when `random_hw_adapt` is enabled, with `video_sample_n_frames=49`, `video_sample_size=1024`, and `image_sample_size=1024`, the resolution of image inputs for training is `512x512` to `1024x1024`, and the resolution of video inputs for training is `512x512x49` to `1024x1024x49`. - For example, when `random_hw_adapt` is enabled, with `video_sample_n_frames=49`, `video_sample_size=1024`, and `image_sample_size=256`, the resolution of image inputs for training is `256x256` to `1024x1024`, and the resolution of video inputs for training is `256x256x49`. - `training_with_video_token_length` specifies training the model according to token length. For training images and videos, the height and width will be set to `image_sample_size` as the maximum and `video_sample_size` as the minimum. @@ -22,6 +22,96 @@ Some parameters in the sh file can be confusing, and they are explained in this - `train_mode` is used to specify the training mode, which can be either normal or inpaint. Since EasyAnimate uses the Inpaint model to achieve image-to-video generation, the default is set to inpaint mode. If you only wish to achieve text-to-video generation, you can remove this line, and it will default to the text-to-video mode. - `uniform_sampling` is used to ensure that each batch can be uniformly sampled from 0 to 1000. - The default parameter for training is the Inpaint model. If you only want to train the T2V model, please set train_made="normal" and use the EasyAnimateV5-12b-zh model. +- `loss_type`: The loss type for training. Currently, flow is used in v5.1, ddpm is used in v5 and v4, sigma is used in v3, v2 and v1. + +EasyAnimateV5.1-InP without deepspeed: +```sh +export MODEL_NAME="models/Diffusion_Transformer/EasyAnimateV5.1-12b-zh-InP" +export DATASET_NAME="datasets/internal_datasets/" +export DATASET_META_NAME="datasets/internal_datasets/metadata.json" +export NCCL_IB_DISABLE=1 +export NCCL_P2P_DISABLE=1 +NCCL_DEBUG=INFO + +# When train model with multi machines, use "--config_file accelerate.yaml" instead of "--mixed_precision='bf16'". +accelerate launch --mixed_precision="bf16" scripts/train_lora.py \ + --pretrained_model_name_or_path=$MODEL_NAME \ + --train_data_dir=$DATASET_NAME \ + --train_data_meta=$DATASET_META_NAME \ + --config_path "config/easyanimate_video_v5.1_magvit_qwen.yaml" \ + --image_sample_size=1024 \ + --video_sample_size=256 \ + --token_sample_size=512 \ + --video_sample_stride=3 \ + --video_sample_n_frames=49 \ + --train_batch_size=1 \ + --video_repeat=1 \ + --gradient_accumulation_steps=1 \ + --dataloader_num_workers=8 \ + --num_train_epochs=100 \ + --checkpointing_steps=100 \ + --learning_rate=1e-04 \ + --seed=42 \ + --low_vram \ + --output_dir="output_dir" \ + --gradient_checkpointing \ + --mixed_precision="bf16" \ + --adam_weight_decay=5e-3 \ + --adam_epsilon=1e-10 \ + --vae_mini_batch=1 \ + --max_grad_norm=0.05 \ + --random_hw_adapt \ + --training_with_video_token_length \ + --loss_type="flow" \ + --enable_bucket \ + --uniform_sampling \ + --train_mode="inpaint" +``` + +EasyAnimateV5.1-InP with deepspeed: +```sh +export MODEL_NAME="models/Diffusion_Transformer/EasyAnimateV5.1-12b-zh-InP" +export DATASET_NAME="datasets/internal_datasets/" +export DATASET_META_NAME="datasets/internal_datasets/metadata.json" +export NCCL_IB_DISABLE=1 +export NCCL_P2P_DISABLE=1 +NCCL_DEBUG=INFO + +# When train model with multi machines, use "--config_file accelerate.yaml" instead of "--mixed_precision='bf16'". +accelerate launch --use_deepspeed --deepspeed_config_file config/zero_stage2_config.json --deepspeed_multinode_launcher standard scripts/train_lora.py \ + --pretrained_model_name_or_path=$MODEL_NAME \ + --train_data_dir=$DATASET_NAME \ + --train_data_meta=$DATASET_META_NAME \ + --config_path "config/easyanimate_video_v5.1_magvit_qwen.yaml" \ + --image_sample_size=1024 \ + --video_sample_size=256 \ + --token_sample_size=512 \ + --video_sample_stride=3 \ + --video_sample_n_frames=49 \ + --train_batch_size=1 \ + --video_repeat=1 \ + --gradient_accumulation_steps=1 \ + --dataloader_num_workers=8 \ + --num_train_epochs=100 \ + --checkpointing_steps=100 \ + --learning_rate=1e-04 \ + --seed=42 \ + --low_vram \ + --output_dir="output_dir" \ + --gradient_checkpointing \ + --mixed_precision="bf16" \ + --adam_weight_decay=5e-3 \ + --adam_epsilon=1e-10 \ + --vae_mini_batch=1 \ + --max_grad_norm=0.05 \ + --random_hw_adapt \ + --training_with_video_token_length \ + --loss_type="flow" \ + --enable_bucket \ + --use_deepspeed \ + --uniform_sampling \ + --train_mode="inpaint" +``` EasyAnimateV5-InP without deepspeed: ```sh @@ -61,7 +151,7 @@ accelerate launch --mixed_precision="bf16" scripts/train_lora.py \ --max_grad_norm=0.05 \ --random_hw_adapt \ --training_with_video_token_length \ - --not_sigma_loss \ + --loss_type="ddpm" \ --enable_bucket \ --uniform_sampling \ --train_mode="inpaint" @@ -105,7 +195,7 @@ accelerate launch --use_deepspeed --deepspeed_config_file config/zero_stage2_con --max_grad_norm=0.05 \ --random_hw_adapt \ --training_with_video_token_length \ - --not_sigma_loss \ + --loss_type="ddpm" \ --enable_bucket \ --use_deepspeed \ --uniform_sampling \ @@ -153,7 +243,7 @@ accelerate launch --mixed_precision="bf16" scripts/train_lora.py \ --max_grad_norm=0.05 \ --random_hw_adapt \ --motion_sub_loss \ - --not_sigma_loss \ + --loss_type="ddpm" \ --enable_bucket \ --train_mode="inpaint" ``` @@ -196,7 +286,7 @@ accelerate launch --use_deepspeed --deepspeed_config_file config/zero_stage2_con --max_grad_norm=0.05 \ --random_hw_adapt \ --motion_sub_loss \ - --not_sigma_loss \ + --loss_type="ddpm" \ --enable_bucket \ --use_deepspeed \ --train_mode="inpaint" diff --git a/scripts/README_TRAIN_REWARD.md b/scripts/README_TRAIN_REWARD.md index e9c2873..db8085b 100644 --- a/scripts/README_TRAIN_REWARD.md +++ b/scripts/README_TRAIN_REWARD.md @@ -2,6 +2,9 @@ We explore the Reward Backpropagation technique <sup>[1](#ref1) [2](#ref2)</sup> to optimized the generated videos by [EasyAnimateV5](https://github.com/aigc-apps/EasyAnimate/tree/main/easyanimate) for better alignment with human preferences. We provide pre-trained models (i.e. LoRAs) along with the training script. You can use these LoRAs to enhance the corresponding base model as a plug-in or train your own reward LoRA. +> [!NOTE] +> For EasyAnimateV5.1, we have merged the reward LoRAs into the base model. Please use the base model directly. + - [Enhance EasyAnimate with Reward Backpropagation (Preference Optimization)](#enhance-easyanimate-with-reward-backpropagation-preference-optimization) - [Demo](#demo) - [EasyAnimateV5-12b-zh-InP](#easyanimatev5-12b-zh-inp) @@ -175,7 +178,7 @@ from omegaconf import OmegaConf from transformers import BertModel, BertTokenizer, T5EncoderModel, T5Tokenizer from easyanimate.models import AutoencoderKLMagvit, EasyAnimateTransformer3DModel -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder_inpaint import EasyAnimatePipeline_Multi_Text_Encoder_Inpaint +from easyanimate.pipeline.pipeline_easyanimate_inpaint import EasyAnimateInpaintPipeline from easyanimate.utils.lora_utils import merge_lora from easyanimate.utils.utils import get_image_to_video_latent, save_videos_grid from easyanimate.utils.fp8_optimization import convert_weight_dtype_wrapper @@ -210,7 +213,7 @@ vae = AutoencoderKLMagvit.from_pretrained( if config['vae_kwargs'].get('vae_type', 'AutoencoderKL') == 'AutoencoderKLMagvit' and weight_dtype == torch.float16: vae.upcast_vae = True -pipeline = EasyAnimatePipeline_Multi_Text_Encoder_Inpaint.from_pretrained( +pipeline = EasyAnimateInpaintPipeline.from_pretrained( model_path, text_encoder=BertModel.from_pretrained(model_path, subfolder="text_encoder").to(weight_dtype), text_encoder_2=T5EncoderModel.from_pretrained(model_path, subfolder="text_encoder_2").to(weight_dtype), @@ -243,7 +246,7 @@ sample = pipeline( num_inference_steps = 50, video = input_video, mask_video = input_video_mask, -).videos +).frames save_videos_grid(sample, "samples/output.mp4", fps=8) ``` @@ -282,18 +285,22 @@ Due to the resize and crop preprocessing operations, we suggest using a 1:1 aspe can be found in [reward_fn.py](../cogvideox/reward/reward_fn.py). You can also customize your own reward model (e.g., combining aesthetic predictor with HPS). + `num_decoded_latents` and `num_sampled_frames`: The number of decoded latents (for VAE) and sampled frames (for the reward model). -Since CogVideoX-Fun adopts the 3D casual VAE, we found decoding only the first latent to obtain the first frame for computing the reward -not only reduces training memory usage but also prevents excessive reward optimization and maintains the dynamics of generated videos. +Since EasyAnimate adopts the 3D casual VAE, we found decoding only the first latent to obtain the first frame for computing the reward +not only reduces training GPU memory usage but also prevents excessive reward optimization and maintains the dynamics of generated videos. + +> [!NOTE] +> In EasyAnimateV5, we only retained the gradient of the last step in the denoising process to reduce GPU memory usage. However, for V5.1, we found that if we only perform reward backpropagation on the last step, the gradient norm becomes very small (usually below 0.001), making it difficult for reward training to converge. This might be due to V5.1 adopts the flow-matching sampling in the training and inference. Therefore, in pratice, we retain the gradients of the last several steps for V5.1. ## Limitations 1. We observe after training to a certain extent, the reward continues to increase, but the quality of the generated videos does not further improve. - The model trickly learns some shortcuts (by adding artifacts in the background, i.e., adversarial patches) to increase the reward. + The model trickly learns some shortcuts (by adding artifacts in the background, i.e., reward hacking) to increase the reward. 2. Currently, there is still a lack of suitable preference models for video generation. Directly using image preference models cannot evaluate preferences along the temporal dimension (such as dynamism and consistency). Further more, We find using image preference models leads to a decrease in the dynamism of generated videos. Although this can be mitigated by computing the reward using only the first frame of the decoded video, the impact still persists. ## References <ol> - <li id="ref1">Clark, Kevin, et al. "Directly fine-tuning diffusion models on differentiable rewards.". In ICLR 2024.</li> - <li id="ref2">Prabhudesai, Mihir, et al. "Aligning text-to-image diffusion models with reward backpropagation." arXiv preprint arXiv:2310.03739 (2023).</li> + <li id="ref1">Wu, Xiaoshi, et al. "Deep reward supervisions for tuning text-to-image diffusion models." In ECCV 2025.</li> + <li id="ref2">Clark, Kevin, et al. "Directly fine-tuning diffusion models on differentiable rewards.". In ICLR 2024.</li> + <li id="ref3">Prabhudesai, Mihir, et al. "Aligning text-to-image diffusion models with reward backpropagation." arXiv preprint arXiv:2310.03739 (2023).</li> </ol> \ No newline at end of file diff --git a/scripts/train.py b/scripts/train.py index 10b2ca7..20199f3 100644 --- a/scripts/train.py +++ b/scripts/train.py @@ -35,9 +35,14 @@ from accelerate import Accelerator from accelerate.logging import get_logger from accelerate.state import AcceleratorState from accelerate.utils import ProjectConfiguration, set_seed -from diffusers import AutoencoderKL, DDPMScheduler +from diffusers import (DDIMScheduler, DDPMScheduler, + FlowMatchEulerDiscreteScheduler) from diffusers.optimization import get_scheduler -from diffusers.training_utils import EMAModel +from diffusers.training_utils import (EMAModel, + _set_state_dict_into_text_encoder, + cast_training_params, + compute_density_for_timestep_sampling, + compute_loss_weighting_for_sd3) from diffusers.utils import check_min_version, deprecate, is_wandb_available from diffusers.utils.import_utils import is_xformers_available from diffusers.utils.torch_utils import is_compiled_module @@ -50,9 +55,11 @@ from torch.utils.data import RandomSampler from torch.utils.tensorboard import SummaryWriter from torchvision import transforms from tqdm.auto import tqdm -from transformers import (BertModel, BertTokenizer, CLIPImageProcessor, +from transformers import (Qwen2Tokenizer, AutoTokenizer, BertModel, + BertTokenizer, CLIPImageProcessor, CLIPVisionModelWithProjection, - T5EncoderModel, T5Tokenizer) + Qwen2VLForConditionalGeneration, T5EncoderModel, + T5Tokenizer) from transformers.utils import ContextManagers import datasets @@ -74,13 +81,11 @@ from easyanimate.data.dataset_image_video import (ImageVideoDataset, from easyanimate.models import (name_to_autoencoder_magvit, name_to_transformer3d) from easyanimate.pipeline.pipeline_easyanimate import EasyAnimatePipeline -from easyanimate.pipeline.pipeline_easyanimate_inpaint import \ - EasyAnimateInpaintPipeline -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder import ( - EasyAnimatePipeline_Multi_Text_Encoder, get_2d_rotary_pos_embed, +from easyanimate.pipeline.pipeline_easyanimate import ( + EasyAnimatePipeline, get_2d_rotary_pos_embed, get_3d_rotary_pos_embed, get_resize_crop_region_for_grid) -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder_inpaint import ( - EasyAnimatePipeline_Multi_Text_Encoder_Inpaint, +from easyanimate.pipeline.pipeline_easyanimate_inpaint import ( + EasyAnimateInpaintPipeline, add_noise_to_reference_video, resize_mask) from easyanimate.utils import gaussian_diffusion as gd from easyanimate.utils.discrete_sampler import DiscreteSampling @@ -132,39 +137,76 @@ def encode_prompt( add_special_tokens = False, enable_text_attention_mask = True, ): - if max_sequence_length is None: - max_length = min(tokenizer.model_max_length, tokenizer_max_length) - else: - max_length = max_sequence_length + if type(tokenizer) in [BertTokenizer, T5Tokenizer]: + if max_sequence_length is None: + max_length = min(tokenizer.model_max_length, tokenizer_max_length) + else: + max_length = max_sequence_length - text_inputs = tokenizer( - prompt, - padding="max_length", - max_length=max_length, - truncation=True, - return_attention_mask=True, - add_special_tokens=add_special_tokens, - return_tensors="pt", - ) - - if device is not None: - text_input_ids = text_inputs.input_ids.to(device) - prompt_attention_mask = text_inputs.attention_mask.to(device) + text_inputs = tokenizer( + prompt, + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + add_special_tokens=add_special_tokens, + return_tensors="pt", + ) + if device is not None: + text_input_ids = text_inputs.input_ids.to(device) + prompt_attention_mask = text_inputs.attention_mask.to(device) + else: + text_input_ids = text_inputs.input_ids + prompt_attention_mask = text_inputs.attention_mask + + if enable_text_attention_mask: + prompt_embeds = text_encoder( + text_input_ids, + attention_mask=prompt_attention_mask, + )[0] + else: + prompt_embeds = text_encoder( + text_input_ids + )[0] + prompt_embeds = prompt_embeds.to(dtype=dtype, device=device) + prompt_attention_mask = prompt_attention_mask.to(dtype=dtype, device=device) else: + max_length = tokenizer_max_length + texts = [] + for _prompt in prompt: + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": _prompt}], + } + ] + text = tokenizer.apply_chat_template( + messages, tokenize=False, add_generation_prompt=True + ) + texts.append(text) + text_inputs = tokenizer( + text=texts, + images=None, + videos=None, + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + padding_side="right", + return_tensors="pt", + ) + text_inputs = text_inputs.to(text_encoder.device) + text_input_ids = text_inputs.input_ids prompt_attention_mask = text_inputs.attention_mask - - if enable_text_attention_mask: - prompt_embeds = text_encoder( - text_input_ids, - attention_mask=prompt_attention_mask, - )[0] - else: - prompt_embeds = text_encoder( - text_input_ids - )[0] - prompt_embeds = prompt_embeds.to(dtype=dtype, device=device) - prompt_attention_mask = prompt_attention_mask.to(dtype=dtype, device=device) + if enable_text_attention_mask: + # Inference: Generation of the output + prompt_embeds = text_encoder( + input_ids=text_input_ids, + attention_mask=prompt_attention_mask, + output_hidden_states=True).hidden_states[-2] + else: + raise ValueError("LLM needs attention_mask") return prompt_embeds, prompt_attention_mask def get_random_downsample_ratio(sample_size, image_ratio=[], all_choices=False, rng=None): @@ -220,54 +262,41 @@ def log_validation( transformer_additional_kwargs=OmegaConf.to_container(config['transformer_additional_kwargs']) ).to(weight_dtype) transformer3d_val.load_state_dict(accelerator.unwrap_model(transformer3d).state_dict()) - - if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): - if args.train_mode != "normal": - pipeline = EasyAnimatePipeline_Multi_Text_Encoder_Inpaint.from_pretrained( - args.pretrained_model_name_or_path, - vae=accelerator.unwrap_model(vae).to(weight_dtype), - text_encoder=accelerator.unwrap_model(text_encoder), - text_encoder_2=accelerator.unwrap_model(text_encoder_2), - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - transformer=transformer3d_val, - torch_dtype=weight_dtype, - clip_image_encoder=image_encoder, - clip_image_processor=image_processor, - ) - else: - pipeline = EasyAnimatePipeline_Multi_Text_Encoder.from_pretrained( - args.pretrained_model_name_or_path, - vae=accelerator.unwrap_model(vae).to(weight_dtype), - text_encoder=accelerator.unwrap_model(text_encoder), - text_encoder_2=accelerator.unwrap_model(text_encoder_2), - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - transformer=transformer3d_val, - torch_dtype=weight_dtype - ) + + if args.loss_type == "flow": + scheduler = FlowMatchEulerDiscreteScheduler.from_pretrained( + args.pretrained_model_name_or_path, + subfolder="scheduler" + ) else: - if args.train_mode != "normal": - pipeline = EasyAnimateInpaintPipeline.from_pretrained( - args.pretrained_model_name_or_path, - vae=accelerator.unwrap_model(vae).to(weight_dtype), - text_encoder=accelerator.unwrap_model(text_encoder), - tokenizer=tokenizer, - transformer=transformer3d_val, - torch_dtype=weight_dtype, - clip_image_encoder=image_encoder, - clip_image_processor=image_processor, - ) - else: - pipeline = EasyAnimatePipeline.from_pretrained( - args.pretrained_model_name_or_path, - vae=accelerator.unwrap_model(vae).to(weight_dtype), - text_encoder=accelerator.unwrap_model(text_encoder), - tokenizer=tokenizer, - transformer=transformer3d_val, - torch_dtype=weight_dtype - ) - pipeline = pipeline.to(accelerator.device) + scheduler = DDIMScheduler.from_pretrained( + args.pretrained_model_name_or_path, + subfolder="scheduler" + ) + + if args.train_mode != "normal": + pipeline = EasyAnimateInpaintPipeline( + vae=accelerator.unwrap_model(vae).to(weight_dtype), + text_encoder=accelerator.unwrap_model(text_encoder), + text_encoder_2=accelerator.unwrap_model(text_encoder_2), + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + transformer=transformer3d_val, + scheduler=scheduler, + clip_image_encoder=image_encoder, + clip_image_processor=image_processor, + ) + else: + pipeline = EasyAnimatePipeline( + vae=accelerator.unwrap_model(vae).to(weight_dtype), + text_encoder=accelerator.unwrap_model(text_encoder), + text_encoder_2=accelerator.unwrap_model(text_encoder_2), + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + transformer=transformer3d_val, + scheduler=scheduler, + ) + pipeline = pipeline.to(weight_dtype, accelerator.device) if args.enable_xformers_memory_efficient_attention \ and config['transformer_additional_kwargs'].get('transformer_type', 'Transformer3DModel') == 'Transformer3DModel': @@ -298,7 +327,7 @@ def log_validation( video = input_video, mask_video = input_video_mask, clip_image = clip_image, - ).videos + ).frames os.makedirs(os.path.join(args.output_dir, "sample"), exist_ok=True) save_videos_grid(sample, os.path.join(args.output_dir, f"sample/sample-{global_step}-{i}.gif")) @@ -315,7 +344,7 @@ def log_validation( video = input_video, mask_video = input_video_mask, clip_image = clip_image, - ).videos + ).frames os.makedirs(os.path.join(args.output_dir, "sample"), exist_ok=True) save_videos_grid(sample, os.path.join(args.output_dir, f"sample/sample-{global_step}-image-{i}.gif")) else: @@ -327,7 +356,7 @@ def log_validation( height = args.video_sample_size, width = args.video_sample_size, generator = generator - ).videos + ).frames os.makedirs(os.path.join(args.output_dir, "sample"), exist_ok=True) save_videos_grid(sample, os.path.join(args.output_dir, f"sample/sample-{global_step}-{i}.gif")) @@ -338,7 +367,7 @@ def log_validation( height = args.video_sample_size, width = args.video_sample_size, generator = generator - ).videos + ).frames os.makedirs(os.path.join(args.output_dir, "sample"), exist_ok=True) save_videos_grid(sample, os.path.join(args.output_dir, f"sample/sample-{global_step}-image-{i}.gif")) @@ -641,7 +670,13 @@ def parse_args(): "--uniform_sampling", action="store_true", help="Whether or not to use uniform_sampling." ) parser.add_argument( - "--not_sigma_loss", action="store_true", help="Whether or not to not use sigma_loss." + "--loss_type", + type=str, + default="sigma", + help=( + 'The format of training data. Support `"sigma"`' + ' (default), `"ddpm"`, `"flow"`.' + ), ) parser.add_argument( "--enable_text_encoder_in_dataloader", action="store_true", help="Whether or not to use text encoder in dataloader." @@ -790,6 +825,26 @@ def parse_args(): ), ) + parser.add_argument( + "--weighting_scheme", + type=str, + default="none", + choices=["sigma_sqrt", "logit_normal", "mode", "cosmap", "none"], + help=('We default to the "none" weighting scheme for uniform sampling and uniform loss'), + ) + parser.add_argument( + "--logit_mean", type=float, default=0.0, help="mean to use when using the `'logit_normal'` weighting scheme." + ) + parser.add_argument( + "--logit_std", type=float, default=1.0, help="std to use when using the `'logit_normal'` weighting scheme." + ) + parser.add_argument( + "--mode_scale", + type=float, + default=1.29, + help="Scale of mode weighting scheme. Only effective when using the `'mode'` as the `weighting_scheme`.", + ) + args = parser.parse_args() env_local_rank = int(os.environ.get("LOCAL_RANK", -1)) if env_local_rank != -1 and env_local_rank != args.local_rank: @@ -877,8 +932,10 @@ def main(): args.mixed_precision = accelerator.mixed_precision # Load scheduler, tokenizer and models. - if args.not_sigma_loss: + if args.loss_type == "ddpm": noise_scheduler = DDPMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler") + elif args.loss_type == "flow": + noise_scheduler = FlowMatchEulerDiscreteScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler") else: train_diffusion = SpacedDiffusion( use_timesteps=space_timesteps(1000, str(args.train_sampling_steps)), betas=gd.get_named_beta_schedule("linear", 1000), @@ -891,15 +948,27 @@ def main(): tokenizer = BertTokenizer.from_pretrained( args.pretrained_model_name_or_path, subfolder="tokenizer", revision=args.revision ) - print("Init T5Tokenizer") - tokenizer_2 = T5Tokenizer.from_pretrained( - args.pretrained_model_name_or_path, subfolder="tokenizer_2", revision=args.revision - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + print("Init LLM Processor") + tokenizer_2 = Qwen2Tokenizer.from_pretrained( + os.path.join(args.pretrained_model_name_or_path, "tokenizer_2"), revision=args.revision + ) + else: + print("Init T5Tokenizer") + tokenizer_2 = T5Tokenizer.from_pretrained( + args.pretrained_model_name_or_path, subfolder="tokenizer_2", revision=args.revision + ) else: - print("Init T5Tokenizer") - tokenizer = T5Tokenizer.from_pretrained( - args.pretrained_model_name_or_path, subfolder="tokenizer", revision=args.revision - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + print("Init LLM Processor") + tokenizer = Qwen2Tokenizer.from_pretrained( + os.path.join(args.pretrained_model_name_or_path, "tokenizer"), revision=args.revision + ) + else: + print("Init T5Tokenizer") + tokenizer = T5Tokenizer.from_pretrained( + args.pretrained_model_name_or_path, subfolder="tokenizer", revision=args.revision + ) tokenizer_2 = None def deepspeed_zero_init_disabled_context_manager(): @@ -927,15 +996,27 @@ def main(): args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision, variant=args.variant, torch_dtype=weight_dtype ) - text_encoder_2 = T5EncoderModel.from_pretrained( - args.pretrained_model_name_or_path, subfolder="text_encoder_2", revision=args.revision, variant=args.variant, - torch_dtype=weight_dtype - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder_2 = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(args.pretrained_model_name_or_path, "text_encoder_2"), revision=args.revision, variant=args.variant, + torch_dtype=weight_dtype, + ) + else: + text_encoder_2 = T5EncoderModel.from_pretrained( + args.pretrained_model_name_or_path, subfolder="text_encoder_2", revision=args.revision, variant=args.variant, + torch_dtype=weight_dtype, + ) else: - text_encoder = T5EncoderModel.from_pretrained( - args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision, variant=args.variant, - torch_dtype=weight_dtype - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(args.pretrained_model_name_or_path, "text_encoder"), revision=args.revision, variant=args.variant, + torch_dtype=weight_dtype, + ) + else: + text_encoder = T5EncoderModel.from_pretrained( + args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision, variant=args.variant, + torch_dtype=weight_dtype + ) text_encoder_2 = None # Get Vae @@ -1483,38 +1564,71 @@ def main(): # Potentially load in the weights and states from a previous save if args.resume_from_checkpoint: - if args.resume_from_checkpoint != "latest": - path = os.path.basename(args.resume_from_checkpoint) - else: - # Get the most recent checkpoint - dirs = os.listdir(args.output_dir) - dirs = [d for d in dirs if d.startswith("checkpoint")] - dirs = sorted(dirs, key=lambda x: int(x.split("-")[1])) - path = dirs[-1] if len(dirs) > 0 else None - - if path is None: - accelerator.print( - f"Checkpoint '{args.resume_from_checkpoint}' does not exist. Starting a new training run." - ) - args.resume_from_checkpoint = None - initial_global_step = 0 - else: - global_step = int(path.split("-")[1]) - - initial_global_step = global_step - - pkl_path = os.path.join(os.path.join(args.output_dir, path), "sampler_pos_start.pkl") - if os.path.exists(pkl_path): - with open(pkl_path, 'rb') as file: - _, first_epoch = pickle.load(file) + try: + if args.resume_from_checkpoint != "latest": + path = os.path.basename(args.resume_from_checkpoint) else: - first_epoch = global_step // num_update_steps_per_epoch - print(f"Load pkl from {pkl_path}. Get first_epoch = {first_epoch}.") + # Get the most recent checkpoint + dirs = os.listdir(args.output_dir) + dirs = [d for d in dirs if d.startswith("checkpoint")] + dirs = sorted(dirs, key=lambda x: int(x.split("-")[1])) + path = dirs[-1] if len(dirs) > 0 else None - accelerator.print(f"Resuming from checkpoint {path}") - accelerator.load_state(os.path.join(args.output_dir, path)) + if path is None: + accelerator.print( + f"Checkpoint '{args.resume_from_checkpoint}' does not exist. Starting a new training run." + ) + args.resume_from_checkpoint = None + initial_global_step = 0 + else: + global_step = int(path.split("-")[1]) + + initial_global_step = global_step + + pkl_path = os.path.join(os.path.join(args.output_dir, path), "sampler_pos_start.pkl") + if os.path.exists(pkl_path): + with open(pkl_path, 'rb') as file: + _, first_epoch = pickle.load(file) + else: + first_epoch = global_step // num_update_steps_per_epoch + print(f"Load pkl from {pkl_path}. Get first_epoch = {first_epoch}.") + + accelerator.print(f"Resuming from checkpoint {path}") + accelerator.load_state(os.path.join(args.output_dir, path)) + except: + if args.resume_from_checkpoint != "latest": + path = os.path.basename(args.resume_from_checkpoint) + else: + # Get the most recent checkpoint + dirs = os.listdir(args.output_dir) + dirs = [d for d in dirs if d.startswith("checkpoint")] + dirs = sorted(dirs, key=lambda x: int(x.split("-")[1])) + path = dirs[-2] if len(dirs) > 0 else None + + if path is None: + accelerator.print( + f"Checkpoint '{args.resume_from_checkpoint}' does not exist. Starting a new training run." + ) + args.resume_from_checkpoint = None + initial_global_step = 0 + else: + global_step = int(path.split("-")[1]) + + initial_global_step = global_step + + pkl_path = os.path.join(os.path.join(args.output_dir, path), "sampler_pos_start.pkl") + if os.path.exists(pkl_path): + with open(pkl_path, 'rb') as file: + _, first_epoch = pickle.load(file) + else: + first_epoch = global_step // num_update_steps_per_epoch + print(f"Load pkl from {pkl_path}. Get first_epoch = {first_epoch}.") + + accelerator.print(f"Resuming from checkpoint {path}") + accelerator.load_state(os.path.join(args.output_dir, path)) else: - initial_global_step = 0 + global_step = 0 + initial_global_step = global_step progress_bar = tqdm( range(0, args.max_train_steps), @@ -1841,8 +1955,8 @@ def main(): # timesteps = torch.randint(0, args.train_sampling_steps, (bsz,), device=latents.device, generator=torch_rng) timesteps = idx_sampling(bsz, generator=torch_rng, device=latents.device) timesteps = timesteps.long() - - if args.not_sigma_loss: + + if args.loss_type != "sigma": # Create image_rotary_emb, style embedding & time ids height, width = batch["pixel_values"].size()[-2], batch["pixel_values"].size()[-1] @@ -1886,14 +2000,44 @@ def main(): ) style = style.to(device=latents.device).repeat(bsz) - # Add noise - noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) - if noise_scheduler.config.prediction_type == "epsilon": - target = noise - elif noise_scheduler.config.prediction_type == "v_prediction": - target = noise_scheduler.get_velocity(latents, noise, timesteps) + if args.loss_type == "ddpm": + # Add noise + noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) + if noise_scheduler.config.prediction_type == "epsilon": + target = noise + elif noise_scheduler.config.prediction_type == "v_prediction": + target = noise_scheduler.get_velocity(latents, noise, timesteps) + else: + raise ValueError(f"Unknown prediction type {noise_scheduler.config.prediction_type}") else: - raise ValueError(f"Unknown prediction type {noise_scheduler.config.prediction_type}") + def get_sigmas(timesteps, n_dim=4, dtype=torch.float32): + sigmas = noise_scheduler.sigmas.to(device=accelerator.device, dtype=dtype) + schedule_timesteps = noise_scheduler.timesteps.to(accelerator.device) + timesteps = timesteps.to(accelerator.device) + step_indices = [(schedule_timesteps == t).nonzero().item() for t in timesteps] + + sigma = sigmas[step_indices].flatten() + while len(sigma.shape) < n_dim: + sigma = sigma.unsqueeze(-1) + return sigma + + u = compute_density_for_timestep_sampling( + weighting_scheme=args.weighting_scheme, + batch_size=bsz, + logit_mean=args.logit_mean, + logit_std=args.logit_std, + mode_scale=args.mode_scale, + ) + indices = (u * noise_scheduler.config.num_train_timesteps).long() + timesteps = noise_scheduler.timesteps[indices].to(device=latents.device) + + # Add noise according to flow matching. + # zt = (1 - texp) * x + texp * z1 + sigmas = get_sigmas(timesteps, n_dim=latents.ndim, dtype=latents.dtype) + noisy_latents = (1.0 - sigmas) * latents + sigmas * noise + + # Add noise + target = noise - latents # Predict the noise residual noise_pred = transformer3d( @@ -1914,16 +2058,24 @@ def main(): if noise_pred.size()[1] != vae.config.latent_channels: noise_pred, _ = noise_pred.chunk(2, dim=1) - def custom_mse_loss(noise_pred, target, threshold=50): + def custom_mse_loss(noise_pred, target, weighting=None, threshold=50): noise_pred = noise_pred.float() target = target.float() diff = noise_pred - target mse_loss = F.mse_loss(noise_pred, target, reduction='none') mask = (diff.abs() <= threshold).float() masked_loss = mse_loss * mask + if weighting is not None: + masked_loss = masked_loss * weighting final_loss = masked_loss.mean() return final_loss - loss = custom_mse_loss(noise_pred.float(), target.float()) + + if args.loss_type == "ddpm": + loss = custom_mse_loss(noise_pred.float(), target.float()) + else: + weighting = compute_loss_weighting_for_sd3(weighting_scheme=args.weighting_scheme, sigmas=sigmas) + loss = custom_mse_loss(noise_pred.float(), target.float(), weighting.float()) + loss = loss.mean() if args.motion_sub_loss and noise_pred.size()[2] > 2: gt_sub_noise = noise_pred[:, :, 1:].float() - noise_pred[:, :, :-1].float() diff --git a/scripts/train.sh b/scripts/train.sh index e3b36e5..dfc94a5 100644 --- a/scripts/train.sh +++ b/scripts/train.sh @@ -1,4 +1,4 @@ -export MODEL_NAME="models/Diffusion_Transformer/EasyAnimateV5-12b-zh-InP" +export MODEL_NAME="models/Diffusion_Transformer/EasyAnimateV5.1-12b-zh-InP" export DATASET_NAME="datasets/internal_datasets/" export DATASET_META_NAME="datasets/internal_datasets/metadata.json" export NCCL_IB_DISABLE=1 @@ -10,7 +10,7 @@ accelerate launch --mixed_precision="bf16" scripts/train.py \ --pretrained_model_name_or_path=$MODEL_NAME \ --train_data_dir=$DATASET_NAME \ --train_data_meta=$DATASET_META_NAME \ - --config_path "config/easyanimate_video_v5_magvit_multi_text_encoder.yaml" \ + --config_path "config/easyanimate_video_v5.1_magvit_qwen.yaml" \ --image_sample_size=1024 \ --video_sample_size=256 \ --token_sample_size=512 \ @@ -29,13 +29,13 @@ accelerate launch --mixed_precision="bf16" scripts/train.py \ --output_dir="output_dir" \ --gradient_checkpointing \ --mixed_precision="bf16" \ - --adam_weight_decay=5e-3 \ + --adam_weight_decay=5e-2 \ --adam_epsilon=1e-10 \ --vae_mini_batch=1 \ --max_grad_norm=0.05 \ --random_hw_adapt \ --training_with_video_token_length \ - --not_sigma_loss \ + --loss_type="flow" \ --enable_bucket \ --uniform_sampling \ --train_mode="inpaint" \ diff --git a/scripts/train_control.py b/scripts/train_control.py index 22c8fd4..ce215fd 100644 --- a/scripts/train_control.py +++ b/scripts/train_control.py @@ -16,6 +16,7 @@ # See the License for the specific language governing permissions and import argparse +import copy import gc import logging import math @@ -35,10 +36,13 @@ from accelerate import Accelerator from accelerate.logging import get_logger from accelerate.state import AcceleratorState from accelerate.utils import ProjectConfiguration, set_seed -from diffusers import AutoencoderKL, DDPMScheduler +from diffusers import (DDPMScheduler, DDIMScheduler, + FlowMatchEulerDiscreteScheduler) from diffusers.models.embeddings import get_3d_rotary_pos_embed from diffusers.optimization import get_scheduler -from diffusers.training_utils import EMAModel +from diffusers.training_utils import (EMAModel, + compute_density_for_timestep_sampling, + compute_loss_weighting_for_sd3) from diffusers.utils import check_min_version, deprecate, is_wandb_available from diffusers.utils.import_utils import is_xformers_available from diffusers.utils.torch_utils import is_compiled_module @@ -50,9 +54,11 @@ from torch.utils.data import RandomSampler from torch.utils.tensorboard import SummaryWriter from torchvision import transforms from tqdm.auto import tqdm -from transformers import (BertModel, BertTokenizer, CLIPImageProcessor, - CLIPVisionModelWithProjection, T5Tokenizer, - T5EncoderModel, T5Tokenizer) +from transformers import (Qwen2Tokenizer, AutoTokenizer, BertModel, + BertTokenizer, CLIPImageProcessor, + CLIPVisionModelWithProjection, + Qwen2VLForConditionalGeneration, T5EncoderModel, + T5Tokenizer) from transformers.utils import ContextManagers import datasets @@ -67,14 +73,16 @@ from easyanimate.data.bucket_sampler import (ASPECT_RATIO_512, ASPECT_RATIO_RANDOM_CROP_PROB, AspectRatioBatchImageVideoSampler, RandomSampler, get_closest_ratio) -from easyanimate.data.dataset_image_video import (ImageVideoControlDataset, +from easyanimate.data.dataset_image_video import (ImageVideoControlDataset, process_pose_params, process_pose_file, ImageVideoSampler) from easyanimate.models import (name_to_autoencoder_magvit, name_to_transformer3d) -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder import (get_2d_rotary_pos_embed, - get_3d_rotary_pos_embed, get_resize_crop_region_for_grid) -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder_control import \ - EasyAnimatePipeline_Multi_Text_Encoder_Control +from easyanimate.pipeline.pipeline_easyanimate import ( + get_2d_rotary_pos_embed, get_3d_rotary_pos_embed, + get_resize_crop_region_for_grid) +from easyanimate.pipeline.pipeline_easyanimate_inpaint import resize_mask +from easyanimate.pipeline.pipeline_easyanimate_control import \ + EasyAnimateControlPipeline from easyanimate.utils import gaussian_diffusion as gd from easyanimate.utils.discrete_sampler import DiscreteSampling from easyanimate.utils.respace import SpacedDiffusion, space_timesteps @@ -125,39 +133,76 @@ def encode_prompt( add_special_tokens = False, enable_text_attention_mask = True, ): - if max_sequence_length is None: - max_length = min(tokenizer.model_max_length, tokenizer_max_length) - else: - max_length = max_sequence_length + if type(tokenizer) in [BertTokenizer, T5Tokenizer]: + if max_sequence_length is None: + max_length = min(tokenizer.model_max_length, tokenizer_max_length) + else: + max_length = max_sequence_length - text_inputs = tokenizer( - prompt, - padding="max_length", - max_length=max_length, - truncation=True, - return_attention_mask=True, - add_special_tokens=add_special_tokens, - return_tensors="pt", - ) - - if device is not None: - text_input_ids = text_inputs.input_ids.to(device) - prompt_attention_mask = text_inputs.attention_mask.to(device) + text_inputs = tokenizer( + prompt, + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + add_special_tokens=add_special_tokens, + return_tensors="pt", + ) + if device is not None: + text_input_ids = text_inputs.input_ids.to(device) + prompt_attention_mask = text_inputs.attention_mask.to(device) + else: + text_input_ids = text_inputs.input_ids + prompt_attention_mask = text_inputs.attention_mask + + if enable_text_attention_mask: + prompt_embeds = text_encoder( + text_input_ids, + attention_mask=prompt_attention_mask, + )[0] + else: + prompt_embeds = text_encoder( + text_input_ids + )[0] + prompt_embeds = prompt_embeds.to(dtype=dtype, device=device) + prompt_attention_mask = prompt_attention_mask.to(dtype=dtype, device=device) else: + max_length = tokenizer_max_length + texts = [] + for _prompt in prompt: + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": _prompt}], + } + ] + text = tokenizer.apply_chat_template( + messages, tokenize=False, add_generation_prompt=True + ) + texts.append(text) + text_inputs = tokenizer( + text=texts, + images=None, + videos=None, + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + padding_side="right", + return_tensors="pt", + ) + text_inputs = text_inputs.to(text_encoder.device) + text_input_ids = text_inputs.input_ids prompt_attention_mask = text_inputs.attention_mask - - if enable_text_attention_mask: - prompt_embeds = text_encoder( - text_input_ids, - attention_mask=prompt_attention_mask, - )[0] - else: - prompt_embeds = text_encoder( - text_input_ids - )[0] - prompt_embeds = prompt_embeds.to(dtype=dtype, device=device) - prompt_attention_mask = prompt_attention_mask.to(dtype=dtype, device=device) + if enable_text_attention_mask: + # Inference: Generation of the output + prompt_embeds = text_encoder( + input_ids=text_input_ids, + attention_mask=prompt_attention_mask, + output_hidden_states=True).hidden_states[-2] + else: + raise ValueError("LLM needs attention_mask") return prompt_embeds, prompt_attention_mask def get_random_downsample_ratio(sample_size, image_ratio=[], all_choices=False, rng=None): @@ -214,20 +259,27 @@ def log_validation( ).to(weight_dtype) transformer3d_val.load_state_dict(accelerator.unwrap_model(transformer3d).state_dict()) - if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): - pipeline = EasyAnimatePipeline_Multi_Text_Encoder_Control.from_pretrained( + if args.loss_type == "flow": + scheduler = FlowMatchEulerDiscreteScheduler.from_pretrained( args.pretrained_model_name_or_path, - vae=accelerator.unwrap_model(vae).to(weight_dtype), - text_encoder=accelerator.unwrap_model(text_encoder), - text_encoder_2=accelerator.unwrap_model(text_encoder_2), - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - transformer=transformer3d_val, - torch_dtype=weight_dtype, + subfolder="scheduler" ) else: - raise ValueError("enable_multi_text_encoder == False is not support now") - pipeline = pipeline.to(accelerator.device) + scheduler = DDIMScheduler.from_pretrained( + args.pretrained_model_name_or_path, + subfolder="scheduler" + ) + + pipeline = EasyAnimateControlPipeline( + vae=accelerator.unwrap_model(vae).to(weight_dtype), + text_encoder=accelerator.unwrap_model(text_encoder), + text_encoder_2=accelerator.unwrap_model(text_encoder_2), + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + transformer=transformer3d_val, + scheduler=scheduler, + ) + pipeline = pipeline.to(weight_dtype, accelerator.device) if args.enable_xformers_memory_efficient_attention \ and config['transformer_additional_kwargs'].get('transformer_type', 'Transformer3DModel') == 'Transformer3DModel': @@ -247,7 +299,14 @@ def log_validation( else: video_length = int(args.video_sample_n_frames // vae.mini_batch_encoder * vae.mini_batch_encoder) if args.video_sample_n_frames != 1 else 1 - input_video, input_video_mask, clip_image = get_video_to_video_latent(args.validation_paths[i], video_length=video_length, sample_size=[args.video_sample_size, args.video_sample_size]) + if args.train_mode == "control_camera_ref": + input_video, input_video_mask = None, None + control_camera_video = process_pose_file(args.validation_paths[i], args.video_sample_size, args.video_sample_size) + control_camera_video = control_camera_video[::int(args.video_sample_stride)][:video_length].permute([3, 0, 1, 2]).unsqueeze(0) + else: + input_video, input_video_mask, clip_image = get_video_to_video_latent(args.validation_paths[i], video_length=video_length, sample_size=[args.video_sample_size, args.video_sample_size]) + control_camera_video = None + sample = pipeline( args.validation_prompts[i], video_length = video_length, @@ -257,7 +316,8 @@ def log_validation( generator = generator, control_video = input_video, - ).videos + control_camera_video = control_camera_video, + ).frames os.makedirs(os.path.join(args.output_dir, "sample"), exist_ok=True) save_videos_grid(sample, os.path.join(args.output_dir, f"sample/sample-{global_step}-{i}.gif")) @@ -567,7 +627,13 @@ def parse_args(): "--uniform_sampling", action="store_true", help="Whether or not to use uniform_sampling." ) parser.add_argument( - "--not_sigma_loss", action="store_true", help="Whether or not to not use sigma_loss." + "--loss_type", + type=str, + default="sigma", + help=( + 'The format of training data. Support `"sigma"`' + ' (default), `"ddpm"`, `"flow"`.' + ), ) parser.add_argument( "--enable_text_encoder_in_dataloader", action="store_true", help="Whether or not to use text encoder in dataloader." @@ -706,6 +772,44 @@ def parse_args(): 'The initial gradient is relative to the multiple of the max_grad_norm. ' ), ) + parser.add_argument( + "--train_mode", + type=str, + default="control", + help=( + 'The format of training data. Support `"control"`' + ' (default), `"control_ref"`, `"control_camera_ref"`.' + ), + ) + parser.add_argument( + "--control_ref_image", + type=str, + default="first_frame", + help=( + 'The format of training data. Support `"first_frame"`' + ' (default), `"random"`.' + ), + ) + + parser.add_argument( + "--weighting_scheme", + type=str, + default="none", + choices=["sigma_sqrt", "logit_normal", "mode", "cosmap", "none"], + help=('We default to the "none" weighting scheme for uniform sampling and uniform loss'), + ) + parser.add_argument( + "--logit_mean", type=float, default=0.0, help="mean to use when using the `'logit_normal'` weighting scheme." + ) + parser.add_argument( + "--logit_std", type=float, default=1.0, help="std to use when using the `'logit_normal'` weighting scheme." + ) + parser.add_argument( + "--mode_scale", + type=float, + default=1.29, + help="Scale of mode weighting scheme. Only effective when using the `'mode'` as the `weighting_scheme`.", + ) args = parser.parse_args() env_local_rank = int(os.environ.get("LOCAL_RANK", -1)) @@ -794,8 +898,10 @@ def main(): args.mixed_precision = accelerator.mixed_precision # Load scheduler, tokenizer and models. - if args.not_sigma_loss: + if args.loss_type == "ddpm": noise_scheduler = DDPMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler") + elif args.loss_type == "flow": + noise_scheduler = FlowMatchEulerDiscreteScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler") else: train_diffusion = SpacedDiffusion( use_timesteps=space_timesteps(1000, str(args.train_sampling_steps)), betas=gd.get_named_beta_schedule("linear", 1000), @@ -808,15 +914,27 @@ def main(): tokenizer = BertTokenizer.from_pretrained( args.pretrained_model_name_or_path, subfolder="tokenizer", revision=args.revision ) - print("Init T5Tokenizer") - tokenizer_2 = T5Tokenizer.from_pretrained( - args.pretrained_model_name_or_path, subfolder="tokenizer_2", revision=args.revision - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + print("Init LLM Processor") + tokenizer_2 = Qwen2Tokenizer.from_pretrained( + os.path.join(args.pretrained_model_name_or_path, "tokenizer_2"), revision=args.revision + ) + else: + print("Init T5Tokenizer") + tokenizer_2 = T5Tokenizer.from_pretrained( + args.pretrained_model_name_or_path, subfolder="tokenizer_2", revision=args.revision + ) else: - print("Init T5Tokenizer") - tokenizer = T5Tokenizer.from_pretrained( - args.pretrained_model_name_or_path, subfolder="tokenizer", revision=args.revision - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + print("Init LLM Processor") + tokenizer = Qwen2Tokenizer.from_pretrained( + os.path.join(args.pretrained_model_name_or_path, "tokenizer"), revision=args.revision + ) + else: + print("Init T5Tokenizer") + tokenizer = T5Tokenizer.from_pretrained( + args.pretrained_model_name_or_path, subfolder="tokenizer", revision=args.revision + ) tokenizer_2 = None def deepspeed_zero_init_disabled_context_manager(): @@ -844,17 +962,30 @@ def main(): args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision, variant=args.variant, torch_dtype=weight_dtype ) - text_encoder_2 = T5EncoderModel.from_pretrained( - args.pretrained_model_name_or_path, subfolder="text_encoder_2", revision=args.revision, variant=args.variant, - torch_dtype=weight_dtype - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder_2 = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(args.pretrained_model_name_or_path, "text_encoder_2"), revision=args.revision, variant=args.variant, + torch_dtype=weight_dtype, + ) + else: + text_encoder_2 = T5EncoderModel.from_pretrained( + args.pretrained_model_name_or_path, subfolder="text_encoder_2", revision=args.revision, variant=args.variant, + torch_dtype=weight_dtype, + ) else: - text_encoder = T5EncoderModel.from_pretrained( - args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision, variant=args.variant, - torch_dtype=weight_dtype - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(args.pretrained_model_name_or_path, "text_encoder"), revision=args.revision, variant=args.variant, + torch_dtype=weight_dtype, + ) + else: + text_encoder = T5EncoderModel.from_pretrained( + args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision, variant=args.variant, + torch_dtype=weight_dtype + ) text_encoder_2 = None + # Get Vae Choosen_AutoencoderKL = name_to_autoencoder_magvit[ config['vae_kwargs'].get('vae_type', 'AutoencoderKL') @@ -1090,6 +1221,7 @@ def main(): video_repeat=args.video_repeat, image_sample_size=args.image_sample_size, enable_bucket=args.enable_bucket, enable_inpaint=False, + enable_camera_info=args.train_mode == "control_camera_ref" ) if args.enable_bucket: @@ -1134,6 +1266,13 @@ def main(): new_examples["text"] = [] # Used in Control Mode new_examples["control_pixel_values"] = [] + # Used in Control Ref Mode + if args.train_mode != "control": + new_examples["ref_pixel_values"] = [] + new_examples["clip_pixel_values"] = [] + # Used in Control Camera Ref Mode + if args.train_mode == "control_camera_ref": + new_examples["control_camera_values"] = [] # Get downsample ratio in image and videos pixel_value = examples[0]["pixel_values"] @@ -1185,14 +1324,14 @@ def main(): random_sample_size = [int(x / 16) * 16 for x in random_sample_size] for example in examples: + # To 0~1 + pixel_values = torch.from_numpy(example["pixel_values"]).permute(0, 3, 1, 2).contiguous() + pixel_values = pixel_values / 255. + + control_pixel_values = torch.from_numpy(example["control_pixel_values"]).permute(0, 3, 1, 2).contiguous() + control_pixel_values = control_pixel_values / 255. + if args.random_ratio_crop: - # To 0~1 - pixel_values = torch.from_numpy(example["pixel_values"]).permute(0, 3, 1, 2).contiguous() - pixel_values = pixel_values / 255. - - control_pixel_values = torch.from_numpy(example["control_pixel_values"]).permute(0, 3, 1, 2).contiguous() - control_pixel_values = control_pixel_values / 255. - # Get adapt hw for resize b, c, h, w = pixel_values.size() th, tw = random_sample_size @@ -1208,14 +1347,12 @@ def main(): transforms.CenterCrop([int(x) for x in random_sample_size]), transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5], inplace=True), ]) + + transform_no_normalize = transforms.Compose([ + transforms.Resize([nh, nw]), + transforms.CenterCrop([int(x) for x in random_sample_size]), + ]) else: - # To 0~1 - pixel_values = torch.from_numpy(example["pixel_values"]).permute(0, 3, 1, 2).contiguous() - pixel_values = pixel_values / 255. - - control_pixel_values = torch.from_numpy(example["control_pixel_values"]).permute(0, 3, 1, 2).contiguous() - control_pixel_values = control_pixel_values / 255. - # Get adapt hw for resize closest_size = list(map(lambda x: int(x), closest_size)) if closest_size[0] / h > closest_size[1] / w: @@ -1229,8 +1366,28 @@ def main(): transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5], inplace=True), ]) + transform_no_normalize = transforms.Compose([ + transforms.Resize(resize_size, interpolation=transforms.InterpolationMode.BILINEAR), # Image.BICUBIC + transforms.CenterCrop(closest_size), + ]) new_examples["pixel_values"].append(transform(pixel_values)) new_examples["control_pixel_values"].append(transform(control_pixel_values)) + + if args.train_mode == "control_camera_ref": + control_camera_values = example.get("control_camera_values", None) + if control_camera_values is None: + control_camera_values_size = ( + new_examples["control_pixel_values"][-1].size()[0], + 6, + new_examples["control_pixel_values"][-1].size()[2], + new_examples["control_pixel_values"][-1].size()[3] + ) + local_control_camera_values = torch.zeros(control_camera_values_size) + new_examples["control_camera_values"].append(local_control_camera_values) + else: + local_control_camera_values = process_pose_params(example["control_camera_values"], height=resize_size[0], width=resize_size[1]).permute(0, 3, 1, 2).contiguous() + new_examples["control_camera_values"].append(transform_no_normalize(local_control_camera_values)) + new_examples["text"].append(example["text"]) # Magvae needs the number of frames to be 4n + 1. if vae.cache_mag_vae: @@ -1250,9 +1407,39 @@ def main(): if batch_video_length == 0: batch_video_length = 1 + if args.train_mode != "control": + if args.control_ref_image == "first_frame": + clip_index = 0 + elif control_camera_values is not None: + clip_index = 0 + else: + def _create_special_list(length): + if length == 1: + return [1.0] + if length >= 2: + first_element = 0.40 + remaining_sum = 1.0 - first_element + other_elements_value = remaining_sum / (length - 1) + special_list = [first_element] + [other_elements_value] * (length - 1) + return special_list + number_list_prob = np.array(_create_special_list(len(new_examples["pixel_values"][-1]))) + clip_index = np.random.choice(list(range(len(new_examples["pixel_values"][-1]))), p = number_list_prob) + + ref_pixel_values = new_examples["pixel_values"][-1][clip_index].unsqueeze(0) + new_examples["ref_pixel_values"].append(ref_pixel_values) + + clip_pixel_values = new_examples["pixel_values"][-1][clip_index].permute(1, 2, 0).contiguous() + clip_pixel_values = (clip_pixel_values * 0.5 + 0.5) * 255 + new_examples["clip_pixel_values"].append(clip_pixel_values) + # Limit the number of frames to the same new_examples["pixel_values"] = torch.stack([example[:batch_video_length] for example in new_examples["pixel_values"]]) new_examples["control_pixel_values"] = torch.stack([example[:batch_video_length] for example in new_examples["control_pixel_values"]]) + if args.train_mode != "control": + new_examples["ref_pixel_values"] = torch.stack([example[:batch_video_length] for example in new_examples["ref_pixel_values"]]) + new_examples["clip_pixel_values"] = torch.stack([example for example in new_examples["clip_pixel_values"]]) + if args.train_mode == "control_camera_ref": + new_examples["control_camera_values"] = torch.stack([example[:batch_video_length] for example in new_examples["control_camera_values"]]) # Encode prompts when enable_text_encoder_in_dataloader=True if args.enable_text_encoder_in_dataloader: @@ -1440,17 +1627,29 @@ def main(): gif_name = '-'.join(text.replace('/', '').split()[:10]) if not text == '' else f'{global_step}-{idx}' save_videos_grid(pixel_value, f"{args.output_dir}/sanity_check/{gif_name[:10]}.gif", rescale=True) save_videos_grid(control_pixel_value, f"{args.output_dir}/sanity_check/{gif_name[:10]}_control.gif", rescale=True) + + if args.train_mode != "control": + ref_pixel_values = batch["ref_pixel_values"].cpu() + ref_pixel_values = rearrange(ref_pixel_values, "b f c h w -> b c f h w") + for idx, (ref_pixel_value, text) in enumerate(zip(ref_pixel_values, texts)): + ref_pixel_value = ref_pixel_value[None, ...] + gif_name = '-'.join(text.replace('/', '').split()[:10]) if not text == '' else f'{global_step}-{idx}' + save_videos_grid(ref_pixel_value, f"{args.output_dir}/sanity_check/{gif_name[:10]}_ref.gif", rescale=True) with accelerator.accumulate(transformer3d): # Convert images to latent space pixel_values = batch["pixel_values"].to(weight_dtype) control_pixel_values = batch["control_pixel_values"].to(weight_dtype) + if args.train_mode == "control_camera_ref": + control_camera_values = batch["control_camera_values"].to(weight_dtype) # Increase the batch size when the length of the latent sequence of the current sample is small if args.training_with_video_token_length: if args.video_sample_n_frames * args.token_sample_size * args.token_sample_size // 16 >= pixel_values.size()[1] * pixel_values.size()[3] * pixel_values.size()[4]: pixel_values = torch.tile(pixel_values, (4, 1, 1, 1, 1)) control_pixel_values = torch.tile(control_pixel_values, (4, 1, 1, 1, 1)) + if args.train_mode == "control_camera_ref": + control_camera_values = torch.tile(control_camera_values, (4, 1, 1, 1, 1)) if args.enable_text_encoder_in_dataloader: batch['prompt_embeds'] = torch.tile(batch['prompt_embeds'], (4, 1, 1)) batch['prompt_attention_mask'] = torch.tile(batch['prompt_attention_mask'], (4, 1)) @@ -1462,6 +1661,8 @@ def main(): elif args.video_sample_n_frames * args.token_sample_size * args.token_sample_size // 4 >= pixel_values.size()[1] * pixel_values.size()[3] * pixel_values.size()[4]: pixel_values = torch.tile(pixel_values, (2, 1, 1, 1, 1)) control_pixel_values = torch.tile(control_pixel_values, (2, 1, 1, 1, 1)) + if args.train_mode == "control_camera_ref": + control_camera_values = torch.tile(control_camera_values, (2, 1, 1, 1, 1)) if args.enable_text_encoder_in_dataloader: batch['prompt_embeds'] = torch.tile(batch['prompt_embeds'], (2, 1, 1)) batch['prompt_attention_mask'] = torch.tile(batch['prompt_attention_mask'], (2, 1)) @@ -1471,6 +1672,18 @@ def main(): else: batch['text'] = batch['text'] * 2 + if args.train_mode != "control": + ref_pixel_values = batch["ref_pixel_values"].to(weight_dtype) + clip_pixel_values = batch["clip_pixel_values"] + # Increase the batch size when the length of the latent sequence of the current sample is small + if args.training_with_video_token_length: + if args.video_sample_n_frames * args.token_sample_size * args.token_sample_size // 16 >= pixel_values.size()[1] * pixel_values.size()[3] * pixel_values.size()[4]: + clip_pixel_values = torch.tile(clip_pixel_values, (4, 1, 1, 1)) + ref_pixel_values = torch.tile(ref_pixel_values, (4, 1, 1, 1, 1)) + elif args.video_sample_n_frames * args.token_sample_size * args.token_sample_size // 4 >= pixel_values.size()[1] * pixel_values.size()[3] * pixel_values.size()[4]: + clip_pixel_values = torch.tile(clip_pixel_values, (2, 1, 1, 1)) + ref_pixel_values = torch.tile(ref_pixel_values, (2, 1, 1, 1, 1)) + # Random crop number of frames to adapt different frames of video. if args.random_frame_crop: def _create_special_list(length): @@ -1568,10 +1781,41 @@ def main(): else: latents = _batch_encode_vae(pixel_values) latents = latents * vae.config.scaling_factor - - control_latents = _batch_encode_vae(control_pixel_values) - control_latents = control_latents * vae.config.scaling_factor - + + if args.train_mode != "control_camera_ref": + control_latents = _batch_encode_vae(control_pixel_values) + control_latents = control_latents * vae.config.scaling_factor + # Make control latents to zero + for bs_index in range(control_latents.size()[0]): + if rng is None: + zero_init_control_latents_conv_in = np.random.choice([0, 1], p = [0.80, 0.20]) + else: + zero_init_control_latents_conv_in = rng.choice([0, 1], p = [0.80, 0.20]) + + if zero_init_control_latents_conv_in: + control_latents[bs_index] = control_latents[bs_index] * 0 + else: + control_latents = rearrange(control_camera_values, "b f c h w -> b c f h w", f=video_length) + control_latents = resize_mask(control_latents, latents, vae.cache_mag_vae) + control_latents = control_latents * 6 + + if args.train_mode != "control": + ref_latents = _batch_encode_vae(ref_pixel_values) + ref_latents = ref_latents * vae.config.scaling_factor + + ref_latents_conv_in = torch.zeros_like(latents).to(ref_latents.device, ref_latents.dtype) + ref_latents_conv_in[:, :, :1] = ref_latents + for bs_index in range(ref_latents.size()[0]): + if rng is None: + zero_init_ref_latents_conv_in = np.random.choice([0, 1], p = [0.80, 0.20]) + else: + zero_init_ref_latents_conv_in = rng.choice([0, 1], p = [0.80, 0.20]) + + if zero_init_ref_latents_conv_in and control_latents.size()[1] != 1: + ref_latents_conv_in[bs_index, :, :1] = ref_latents_conv_in[bs_index, :, :1] * 0 + + control_latents = torch.cat([control_latents, ref_latents_conv_in], dim = 1) + # wait for latents = vae.encode(pixel_values) to complete if vae_stream_1 is not None: torch.cuda.current_stream().wait_stream(vae_stream_1) @@ -1651,7 +1895,7 @@ def main(): timesteps = idx_sampling(bsz, generator=torch_rng, device=latents.device) timesteps = timesteps.long() - if args.not_sigma_loss: + if args.loss_type != "sigma": # Create image_rotary_emb, style embedding & time ids height, width = batch["pixel_values"].size()[-2], batch["pixel_values"].size()[-1] @@ -1695,14 +1939,44 @@ def main(): ) style = style.to(device=latents.device).repeat(bsz) - # Add noise - noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) - if noise_scheduler.config.prediction_type == "epsilon": - target = noise - elif noise_scheduler.config.prediction_type == "v_prediction": - target = noise_scheduler.get_velocity(latents, noise, timesteps) + if args.loss_type == "ddpm": + # Add noise + noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) + if noise_scheduler.config.prediction_type == "epsilon": + target = noise + elif noise_scheduler.config.prediction_type == "v_prediction": + target = noise_scheduler.get_velocity(latents, noise, timesteps) + else: + raise ValueError(f"Unknown prediction type {noise_scheduler.config.prediction_type}") else: - raise ValueError(f"Unknown prediction type {noise_scheduler.config.prediction_type}") + def get_sigmas(timesteps, n_dim=4, dtype=torch.float32): + sigmas = noise_scheduler.sigmas.to(device=accelerator.device, dtype=dtype) + schedule_timesteps = noise_scheduler.timesteps.to(accelerator.device) + timesteps = timesteps.to(accelerator.device) + step_indices = [(schedule_timesteps == t).nonzero().item() for t in timesteps] + + sigma = sigmas[step_indices].flatten() + while len(sigma.shape) < n_dim: + sigma = sigma.unsqueeze(-1) + return sigma + + u = compute_density_for_timestep_sampling( + weighting_scheme=args.weighting_scheme, + batch_size=bsz, + logit_mean=args.logit_mean, + logit_std=args.logit_std, + mode_scale=args.mode_scale, + ) + indices = (u * noise_scheduler.config.num_train_timesteps).long() + timesteps = noise_scheduler.timesteps[indices].to(device=latents.device) + + # Add noise according to flow matching. + # zt = (1 - texp) * x + texp * z1 + sigmas = get_sigmas(timesteps, n_dim=latents.ndim, dtype=latents.dtype) + noisy_latents = (1.0 - sigmas) * latents + sigmas * noise + + # Add noise + target = noise - latents # Predict the noise residual noise_pred = transformer3d( @@ -1721,16 +1995,26 @@ def main(): if noise_pred.size()[1] != vae.config.latent_channels: noise_pred, _ = noise_pred.chunk(2, dim=1) - def custom_mse_loss(noise_pred, target, threshold=50): + def custom_mse_loss(noise_pred, target, weighting=None, threshold=50): noise_pred = noise_pred.float() target = target.float() diff = noise_pred - target mse_loss = F.mse_loss(noise_pred, target, reduction='none') mask = (diff.abs() <= threshold).float() masked_loss = mse_loss * mask + if weighting is not None: + masked_loss = masked_loss * weighting final_loss = masked_loss.mean() return final_loss - loss = custom_mse_loss(noise_pred.float(), target.float()) + + if args.loss_type == "ddpm": + loss = custom_mse_loss(noise_pred.float(), target.float()) + else: + weighting = compute_loss_weighting_for_sd3(weighting_scheme=args.weighting_scheme, sigmas=sigmas) + # loss = (weighting.float() * (noise_pred.float() - target.float()) ** 2).reshape(target.shape[0], -1) + # loss = loss[~torch.isnan(loss)] + loss = custom_mse_loss(noise_pred.float(), target.float(), weighting.float()) + loss = loss.mean() if args.motion_sub_loss and noise_pred.size()[2] > 2: gt_sub_noise = noise_pred[:, :, 1:].float() - noise_pred[:, :, :-1].float() diff --git a/scripts/train_control.sh b/scripts/train_control.sh index 3410811..59d9450 100644 --- a/scripts/train_control.sh +++ b/scripts/train_control.sh @@ -1,4 +1,4 @@ -export MODEL_NAME="models/Diffusion_Transformer/EasyAnimateV5-12b-zh-Control" +export MODEL_NAME="models/Diffusion_Transformer/EasyAnimateV5.1-12b-zh-Control" export DATASET_NAME="datasets/internal_datasets/" export DATASET_META_NAME="datasets/internal_datasets/metadata.json" export NCCL_IB_DISABLE=1 @@ -10,7 +10,7 @@ accelerate launch --mixed_precision="bf16" scripts/train_control.py \ --pretrained_model_name_or_path=$MODEL_NAME \ --train_data_dir=$DATASET_NAME \ --train_data_meta=$DATASET_META_NAME \ - --config_path "config/easyanimate_video_v5_magvit_multi_text_encoder.yaml" \ + --config_path "config/easyanimate_video_v5.1_magvit_qwen.yaml" \ --image_sample_size=1024 \ --video_sample_size=256 \ --token_sample_size=512 \ @@ -35,7 +35,8 @@ accelerate launch --mixed_precision="bf16" scripts/train_control.py \ --max_grad_norm=0.05 \ --random_hw_adapt \ --training_with_video_token_length \ - --not_sigma_loss \ + --loss_type="flow" \ --enable_bucket \ --uniform_sampling \ + --train_mode="control_ref" \ --trainable_modules "." \ No newline at end of file diff --git a/scripts/train_lcm_lora.py b/scripts/train_lcm_lora.py index 3dfd283..56f129e 100644 --- a/scripts/train_lcm_lora.py +++ b/scripts/train_lcm_lora.py @@ -84,12 +84,9 @@ from easyanimate.models.autoencoder_magvit import AutoencoderKLMagvit from easyanimate.models.transformer2d import Transformer2DModel from easyanimate.models.transformer3d import (HunyuanTransformer3DModel, Transformer3DModel) -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder import EasyAnimatePipeline_Multi_Text_Encoder -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder_inpaint import EasyAnimatePipeline_Multi_Text_Encoder_Inpaint from easyanimate.pipeline.pipeline_easyanimate import EasyAnimatePipeline -from easyanimate.pipeline.pipeline_easyanimate_inpaint import \ - EasyAnimateInpaintPipeline -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder import ( +from easyanimate.pipeline.pipeline_easyanimate_inpaint import EasyAnimateInpaintPipeline +from easyanimate.pipeline.pipeline_easyanimate import ( get_2d_rotary_pos_embed, get_resize_crop_region_for_grid) from easyanimate.pipeline.pipeline_pixart_magvit import \ PixArtAlphaMagvitPipeline @@ -205,70 +202,35 @@ def log_validation(vae, text_encoder, text_encoder_2, tokenizer, tokenizer_2, tr ).to(weight_dtype) transformer3d_val.load_state_dict(accelerator.unwrap_model(transformer3d).state_dict()) - if config.get('enable_multi_text_encoder', False): - if args.train_mode != "normal": - clip_image_encoder = CLIPVisionModelWithProjection.from_pretrained( - args.pretrained_model_name_or_path, subfolder="image_encoder" - ) - clip_image_processor = CLIPImageProcessor.from_pretrained( - args.pretrained_model_name_or_path, subfolder="image_encoder" - ) - pipeline = EasyAnimatePipeline_Multi_Text_Encoder_Inpaint.from_pretrained( - args.pretrained_model_name_or_path, - vae=accelerator.unwrap_model(vae).to(weight_dtype), - text_encoder=accelerator.unwrap_model(text_encoder), - text_encoder_2=accelerator.unwrap_model(text_encoder_2), - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - transformer=transformer3d_val, - torch_dtype=weight_dtype, - clip_image_encoder=clip_image_encoder, - clip_image_processor=clip_image_processor, - scheduler=LCMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler"), - ) - else: - pipeline = EasyAnimatePipeline_Multi_Text_Encoder.from_pretrained( - args.pretrained_model_name_or_path, - vae=accelerator.unwrap_model(vae).to(weight_dtype), - text_encoder=accelerator.unwrap_model(text_encoder), - text_encoder_2=accelerator.unwrap_model(text_encoder_2), - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - transformer=transformer3d_val, - scheduler=LCMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler"), - torch_dtype=weight_dtype - ) + if args.train_mode != "normal": + clip_image_encoder = CLIPVisionModelWithProjection.from_pretrained( + args.pretrained_model_name_or_path, subfolder="image_encoder" + ) + clip_image_processor = CLIPImageProcessor.from_pretrained( + args.pretrained_model_name_or_path, subfolder="image_encoder" + ) + pipeline = EasyAnimateInpaintPipeline( + vae=accelerator.unwrap_model(vae).to(weight_dtype), + text_encoder=accelerator.unwrap_model(text_encoder), + text_encoder_2=accelerator.unwrap_model(text_encoder_2), + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + transformer=transformer3d_val, + clip_image_encoder=clip_image_encoder, + clip_image_processor=clip_image_processor, + scheduler=LCMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler"), + ) else: - if args.train_mode != "normal": - clip_image_encoder = CLIPVisionModelWithProjection.from_pretrained( - args.pretrained_model_name_or_path, subfolder="image_encoder" - ) - clip_image_processor = CLIPImageProcessor.from_pretrained( - args.pretrained_model_name_or_path, subfolder="image_encoder" - ) - pipeline = EasyAnimateInpaintPipeline.from_pretrained( - args.pretrained_model_name_or_path, - vae=accelerator.unwrap_model(vae).to(weight_dtype), - text_encoder=accelerator.unwrap_model(text_encoder), - tokenizer=tokenizer, - transformer=transformer3d_val, - torch_dtype=weight_dtype, - clip_image_encoder=clip_image_encoder, - clip_image_processor=clip_image_processor, - scheduler=LCMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler"), - ) - else: - pipeline = EasyAnimatePipeline.from_pretrained( - args.pretrained_model_name_or_path, - vae=accelerator.unwrap_model(vae).to(weight_dtype), - text_encoder=accelerator.unwrap_model(text_encoder), - tokenizer=tokenizer, - transformer=transformer3d_val, - scheduler=LCMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler"), - torch_dtype=weight_dtype - ) - - pipeline = pipeline.to(accelerator.device) + pipeline = EasyAnimatePipeline( + vae=accelerator.unwrap_model(vae).to(weight_dtype), + text_encoder=accelerator.unwrap_model(text_encoder), + text_encoder_2=accelerator.unwrap_model(text_encoder_2), + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + transformer=transformer3d_val, + scheduler=LCMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler"), + ) + pipeline = pipeline.to(weight_dtype, accelerator.device) pipeline = merge_lora( pipeline, None, 1, accelerator.device, state_dict=accelerator.unwrap_model(network).state_dict(), transformer_only=True ) @@ -300,7 +262,7 @@ def log_validation(vae, text_encoder, text_encoder_2, tokenizer, tokenizer_2, tr video = input_video, mask_video = input_video_mask, clip_image = clip_image, - ).videos + ).frames os.makedirs(os.path.join(args.output_dir, "sample"), exist_ok=True) save_videos_grid(sample, os.path.join(args.output_dir, f"sample/sample-{global_step}-{i}.gif")) @@ -319,7 +281,7 @@ def log_validation(vae, text_encoder, text_encoder_2, tokenizer, tokenizer_2, tr video = input_video, mask_video = input_video_mask, clip_image = clip_image, - ).videos + ).frames os.makedirs(os.path.join(args.output_dir, "sample"), exist_ok=True) save_videos_grid(sample, os.path.join(args.output_dir, f"sample/sample-{global_step}-image-{i}.gif")) else: @@ -333,7 +295,7 @@ def log_validation(vae, text_encoder, text_encoder_2, tokenizer, tokenizer_2, tr num_inference_steps=4, guidance_scale = 0, generator = generator - ).videos + ).frames os.makedirs(os.path.join(args.output_dir, "sample"), exist_ok=True) save_videos_grid(sample, os.path.join(args.output_dir, f"sample/sample-{global_step}-{i}.gif")) @@ -346,7 +308,7 @@ def log_validation(vae, text_encoder, text_encoder_2, tokenizer, tokenizer_2, tr num_inference_steps=4, guidance_scale = 0, generator = generator - ).videos + ).frames os.makedirs(os.path.join(args.output_dir, "sample"), exist_ok=True) save_videos_grid(sample, os.path.join(args.output_dir, f"sample/sample-{global_step}-image-{i}.gif")) diff --git a/scripts/train_lora.py b/scripts/train_lora.py index 038dd2d..316f2ed 100644 --- a/scripts/train_lora.py +++ b/scripts/train_lora.py @@ -36,9 +36,14 @@ from accelerate import Accelerator from accelerate.logging import get_logger from accelerate.state import AcceleratorState from accelerate.utils import ProjectConfiguration, set_seed -from diffusers import AutoencoderKL, DDPMScheduler +from diffusers import (DDIMScheduler, DDPMScheduler, + FlowMatchEulerDiscreteScheduler) from diffusers.optimization import get_scheduler -from diffusers.training_utils import EMAModel +from diffusers.training_utils import (EMAModel, + _set_state_dict_into_text_encoder, + cast_training_params, + compute_density_for_timestep_sampling, + compute_loss_weighting_for_sd3) from diffusers.utils import check_min_version, deprecate, is_wandb_available from diffusers.utils.import_utils import is_xformers_available from diffusers.utils.torch_utils import is_compiled_module @@ -51,9 +56,11 @@ from torch.utils.data import RandomSampler from torch.utils.tensorboard import SummaryWriter from torchvision import transforms from tqdm.auto import tqdm -from transformers import (BertModel, BertTokenizer, CLIPImageProcessor, +from transformers import (Qwen2Tokenizer, AutoTokenizer, BertModel, + BertTokenizer, CLIPImageProcessor, CLIPVisionModelWithProjection, - T5EncoderModel, T5Tokenizer) + Qwen2VLForConditionalGeneration, T5EncoderModel, + T5Tokenizer) from transformers.utils import ContextManagers import datasets @@ -63,39 +70,21 @@ project_roots = [os.path.dirname(current_file_path), os.path.dirname(os.path.dir for project_root in project_roots: sys.path.insert(0, project_root) if project_root not in sys.path else None -from transformers import (CLIPImageProcessor, CLIPVisionModelWithProjection, - T5EncoderModel, T5Tokenizer) -from transformers.utils import ContextManagers - from easyanimate.data.bucket_sampler import (ASPECT_RATIO_512, ASPECT_RATIO_RANDOM_CROP_512, ASPECT_RATIO_RANDOM_CROP_PROB, - AspectRatioBatchImageSampler, AspectRatioBatchImageVideoSampler, - AspectRatioBatchSampler, RandomSampler, get_closest_ratio) -from easyanimate.data.dataset_image import CC15M from easyanimate.data.dataset_image_video import (ImageVideoDataset, ImageVideoSampler, get_random_mask) -from easyanimate.data.dataset_video import VideoDataset, WebVid10M from easyanimate.models import (name_to_autoencoder_magvit, name_to_transformer3d) -from easyanimate.models.autoencoder_magvit import AutoencoderKLMagvit -from easyanimate.models.transformer2d import Transformer2DModel -from easyanimate.models.transformer3d import (HunyuanTransformer3DModel, - Transformer3DModel) -from easyanimate.pipeline.pipeline_easyanimate import EasyAnimatePipeline -from easyanimate.pipeline.pipeline_easyanimate_inpaint import \ - EasyAnimateInpaintPipeline -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder import ( - EasyAnimatePipeline_Multi_Text_Encoder, get_2d_rotary_pos_embed, - get_3d_rotary_pos_embed, get_resize_crop_region_for_grid) -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder_inpaint import ( - EasyAnimatePipeline_Multi_Text_Encoder_Inpaint, - add_noise_to_reference_video, resize_mask) -from easyanimate.pipeline.pipeline_pixart_magvit import \ - PixArtAlphaMagvitPipeline +from easyanimate.pipeline.pipeline_easyanimate import ( + EasyAnimatePipeline, get_2d_rotary_pos_embed, get_3d_rotary_pos_embed, + get_resize_crop_region_for_grid) +from easyanimate.pipeline.pipeline_easyanimate_inpaint import ( + EasyAnimateInpaintPipeline, add_noise_to_reference_video, resize_mask) from easyanimate.utils import gaussian_diffusion as gd from easyanimate.utils.discrete_sampler import DiscreteSampling from easyanimate.utils.lora_utils import (create_network, merge_lora, @@ -148,39 +137,76 @@ def encode_prompt( add_special_tokens = False, enable_text_attention_mask = True, ): - if max_sequence_length is None: - max_length = min(tokenizer.model_max_length, tokenizer_max_length) - else: - max_length = max_sequence_length + if type(tokenizer) in [BertTokenizer, T5Tokenizer]: + if max_sequence_length is None: + max_length = min(tokenizer.model_max_length, tokenizer_max_length) + else: + max_length = max_sequence_length - text_inputs = tokenizer( - prompt, - padding="max_length", - max_length=max_length, - truncation=True, - return_attention_mask=True, - add_special_tokens=add_special_tokens, - return_tensors="pt", - ) - - if device is not None: - text_input_ids = text_inputs.input_ids.to(device) - prompt_attention_mask = text_inputs.attention_mask.to(device) + text_inputs = tokenizer( + prompt, + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + add_special_tokens=add_special_tokens, + return_tensors="pt", + ) + if device is not None: + text_input_ids = text_inputs.input_ids.to(device) + prompt_attention_mask = text_inputs.attention_mask.to(device) + else: + text_input_ids = text_inputs.input_ids + prompt_attention_mask = text_inputs.attention_mask + + if enable_text_attention_mask: + prompt_embeds = text_encoder( + text_input_ids, + attention_mask=prompt_attention_mask, + )[0] + else: + prompt_embeds = text_encoder( + text_input_ids + )[0] + prompt_embeds = prompt_embeds.to(dtype=dtype, device=device) + prompt_attention_mask = prompt_attention_mask.to(dtype=dtype, device=device) else: + max_length = tokenizer_max_length + texts = [] + for _prompt in prompt: + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": _prompt}], + } + ] + text = tokenizer.apply_chat_template( + messages, tokenize=False, add_generation_prompt=True + ) + texts.append(text) + text_inputs = tokenizer( + text=texts, + images=None, + videos=None, + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + padding_side="right", + return_tensors="pt", + ) + text_inputs = text_inputs.to(text_encoder.device) + text_input_ids = text_inputs.input_ids prompt_attention_mask = text_inputs.attention_mask - - if enable_text_attention_mask: - prompt_embeds = text_encoder( - text_input_ids, - attention_mask=prompt_attention_mask, - )[0] - else: - prompt_embeds = text_encoder( - text_input_ids - )[0] - prompt_embeds = prompt_embeds.to(dtype=dtype, device=device) - prompt_attention_mask = prompt_attention_mask.to(dtype=dtype, device=device) + if enable_text_attention_mask: + # Inference: Generation of the output + prompt_embeds = text_encoder( + input_ids=text_input_ids, + attention_mask=prompt_attention_mask, + output_hidden_states=True).hidden_states[-2] + else: + raise ValueError("LLM needs attention_mask") return prompt_embeds, prompt_attention_mask def get_random_downsample_ratio(sample_size, image_ratio=[], all_choices=False, rng=None): @@ -236,54 +262,41 @@ def log_validation( transformer_additional_kwargs=OmegaConf.to_container(config['transformer_additional_kwargs']) ).to(weight_dtype) transformer3d_val.load_state_dict(accelerator.unwrap_model(transformer3d).state_dict()) - - if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): - if args.train_mode != "normal": - pipeline = EasyAnimatePipeline_Multi_Text_Encoder_Inpaint.from_pretrained( - args.pretrained_model_name_or_path, - vae=accelerator.unwrap_model(vae).to(weight_dtype), - text_encoder=accelerator.unwrap_model(text_encoder), - text_encoder_2=accelerator.unwrap_model(text_encoder_2), - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - transformer=transformer3d_val, - torch_dtype=weight_dtype, - clip_image_encoder=image_encoder, - clip_image_processor=image_processor, - ) - else: - pipeline = EasyAnimatePipeline_Multi_Text_Encoder.from_pretrained( - args.pretrained_model_name_or_path, - vae=accelerator.unwrap_model(vae).to(weight_dtype), - text_encoder=accelerator.unwrap_model(text_encoder), - text_encoder_2=accelerator.unwrap_model(text_encoder_2), - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - transformer=transformer3d_val, - torch_dtype=weight_dtype - ) + + if args.loss_type == "flow": + scheduler = FlowMatchEulerDiscreteScheduler.from_pretrained( + args.pretrained_model_name_or_path, + subfolder="scheduler" + ) else: - if args.train_mode != "normal": - pipeline = EasyAnimateInpaintPipeline.from_pretrained( - args.pretrained_model_name_or_path, - vae=accelerator.unwrap_model(vae).to(weight_dtype), - text_encoder=accelerator.unwrap_model(text_encoder), - tokenizer=tokenizer, - transformer=transformer3d_val, - torch_dtype=weight_dtype, - clip_image_encoder=image_encoder, - clip_image_processor=image_processor, - ) - else: - pipeline = EasyAnimatePipeline.from_pretrained( - args.pretrained_model_name_or_path, - vae=accelerator.unwrap_model(vae).to(weight_dtype), - text_encoder=accelerator.unwrap_model(text_encoder), - tokenizer=tokenizer, - transformer=transformer3d_val, - torch_dtype=weight_dtype - ) - pipeline = pipeline.to(accelerator.device) + scheduler = DDIMScheduler.from_pretrained( + args.pretrained_model_name_or_path, + subfolder="scheduler" + ) + + if args.train_mode != "normal": + pipeline = EasyAnimateInpaintPipeline( + vae=accelerator.unwrap_model(vae).to(weight_dtype), + text_encoder=accelerator.unwrap_model(text_encoder), + text_encoder_2=accelerator.unwrap_model(text_encoder_2), + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + transformer=transformer3d_val, + scheduler=scheduler, + clip_image_encoder=image_encoder, + clip_image_processor=image_processor, + ) + else: + pipeline = EasyAnimatePipeline( + vae=accelerator.unwrap_model(vae).to(weight_dtype), + text_encoder=accelerator.unwrap_model(text_encoder), + text_encoder_2=accelerator.unwrap_model(text_encoder_2), + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + transformer=transformer3d_val, + scheduler=scheduler, + ) + pipeline = pipeline.to(weight_dtype, accelerator.device) pipeline = merge_lora( pipeline, None, 1, accelerator.device, state_dict=accelerator.unwrap_model(network).state_dict(), transformer_only=True ) @@ -317,7 +330,7 @@ def log_validation( video = input_video, mask_video = input_video_mask, clip_image = clip_image, - ).videos + ).frames os.makedirs(os.path.join(args.output_dir, "sample"), exist_ok=True) save_videos_grid(sample, os.path.join(args.output_dir, f"sample/sample-{global_step}-{i}.gif")) @@ -334,7 +347,7 @@ def log_validation( video = input_video, mask_video = input_video_mask, clip_image = clip_image, - ).videos + ).frames os.makedirs(os.path.join(args.output_dir, "sample"), exist_ok=True) save_videos_grid(sample, os.path.join(args.output_dir, f"sample/sample-{global_step}-image-{i}.gif")) else: @@ -346,7 +359,7 @@ def log_validation( height = args.video_sample_size, width = args.video_sample_size, generator = generator - ).videos + ).frames os.makedirs(os.path.join(args.output_dir, "sample"), exist_ok=True) save_videos_grid(sample, os.path.join(args.output_dir, f"sample/sample-{global_step}-{i}.gif")) @@ -357,7 +370,7 @@ def log_validation( height = args.video_sample_size, width = args.video_sample_size, generator = generator - ).videos + ).frames os.makedirs(os.path.join(args.output_dir, "sample"), exist_ok=True) save_videos_grid(sample, os.path.join(args.output_dir, f"sample/sample-{global_step}-image-{i}.gif")) @@ -678,7 +691,13 @@ def parse_args(): "--uniform_sampling", action="store_true", help="Whether or not to use uniform_sampling." ) parser.add_argument( - "--not_sigma_loss", action="store_true", help="Whether or not to not use sigma_loss." + "--loss_type", + type=str, + default="sigma", + help=( + 'The format of training data. Support `"sigma"`' + ' (default), `"ddpm"`, `"flow"`.' + ), ) parser.add_argument( "--enable_text_encoder_in_dataloader", action="store_true", help="Whether or not to use text encoder in dataloader." @@ -823,6 +842,26 @@ def parse_args(): ), ) + parser.add_argument( + "--weighting_scheme", + type=str, + default="none", + choices=["sigma_sqrt", "logit_normal", "mode", "cosmap", "none"], + help=('We default to the "none" weighting scheme for uniform sampling and uniform loss'), + ) + parser.add_argument( + "--logit_mean", type=float, default=0.0, help="mean to use when using the `'logit_normal'` weighting scheme." + ) + parser.add_argument( + "--logit_std", type=float, default=1.0, help="std to use when using the `'logit_normal'` weighting scheme." + ) + parser.add_argument( + "--mode_scale", + type=float, + default=1.29, + help="Scale of mode weighting scheme. Only effective when using the `'mode'` as the `weighting_scheme`.", + ) + args = parser.parse_args() env_local_rank = int(os.environ.get("LOCAL_RANK", -1)) if env_local_rank != -1 and env_local_rank != args.local_rank: @@ -910,8 +949,10 @@ def main(): args.mixed_precision = accelerator.mixed_precision # Load scheduler, tokenizer and models. - if args.not_sigma_loss: + if args.loss_type == "ddpm": noise_scheduler = DDPMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler") + elif args.loss_type == "flow": + noise_scheduler = FlowMatchEulerDiscreteScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler") else: train_diffusion = SpacedDiffusion( use_timesteps=space_timesteps(1000, str(args.train_sampling_steps)), betas=gd.get_named_beta_schedule("linear", 1000), @@ -924,15 +965,27 @@ def main(): tokenizer = BertTokenizer.from_pretrained( args.pretrained_model_name_or_path, subfolder="tokenizer", revision=args.revision ) - print("Init T5Tokenizer") - tokenizer_2 = T5Tokenizer.from_pretrained( - args.pretrained_model_name_or_path, subfolder="tokenizer_2", revision=args.revision - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + print("Init LLM Processor") + tokenizer_2 = Qwen2Tokenizer.from_pretrained( + os.path.join(args.pretrained_model_name_or_path, "tokenizer_2"), revision=args.revision + ) + else: + print("Init T5Tokenizer") + tokenizer_2 = T5Tokenizer.from_pretrained( + args.pretrained_model_name_or_path, subfolder="tokenizer_2", revision=args.revision + ) else: - print("Init T5Tokenizer") - tokenizer = T5Tokenizer.from_pretrained( - args.pretrained_model_name_or_path, subfolder="tokenizer", revision=args.revision - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + print("Init LLM Processor") + tokenizer = Qwen2Tokenizer.from_pretrained( + os.path.join(args.pretrained_model_name_or_path, "tokenizer"), revision=args.revision + ) + else: + print("Init T5Tokenizer") + tokenizer = T5Tokenizer.from_pretrained( + args.pretrained_model_name_or_path, subfolder="tokenizer", revision=args.revision + ) tokenizer_2 = None def deepspeed_zero_init_disabled_context_manager(): @@ -960,15 +1013,27 @@ def main(): args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision, variant=args.variant, torch_dtype=weight_dtype ) - text_encoder_2 = T5EncoderModel.from_pretrained( - args.pretrained_model_name_or_path, subfolder="text_encoder_2", revision=args.revision, variant=args.variant, - torch_dtype=weight_dtype - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder_2 = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(args.pretrained_model_name_or_path, "text_encoder_2"), revision=args.revision, variant=args.variant, + torch_dtype=weight_dtype, + ) + else: + text_encoder_2 = T5EncoderModel.from_pretrained( + args.pretrained_model_name_or_path, subfolder="text_encoder_2", revision=args.revision, variant=args.variant, + torch_dtype=weight_dtype, + ) else: - text_encoder = T5EncoderModel.from_pretrained( - args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision, variant=args.variant, - torch_dtype=weight_dtype - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(args.pretrained_model_name_or_path, "text_encoder"), revision=args.revision, variant=args.variant, + torch_dtype=weight_dtype, + ) + else: + text_encoder = T5EncoderModel.from_pretrained( + args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision, variant=args.variant, + torch_dtype=weight_dtype + ) text_encoder_2 = None # Get Vae @@ -1068,9 +1133,6 @@ def main(): if accelerator.is_main_process: safetensor_save_path = os.path.join(output_dir, f"lora_diffusion_pytorch_model.safetensors") save_model(safetensor_save_path, accelerator.unwrap_model(models[-1])) - if not args.use_deepspeed: - for _ in range(len(weights)): - weights.pop() with open(os.path.join(output_dir, "sampler_pos_start.pkl"), 'wb') as file: pickle.dump([batch_sampler.sampler._pos_start, first_epoch], file) @@ -1819,8 +1881,8 @@ def main(): # timesteps = torch.randint(0, args.train_sampling_steps, (bsz,), device=latents.device, generator=torch_rng) timesteps = idx_sampling(bsz, generator=torch_rng, device=latents.device) timesteps = timesteps.long() - - if args.not_sigma_loss: + + if args.loss_type != "sigma": # Create image_rotary_emb, style embedding & time ids height, width = batch["pixel_values"].size()[-2], batch["pixel_values"].size()[-1] @@ -1864,14 +1926,44 @@ def main(): ) style = style.to(device=latents.device).repeat(bsz) - # Add noise - noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) - if noise_scheduler.config.prediction_type == "epsilon": - target = noise - elif noise_scheduler.config.prediction_type == "v_prediction": - target = noise_scheduler.get_velocity(latents, noise, timesteps) + if args.loss_type == "ddpm": + # Add noise + noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) + if noise_scheduler.config.prediction_type == "epsilon": + target = noise + elif noise_scheduler.config.prediction_type == "v_prediction": + target = noise_scheduler.get_velocity(latents, noise, timesteps) + else: + raise ValueError(f"Unknown prediction type {noise_scheduler.config.prediction_type}") else: - raise ValueError(f"Unknown prediction type {noise_scheduler.config.prediction_type}") + def get_sigmas(timesteps, n_dim=4, dtype=torch.float32): + sigmas = noise_scheduler.sigmas.to(device=accelerator.device, dtype=dtype) + schedule_timesteps = noise_scheduler.timesteps.to(accelerator.device) + timesteps = timesteps.to(accelerator.device) + step_indices = [(schedule_timesteps == t).nonzero().item() for t in timesteps] + + sigma = sigmas[step_indices].flatten() + while len(sigma.shape) < n_dim: + sigma = sigma.unsqueeze(-1) + return sigma + + u = compute_density_for_timestep_sampling( + weighting_scheme=args.weighting_scheme, + batch_size=bsz, + logit_mean=args.logit_mean, + logit_std=args.logit_std, + mode_scale=args.mode_scale, + ) + indices = (u * noise_scheduler.config.num_train_timesteps).long() + timesteps = noise_scheduler.timesteps[indices].to(device=latents.device) + + # Add noise according to flow matching. + # zt = (1 - texp) * x + texp * z1 + sigmas = get_sigmas(timesteps, n_dim=latents.ndim, dtype=latents.dtype) + noisy_latents = (1.0 - sigmas) * latents + sigmas * noise + + # Add noise + target = noise - latents # Predict the noise residual noise_pred = transformer3d( @@ -1892,16 +1984,24 @@ def main(): if noise_pred.size()[1] != vae.config.latent_channels: noise_pred, _ = noise_pred.chunk(2, dim=1) - def custom_mse_loss(noise_pred, target, threshold=50): + def custom_mse_loss(noise_pred, target, weighting=None, threshold=50): noise_pred = noise_pred.float() target = target.float() diff = noise_pred - target mse_loss = F.mse_loss(noise_pred, target, reduction='none') mask = (diff.abs() <= threshold).float() masked_loss = mse_loss * mask + if weighting is not None: + masked_loss = masked_loss * weighting final_loss = masked_loss.mean() return final_loss - loss = custom_mse_loss(noise_pred.float(), target.float()) + + if args.loss_type == "ddpm": + loss = custom_mse_loss(noise_pred.float(), target.float()) + else: + weighting = compute_loss_weighting_for_sd3(weighting_scheme=args.weighting_scheme, sigmas=sigmas) + loss = custom_mse_loss(noise_pred.float(), target.float(), weighting.float()) + loss = loss.mean() if args.motion_sub_loss and noise_pred.size()[2] > 2: gt_sub_noise = noise_pred[:, :, 1:].float() - noise_pred[:, :, :-1].float() diff --git a/scripts/train_lora.sh b/scripts/train_lora.sh index a157220..a5feadd 100644 --- a/scripts/train_lora.sh +++ b/scripts/train_lora.sh @@ -1,4 +1,4 @@ -export MODEL_NAME="models/Diffusion_Transformer/EasyAnimateV5-12b-zh-InP" +export MODEL_NAME="models/Diffusion_Transformer/EasyAnimateV5.1-12b-zh-InP" export DATASET_NAME="datasets/internal_datasets/" export DATASET_META_NAME="datasets/internal_datasets/metadata.json" export NCCL_IB_DISABLE=1 @@ -10,7 +10,7 @@ accelerate launch --mixed_precision="bf16" scripts/train_lora.py \ --pretrained_model_name_or_path=$MODEL_NAME \ --train_data_dir=$DATASET_NAME \ --train_data_meta=$DATASET_META_NAME \ - --config_path "config/easyanimate_video_v5_magvit_multi_text_encoder.yaml" \ + --config_path "config/easyanimate_video_v5.1_magvit_qwen.yaml" \ --image_sample_size=1024 \ --video_sample_size=256 \ --token_sample_size=512 \ @@ -28,13 +28,13 @@ accelerate launch --mixed_precision="bf16" scripts/train_lora.py \ --output_dir="output_dir" \ --gradient_checkpointing \ --mixed_precision="bf16" \ - --adam_weight_decay=5e-3 \ + --adam_weight_decay=5e-2 \ --adam_epsilon=1e-10 \ --vae_mini_batch=1 \ --max_grad_norm=0.05 \ --random_hw_adapt \ --training_with_video_token_length \ - --not_sigma_loss \ + --loss_type="flow" \ --enable_bucket \ --uniform_sampling \ --train_mode="inpaint" \ No newline at end of file diff --git a/scripts/train_reward_lora.py b/scripts/train_reward_lora.py index ac4ec3c..a627ae8 100644 --- a/scripts/train_reward_lora.py +++ b/scripts/train_reward_lora.py @@ -20,7 +20,6 @@ import gc import logging import math import os -import pickle import shutil import sys import json @@ -40,17 +39,16 @@ from accelerate import Accelerator from accelerate.logging import get_logger from accelerate.state import AcceleratorState from accelerate.utils import ProjectConfiguration, set_seed -from diffusers import DDIMScheduler +from diffusers import DDIMScheduler, FlowMatchEulerDiscreteScheduler from diffusers.optimization import get_scheduler -from diffusers.utils import check_min_version, deprecate, is_wandb_available +from diffusers.utils import check_min_version, is_wandb_available from diffusers.utils.import_utils import is_xformers_available -from diffusers.utils.torch_utils import is_compiled_module from decord import VideoReader from einops import rearrange from omegaconf import OmegaConf from packaging import version from tqdm.auto import tqdm -from transformers import BertModel, BertTokenizer, T5EncoderModel, T5Tokenizer +from transformers import BertModel, BertTokenizer, Qwen2Tokenizer, Qwen2VLForConditionalGeneration, T5EncoderModel, T5Tokenizer from transformers.utils import ContextManagers import datasets @@ -66,11 +64,9 @@ from transformers.utils import ContextManagers import easyanimate.reward.reward_fn as reward_fn from easyanimate.models import (name_to_autoencoder_magvit, name_to_transformer3d) -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder import get_3d_rotary_pos_embed, get_resize_crop_region_for_grid -from easyanimate.pipeline.pipeline_easyanimate_multi_text_encoder_inpaint import EasyAnimatePipeline_Multi_Text_Encoder_Inpaint -from easyanimate.utils import gaussian_diffusion as gd +from easyanimate.pipeline.pipeline_easyanimate_inpaint import get_3d_rotary_pos_embed, get_resize_crop_region_for_grid +from easyanimate.pipeline.pipeline_easyanimate_inpaint import EasyAnimateInpaintPipeline from easyanimate.utils.lora_utils import create_network, merge_lora -from easyanimate.utils.respace import SpacedDiffusion, space_timesteps from easyanimate.utils.utils import get_image_to_video_latent, save_videos_grid if is_wandb_available(): @@ -98,99 +94,122 @@ def log_validation( vae, text_encoder, text_encoder_2, tokenizer, tokenizer_2, transformer3d, network, loss_fn, config, args, accelerator, weight_dtype, global_step, validation_prompts_idx ): - logger.info("Running validation... ") + try: + logger.info("Running validation... ") - # Get New Transformer - Choosen_Transformer3DModel = name_to_transformer3d[ - config['transformer_additional_kwargs'].get('transformer_type', 'Transformer3DModel') - ] + # Get New Transformer + Choosen_Transformer3DModel = name_to_transformer3d[ + config['transformer_additional_kwargs'].get('transformer_type', 'Transformer3DModel') + ] - transformer3d_val = Choosen_Transformer3DModel.from_pretrained_2d( - args.pretrained_model_name_or_path, subfolder="transformer", - transformer_additional_kwargs=OmegaConf.to_container(config['transformer_additional_kwargs']) - ).to(weight_dtype) - transformer3d_val.load_state_dict(accelerator.unwrap_model(transformer3d).state_dict()) + transformer3d_val = Choosen_Transformer3DModel.from_pretrained_2d( + args.pretrained_model_name_or_path, subfolder="transformer", + transformer_additional_kwargs=OmegaConf.to_container(config['transformer_additional_kwargs']) + ).to(weight_dtype) + transformer3d_val.load_state_dict(accelerator.unwrap_model(transformer3d).state_dict()) - scheduler = DDIMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler") - pipeline = EasyAnimatePipeline_Multi_Text_Encoder_Inpaint.from_pretrained( - args.pretrained_model_name_or_path, - vae=accelerator.unwrap_model(vae).to(weight_dtype), - text_encoder=accelerator.unwrap_model(text_encoder), - text_encoder_2=accelerator.unwrap_model(text_encoder_2), - tokenizer=tokenizer, - tokenizer_2=tokenizer_2, - transformer=transformer3d_val, - scheduler=scheduler, - torch_dtype=weight_dtype, - ) - pipeline = pipeline.to(accelerator.device) - pipeline = merge_lora( - pipeline, None, 1, accelerator.device, state_dict=accelerator.unwrap_model(network).state_dict(), transformer_only=True - ) - to_tensor = transforms.ToTensor() - validation_loss, validation_reward = 0, 0 + if "EasyAnimateV5.1" in args.pretrained_model_name_or_path: + scheduler = FlowMatchEulerDiscreteScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler") + else: + scheduler = DDIMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler") + + # Initialize a new vae if gradient checkpointing is enabled. + if args.vae_gradient_checkpointing: + # Get Vae + Choosen_AutoencoderKL = name_to_autoencoder_magvit[ + config['vae_kwargs'].get('vae_type', 'AutoencoderKL') + ] + vae = Choosen_AutoencoderKL.from_pretrained( + args.pretrained_model_name_or_path, subfolder="vae", revision=args.revision, variant=args.variant + ).to(weight_dtype) - if args.enable_xformers_memory_efficient_attention \ - and config['transformer_additional_kwargs'].get('transformer_type', 'Transformer3DModel') == 'Transformer3DModel': - pipeline.enable_xformers_memory_efficient_attention() + pipeline = EasyAnimateInpaintPipeline( + vae=vae if args.vae_gradient_checkpointing else accelerator.unwrap_model(vae).to(weight_dtype), + text_encoder=accelerator.unwrap_model(text_encoder), + text_encoder_2=accelerator.unwrap_model(text_encoder_2), + tokenizer=tokenizer, + tokenizer_2=tokenizer_2, + transformer=transformer3d_val, + scheduler=scheduler, + ) + pipeline = pipeline.to(dtype=weight_dtype) + if args.low_vram: + pipeline.enable_model_cpu_offload() + else: + pipeline = pipeline.to(device=accelerator.device) + pipeline = merge_lora( + pipeline, None, 1, accelerator.device, state_dict=accelerator.unwrap_model(network).state_dict(), transformer_only=True + ) + to_tensor = transforms.ToTensor() + validation_loss, validation_reward = 0, 0 - for i in range(len(validation_prompts_idx)): - validation_idx, validation_prompt = validation_prompts_idx[i] - with torch.no_grad(): - with torch.autocast("cuda", dtype=weight_dtype): - if vae.cache_mag_vae: - video_length = int((args.video_length - 1) // vae.mini_batch_encoder * vae.mini_batch_encoder) + 1 if args.video_length != 1 else 1 - else: - video_length = int(args.video_length // vae.mini_batch_encoder * vae.mini_batch_encoder) if args.video_length != 1 else 1 - sample_size = [args.validation_sample_height, args.validation_sample_width] - input_video, input_video_mask, clip_image = get_image_to_video_latent( - None, None, video_length=args.video_length, sample_size=sample_size - ) + if args.enable_xformers_memory_efficient_attention \ + and config['transformer_additional_kwargs'].get('transformer_type', 'Transformer3DModel') == 'Transformer3DModel': + pipeline.enable_xformers_memory_efficient_attention() - if args.seed is None: - generator = None - else: - generator = torch.Generator(device=accelerator.device).manual_seed(args.seed) + for i in range(len(validation_prompts_idx)): + validation_idx, validation_prompt = validation_prompts_idx[i] + with torch.no_grad(): + with torch.autocast("cuda", dtype=weight_dtype): + if vae.cache_mag_vae: + video_length = int((args.video_length - 1) // vae.mini_batch_encoder * vae.mini_batch_encoder) + 1 if args.video_length != 1 else 1 + else: + video_length = int(args.video_length // vae.mini_batch_encoder * vae.mini_batch_encoder) if args.video_length != 1 else 1 + sample_size = [args.validation_sample_height, args.validation_sample_width] + input_video, input_video_mask, clip_image = get_image_to_video_latent( + None, None, video_length=args.video_length, sample_size=sample_size + ) - sample = pipeline( - validation_prompt, - video_length = video_length, - negative_prompt = "bad detailed", - height = args.validation_sample_height, - width = args.validation_sample_width, - guidance_scale = 7, - generator = generator, + if args.seed is None: + generator = None + else: + generator = torch.Generator(device=accelerator.device).manual_seed(args.seed) - video = input_video, - mask_video = input_video_mask, - clip_image = clip_image, - ).videos - sample_saved_path = os.path.join(args.output_dir, f"validation_sample/sample-{global_step}-{validation_idx}.mp4") - save_videos_grid(sample, sample_saved_path, fps=8) + sample = pipeline( + validation_prompt, + video_length = video_length, + negative_prompt = "bad detailed", + height = args.validation_sample_height, + width = args.validation_sample_width, + guidance_scale = 7, + generator = generator, - num_sampled_frames = 4 - sampled_frames_list = [] - with video_reader(sample_saved_path) as vr: - sampled_frame_idx_list = np.linspace(0, len(vr), num_sampled_frames, endpoint=False, dtype=int) - sampled_frame_list = vr.get_batch(sampled_frame_idx_list).asnumpy() - sampled_frames = torch.stack([to_tensor(frame) for frame in sampled_frame_list], dim=0) - sampled_frames_list.append(sampled_frames) - - sampled_frames = torch.stack(sampled_frames_list) - sampled_frames = rearrange(sampled_frames, "b t c h w -> b c t h w") - loss, reward = loss_fn(sampled_frames, [validation_prompt]) - validation_loss, validation_reward = validation_loss + loss, validation_reward + reward - - validation_loss = validation_loss / len(validation_prompts_idx) - validation_reward = validation_reward / len(validation_prompts_idx) + video = input_video, + mask_video = input_video_mask, + clip_image = clip_image, + ).frames + sample_saved_path = os.path.join(args.output_dir, f"validation_sample/sample-{global_step}-{validation_idx}.mp4") + save_videos_grid(sample, sample_saved_path, fps=8) - del pipeline - del transformer3d_val - gc.collect() - torch.cuda.empty_cache() - torch.cuda.ipc_collect() + num_sampled_frames = 4 + sampled_frames_list = [] + with video_reader(sample_saved_path) as vr: + sampled_frame_idx_list = np.linspace(0, len(vr), num_sampled_frames, endpoint=False, dtype=int) + sampled_frame_list = vr.get_batch(sampled_frame_idx_list).asnumpy() + sampled_frames = torch.stack([to_tensor(frame) for frame in sampled_frame_list], dim=0) + sampled_frames_list.append(sampled_frames) + + sampled_frames = torch.stack(sampled_frames_list) + sampled_frames = rearrange(sampled_frames, "b t c h w -> b c t h w") + loss, reward = loss_fn(sampled_frames, [validation_prompt]) + validation_loss, validation_reward = validation_loss + loss, validation_reward + reward + + validation_loss = validation_loss / len(validation_prompts_idx) + validation_reward = validation_reward / len(validation_prompts_idx) - return validation_loss, validation_reward + del pipeline + del transformer3d_val + gc.collect() + torch.cuda.empty_cache() + torch.cuda.ipc_collect() + + return validation_loss, validation_reward + except Exception as e: + gc.collect() + torch.cuda.empty_cache() + torch.cuda.ipc_collect() + print(f"Eval error with info {e}") + return None, None def load_prompts(prompt_path, prompt_column="prompt", start_idx=None, end_idx=None): @@ -211,7 +230,7 @@ def load_prompts(prompt_path, prompt_column="prompt", start_idx=None, end_idx=No return prompt_list -# Modified from EasyAnimatePipeline_Multi_Text_Encoder_Inpaint.encode_prompt +# Modified from EasyAnimateInpaintPipeline.encode_prompt def encode_prompt( tokenizer, tokenizer_2, @@ -254,19 +273,9 @@ def encode_prompt( batch_size = prompt_embeds.shape[0] if prompt_embeds is None: - text_inputs = tokenizer( - prompt, - padding="max_length", - max_length=max_length, - truncation=True, - return_attention_mask=True, - return_tensors="pt", - ) - text_input_ids = text_inputs.input_ids - if text_input_ids.shape[-1] > actual_max_sequence_length: - reprompt = tokenizer.batch_decode(text_input_ids[:, :actual_max_sequence_length], skip_special_tokens=True) + if type(tokenizer) in [BertTokenizer, T5Tokenizer]: text_inputs = tokenizer( - reprompt, + prompt, padding="max_length", max_length=max_length, truncation=True, @@ -274,29 +283,81 @@ def encode_prompt( return_tensors="pt", ) text_input_ids = text_inputs.input_ids - untruncated_ids = tokenizer(prompt, padding="longest", return_tensors="pt").input_ids + if text_input_ids.shape[-1] > actual_max_sequence_length: + reprompt = tokenizer.batch_decode(text_input_ids[:, :actual_max_sequence_length], skip_special_tokens=True) + text_inputs = tokenizer( + reprompt, + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + return_tensors="pt", + ) + text_input_ids = text_inputs.input_ids + untruncated_ids = tokenizer(prompt, padding="longest", return_tensors="pt").input_ids - if untruncated_ids.shape[-1] >= text_input_ids.shape[-1] and not torch.equal( - text_input_ids, untruncated_ids - ): - _actual_max_sequence_length = min(tokenizer.model_max_length, actual_max_sequence_length) - removed_text = tokenizer.batch_decode(untruncated_ids[:, _actual_max_sequence_length - 1 : -1]) - logger.warning( - "The following part of your input was truncated because CLIP can only handle sequences up to" - f" {_actual_max_sequence_length} tokens: {removed_text}" - ) - prompt_attention_mask = text_inputs.attention_mask.to(device) - if enable_text_attention_mask: - prompt_embeds = text_encoder( - text_input_ids.to(device), - attention_mask=prompt_attention_mask, - ) + if untruncated_ids.shape[-1] >= text_input_ids.shape[-1] and not torch.equal( + text_input_ids, untruncated_ids + ): + _actual_max_sequence_length = min(tokenizer.model_max_length, actual_max_sequence_length) + removed_text = tokenizer.batch_decode(untruncated_ids[:, _actual_max_sequence_length - 1 : -1]) + logger.warning( + "The following part of your input was truncated because CLIP can only handle sequences up to" + f" {_actual_max_sequence_length} tokens: {removed_text}" + ) + prompt_attention_mask = text_inputs.attention_mask.to(device) + if enable_text_attention_mask: + prompt_embeds = text_encoder( + text_input_ids.to(device), + attention_mask=prompt_attention_mask, + ) + else: + prompt_embeds = text_encoder( + text_input_ids.to(device) + ) + prompt_embeds = prompt_embeds[0] + prompt_attention_mask = prompt_attention_mask.repeat(num_images_per_prompt, 1) else: - prompt_embeds = text_encoder( - text_input_ids.to(device) + if prompt is not None and isinstance(prompt, str): + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": prompt}], + } + ] + else: + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": _prompt}], + } for _prompt in prompt + ] + text = tokenizer.apply_chat_template( + messages, tokenize=False, add_generation_prompt=True ) - prompt_embeds = prompt_embeds[0] - prompt_attention_mask = prompt_attention_mask.repeat(num_images_per_prompt, 1) + + text_inputs = tokenizer( + text=[text], + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + padding_side="right", + return_tensors="pt", + ) + text_inputs = text_inputs.to(text_encoder.device) + + text_input_ids = text_inputs.input_ids + prompt_attention_mask = text_inputs.attention_mask + if enable_text_attention_mask: + # Inference: Generation of the output + prompt_embeds = text_encoder( + input_ids=text_input_ids, + attention_mask=prompt_attention_mask, + output_hidden_states=True).hidden_states[-2] + else: + raise ValueError("LLM needs attention_mask") + prompt_attention_mask = prompt_attention_mask.repeat(num_images_per_prompt, 1) prompt_embeds = prompt_embeds.to(dtype=dtype, device=device) @@ -304,61 +365,104 @@ def encode_prompt( # duplicate text embeddings for each generation per prompt, using mps friendly method prompt_embeds = prompt_embeds.repeat(1, num_images_per_prompt, 1) prompt_embeds = prompt_embeds.view(bs_embed * num_images_per_prompt, seq_len, -1) + prompt_attention_mask = prompt_attention_mask.to(device=device) # get unconditional embeddings for classifier free guidance if do_classifier_free_guidance and negative_prompt_embeds is None: - uncond_tokens: List[str] - if negative_prompt is None: - uncond_tokens = [""] * batch_size - elif prompt is not None and type(prompt) is not type(negative_prompt): - raise TypeError( - f"`negative_prompt` should be the same type to `prompt`, but got {type(negative_prompt)} !=" - f" {type(prompt)}." - ) - elif isinstance(negative_prompt, str): - uncond_tokens = [negative_prompt] - elif batch_size != len(negative_prompt): - raise ValueError( - f"`negative_prompt`: {negative_prompt} has batch size {len(negative_prompt)}, but `prompt`:" - f" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches" - " the batch size of `prompt`." - ) - else: - uncond_tokens = negative_prompt + if type(tokenizer) in [BertTokenizer, T5Tokenizer]: + uncond_tokens: List[str] + if negative_prompt is None: + uncond_tokens = [""] * batch_size + elif prompt is not None and type(prompt) is not type(negative_prompt): + raise TypeError( + f"`negative_prompt` should be the same type to `prompt`, but got {type(negative_prompt)} !=" + f" {type(prompt)}." + ) + elif isinstance(negative_prompt, str): + uncond_tokens = [negative_prompt] + elif batch_size != len(negative_prompt): + raise ValueError( + f"`negative_prompt`: {negative_prompt} has batch size {len(negative_prompt)}, but `prompt`:" + f" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches" + " the batch size of `prompt`." + ) + else: + uncond_tokens = negative_prompt - max_length = prompt_embeds.shape[1] - uncond_input = tokenizer( - uncond_tokens, - padding="max_length", - max_length=max_length, - truncation=True, - return_tensors="pt", - ) - uncond_input_ids = uncond_input.input_ids - if uncond_input_ids.shape[-1] > actual_max_sequence_length: - reuncond_tokens = tokenizer.batch_decode(uncond_input_ids[:, :actual_max_sequence_length], skip_special_tokens=True) + max_length = prompt_embeds.shape[1] uncond_input = tokenizer( - reuncond_tokens, + uncond_tokens, + padding="max_length", + max_length=max_length, + truncation=True, + return_tensors="pt", + ) + uncond_input_ids = uncond_input.input_ids + if uncond_input_ids.shape[-1] > actual_max_sequence_length: + reuncond_tokens = tokenizer.batch_decode(uncond_input_ids[:, :actual_max_sequence_length], skip_special_tokens=True) + uncond_input = tokenizer( + reuncond_tokens, + padding="max_length", + max_length=max_length, + truncation=True, + return_attention_mask=True, + return_tensors="pt", + ) + uncond_input_ids = uncond_input.input_ids + + negative_prompt_attention_mask = uncond_input.attention_mask.to(device) + if enable_text_attention_mask: + negative_prompt_embeds = text_encoder( + uncond_input.input_ids.to(device), + attention_mask=negative_prompt_attention_mask, + ) + else: + negative_prompt_embeds = text_encoder( + uncond_input.input_ids.to(device) + ) + negative_prompt_embeds = negative_prompt_embeds[0] + negative_prompt_attention_mask = negative_prompt_attention_mask.repeat(num_images_per_prompt, 1) + else: + if negative_prompt is not None and isinstance(negative_prompt, str): + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": negative_prompt}], + } + ] + else: + messages = [ + { + "role": "user", + "content": [{"type": "text", "text": _negative_prompt}], + } for _negative_prompt in negative_prompt + ] + text = tokenizer.apply_chat_template( + messages, tokenize=False, add_generation_prompt=True + ) + + text_inputs = tokenizer( + text=[text], padding="max_length", max_length=max_length, truncation=True, return_attention_mask=True, + padding_side="right", return_tensors="pt", ) - uncond_input_ids = uncond_input.input_ids + text_inputs = text_inputs.to(text_encoder.device) - negative_prompt_attention_mask = uncond_input.attention_mask.to(device) - if enable_text_attention_mask: - negative_prompt_embeds = text_encoder( - uncond_input.input_ids.to(device), - attention_mask=negative_prompt_attention_mask, - ) - else: - negative_prompt_embeds = text_encoder( - uncond_input.input_ids.to(device) - ) - negative_prompt_embeds = negative_prompt_embeds[0] - negative_prompt_attention_mask = negative_prompt_attention_mask.repeat(num_images_per_prompt, 1) + text_input_ids = text_inputs.input_ids + negative_prompt_attention_mask = text_inputs.attention_mask + if enable_text_attention_mask: + # Inference: Generation of the output + negative_prompt_embeds = text_encoder( + input_ids=text_input_ids, + attention_mask=negative_prompt_attention_mask, + output_hidden_states=True).hidden_states[-2] + else: + raise ValueError("LLM needs attention_mask") + negative_prompt_attention_mask = negative_prompt_attention_mask.repeat(num_images_per_prompt, 1) if do_classifier_free_guidance: # duplicate unconditional embeddings for each generation per prompt, using mps friendly method @@ -368,11 +472,12 @@ def encode_prompt( negative_prompt_embeds = negative_prompt_embeds.repeat(1, num_images_per_prompt, 1) negative_prompt_embeds = negative_prompt_embeds.view(batch_size * num_images_per_prompt, seq_len, -1) + negative_prompt_attention_mask = negative_prompt_attention_mask.to(device=device) return prompt_embeds, negative_prompt_embeds, prompt_attention_mask, negative_prompt_attention_mask -# Modified from EasyAnimatePipeline_Multi_Text_Encoder_Inpaint.prepare_extra_step_kwargs +# Modified from EasyAnimateInpaintPipeline.prepare_extra_step_kwargs def prepare_extra_step_kwargs(scheduler, generator, eta): # prepare extra kwargs for the scheduler step, since not all schedulers have the same signature # eta (η) is only used with the DDIMScheduler, it will be ignored for other schedulers. @@ -476,7 +581,12 @@ def parse_args(): parser.add_argument( "--gradient_checkpointing", action="store_true", - help="Whether or not to use gradient checkpointing to save memory at the expense of slower backward pass.", + help="Whether or not to use gradient checkpointing (for DiT) to save memory at the expense of slower backward pass.", + ) + parser.add_argument( + "--vae_gradient_checkpointing", + action="store_true", + help="Whether or not to use gradient checkpointing (for VAE) to save memory at the expense of slower backward pass.", ) parser.add_argument( "--learning_rate", @@ -513,17 +623,6 @@ def parse_args(): " https://pytorch.org/docs/stable/notes/cuda.html#tensorfloat-32-tf32-on-ampere-devices" ), ) - parser.add_argument("--use_ema", action="store_true", help="Whether to use EMA model.") - parser.add_argument( - "--non_ema_revision", - type=str, - default=None, - required=False, - help=( - "Revision of pretrained non-ema model identifier. Must be a branch, tag or git identifier of the local or" - " remote repository specified with --pretrained_model_name_or_path." - ), - ) parser.add_argument( "--dataloader_num_workers", type=int, @@ -539,12 +638,6 @@ def parse_args(): parser.add_argument("--max_grad_norm", default=1.0, type=float, help="Max gradient norm.") parser.add_argument("--push_to_hub", action="store_true", help="Whether or not to push the model to the Hub.") parser.add_argument("--hub_token", type=str, default=None, help="The token to use to push to the Model Hub.") - parser.add_argument( - "--prediction_type", - type=str, - default=None, - help="The prediction_type that shall be used for training. Choose between 'epsilon' or 'v_prediction' or leave `None`. If left to `None` the default prediction type of the scheduler: `noise_scheduler.config.prediciton_type` is chosen.", - ) parser.add_argument( "--hub_model_id", type=str, @@ -611,7 +704,6 @@ def parse_args(): parser.add_argument( "--enable_xformers_memory_efficient_attention", action="store_true", help="Whether or not to use xformers." ) - parser.add_argument("--noise_offset", type=float, default=0, help="The scale of noise offset.") parser.add_argument( "--validation_epochs", type=int, @@ -651,18 +743,6 @@ def parse_args(): action="store_true", help="Whether to train the text encoder. If set, the text encoder should be float32 precision.", ) - parser.add_argument( - "--token_sample_size", - type=int, - default=512, - help="Sample size of the token.", - ) - parser.add_argument( - "--video_sample_n_frames", - type=int, - default=17, - help="Num frame of video.", - ) parser.add_argument( "--config_path", type=str, @@ -688,6 +768,9 @@ def parse_args(): parser.add_argument( "--use_deepspeed", action="store_true", help="Whether or not to use deepspeed." ) + parser.add_argument( + "--low_vram", action="store_true", help="Whether enable low_vram mode." + ) parser.add_argument( "--prompt_path", @@ -760,7 +843,44 @@ def parse_args(): "--backprop", action="store_true", default=False, - help="Whether to use the backprop training mode.", + help="Whether to use the reward backprop training mode.", + ) + parser.add_argument( + "--backprop_step_list", + nargs="+", + type=int, + default=None, + help="The preset step list for reward backprop. If provided, overrides `backprop_strategy`." + ) + parser.add_argument( + "--backprop_strategy", + choices=["last", "tail", "uniform", "random"], + default="last", + help="The strategy for reward backprop." + ) + parser.add_argument( + "--stop_latent_model_input_gradient", + action="store_true", + default=False, + help="Whether to stop the gradient of the latents during reward backprop.", + ) + parser.add_argument( + "--backprop_random_start_step", + type=int, + default=0, + help="The random start step for reward backprop. Only used when `backprop_strategy` is random." + ) + parser.add_argument( + "--backprop_random_end_step", + type=int, + default=50, + help="The random end step for reward backprop. Only used when `backprop_strategy` is random." + ) + parser.add_argument( + "--backprop_num_steps", + type=int, + default=5, + help="The number of steps for backprop. Only used when `backprop_strategy` is tail/uniform/random." ) args = parser.parse_args() @@ -768,10 +888,6 @@ def parse_args(): if env_local_rank != -1 and env_local_rank != args.local_rank: args.local_rank = env_local_rank - # default to using the same revision for the non-ema model if not specified - if args.non_ema_revision is None: - args.non_ema_revision = args.revision - return args @@ -784,15 +900,6 @@ def main(): " Please use `huggingface-cli login` to authenticate with the Hub." ) - if args.non_ema_revision is not None: - deprecate( - "non_ema_revision!=None", - "0.15.0", - message=( - "Downloading 'non_ema' weights from revision branches of the Hub is deprecated. Please make sure to" - " use `--variant=non_ema` instead." - ), - ) logging_dir = os.path.join(args.output_dir, args.logging_dir) config = OmegaConf.load(args.config_path) @@ -804,14 +911,6 @@ def main(): log_with=args.report_to, project_config=accelerator_project_config, ) - - # Sanity check for validation - do_validation = (args.validation_prompt_path is not None or args.validation_prompts is not None) - if do_validation: - if not (os.path.exists(args.validation_prompt_path) or args.validation_prompt_path.endswith(".txt")): - raise ValueError("The `--validation_prompt_path` must be a txt file containing prompts.") - if args.validation_batch_size < accelerator.num_processes or args.validation_batch_size % accelerator.num_processes != 0: - raise ValueError("The `--validation_batch_size` must be divisible by the number of processes.") # Make one log on every process with the configuration for debugging. logging.basicConfig( @@ -828,6 +927,29 @@ def main(): datasets.utils.logging.set_verbosity_error() transformers.utils.logging.set_verbosity_error() diffusers.utils.logging.set_verbosity_error() + + # Sanity check for validation + do_validation = (args.validation_prompt_path is not None or args.validation_prompts is not None) + if do_validation: + if not (os.path.exists(args.validation_prompt_path) or args.validation_prompt_path.endswith(".txt")): + raise ValueError("The `--validation_prompt_path` must be a txt file containing prompts.") + if args.validation_batch_size < accelerator.num_processes or args.validation_batch_size % accelerator.num_processes != 0: + raise ValueError("The `--validation_batch_size` must be divisible by the number of processes.") + + # Sanity check for validation + if args.backprop: + if args.backprop_step_list is not None: + logger.warning( + f"The backprop_strategy {args.backprop_strategy} will be ignored " + f"when using backprop_step_list {args.backprop_step_list}." + ) + assert any(step <= args.num_inference_steps - 1 for step in args.backprop_step_list) + else: + if args.backprop_strategy in set(["tail", "uniform", "random"]): + assert args.backprop_num_steps <= args.num_inference_steps - 1 + if args.backprop_strategy == "random": + assert args.backprop_random_start_step <= args.backprop_random_end_step + assert args.backprop_random_end_step <= args.num_inference_steps - 1 # If passed along, set the training seed now. if args.seed is not None: @@ -849,24 +971,38 @@ def main(): args.mixed_precision = accelerator.mixed_precision # Load scheduler, tokenizer and models. - # Use DDIM instead of DDPM to sample training videos. - noise_scheduler = DDIMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler") - noise_scheduler.set_timesteps(args.num_inference_steps, device=accelerator.device) + if "EasyAnimateV5.1" in args.pretrained_model_name_or_path: + noise_scheduler = FlowMatchEulerDiscreteScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler") + else: + # Use DDIM instead of DDPM to sample training videos. + noise_scheduler = DDIMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler") if config['text_encoder_kwargs'].get('enable_multi_text_encoder', False): print("Init BertTokenizer") tokenizer = BertTokenizer.from_pretrained( args.pretrained_model_name_or_path, subfolder="tokenizer", revision=args.revision ) - print("Init T5Tokenizer") - tokenizer_2 = T5Tokenizer.from_pretrained( - args.pretrained_model_name_or_path, subfolder="tokenizer_2", revision=args.revision - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + print("Init LLM Processor") + tokenizer_2 = Qwen2Tokenizer.from_pretrained( + os.path.join(args.pretrained_model_name_or_path, "tokenizer_2"), revision=args.revision + ) + else: + print("Init T5Tokenizer") + tokenizer_2 = T5Tokenizer.from_pretrained( + args.pretrained_model_name_or_path, subfolder="tokenizer_2", revision=args.revision + ) else: - print("Init T5Tokenizer") - tokenizer = T5Tokenizer.from_pretrained( - args.pretrained_model_name_or_path, subfolder="tokenizer", revision=args.revision - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + print("Init LLM Processor") + tokenizer = Qwen2Tokenizer.from_pretrained( + os.path.join(args.pretrained_model_name_or_path, "tokenizer"), revision=args.revision + ) + else: + print("Init T5Tokenizer") + tokenizer = T5Tokenizer.from_pretrained( + args.pretrained_model_name_or_path, subfolder="tokenizer", revision=args.revision + ) tokenizer_2 = None def deepspeed_zero_init_disabled_context_manager(): @@ -894,15 +1030,27 @@ def main(): args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision, variant=args.variant, torch_dtype=weight_dtype ) - text_encoder_2 = T5EncoderModel.from_pretrained( - args.pretrained_model_name_or_path, subfolder="text_encoder_2", revision=args.revision, variant=args.variant, - torch_dtype=weight_dtype - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder_2 = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(args.pretrained_model_name_or_path, "text_encoder_2"), revision=args.revision, variant=args.variant, + torch_dtype=weight_dtype, + ) + else: + text_encoder_2 = T5EncoderModel.from_pretrained( + args.pretrained_model_name_or_path, subfolder="text_encoder_2", revision=args.revision, variant=args.variant, + torch_dtype=weight_dtype, + ) else: - text_encoder = T5EncoderModel.from_pretrained( - args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision, variant=args.variant, - torch_dtype=weight_dtype - ) + if config['text_encoder_kwargs'].get('replace_t5_to_llm', False): + text_encoder = Qwen2VLForConditionalGeneration.from_pretrained( + os.path.join(args.pretrained_model_name_or_path, "text_encoder"), revision=args.revision, variant=args.variant, + torch_dtype=weight_dtype, + ) + else: + text_encoder = T5EncoderModel.from_pretrained( + args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision, variant=args.variant, + torch_dtype=weight_dtype + ) text_encoder_2 = None # Get Vae @@ -989,15 +1137,20 @@ def main(): if accelerator.is_main_process: safetensor_save_path = os.path.join(output_dir, f"lora_diffusion_pytorch_model.safetensors") save_model(safetensor_save_path, accelerator.unwrap_model(models[-1])) - if not args.use_deepspeed: - for _ in range(len(weights)): - weights.pop() accelerator.register_save_state_pre_hook(save_model_hook) + # Save the model weights directly before save_state instead of using a hook. # accelerator.register_load_state_pre_hook(load_model_hook) if args.gradient_checkpointing: transformer3d.enable_gradient_checkpointing() + + if args.vae_gradient_checkpointing: + # Since 3D casual VAE need a cache to decode all latents autoregressively, .Thus, gradient checkpointing can only be + # enabled when decoding the first batch (i.e. the first three) of latents, in which case the cache is not being used. + if args.num_decoded_latents > 3: + raise ValueError("The vae_gradient_checkpointing is not supported for num_decoded_latents > 3.") + vae.enable_gradient_checkpointing() # Enable TF32 for faster training on Ampere GPUs, # cf https://pytorch.org/docs/stable/notes/cuda.html#tensorfloat-32-tf32-on-ampere-devices @@ -1101,14 +1254,9 @@ def main(): if accelerator.is_main_process: tracker_config = dict(vars(args)) tracker_config.pop("validation_prompts") + tracker_config.pop("backprop_step_list", None) accelerator.init_trackers(args.tracker_project_name, tracker_config) - # Function for unwrapping if model was compiled with `torch.compile`. - def unwrap_model(model): - model = accelerator.unwrap_model(model) - model = model._orig_mod if is_compiled_module(model) else model - return model - # Train! total_batch_size = args.train_batch_size * accelerator.num_processes * args.gradient_accumulation_steps @@ -1144,14 +1292,6 @@ def main(): initial_global_step = global_step - pkl_path = os.path.join(os.path.join(args.output_dir, path), "sampler_pos_start.pkl") - if os.path.exists(pkl_path): - with open(pkl_path, 'rb') as file: - _, first_epoch = pickle.load(file) - else: - first_epoch = global_step // num_update_steps_per_epoch - print(f"Load pkl from {pkl_path}. Get first_epoch = {first_epoch}.") - from safetensors.torch import load_file, safe_open state_dict = load_file(os.path.join(os.path.join(args.output_dir, path), "lora_diffusion_pytorch_model.safetensors")) m, u = accelerator.unwrap_model(network).load_state_dict(state_dict, strict=False) @@ -1181,7 +1321,7 @@ def main(): train_reward = 0.0 # In the following training loop, randomly select training prompts and use the - # `EasyAnimatePipeline_Multi_Text_Encoder_Inpaint` to sample videos, calculate rewards, and update the network. + # `EasyAnimatePipelineInpaint` to sample videos, calculate rewards, and update the network. for _ in range(num_update_steps_per_epoch): # train_prompt = random.sample(prompt_list, args.train_batch_size) train_prompt = random.choices(prompt_list, k=args.train_batch_size) @@ -1196,6 +1336,13 @@ def main(): # corresponds to doing no classifier free guidance. do_classifier_free_guidance = args.guidance_scale > 1.0 + # Reduce the vram by offload text encoders + if args.low_vram: + torch.cuda.empty_cache() + text_encoder.to(accelerator.device) + if text_encoder_2 is not None: + text_encoder_2.to(accelerator.device) + # Encode input prompt ( prompt_embeds, @@ -1215,26 +1362,43 @@ def main(): text_encoder_index=0, enable_text_attention_mask=transformer3d.config.enable_text_attention_mask, ) - ( - prompt_embeds_2, - negative_prompt_embeds_2, - prompt_attention_mask_2, - negative_prompt_attention_mask_2, - ) = encode_prompt( - tokenizer, - tokenizer_2, - text_encoder, - text_encoder_2, - train_prompt, - device=accelerator.device, - dtype=weight_dtype, - do_classifier_free_guidance=do_classifier_free_guidance, - negative_prompt=[""] * len(train_prompt), - text_encoder_index=1, - enable_text_attention_mask=transformer3d.config.enable_text_attention_mask, - ) + if tokenizer_2 is not None: + ( + prompt_embeds_2, + negative_prompt_embeds_2, + prompt_attention_mask_2, + negative_prompt_attention_mask_2, + ) = encode_prompt( + tokenizer, + tokenizer_2, + text_encoder, + text_encoder_2, + train_prompt, + device=accelerator.device, + dtype=weight_dtype, + do_classifier_free_guidance=do_classifier_free_guidance, + negative_prompt=[""] * len(train_prompt), + text_encoder_index=1, + enable_text_attention_mask=transformer3d.config.enable_text_attention_mask, + ) + else: + prompt_embeds_2 = None + negative_prompt_embeds_2 = None + prompt_attention_mask_2 = None + negative_prompt_attention_mask_2 = None + + # Reduce the vram by offload text encoders + if args.low_vram: + text_encoder.to("cpu") + if text_encoder_2 is not None: + text_encoder_2.to("cpu") + torch.cuda.empty_cache() # Prepare timesteps + if hasattr(noise_scheduler, "use_dynamic_shifting") and noise_scheduler.use_dynamic_shifting: + noise_scheduler.set_timesteps(args.num_inference_steps, device=accelerator.device, mu=1) + else: + noise_scheduler.set_timesteps(args.num_inference_steps, device=accelerator.device) timesteps = noise_scheduler.timesteps # Prepare latent variables @@ -1252,7 +1416,9 @@ def main(): with accelerator.accumulate(transformer3d): with accelerator.autocast(): latents = torch.randn(*latent_shape, device=accelerator.device, dtype=weight_dtype) - latents = latents * noise_scheduler.init_noise_sigma + + if hasattr(noise_scheduler, "init_noise_sigma"): + latents = latents * noise_scheduler.init_noise_sigma # Prepare inpaint latents if it needs. # Use zero latents if we want to t2v. @@ -1307,36 +1473,47 @@ def main(): if do_classifier_free_guidance: prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds]) prompt_attention_mask = torch.cat([negative_prompt_attention_mask, prompt_attention_mask]) - prompt_embeds_2 = torch.cat([negative_prompt_embeds_2, prompt_embeds_2]) - prompt_attention_mask_2 = torch.cat([negative_prompt_attention_mask_2, prompt_attention_mask_2]) + if prompt_embeds_2 is not None: + prompt_embeds_2 = torch.cat([negative_prompt_embeds_2, prompt_embeds_2]) + prompt_attention_mask_2 = torch.cat([negative_prompt_attention_mask_2, prompt_attention_mask_2]) add_time_ids = torch.cat([add_time_ids] * 2, dim=0) style = torch.cat([style] * 2, dim=0) prompt_embeds = prompt_embeds.to(device=accelerator.device) prompt_attention_mask = prompt_attention_mask.to(device=accelerator.device) - prompt_embeds_2 = prompt_embeds_2.to(device=accelerator.device) - prompt_attention_mask_2 = prompt_attention_mask_2.to(device=accelerator.device) + if prompt_embeds_2 is not None: + prompt_embeds_2 = prompt_embeds_2.to(device=accelerator.device) + prompt_attention_mask_2 = prompt_attention_mask_2.to(device=accelerator.device) add_time_ids = add_time_ids.to(dtype=prompt_embeds.dtype, device=accelerator.device).repeat( args.train_batch_size, 1 ) style = style.to(device=accelerator.device).repeat(args.train_batch_size) # Denoising loop - for i, t in enumerate(tqdm(timesteps)): - # the reward gradient is back propagated only for the last K steps. - if args.backprop: - # backprop_cutoff_idx = random.randint(0, args.num_sampling_steps - 1) # random - backprop_cutoff_idx = args.num_inference_steps - 1 # last - if i >= backprop_cutoff_idx: - for param in network.parameters(): - param.requires_grad = True + if args.backprop: + if args.backprop_step_list is None: + if args.backprop_strategy == "last": + backprop_step_list = [args.num_inference_steps - 1] + elif args.backprop_strategy == "tail": + backprop_step_list = list(range(args.num_inference_steps))[-args.backprop_num_steps:] + elif args.backprop_strategy == "uniform": + interval = args.num_inference_steps // args.backprop_num_steps + random_start = random.randint(0, interval) + backprop_step_list = [random_start + i * interval for i in range(args.backprop_num_steps)] + elif args.backprop_strategy == "random": + backprop_step_list = random.sample( + range(args.backprop_random_start_step, args.backprop_random_end_step + 1), args.backprop_num_steps + ) else: - for param in network.parameters(): - param.requires_grad = False - + raise ValueError(f"Invalid backprop strategy: {args.backprop_strategy}.") + else: + backprop_step_list = args.backprop_step_list + + for i, t in enumerate(tqdm(timesteps)): # expand the latents if we are doing classifier free guidance latent_model_input = torch.cat([latents] * 2) if do_classifier_free_guidance else latents - latent_model_input = noise_scheduler.scale_model_input(latent_model_input, t) + if hasattr(noise_scheduler, "scale_model_input"): + latent_model_input = noise_scheduler.scale_model_input(latent_model_input, t) # expand scalar t to 1-D tensor to match the 1st dim of latent_model_input t_expand = torch.tensor([t] * latent_model_input.shape[0], device=accelerator.device).to( @@ -1344,6 +1521,9 @@ def main(): ) # predict the noise residual + if args.stop_latent_model_input_gradient: + # See https://arxiv.org/abs/2405.00760 + latent_model_input = latent_model_input.detach() noise_pred = transformer3d( latent_model_input, t_expand, @@ -1360,6 +1540,12 @@ def main(): return_dict=False, )[0] + # Optimize the denoising results only for the specified steps. + if i in backprop_step_list: + noise_pred = noise_pred + else: + noise_pred = noise_pred.detach() + # perform guidance if do_classifier_free_guidance: noise_pred_uncond, noise_pred_text = noise_pred.chunk(2) @@ -1406,9 +1592,12 @@ def main(): accelerator.backward(loss) if accelerator.sync_gradients: total_norm = accelerator.clip_grad_norm_(trainable_params, args.max_grad_norm) - # If `args.use_deepspeed` is enabled, `total_norm` cannot be logged by accelerator. + # If use_deepspeed, `total_norm` cannot be logged by accelerator. if not args.use_deepspeed: accelerator.log({"total_norm": total_norm}, step=global_step) + else: + if hasattr(optimizer, "optimizer") and hasattr(optimizer.optimizer, "_global_grad_norm"): + accelerator.log({"total_norm": optimizer.optimizer._global_grad_norm}, step=global_step) optimizer.step() lr_scheduler.step() optimizer.zero_grad() @@ -1482,11 +1671,15 @@ def main(): global_step, splitted_prompts_idx ) - avg_validation_loss = accelerator.gather(validation_loss).mean() - avg_validation_reward = accelerator.gather(validation_reward).mean() - accelerator.print(avg_validation_loss, avg_validation_reward) - if accelerator.is_main_process: - accelerator.log({"validation_loss": avg_validation_loss, "validation_reward": avg_validation_reward}, step=global_step) + if validation_loss is not None and validation_reward is not None: + avg_validation_loss = accelerator.gather(validation_loss).mean() + avg_validation_reward = accelerator.gather(validation_reward).mean() + accelerator.print(avg_validation_loss, avg_validation_reward) + if accelerator.is_main_process: + accelerator.log( + {"validation_loss": avg_validation_loss, "validation_reward": avg_validation_reward}, + step=global_step + ) accelerator.wait_for_everyone() diff --git a/scripts/train_reward_lora.sh b/scripts/train_reward_lora.sh index deb0e88..463fabf 100644 --- a/scripts/train_reward_lora.sh +++ b/scripts/train_reward_lora.sh @@ -23,6 +23,8 @@ accelerate launch --num_processes=8 --mixed_precision="bf16" --use_deepspeed --d --adam_weight_decay=3e-2 \ --adam_epsilon=1e-10 \ --max_grad_norm=0.3 \ + --low_vram \ + --use_deepspeed \ --prompt_path=$TRAIN_PROMPT_PATH \ --train_sample_height=256 \ --train_sample_width=256 \ @@ -33,4 +35,42 @@ accelerate launch --num_processes=8 --mixed_precision="bf16" --use_deepspeed --d --num_decoded_latents=1 \ --reward_fn="HPSReward" \ --reward_fn_kwargs='{"version": "v2.1"}' \ - --backprop \ No newline at end of file + --backprop + +# For V5.1 +# export MODEL_NAME="models/Diffusion_Transformer/EasyAnimateV5.1-12b-zh-InP" +# export TRAIN_PROMPT_PATH="MovieGenVideoBench_train.txt" +# # Performing validation simultaneously with training will increase time and GPU memory usage. +# export VALIDATION_PROMPT_PATH="MovieGenVideoBench_val.txt" + +# export NCCL_IB_DISABLE=1 +# export NCCL_P2P_DISABLE=1 +# NCCL_DEBUG=INFO + +# # When train model with multi machines, use "--config_file accelerate.yaml" instead of "--mixed_precision='bf16'". +# accelerate launch --num_processes=8 --mixed_precision="bf16" --use_deepspeed --deepspeed_config_file config/zero_stage2_config.json scripts/train_reward_lora.py \ +# --pretrained_model_name_or_path=$MODEL_NAME \ +# --config_path="config/easyanimate_video_v5.1_magvit_qwen.yaml" \ +# --train_batch_size=1 \ +# --gradient_accumulation_steps=1 \ +# --max_train_steps=10000 \ +# --checkpointing_steps=100 \ +# --learning_rate=1e-05 \ +# --seed=42 \ +# --output_dir="output_dir" \ +# --gradient_checkpointing \ +# --mixed_precision="bf16" \ +# --adam_weight_decay=3e-2 \ +# --adam_epsilon=1e-10 \ +# --max_grad_norm=0.3 \ +# --low_vram \ +# --use_deepspeed \ +# --prompt_path=$TRAIN_PROMPT_PATH \ +# --train_sample_height=256 \ +# --train_sample_width=256 \ +# --video_length=49 \ +# --num_decoded_latents=1 \ +# --reward_fn="HPSReward" \ +# --reward_fn_kwargs='{"version": "v2.1"}' \ +# --backprop_strategy "tail" \ +# --backprop_num_steps 10 \ No newline at end of file