MSALab commited on
Commit
13a77b0
·
verified ·
1 Parent(s): 02837fa

Init commit

Browse files
.gitattributes CHANGED
@@ -33,3 +33,16 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ assets/architecture.png filter=lfs diff=lfs merge=lfs -text
37
+ assets/results_1/edit_demo.gif filter=lfs diff=lfs merge=lfs -text
38
+ assets/results_1/edit_input.gif filter=lfs diff=lfs merge=lfs -text
39
+ assets/results_1/mi2v_demo.gif filter=lfs diff=lfs merge=lfs -text
40
+ assets/results_1/ref_edit_demo.gif filter=lfs diff=lfs merge=lfs -text
41
+ assets/results_1/ref_edit_input.gif filter=lfs diff=lfs merge=lfs -text
42
+ assets/results_1/t2v_demo.gif filter=lfs diff=lfs merge=lfs -text
43
+ assets/results_2/edit_demo.gif filter=lfs diff=lfs merge=lfs -text
44
+ assets/results_2/edit_input.gif filter=lfs diff=lfs merge=lfs -text
45
+ assets/results_2/mi2v_demo.gif filter=lfs diff=lfs merge=lfs -text
46
+ assets/results_2/ref_edit_demo.gif filter=lfs diff=lfs merge=lfs -text
47
+ assets/results_2/ref_edit_input.gif filter=lfs diff=lfs merge=lfs -text
48
+ assets/results_2/t2v_demo.gif filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,581 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div align="center">
2
+
3
+ # LoomVideo: Unifying Multimodal Inputs into <br> Video Generation and Editing
4
+
5
+ <h3>Peking University &middot; Alibaba Group</h3>
6
+
7
+ <a href="TODO" target="_blank"><img src="https://img.shields.io/badge/Paper-b5212f.svg?logo=arxiv" height="22px"></a>
8
+ <a href="https://github.com/MSALab-PKU/LoomVideo" target="_blank"><img src="https://img.shields.io/badge/GitHub-bb8a2e.svg?logo=github" height="22px"></a>
9
+ <a href="https://msalab-pku.github.io/projects/LoomVideo/index.html" target="_blank"><img src="https://img.shields.io/badge/Project%20Page-333399.svg?logo=homepage" height="22px"></a>
10
+
11
+ </div>
12
+
13
+ # 🔥 News
14
+
15
+ - [2026-06-01] We release the [codebase](https://github.com/MSRA-Vision-Lab/LoomVideo) and [model weights](TODO) of LoomVideo!
16
+ - [2026-06-01] We release the [project page](https://msalab-pku.github.io/projects/LoomVideo/index.html) of LoomVideo!
17
+
18
+ # 📌 TL;DR
19
+
20
+ **The Problem:** Existing unified video generation & editing models are massive (13B+) and rely on token concatenation for source conditioning — doubling sequence length and quadrupling attention cost.
21
+
22
+ **The Method:** We present **LoomVideo**, a compact **5B-parameter** unified architecture built on MLLM + DiT that introduces three key designs:
23
+ - **Deepstack Injection** — extracts features from every MLLM layer and injects them into corresponding DiT layers via cross-attention, enabling rich multi-granular semantic guidance.
24
+ - **Scale-and-Add Conditioning** — a zero-overhead approach that scales the clean source latent by the current timestep and directly adds it to the noised target, completely bypassing token concatenation.
25
+ - **Negative Temporal RoPE** — assigns negative temporal indices to reference images, seamlessly integrating multi-image conditions without architectural modification.
26
+
27
+ **The Result:** Our 5B model achieves state-of-the-art or highly competitive performance across comprehensive benchmarks, with at least **5.41×** inference speedup over models of similar capabilities — demonstrating that efficiency and quality can coexist.
28
+
29
+ <p align="center">
30
+ <img src="assets/architecture.png" width="90%">
31
+ </p>
32
+
33
+
34
+ # 🎯 Supported Tasks
35
+
36
+ LoomVideo supports **four** unified video generation and editing tasks within a single model:
37
+
38
+ | Task | Input | Output | Description |
39
+ |:-----|:------|:-------|:------------|
40
+ | **Text-to-Video** | Text 📝 | Video 🎬 | Generate a video from a text prompt |
41
+ | **Instruction Editing** | Video 🎬 + Text 📝 | Video 🎬 | Edit a video following text instructions |
42
+ | **Instruction-Image Editing** | Video 🎬 + Image 🖼 + Text 📝 | Video 🎬 | Edit a video with a reference image as guidance |
43
+ | **Multi-Image-to-Video** | Images 🖼 + Text 📝 | Video 🎬 | Compose multiple reference images into a coherent video |
44
+
45
+ ### 🎬 Text-to-Video
46
+
47
+ <p align="center">
48
+ <img src="assets/results_1/t2v_demo.gif" width="480"/>
49
+ </p>
50
+
51
+ > **Prompt:** *Snow rocky mountains peaks canyon. Snow blanketed rocky mountains surround and shadow deep canyons. The canyons twist and bend through the high elevated mountain peaks.*
52
+
53
+ <p align="center">
54
+ <img src="assets/results_2/t2v_demo.gif" width="480"/>
55
+ </p>
56
+
57
+ > **Prompt:** *Vampire makeup face of beautiful girl, red contact lenses.*
58
+
59
+ ### ✂️ Instruction Editing
60
+
61
+ <table align="center">
62
+ <tr>
63
+ <td align="center" valign="middle"><img src="assets/results_1/edit_input.gif" height="180"/></td>
64
+ <td align="center" valign="middle"><b><font size="5">→</font></b></td>
65
+ <td align="center" valign="middle"><img src="assets/results_1/edit_demo.gif" height="180"/></td>
66
+ </tr>
67
+ </table>
68
+
69
+ > **Prompt:** *Apply the Impressionist aesthetic to this video, ensuring seamless temporal consistency across all frames. The result should emulate the fluid brushstroke techniques and atmospheric focus of 19th-century Impressionist art, with each frame retaining the original motion, character actions, and camera movements.*
70
+
71
+ <table align="center">
72
+ <tr>
73
+ <td align="center" valign="middle"><img src="assets/results_2/edit_input.gif" height="180"/></td>
74
+ <td align="center" valign="middle"><b><font size="5">→</font></b></td>
75
+ <td align="center" valign="middle"><img src="assets/results_2/edit_demo.gif" height="180"/></td>
76
+ </tr>
77
+ </table>
78
+
79
+ > **Prompt:** *Replace the tree with a golden-leaved tree that shimmers softly, ensuring it maintains the same position and pose within the video scene.*
80
+
81
+ ### 🖼️ Instruction-Image Editing
82
+
83
+ <table align="center">
84
+ <tr>
85
+ <td align="center" valign="middle"><img src="assets/results_1/ref_edit_input.gif" height="180"/></td>
86
+ <td align="center" valign="middle"><img src="assets/results_1/ref_edit_reference.jpg" height="100"/></td>
87
+ <td align="center" valign="middle"><b><font size="5">→</font></b></td>
88
+ <td align="center" valign="middle"><img src="assets/results_1/ref_edit_demo.gif" height="180"/></td>
89
+ </tr>
90
+ </table>
91
+
92
+ > **Prompt:** *Replace the green t-shirt of the man with the suit in the image.*
93
+
94
+ <table align="center">
95
+ <tr>
96
+ <td align="center" valign="middle"><img src="assets/results_2/ref_edit_input.gif" height="180"/></td>
97
+ <td align="center" valign="middle"><img src="assets/results_2/ref_edit_reference.jpg" height="100"/></td>
98
+ <td align="center" valign="middle"><b><font size="5">→</font></b></td>
99
+ <td align="center" valign="middle"><img src="assets/results_2/ref_edit_demo.gif" height="180"/></td>
100
+ </tr>
101
+ </table>
102
+
103
+ > **Prompt:** *Replace the background with a Chinese ink painting, featuring a large golden mountain peak rising above swirling clouds, ensuring it appears in the same position and pose within the video scene.*
104
+
105
+ ### 🎞️ Multi-Image-to-Video
106
+
107
+ <table align="center">
108
+ <tr>
109
+ <td align="center" valign="middle"><img src="assets/results_1/mi2v_input_1.jpg" height="140"/> <img src="assets/results_1/mi2v_input_2.jpg" height="140"/> <img src="assets/results_1/mi2v_input_3.jpg" height="140"/></td>
110
+ <td align="center" valign="middle"><b><font size="5">→</font></b></td>
111
+ <td align="center" valign="middle"><img src="assets/results_1/mi2v_demo.gif" height="180"/></td>
112
+ </tr>
113
+ </table>
114
+
115
+ > **Prompt:** *The girl (@Image 2), wearing the denim jacket (@Image 3), black inner top, and black shorts, wearing sunglasses and carrying the handbag, walks down the street (@Image 1). Then, the girl (@Image 2) stops walking and turns her head to look to one side, followed by the girl (@Image 2) crossing her arms over her chest and striking a confident pose.*
116
+
117
+ <table align="center">
118
+ <tr>
119
+ <td align="center" valign="middle"><img src="assets/results_2/mi2v_input_1.jpg" height="140"/> <img src="assets/results_2/mi2v_input_2.jpg" height="140"/></td>
120
+ <td align="center" valign="middle"><b><font size="5">→</font></b></td>
121
+ <td align="center" valign="middle"><img src="assets/results_2/mi2v_demo.gif" height="180"/></td>
122
+ </tr>
123
+ </table>
124
+
125
+ > **Prompt:** *The man wearing a Polo shirt (@Image 2), black casual pants, white sneakers, sunglasses, and a watch, striding forward on the lawn (@Image 1) with one hand in his pocket.*
126
+
127
+
128
+ # 🔧 Preparation
129
+
130
+ ## Step 1: Clone the Repository
131
+
132
+ ```bash
133
+ git clone TODO
134
+ cd LoomVideo
135
+ ```
136
+
137
+ ## Step 2: Install Dependencies
138
+
139
+ We recommend using [uv](https://github.com/astral-sh/uv) for a fast and fully reproducible environment setup.
140
+
141
+ ```bash
142
+ uv sync
143
+ source .venv/bin/activate
144
+
145
+ # (Optional) Include evaluation dependencies
146
+ uv sync --extra eval
147
+ ```
148
+
149
+ Additionally, install [Flash Attention](https://github.com/Dao-AILab/flash-attention) for faster inference and reduced GPU memory consumption. (for reference, our environment uses v2.7.4)
150
+
151
+ ## Step 3: Download Model Weights
152
+
153
+ Download the pretrained LoomVideo checkpoint from [Hugging Face](TODO) and place it under `checkpoints/LoomVideo/`:
154
+
155
+ ```
156
+ checkpoints/LoomVideo/
157
+ └── gen_model.pth
158
+ ```
159
+
160
+ You can also specify a custom path via the `--ckpt_path` argument at inference time.
161
+
162
+
163
+ # 🎬 Inference
164
+ LoomVideo provides a unified inference script that supports **four generation tasks** through a single entry point. Each task is selected via the `--task` flag.
165
+
166
+ ### 1. Text-to-Video / Text-to-Image (`t2v`)
167
+
168
+ Generate a video from a text description. Default resolution is **480×832** at **81 frames**. When `--num_frames` is set to `1`, the pipeline automatically switches to **image generation** mode and saves the output as a `.jpg` file.
169
+
170
+ **Required:** `--prompt`
171
+
172
+ ```bash
173
+ NUM_GPUS=1
174
+
175
+ accelerate launch --num_processes=${NUM_GPUS} \
176
+ scripts/inference/generate.py \
177
+ --config_path configs/inference/generation.yaml \
178
+ --ckpt_path checkpoints/LoomVideo \
179
+ --task t2v \
180
+ --prompt "Your prompt here" \
181
+ --height 480 \
182
+ --width 832 \
183
+ --num_frames 97 \
184
+ --num_inference_steps 50 \
185
+ --seed 0 \
186
+ --output_path outputs/t2v.mp4
187
+ ```
188
+
189
+ ### 2. Instruction Editing (`edit`)
190
+
191
+ Edit an existing image or video based on a text instruction. The source can be either an image file (`.jpg`, `.png`, etc.) or a video file (`.mp4`). Resolution and frame count are automatically inferred from the source when not specified.
192
+
193
+ **Required:** `--prompt` `--source_video_path`
194
+
195
+ ```bash
196
+ NUM_GPUS=1
197
+
198
+ accelerate launch --num_processes=${NUM_GPUS} \
199
+ scripts/inference/generate.py \
200
+ --config_path configs/inference/generation.yaml \
201
+ --ckpt_path checkpoints/LoomVideo \
202
+ --task edit \
203
+ --prompt "Your editing instruction here" \
204
+ --source_video_path /path/to/source_video.mp4 \
205
+ --num_inference_steps 50 \
206
+ --seed 0 \
207
+ --output_path outputs/edit.mp4
208
+ ```
209
+
210
+ ### 3. Instruction-Image Editing (`ref_edit`)
211
+
212
+ Edit a source video with guidance from one or more reference images along with a text instruction.
213
+
214
+ **Required:** `--prompt` `--source_video_path` `--ref_image_paths`
215
+
216
+ ```bash
217
+ NUM_GPUS=1
218
+
219
+ accelerate launch --num_processes=${NUM_GPUS} \
220
+ scripts/inference/generate.py \
221
+ --config_path configs/inference/generation.yaml \
222
+ --ckpt_path checkpoints/LoomVideo \
223
+ --task ref_edit \
224
+ --prompt "Your editing instruction" \
225
+ --source_video_path /path/to/source_video.mp4 \
226
+ --ref_image_paths /path/to/ref1.jpg /path/to/ref2.jpg \
227
+ --num_inference_steps 50 \
228
+ --seed 0 \
229
+ --output_path outputs/ref_edit.mp4
230
+ ```
231
+
232
+ ### 4. Multi-Image-to-Video (`mi2v`)
233
+
234
+ Generate a video conditioned on multiple reference images and a text prompt. We recommend using `@Image N` in the prompt to reference specific input images.
235
+
236
+ **Required:** `--prompt` `--ref_image_paths`
237
+
238
+ ```bash
239
+ NUM_GPUS=1
240
+
241
+ accelerate launch --num_processes=${NUM_GPUS} \
242
+ scripts/inference/generate.py \
243
+ --config_path configs/inference/generation.yaml \
244
+ --ckpt_path checkpoints/LoomVideo \
245
+ --task mi2v \
246
+ --prompt "Your prompt here" \
247
+ --ref_image_paths /path/to/img1.jpg /path/to/img2.jpg /path/to/img3.jpg \
248
+ --num_frames 97 \
249
+ --num_inference_steps 50 \
250
+ --seed 0 \
251
+ --output_path outputs/mi2v.mp4
252
+ ```
253
+
254
+
255
+ ## Additional Arguments
256
+
257
+ The following arguments can be appended to any task command for further customization:
258
+
259
+ ### Generation Control
260
+
261
+ <table>
262
+ <thead>
263
+ <tr><th>Argument</th><th>Type</th><th>Default</th><th>Description</th></tr>
264
+ </thead>
265
+ <tbody>
266
+ <tr><td nowrap><code>--num_inference_steps</code></td><td>int</td><td><code>50</code></td><td>Number of denoising steps.</td></tr>
267
+ <tr><td nowrap><code>--guidance_scale</code></td><td>float</td><td><code>5.0</code> / <code>2.5</code></td><td>Text CFG scale. <code>5.0</code> for t2v/mi2v, <code>2.5</code> for edit/ref_edit.</td></tr>
268
+ <tr><td nowrap><code>--guidance_scale_visual</code></td><td>float</td><td><code>1.5</code></td><td>Visual CFG scale for source/reference conditioning.</td></tr>
269
+ <tr><td nowrap><code>--negative_prompt</code></td><td>str</td><td><em>(from config)</em></td><td>Negative prompt for quality improvement.</td></tr>
270
+ <tr><td nowrap><code>--seed</code></td><td>int</td><td><code>0</code></td><td>Random seed. Set to <code>-1</code> for random generation.</td></tr>
271
+ </tbody>
272
+ </table>
273
+
274
+ ### Resolution & Frames
275
+
276
+ <table>
277
+ <thead>
278
+ <tr><th>Argument</th><th>Type</th><th>Default</th><th>Description</th></tr>
279
+ </thead>
280
+ <tbody>
281
+ <tr><td nowrap><code>--height</code></td><td>int</td><td><em>auto</em></td><td>Output height. <code>480</code> for t2v; inferred from source for edit.</td></tr>
282
+ <tr><td nowrap><code>--width</code></td><td>int</td><td><em>auto</em></td><td>Output width. <code>832</code> for t2v; inferred from source for edit.</td></tr>
283
+ <tr><td nowrap><code>--num_frames</code></td><td>int</td><td><em>auto</em></td><td>Output frames. <code>81</code> for t2v/mi2v; inferred for edit.</td></tr>
284
+ <tr><td nowrap><code>--fps</code></td><td>int</td><td><code>24</code></td><td>Output video FPS.</td></tr>
285
+ </tbody>
286
+ </table>
287
+
288
+
289
+ # 📦 Data Preparation
290
+
291
+ Since our training relies heavily on proprietary datasets, we are unable to release the original data directly. However, we provide a **flexible data organization framework** that makes it easy to plug in your own data or publicly available datasets.
292
+
293
+ ## Open-Source Datasets
294
+
295
+ Below are the open-source datasets used in our training. You can download them or substitute with your own data:
296
+
297
+ | Category | Dataset |
298
+ |---|---|
299
+ | Video Generation | [Koala-36M](https://huggingface.co/datasets/Koala-36M/Koala-36M-v1), [OpenVid-1M](https://huggingface.co/datasets/nkp37/OpenVid-1M) |
300
+ | Image Editing | [CrispEdit-2M](https://huggingface.co/datasets/WeiChow/CrispEdit-2M), [OmniGen-2-Edit](https://huggingface.co/OmniGen2), [GPT-Image-Edit-1.5M](https://huggingface.co/datasets/UCSC-VLAA/GPT-Image-Edit-1.5M), [NHR-Edit](https://huggingface.co/datasets/iitolstykh/NHR-Edit), [Pico-Banana](https://huggingface.co/papers/2510.19808), [ShareGPT-4o-Image](https://huggingface.co/datasets/FreedomIntelligence/ShareGPT-4o-Image) |
301
+ | Video Editing | [KIWI-Edit](https://huggingface.co/datasets/linyq/kiwi_edit_training_data) |
302
+ | Video Ref Editing / MI2V | [RefVIE](https://huggingface.co/datasets/linyq/kiwi_edit_training_data), [Phantom-Data](https://huggingface.co/datasets/ZhuoweiChen/Phantom-data-Koala36M) |
303
+
304
+ ## Organize Data as Single JSON Files
305
+
306
+ Each data sample should be stored as an **individual JSON file**, placed in a single directory (e.g., `single_jsons/`), and named sequentially starting from `0.json`:
307
+
308
+ ```
309
+ your_dataset/
310
+ └── single_jsons/
311
+ ├── 0.json
312
+ ├── 1.json
313
+ ├── 2.json
314
+ ├── ...
315
+ ```
316
+
317
+ ## JSON Format for Each Task
318
+
319
+ Each task type expects a specific set of keys in its JSON file. Below are the templates — fill in according to your data:
320
+
321
+ **Text-to-Video** (`process_t2v_data`):
322
+ ```json
323
+ {
324
+ "text": "A caption describing the video content.",
325
+ "path": "relative/path/to/video.mp4"
326
+ }
327
+ ```
328
+
329
+ **Text-to-Image** (`process_t2i_data`):
330
+ ```json
331
+ {
332
+ "caption": "A caption describing the image content.",
333
+ "image_path": "relative/path/to/image.jpg"
334
+ }
335
+ ```
336
+
337
+ **Video Editing** (`process_video_edit_data`):
338
+ ```json
339
+ {
340
+ "source_video_path": "relative/path/to/source_video.mp4",
341
+ "instruction": "The editing instruction.",
342
+ "target_video_path": "relative/path/to/target_video.mp4"
343
+ }
344
+ ```
345
+
346
+ **Image Editing** (`process_image_edit_data`):
347
+ ```json
348
+ {
349
+ "source_image_path": "relative/path/to/source_image.jpg",
350
+ "instruction": "The editing instruction.",
351
+ "target_image_path": "relative/path/to/target_image.jpg"
352
+ }
353
+ ```
354
+
355
+ **Multi-Image-to-Video** (`process_t2v_data_withref`):
356
+ ```json
357
+ {
358
+ "instruction": "A prompt describing the video to generate with reference images.",
359
+ "reference_image_paths": [
360
+ "relative/path/to/ref1.jpg",
361
+ "relative/path/to/ref2.jpg"
362
+ ],
363
+ "target_video_path": "relative/path/to/target_video.mp4"
364
+ }
365
+ ```
366
+
367
+ **Reference-Guided Video Editing** (`process_video_edit_data_withref`):
368
+ ```json
369
+ {
370
+ "source_video_path": "relative/path/to/source_video.mp4",
371
+ "reference_image_paths": [
372
+ "relative/path/to/ref1.jpg"
373
+ ],
374
+ "instruction": "The editing instruction with reference guidance.",
375
+ "target_video_path": "relative/path/to/target_video.mp4"
376
+ }
377
+ ```
378
+
379
+ > 💡 All paths in JSON files are **relative** to the `data_root` specified in the dataset config.
380
+
381
+ ## Custom Process Functions (Optional)
382
+
383
+ You may also organize your JSON files in any format you prefer, as long as you implement a corresponding `process_*` function. We provide several reference implementations in `src/dataset/processors.py`. Each process function takes `(dataset_info, data_info)` and returns a list of segments describing the data flow. See the existing functions for examples.
384
+
385
+ ## Dataset Config
386
+
387
+ Create a YAML config file to register your datasets. See `configs/dataset/train_demo.yaml` as a reference. The config is organized into `train`, `val`, and `eval` sections, each containing dataset entries with the following arguments:
388
+
389
+ | Argument | Description |
390
+ |---|---|
391
+ | `task_weight` | Controls the sampling probability of this task group relative to others during training. |
392
+ | `process_func_name` | Name of the processing function in `src/dataset/processors.py` that parses each JSON sample. |
393
+ | `data_root` | Base directory for resolving relative paths in JSON files. |
394
+ | `data_json_dir` | Directory containing the JSON files (`0.json`, `1.json`, ...). |
395
+ | `num_samples` | Total number of samples in the directory. |
396
+ | `sample_weight` | Sampling weight of this dataset within its task group. |
397
+
398
+
399
+ # 🏋️ Training
400
+
401
+ ## Training Config
402
+
403
+ The training behavior is fully controlled by a YAML config file (e.g., `configs/train/stage3.yaml`).
404
+
405
+ **Key arguments:**
406
+
407
+ | Argument | Description |
408
+ |---|---|
409
+ | `log_dir` | Directory for saving logs, checkpoints, and generated samples. |
410
+ | `dataset_config_path` | Path to the dataset config YAML file. |
411
+ | `train_steps` | Total number of training iterations. |
412
+ | `checkpointing_interval` | Save a checkpoint every N steps. |
413
+ | `validation_interval` | Run validation every N steps. |
414
+ | `evaluation_interval` | Run evaluation benchmarks every N steps. |
415
+
416
+ **Model settings:**
417
+
418
+ | Argument | Description |
419
+ |---|---|
420
+ | `model.trainable_modules.gen_model` | Which modules to train. `"all"` trains the full generation model. |
421
+ | `model.gradient_checkpointing` | Enable gradient checkpointing to reduce GPU memory usage. |
422
+ | `model.und.pretrained_model_path` | Path to the pretrained understanding backbone. |
423
+ | `model.gen.pretrained_model_path` | Path to the pretrained generation backbone. |
424
+ | `model.pretrained_ckpt_path` | *(Optional)* Load weights from a previous training stage for continued training. |
425
+
426
+ **Data settings:**
427
+
428
+ | Argument | Description |
429
+ |---|---|
430
+ | `data.train.resolution_buckets` | List of resolution buckets for dynamic batching. |
431
+ | `data.train.num_frames` | Number of frames per training sample. |
432
+ | `data.train.fps` | Video FPS for frame sampling. |
433
+ | `data.train.all_dropout_rate` | Probability of dropping all conditions (for unconditional training). |
434
+ | `data.train.text_dropout_rate` | Probability of dropping text condition (for classifier-free guidance). |
435
+
436
+ ## Launch Training
437
+
438
+ Once the data and configs are ready, you can simply start training with:
439
+
440
+ ```bash
441
+ NUM_GPUS=8
442
+
443
+ accelerate launch --num_processes=${NUM_GPUS} \
444
+ -m scripts.train.train \
445
+ --config_path path/to/your/config.yaml
446
+ ```
447
+
448
+ > 💡 All training outputs — including checkpoints, EMA weights, logs, and generated samples — are saved under the `log_dir` directory specified in the config.
449
+
450
+
451
+ # 📊 Evaluation
452
+
453
+ ## Environment Setup
454
+
455
+ ### Step 1: Prepare Benchmark Data
456
+
457
+ We evaluate on the following benchmarks. Download each dataset and organize it into the same **single JSON** format used for training data (see [Data Preparation](#-data-preparation)):
458
+
459
+ | Benchmark | Category | Samples |
460
+ |---|---|---|
461
+ | [GenEval](https://github.com/djghosh13/geneval) | Image Generation | 553 |
462
+ | [ImgEdit-Bench](https://github.com/pku-yuangroup/imgedit) | Image Editing | 737 |
463
+ | [VBench](https://github.com/Vchitect/VBench) | Video Generation | 165 |
464
+ | [OpenVE-Bench](https://huggingface.co/datasets/Lewandofski/OpenVE-Bench) | Video Editing | 431 |
465
+ | [RefVIE-Bench](https://huggingface.co/datasets/linyq/RefVIE-Bench) | Reference Video Editing | 120 |
466
+ | [Intelligent-VBench-MI2V](https://github.com/Tencent-Hunyuan/OmniWeaving) | Multi-Image-to-Video | 320 |
467
+ | [Intelligent-VBench-TIV2V](https://github.com/Tencent-Hunyuan/OmniWeaving) | Text-Image-Video-to-Video | 210 |
468
+
469
+ > 💡 For **Intelligent-VBench**, we split the original benchmark into two subsets based on task type — **MI2V** and **TIV2V**. Their JSON files should be placed in separate directories.
470
+
471
+ After downloading, update the `data_root` and `data_json_dir` paths in `configs/dataset/benchmarks.yaml` to point to your local directories.
472
+
473
+ ### Step 2: Install Evaluation Dependencies
474
+
475
+ **VBench:**
476
+
477
+ ```bash
478
+ mkdir -p libs && cd libs
479
+ git clone https://github.com/Vchitect/VBench.git
480
+ ```
481
+
482
+ Add the following to `libs/VBench/vbench/__init__.py`:
483
+
484
+ ```python
485
+ import sys, os
486
+ local_lib_path = os.path.abspath("libs/VBench")
487
+ if local_lib_path not in sys.path:
488
+ sys.path.append(local_lib_path)
489
+ ```
490
+
491
+ If you encounter a NumPy 2.0 compatibility error (`np.sctypes was removed`), modify lines 45–47 of `[YOUR_PYTHON_LIBS]/imgaug/imgaug.py`:
492
+
493
+ ```python
494
+ # Replace:
495
+ # NP_FLOAT_TYPES = set(np.sctypes["float"])
496
+ # NP_INT_TYPES = set(np.sctypes["int"])
497
+ # NP_UINT_TYPES = set(np.sctypes["uint"])
498
+
499
+ # With:
500
+ NP_FLOAT_TYPES = {np.float16, np.float32, np.float64, np.longdouble}
501
+ NP_INT_TYPES = {np.int8, np.int16, np.int32, np.int64, np.longlong}
502
+ NP_UINT_TYPES = {np.uint8, np.uint16, np.uint32, np.uint64, np.ulonglong}
503
+ ```
504
+
505
+ To save disk space, remove unnecessary files:
506
+
507
+ ```bash
508
+ rm -rf libs/VBench/VBench-2.0 libs/VBench/.git libs/VBench/asset libs/VBench/vbench2_beta_trustworthiness
509
+ ```
510
+
511
+ **GenEval:**
512
+
513
+ ```bash
514
+ cd libs
515
+ git clone https://github.com/djghosh13/geneval.git
516
+ cd geneval
517
+ ./evaluation/download_models.sh "../../checkpoints/"
518
+
519
+ cd ..
520
+ pip install mmcv-full
521
+ git clone https://github.com/open-mmlab/mmdetection.git
522
+ cd mmdetection && git checkout 2.x
523
+ pip install -v -e . --no-build-isolation
524
+ ```
525
+
526
+ The GenEval model paths are configured in `configs/evaluation/evaluation.yaml` under `model.evaluation.geneval`:
527
+
528
+ ```yaml
529
+ model:
530
+ evaluation:
531
+ geneval:
532
+ model_path: checkpoints/evaluation/mask2former_swin-s-p4-w7-224_lsj_8x2_50e_coco.pth
533
+ model_config_path: libs/mmdetection/configs/mask2former/mask2former_swin-s-p4-w7-224_lsj_8x2_50e_coco.py
534
+ clip_path: checkpoints/evaluation/ViT-L-14.pt
535
+ ```
536
+
537
+ ### Step 3: Configure API Keys
538
+
539
+ Some benchmarks (OpenVE-Bench, RefVIE-Bench, ImgEdit-Bench, Intelligent-VBench) require LLM API calls for metric computation. Configure your API keys in `configs/evaluation/evaluation.yaml` under `model.evaluation`:
540
+
541
+ ```yaml
542
+ model:
543
+ evaluation:
544
+ # For OpenVE-Bench, RefVIE-Bench, Intelligent-VBench
545
+ gemini:
546
+ api_key: "YOUR_GEMINI_API_KEY"
547
+ base_url: "YOUR_GEMINI_BASE_URL"
548
+ model: "gemini-2.5-pro-06-17"
549
+ # For ImgEdit-Bench
550
+ openai:
551
+ api_key: "YOUR_OPENAI_API_KEY"
552
+ base_url: "YOUR_OPENAI_BASE_URL"
553
+ model: "gpt-4.1"
554
+ ```
555
+
556
+
557
+ ## Run Evaluation
558
+
559
+ Once the environment is set up, you can simply run evaluation with:
560
+
561
+ ```bash
562
+ NUM_GPUS=8
563
+
564
+ accelerate launch --num_processes=${NUM_GPUS} \
565
+ -m scripts.evaluation.evaluate \
566
+ --config configs/evaluation/evaluation.yaml \
567
+ --checkpoint_dir checkpoints/LoomVideo \
568
+ --generation_configs configs/dataset/benchmarks.yaml \
569
+ --output_dir results/evaluation \
570
+ --calculate_metrics
571
+ ```
572
+
573
+
574
+ # 📧 Contact
575
+
576
+ Jianzong Wu (吴健宗): jzwu@stu.pku.edu.cn
577
+
578
+
579
+ # 📄 Citation
580
+
581
+ *TODO*
assets/architecture.png ADDED

Git LFS Details

  • SHA256: 24b82c042ecb9d791df84e0846f4e1d4a593066889e8833d2bd25f570705b55d
  • Pointer size: 132 Bytes
  • Size of remote file: 1.27 MB
assets/logo.png ADDED
assets/results_1/edit_demo.gif ADDED

Git LFS Details

  • SHA256: 650031a70aaabba4deebad511dfbd5a9c50e776a5d4ea5e560edbc59bcf6a666
  • Pointer size: 131 Bytes
  • Size of remote file: 724 kB
assets/results_1/edit_input.gif ADDED

Git LFS Details

  • SHA256: 55b67b3e52ebfe6610ec732b52367de529db181747e4eaf562fb6127265d3284
  • Pointer size: 131 Bytes
  • Size of remote file: 680 kB
assets/results_1/mi2v_demo.gif ADDED

Git LFS Details

  • SHA256: dfa31bd2cd75971a9622da31ea4534ff08b47294c0276f37b062e32044a7e423
  • Pointer size: 132 Bytes
  • Size of remote file: 1.62 MB
assets/results_1/mi2v_input_1.jpg ADDED
assets/results_1/mi2v_input_2.jpg ADDED
assets/results_1/mi2v_input_3.jpg ADDED
assets/results_1/ref_edit_demo.gif ADDED

Git LFS Details

  • SHA256: d067f33a4b5f36bb1b10a482f42d6a19912661b374c53c8f14c46d2a698d029b
  • Pointer size: 131 Bytes
  • Size of remote file: 482 kB
assets/results_1/ref_edit_input.gif ADDED

Git LFS Details

  • SHA256: 3f3ffff68dacf97f355a1d3ac1ff105e2648c29b3660efd5434fc71355d04aad
  • Pointer size: 131 Bytes
  • Size of remote file: 478 kB
assets/results_1/ref_edit_reference.jpg ADDED
assets/results_1/t2v_demo.gif ADDED

Git LFS Details

  • SHA256: 8ce43194ed3eb8551b5ee591b8eef24ce484a7f3977d2268e5739d9c59d58dc7
  • Pointer size: 132 Bytes
  • Size of remote file: 1.93 MB
assets/results_2/edit_demo.gif ADDED

Git LFS Details

  • SHA256: f775054cb22371c029ab5b3104172bb8f80da53cd1e14f694cb4bbe2f2b4114f
  • Pointer size: 131 Bytes
  • Size of remote file: 368 kB
assets/results_2/edit_input.gif ADDED

Git LFS Details

  • SHA256: b0ac44e861c5bf360200134a238f18a4e0fc5c4486d06cb46400286ca3454e3e
  • Pointer size: 131 Bytes
  • Size of remote file: 388 kB
assets/results_2/mi2v_demo.gif ADDED

Git LFS Details

  • SHA256: bb6f94020b62cb3f2bebcee15b9e3827afee312885671035049eda097f069e65
  • Pointer size: 132 Bytes
  • Size of remote file: 1.32 MB
assets/results_2/mi2v_input_1.jpg ADDED
assets/results_2/mi2v_input_2.jpg ADDED
assets/results_2/ref_edit_demo.gif ADDED

Git LFS Details

  • SHA256: 3966d318daf51d904deb2cc436129295921fb5aa1b43d436d161b81ba8e32e58
  • Pointer size: 131 Bytes
  • Size of remote file: 390 kB
assets/results_2/ref_edit_input.gif ADDED

Git LFS Details

  • SHA256: 172c0b1a42285e6b8182eb4f504dd7257440848519c30bca46604cff2212dd5d
  • Pointer size: 131 Bytes
  • Size of remote file: 351 kB
assets/results_2/ref_edit_reference.jpg ADDED
assets/results_2/t2v_demo.gif ADDED

Git LFS Details

  • SHA256: 63a41c42c8f91f6edd4ff5f42c3678d9403589a8e1f7e8fdd6c0ba6dcdc90ce7
  • Pointer size: 132 Bytes
  • Size of remote file: 1.46 MB
gen_model.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:af3e2b59be11db654ee1bf323457e25b866b43d81188bfca26dfa2ab21a44ff0
3
+ size 10376553122