Upload 2 files
Browse files- README.md +229 -3
- README_zh.md +230 -0
README.md
CHANGED
@@ -1,3 +1,229 @@
|
|
1 |
-
---
|
2 |
-
license: apache-2.0
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
license: apache-2.0
|
3 |
+
base_model:
|
4 |
+
- THUDM/CogVideoX-5b
|
5 |
+
language:
|
6 |
+
- en
|
7 |
+
tags:
|
8 |
+
- video-generation
|
9 |
+
- paddlemix
|
10 |
+
---
|
11 |
+
|
12 |
+
Englishh | [简体中文](README_zh.md)
|
13 |
+
# VCtrl
|
14 |
+
<p style="text-align: center;">
|
15 |
+
<p align="center">
|
16 |
+
<a href="https://huggingface.co/PaddleMIX">🤗 Huggingface Space</a> |
|
17 |
+
<a href="https://github.com/PaddlePaddle/PaddleMIX/tree/develop/ppdiffusers/examples/ppvctrl">🌐 Github </a> |
|
18 |
+
<a href="">📜 arxiv </a> |
|
19 |
+
<a href="https://pp-vctrl.github.io/">📷 Project </a>
|
20 |
+
</p>
|
21 |
+
|
22 |
+
## Model Introduction
|
23 |
+
**VCtrl** is a versatile video generation control model that introduces an auxiliary conditional encoder to flexibly connect with various control modules while avoiding large-scale retraining of the original generator. The model efficiently transmits control signals through sparse residual connections and standardizes diverse control inputs into a unified representation via a consistent encoding process. Task-specific masks are further incorporated to enhance adaptability. Thanks to this unified and flexible design, VCtrl can be widely applied in **character animation**, **scene transition**, **video editing**, and other video generation scenarios. The table below provides detailed information about the video generation models we offer:
|
24 |
+
|
25 |
+
<table style="border-collapse: collapse; width: 100%;">
|
26 |
+
<tr>
|
27 |
+
<th style="text-align: center;">Model Name</th>
|
28 |
+
<th style="text-align: center;">VCtrl-Canny</th>
|
29 |
+
<th style="text-align: center;">VCtrl-Mask</th>
|
30 |
+
<th style="text-align: center;">VCtrl-Pose</th>
|
31 |
+
</tr>
|
32 |
+
<tr>
|
33 |
+
<td style="text-align: center;">Video Resolution</td>
|
34 |
+
<td colspan="1" style="text-align: center;">720 * 480</td>
|
35 |
+
<td colspan="1" style="text-align: center;"> 720 * 480 </td>
|
36 |
+
<td colspan="1 style="text-align: center;"> 720 * 480 & 480 * 720 </td>
|
37 |
+
</tr>
|
38 |
+
<tr>
|
39 |
+
<td style="text-align: center;">Inference Precision</td>
|
40 |
+
<td colspan="3" style="text-align: center;"><b>FP16(Recommended)</b></td>
|
41 |
+
</tr>
|
42 |
+
<tr>
|
43 |
+
<td style="text-align: center;">Single GPU VRAM Usage</td>
|
44 |
+
<td colspan="3" style="text-align: center;"><b>V100: 32GB minimum*</b></td>
|
45 |
+
</tr>
|
46 |
+
<tr>
|
47 |
+
<td style="text-align: center;">Inference Speed<br>(Step = 25, FP16)</td>
|
48 |
+
<td colspan="3" style="text-align: center;">Single A100: ~300s(49 frames)<br>Single V100: ~400s(49 frames)</td>
|
49 |
+
</tr>
|
50 |
+
<tr>
|
51 |
+
<td style="text-align: center;">Prompt Language</td>
|
52 |
+
<td colspan="5" style="text-align: center;">English*</td>
|
53 |
+
</tr>
|
54 |
+
<tr>
|
55 |
+
<td style="text-align: center;">Prompt Length Limit</td>
|
56 |
+
<td colspan="3" style="text-align: center;">224 Tokens</td>
|
57 |
+
</tr>
|
58 |
+
<tr>
|
59 |
+
<td style="text-align: center;">Video Length</td>
|
60 |
+
<td colspan="3" style="text-align: center;">T2V model supports only 49 frames, I2V model can extend to any frame count</td>
|
61 |
+
</tr>
|
62 |
+
<tr>
|
63 |
+
<td style="text-align: center;">Frame Rate</td>
|
64 |
+
<td colspan="3" style="text-align: center;">30 FPS </td>
|
65 |
+
</tr>
|
66 |
+
</table>
|
67 |
+
|
68 |
+
## Quick Start 🤗
|
69 |
+
|
70 |
+
This model is now supported for deployment using the ppdiffusers library from paddlemix. Follow the steps below to get started.
|
71 |
+
|
72 |
+
**We recommend visiting our [github](https://github.com/PaddlePaddle/PaddleMIX/tree/develop/ppdiffusers/examples/ppvctrl) for a better experience.**
|
73 |
+
|
74 |
+
1. Install dependencies
|
75 |
+
|
76 |
+
```shell
|
77 |
+
# Clone the PaddleMIX repository
|
78 |
+
git clone https://github.com/PaddlePaddle/PaddleMIX.git
|
79 |
+
# Install paddlemix
|
80 |
+
cd PaddleMIX
|
81 |
+
pip install -e .
|
82 |
+
# Install ppdiffusers
|
83 |
+
pip install -e ppdiffusers
|
84 |
+
# Install paddlenlp
|
85 |
+
pip install paddlenlp==v3.0.0-beta2
|
86 |
+
# Navigate to the vctrl directory
|
87 |
+
cd ppdiffusers/examples/ppvctrl
|
88 |
+
# Install other required dependencies
|
89 |
+
pip install -r requirements.txt
|
90 |
+
# Install paddlex
|
91 |
+
pip install paddlex==3.0.0b2
|
92 |
+
```
|
93 |
+
|
94 |
+
2. Run the code
|
95 |
+
|
96 |
+
```python
|
97 |
+
import os
|
98 |
+
import paddle
|
99 |
+
import numpy as np
|
100 |
+
from decord import VideoReader
|
101 |
+
from moviepy.editor import ImageSequenceClip
|
102 |
+
from PIL import Image
|
103 |
+
from ppdiffusers import (
|
104 |
+
CogVideoXDDIMScheduler,
|
105 |
+
CogVideoXTransformer3DVCtrlModel,
|
106 |
+
CogVideoXVCtrlPipeline,
|
107 |
+
VCtrlModel,
|
108 |
+
)
|
109 |
+
def write_mp4(video_path, samples, fps=8):
|
110 |
+
clip = ImageSequenceClip(samples, fps=fps)
|
111 |
+
clip.write_videofile(video_path, audio_codec="aac")
|
112 |
+
|
113 |
+
|
114 |
+
def save_vid_side_by_side(batch_output, validation_control_images, output_folder, fps):
|
115 |
+
flattened_batch_output = [img for sublist in batch_output for img in sublist]
|
116 |
+
ori_video_path = output_folder + "/origin_predict.mp4"
|
117 |
+
video_path = output_folder + "/test_1.mp4"
|
118 |
+
ori_final_images = []
|
119 |
+
final_images = []
|
120 |
+
outputs = []
|
121 |
+
|
122 |
+
def get_concat_h(im1, im2):
|
123 |
+
dst = Image.new("RGB", (im1.width + im2.width, max(im1.height, im2.height)))
|
124 |
+
dst.paste(im1, (0, 0))
|
125 |
+
dst.paste(im2, (im1.width, 0))
|
126 |
+
return dst
|
127 |
+
|
128 |
+
for image_list in zip(validation_control_images, flattened_batch_output):
|
129 |
+
predict_img = image_list[1].resize(image_list[0].size)
|
130 |
+
result = get_concat_h(image_list[0], predict_img)
|
131 |
+
ori_final_images.append(np.array(image_list[1]))
|
132 |
+
final_images.append(np.array(result))
|
133 |
+
outputs.append(np.array(predict_img))
|
134 |
+
write_mp4(ori_video_path, ori_final_images, fps=fps)
|
135 |
+
write_mp4(video_path, final_images, fps=fps)
|
136 |
+
output_path = output_folder + "/output.mp4"
|
137 |
+
write_mp4(output_path, outputs, fps=fps)
|
138 |
+
|
139 |
+
|
140 |
+
def load_images_from_folder_to_pil(folder):
|
141 |
+
images = []
|
142 |
+
valid_extensions = {".jpg", ".jpeg", ".png", ".bmp", ".gif", ".tiff"}
|
143 |
+
|
144 |
+
def frame_number(filename):
|
145 |
+
new_pattern_match = re.search("frame_(\\d+)_7fps", filename)
|
146 |
+
if new_pattern_match:
|
147 |
+
return int(new_pattern_match.group(1))
|
148 |
+
matches = re.findall("\\d+", filename)
|
149 |
+
if matches:
|
150 |
+
if matches[-1] == "0000" and len(matches) > 1:
|
151 |
+
return int(matches[-2])
|
152 |
+
return int(matches[-1])
|
153 |
+
return float("inf")
|
154 |
+
|
155 |
+
sorted_files = sorted(os.listdir(folder), key=frame_number)
|
156 |
+
for filename in sorted_files:
|
157 |
+
ext = os.path.splitext(filename)[1].lower()
|
158 |
+
if ext in valid_extensions:
|
159 |
+
img = Image.open(os.path.join(folder, filename)).convert("RGB")
|
160 |
+
images.append(img)
|
161 |
+
return images
|
162 |
+
|
163 |
+
|
164 |
+
def load_images_from_video_to_pil(video_path):
|
165 |
+
images = []
|
166 |
+
vr = VideoReader(video_path)
|
167 |
+
length = len(vr)
|
168 |
+
for idx in range(length):
|
169 |
+
frame = vr[idx].asnumpy()
|
170 |
+
images.append(Image.fromarray(frame))
|
171 |
+
return images
|
172 |
+
|
173 |
+
|
174 |
+
validation_control_images = load_images_from_video_to_pil('your_path')
|
175 |
+
prompt = 'Group of fishes swimming in aquarium.'
|
176 |
+
vctrl = VCtrlModel.from_pretrained(
|
177 |
+
paddlemix/vctrl-5b-t2v-canny,
|
178 |
+
low_cpu_mem_usage=True,
|
179 |
+
paddle_dtype=paddle.float16
|
180 |
+
)
|
181 |
+
pipeline = CogVideoXVCtrlPipeline.from_pretrained(
|
182 |
+
paddlemix/cogvideox-5b-vctrl,
|
183 |
+
vctrl=vctrl,
|
184 |
+
paddle_dtype=paddle.float16,
|
185 |
+
low_cpu_mem_usage=True,
|
186 |
+
map_location="cpu",
|
187 |
+
)
|
188 |
+
pipeline.scheduler = CogVideoXDDIMScheduler.from_config(pipeline.scheduler.config, timestep_spacing="trailing")
|
189 |
+
pipeline.vae.enable_tiling()
|
190 |
+
pipeline.vae.enable_slicing()
|
191 |
+
task='canny'
|
192 |
+
final_result=[]
|
193 |
+
video = pipeline(
|
194 |
+
prompt=prompt,
|
195 |
+
num_inference_steps=25,
|
196 |
+
num_frames=49,
|
197 |
+
guidance_scale=35,
|
198 |
+
generator=paddle.Generator().manual_seed(42),
|
199 |
+
conditioning_frames=validation_control_images[:num_frames],
|
200 |
+
conditioning_frame_indices=list(range(num_frames)),
|
201 |
+
conditioning_scale=1.0,
|
202 |
+
width=720,
|
203 |
+
height=480,
|
204 |
+
task='canny',
|
205 |
+
conditioning_masks=validation_mask_images[:num_frames] if task == "mask" else None,
|
206 |
+
vctrl_layout_type='spacing',
|
207 |
+
).frames[0]
|
208 |
+
final_result.append(video)
|
209 |
+
save_vid_side_by_side(final_result, validation_control_images[:num_frames], 'save.mp4', fps=30)
|
210 |
+
```
|
211 |
+
|
212 |
+
## In-Depth Exploration
|
213 |
+
|
214 |
+
Welcome to our[github]("https://github.com/PaddlePaddle/PaddleMIX/tree/develop/ppdiffusers/examples/ppvctrl"), where you will find:
|
215 |
+
|
216 |
+
1. More detailed technical explanations and code walkthroughs.
|
217 |
+
2. Algorithm details for extracting control conditions.
|
218 |
+
3. Detailed code for model inference.
|
219 |
+
4. Project update logs and more interactive opportunities.
|
220 |
+
5. PaddleMix toolchain to help you better utilize the model.
|
221 |
+
|
222 |
+
## Citation
|
223 |
+
|
224 |
+
```
|
225 |
+
@article{yang2024cogvideox,
|
226 |
+
title={VCtrl: Enabling Versatile Controls for Video Diffusion Models},
|
227 |
+
year={2025}
|
228 |
+
}
|
229 |
+
```
|
README_zh.md
ADDED
@@ -0,0 +1,230 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
license: apache-2.0
|
3 |
+
base_model:
|
4 |
+
- THUDM/CogVideoX-5b
|
5 |
+
language:
|
6 |
+
- en
|
7 |
+
tags:
|
8 |
+
- video-generation
|
9 |
+
- paddlemix
|
10 |
+
---
|
11 |
+
|
12 |
+
简体中文 | [English](README.md)
|
13 |
+
# VCtrl
|
14 |
+
<p style="text-align: center;">
|
15 |
+
<p align="center">
|
16 |
+
<a href="https://huggingface.co/PaddleMIX">🤗 Huggingface Space</a> |
|
17 |
+
<a href="https://github.com/PaddlePaddle/PaddleMIX/tree/develop/ppdiffusers/examples/ppvctrl">🌐 Github </a> |
|
18 |
+
<a href="">📜 arxiv </a> |
|
19 |
+
<a href="https://pp-vctrl.github.io/">📷 Project </a>
|
20 |
+
</p>
|
21 |
+
|
22 |
+
## 模型介绍
|
23 |
+
**VCtrl** 是一个通用的视频生成控制模型,通过引入辅助条件编码器,能够灵活对接各类控制模块,并且在不改变原始生成器的前提下避免了大规模重训练。该模型利用稀疏残差连接实现对控制信号的高效传递,同时通过统一的条件编码流程,将多种控制输入转换为标准化表示,再结合任务特定掩码以提升适应性。得益于这种统一而灵活的设计,VCtrl 可广泛应用于**人物动画**、**场景转换**、**视频编辑**等视频生成场景。下表展示我们在本代提供的视频生成模型列表相关信息:
|
24 |
+
|
25 |
+
<table style="border-collapse: collapse; width: 100%;">
|
26 |
+
<tr>
|
27 |
+
<th style="text-align: center;">模型名</th>
|
28 |
+
<th style="text-align: center;">VCtrl-Canny</th>
|
29 |
+
<th style="text-align: center;">VCtrl-Mask</th>
|
30 |
+
<th style="text-align: center;">VCtrl-Pose</th>
|
31 |
+
</tr>
|
32 |
+
<tr>
|
33 |
+
<td style="text-align: center;">视频分辨率</td>
|
34 |
+
<td colspan="1" style="text-align: center;">720 * 480</td>
|
35 |
+
<td colspan="1" style="text-align: center;"> 720*480 </td>
|
36 |
+
<td colspan="1" style="text-align: center;"> 720*480 & 480*720 </td>
|
37 |
+
</tr>
|
38 |
+
<tr>
|
39 |
+
<td style="text-align: center;">推理精度</td>
|
40 |
+
<td colspan="3" style="text-align: center;"><b>FP16(推荐)</b></td>
|
41 |
+
</tr>
|
42 |
+
<tr>
|
43 |
+
<td style="text-align: center;">单GPU显存消耗</td>
|
44 |
+
<td colspan="3" style="text-align: center;"><b>V100: 32GB minimum*</b></td>
|
45 |
+
</tr>
|
46 |
+
<tr>
|
47 |
+
<td style="text-align: center;">推理速度<br>(Step = 25, FP16)</td>
|
48 |
+
<td colspan="3" style="text-align: center;">单卡A100: ~300秒(49帧)<br>单卡V100: ~400秒(49帧)</td>
|
49 |
+
</tr>
|
50 |
+
<tr>
|
51 |
+
<td style="text-align: center;">提示词语言</td>
|
52 |
+
<td colspan="5" style="text-align: center;">English*</td>
|
53 |
+
</tr>
|
54 |
+
<tr>
|
55 |
+
<td style="text-align: center;">提示词长度上限</td>
|
56 |
+
<td colspan="3" style="text-align: center;">224 Tokens</td>
|
57 |
+
</tr>
|
58 |
+
<tr>
|
59 |
+
<td style="text-align: center;">视频长度</td>
|
60 |
+
<td colspan="3" style="text-align: center;">T2V模型只支持49帧,I2V模型可以扩展为任意帧</td>
|
61 |
+
</tr>
|
62 |
+
<tr>
|
63 |
+
<td style="text-align: center;">帧率</td>
|
64 |
+
<td colspan="3" style="text-align: center;">30 帧 / 秒 </td>
|
65 |
+
</tr>
|
66 |
+
</table>
|
67 |
+
|
68 |
+
## 快速开始 🤗
|
69 |
+
|
70 |
+
本模型已经支持使用 paddlemix 的 ppdiffusers 库进行部署,你可以按照以下步骤进行部署。
|
71 |
+
|
72 |
+
**我们推荐您进入我们的 [github](https://github.com/PaddlePaddle/PaddleMIX/tree/develop/ppdiffusers/examples/ppvctrl)以获得更好的体验。**
|
73 |
+
|
74 |
+
1. 安装对应的依赖
|
75 |
+
|
76 |
+
```shell
|
77 |
+
# 克隆 PaddleMIX 仓库
|
78 |
+
git clone https://github.com/PaddlePaddle/PaddleMIX.git
|
79 |
+
#安装paddlemix
|
80 |
+
cd PaddleMIX
|
81 |
+
pip install -e .
|
82 |
+
# 安装ppdiffusers
|
83 |
+
pip install -e ppdiffusers
|
84 |
+
# 安装paddlenlp
|
85 |
+
pip install paddlenlp==v3.0.0-beta2
|
86 |
+
# 进入 vctrl目录
|
87 |
+
cd ppdiffusers/examples/ppvctrl
|
88 |
+
# 安装其他所需的依赖
|
89 |
+
pip install -r requirements.txt
|
90 |
+
#安装paddlex
|
91 |
+
pip install paddlex==3.0.0b2
|
92 |
+
|
93 |
+
```
|
94 |
+
|
95 |
+
2. 运行代码
|
96 |
+
|
97 |
+
```python
|
98 |
+
import os
|
99 |
+
import paddle
|
100 |
+
import numpy as np
|
101 |
+
from decord import VideoReader
|
102 |
+
from moviepy.editor import ImageSequenceClip
|
103 |
+
from PIL import Image
|
104 |
+
from ppdiffusers import (
|
105 |
+
CogVideoXDDIMScheduler,
|
106 |
+
CogVideoXTransformer3DVCtrlModel,
|
107 |
+
CogVideoXVCtrlPipeline,
|
108 |
+
VCtrlModel,
|
109 |
+
)
|
110 |
+
def write_mp4(video_path, samples, fps=8):
|
111 |
+
clip = ImageSequenceClip(samples, fps=fps)
|
112 |
+
clip.write_videofile(video_path, audio_codec="aac")
|
113 |
+
|
114 |
+
|
115 |
+
def save_vid_side_by_side(batch_output, validation_control_images, output_folder, fps):
|
116 |
+
flattened_batch_output = [img for sublist in batch_output for img in sublist]
|
117 |
+
ori_video_path = output_folder + "/origin_predict.mp4"
|
118 |
+
video_path = output_folder + "/test_1.mp4"
|
119 |
+
ori_final_images = []
|
120 |
+
final_images = []
|
121 |
+
outputs = []
|
122 |
+
|
123 |
+
def get_concat_h(im1, im2):
|
124 |
+
dst = Image.new("RGB", (im1.width + im2.width, max(im1.height, im2.height)))
|
125 |
+
dst.paste(im1, (0, 0))
|
126 |
+
dst.paste(im2, (im1.width, 0))
|
127 |
+
return dst
|
128 |
+
|
129 |
+
for image_list in zip(validation_control_images, flattened_batch_output):
|
130 |
+
predict_img = image_list[1].resize(image_list[0].size)
|
131 |
+
result = get_concat_h(image_list[0], predict_img)
|
132 |
+
ori_final_images.append(np.array(image_list[1]))
|
133 |
+
final_images.append(np.array(result))
|
134 |
+
outputs.append(np.array(predict_img))
|
135 |
+
write_mp4(ori_video_path, ori_final_images, fps=fps)
|
136 |
+
write_mp4(video_path, final_images, fps=fps)
|
137 |
+
output_path = output_folder + "/output.mp4"
|
138 |
+
write_mp4(output_path, outputs, fps=fps)
|
139 |
+
|
140 |
+
|
141 |
+
def load_images_from_folder_to_pil(folder):
|
142 |
+
images = []
|
143 |
+
valid_extensions = {".jpg", ".jpeg", ".png", ".bmp", ".gif", ".tiff"}
|
144 |
+
|
145 |
+
def frame_number(filename):
|
146 |
+
new_pattern_match = re.search("frame_(\\d+)_7fps", filename)
|
147 |
+
if new_pattern_match:
|
148 |
+
return int(new_pattern_match.group(1))
|
149 |
+
matches = re.findall("\\d+", filename)
|
150 |
+
if matches:
|
151 |
+
if matches[-1] == "0000" and len(matches) > 1:
|
152 |
+
return int(matches[-2])
|
153 |
+
return int(matches[-1])
|
154 |
+
return float("inf")
|
155 |
+
|
156 |
+
sorted_files = sorted(os.listdir(folder), key=frame_number)
|
157 |
+
for filename in sorted_files:
|
158 |
+
ext = os.path.splitext(filename)[1].lower()
|
159 |
+
if ext in valid_extensions:
|
160 |
+
img = Image.open(os.path.join(folder, filename)).convert("RGB")
|
161 |
+
images.append(img)
|
162 |
+
return images
|
163 |
+
|
164 |
+
|
165 |
+
def load_images_from_video_to_pil(video_path):
|
166 |
+
images = []
|
167 |
+
vr = VideoReader(video_path)
|
168 |
+
length = len(vr)
|
169 |
+
for idx in range(length):
|
170 |
+
frame = vr[idx].asnumpy()
|
171 |
+
images.append(Image.fromarray(frame))
|
172 |
+
return images
|
173 |
+
|
174 |
+
|
175 |
+
validation_control_images = load_images_from_video_to_pil('your_path')
|
176 |
+
prompt = 'Group of fishes swimming in aquarium.'
|
177 |
+
vctrl = VCtrlModel.from_pretrained(
|
178 |
+
paddlemix/vctrl-5b-t2v-canny,
|
179 |
+
low_cpu_mem_usage=True,
|
180 |
+
paddle_dtype=paddle.float16
|
181 |
+
)
|
182 |
+
pipeline = CogVideoXVCtrlPipeline.from_pretrained(
|
183 |
+
paddlemix/cogvideox-5b-vctrl,
|
184 |
+
vctrl=vctrl,
|
185 |
+
paddle_dtype=paddle.float16,
|
186 |
+
low_cpu_mem_usage=True,
|
187 |
+
map_location="cpu",
|
188 |
+
)
|
189 |
+
pipeline.scheduler = CogVideoXDDIMScheduler.from_config(pipeline.scheduler.config, timestep_spacing="trailing")
|
190 |
+
pipeline.vae.enable_tiling()
|
191 |
+
pipeline.vae.enable_slicing()
|
192 |
+
task='canny'
|
193 |
+
final_result=[]
|
194 |
+
video = pipeline(
|
195 |
+
prompt=prompt,
|
196 |
+
num_inference_steps=25,
|
197 |
+
num_frames=49,
|
198 |
+
guidance_scale=35,
|
199 |
+
generator=paddle.Generator().manual_seed(42),
|
200 |
+
conditioning_frames=validation_control_images[:num_frames],
|
201 |
+
conditioning_frame_indices=list(range(num_frames)),
|
202 |
+
conditioning_scale=1.0,
|
203 |
+
width=720,
|
204 |
+
height=480,
|
205 |
+
task='canny',
|
206 |
+
conditioning_masks=validation_mask_images[:num_frames] if task == "mask" else None,
|
207 |
+
vctrl_layout_type='spacing',
|
208 |
+
).frames[0]
|
209 |
+
final_result.append(video)
|
210 |
+
save_vid_side_by_side(final_result, validation_control_images[:num_frames], 'save.mp4', fps=30)
|
211 |
+
```
|
212 |
+
|
213 |
+
## 深入研究
|
214 |
+
|
215 |
+
欢迎进入我们的 [github]("https://github.com/PaddlePaddle/PaddleMIX/tree/develop/ppdiffusers/examples/ppvctrl"),你将获得:
|
216 |
+
|
217 |
+
1. 更加详细的技术细节介绍和代码解释。
|
218 |
+
2. 控制条件的提取算法细节。
|
219 |
+
3. 模型推理的详细代码。
|
220 |
+
4. 项目更新日志动态,更多互动机会。
|
221 |
+
5. PaddleMix工具链,帮助您更好的使用模型。
|
222 |
+
|
223 |
+
## 引用
|
224 |
+
|
225 |
+
```
|
226 |
+
@article{yang2024cogvideox,
|
227 |
+
title={VCtrl: Enabling Versatile Controls for Video Diffusion Models},
|
228 |
+
year={2025}
|
229 |
+
}
|
230 |
+
```
|