lightx2v commited on
Commit
a8a33c5
·
verified ·
1 Parent(s): c46be91

Upload folder using huggingface_hub

Browse files
Files changed (4) hide show
  1. README.md +332 -1
  2. infer.py +143 -0
  3. prompt_template.py +40 -0
  4. requirements.txt +5 -0
README.md CHANGED
@@ -1,3 +1,334 @@
1
  ---
2
- license: apache-2.0
 
 
 
 
 
 
 
 
 
 
 
3
  ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ base_model: Qwen/Qwen3.6-27B
3
+ library_name: peft
4
+ tags:
5
+ - peft
6
+ - lora
7
+ - prompt-rewriting
8
+ - minimax-h3
9
+ - text-to-audio-video
10
+ - audio-video-generation
11
+ - t2va
12
+ language:
13
+ - en
14
  ---
15
+
16
+ # MiniMax-H3 T2VA Prompt Rewriter LoRA
17
+
18
+ [![LightX2V](https://img.shields.io/badge/Inference-LightX2V-ff6b35)](https://github.com/ModelTC/LightX2V)
19
+ [![GitHub stars](https://img.shields.io/github/stars/ModelTC/LightX2V?style=social)](https://github.com/ModelTC/LightX2V)
20
+ [![MiniMax-H3](https://img.shields.io/badge/Base%20Generator-MiniMax--H3-yellow)](https://huggingface.co/MiniMaxAI/MiniMax-H3)
21
+
22
+ An open, local prompt rewriter for **text-to-audio-video (T2VA)** generation with
23
+ [MiniMax-H3](https://huggingface.co/MiniMaxAI/MiniMax-H3), fine-tuned as a LoRA
24
+ adapter on top of [Qwen3.6-27B](https://huggingface.co/Qwen/Qwen3.6-27B).
25
+
26
+ > **Generate the final audio-video with
27
+ > [LightX2V](https://github.com/ModelTC/LightX2V).** LightX2V provides optimized local
28
+ > MiniMax-H3 inference, including T2AV and other H3 tasks, memory offloading, tensor and
29
+ > sequence parallelism, quantized checkpoints, optimized attention/RMSNorm/RoPE kernels,
30
+ > and feature caching. If this project is useful, please consider giving
31
+ > **[ModelTC/LightX2V](https://github.com/ModelTC/LightX2V) a star**.
32
+
33
+ The complete local workflow is:
34
+
35
+ ```text
36
+ Short prompt ──► this Prompt Rewriter LoRA ──► structured H3 prompt
37
+
38
+ Official MiniMax-H3 weights ──► LightX2V inference ◄─────┘
39
+
40
+
41
+ synchronized video + audio
42
+ ```
43
+
44
+ The [official MiniMax-H3 repository](https://huggingface.co/MiniMaxAI/MiniMax-H3)
45
+ provides the upstream model weights. **LightX2V is the recommended inference entry
46
+ point for the workflow documented here.**
47
+
48
+ This is an unofficial, community-trained project and is not affiliated with or
49
+ endorsed by MiniMax. It is intended as a local alternative for producing structured,
50
+ H3-oriented T2VA prompts when the hosted H3-Context-IR service is unavailable or
51
+ unsuitable for a workflow. It does not reproduce the proprietary H3-Context-IR system,
52
+ and exact output parity is not guaranteed.
53
+
54
+ ## What it does
55
+
56
+ The adapter turns a short prompt plus the requested aspect ratio and duration into a
57
+ structured audio-video description:
58
+
59
+ ```text
60
+ Original prompt + aspect ratio + duration
61
+
62
+
63
+ Qwen3.6-27B + this LoRA
64
+
65
+
66
+ integrated_multimodal_description: [Shot 1] ...
67
+ overall_soundscape: ...
68
+ non_diegetic_music: ...
69
+ ```
70
+
71
+ The rewritten prompt expands shot structure, timing, composition, camera motion,
72
+ physical action, continuity, synchronized diegetic sound, and non-diegetic music while
73
+ preserving the original intent.
74
+
75
+ | Component | Purpose | Model |
76
+ |---|---|---|
77
+ | Inference framework | Runs MiniMax-H3 locally and generates the final synchronized video and audio | **[ModelTC/LightX2V](https://github.com/ModelTC/LightX2V)** |
78
+ | Generator weights | Upstream MiniMax-H3 model weights consumed by LightX2V | [MiniMaxAI/MiniMax-H3](https://huggingface.co/MiniMaxAI/MiniMax-H3) |
79
+ | Base language model | General instruction-following backbone | [Qwen3.6-27B](https://huggingface.co/Qwen/Qwen3.6-27B) |
80
+ | LoRA adapter | H3-oriented T2VA prompt rewriting | [lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA](https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA) |
81
+
82
+ ## Status and roadmap
83
+
84
+ - [x] T2VA prompt rewriting
85
+ - [x] Duration conditioning from 4 to 15 seconds
86
+ - [x] Aspect-ratio conditioning: `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16`
87
+ - [x] Single-prompt inference script
88
+ - [x] End-to-end MiniMax-H3 generation through [LightX2V](https://github.com/ModelTC/LightX2V)
89
+ - [ ] First/last-frame-to-audio-video (FL2VA) prompt rewriting
90
+ - [ ] Reference-to-audio-video (Ref2VA) prompt rewriting
91
+ - [ ] Image-to-audio-video and last-frame variants
92
+ - [ ] Image, video, and audio reference inputs
93
+ - [ ] Quantitative evaluation and a reproducible public benchmark suite
94
+ - [ ] Smaller and quantized rewriter variants
95
+
96
+ Only **T2VA** is supported by this release. The remaining MiniMax-H3 tasks require
97
+ multimodal inputs and task-specific training data; they will be added in future work.
98
+
99
+ ## Installation
100
+
101
+ Clone this repository and install the inference dependencies:
102
+
103
+ ```bash
104
+ git clone https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA
105
+ cd MiniMax-H3-Prompt-Rewriter-LoRA
106
+ pip install -r requirements.txt
107
+ ```
108
+
109
+ The 27B base model is not included in this adapter repository and will be downloaded
110
+ from Hugging Face on first use. Ensure that the machine has enough GPU/CPU memory for
111
+ Qwen3.6-27B. `device_map="auto"` is used to distribute the model over available devices.
112
+
113
+ ## Rewrite one prompt
114
+
115
+ ```bash
116
+ python infer.py \
117
+ --prompt "Epic space-opera teaser: a captain watches the last fleet jump away, leaving her alone." \
118
+ --duration 10 \
119
+ --resolution 16:9 \
120
+ --greedy
121
+ ```
122
+
123
+ The default model IDs are:
124
+
125
+ ```text
126
+ Base model: Qwen/Qwen3.6-27B
127
+ Adapter: lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA
128
+ ```
129
+
130
+ Local paths are supported as well:
131
+
132
+ ```bash
133
+ python infer.py \
134
+ --base-model /path/to/Qwen3.6-27B \
135
+ --adapter /path/to/MiniMax-H3-Prompt-Rewriter-LoRA \
136
+ --prompt "A red fox walks through a snowy forest at dawn." \
137
+ --duration 15 \
138
+ --resolution 21:9 \
139
+ --output rewritten_prompt.json
140
+ ```
141
+
142
+ Use `--output result.txt` for plain text or a `.json` path for a record containing
143
+ the original prompt, conditions, model IDs, and rewritten prompt.
144
+
145
+ To run the base-model baseline without the LoRA:
146
+
147
+ ```bash
148
+ python infer.py \
149
+ --base-only \
150
+ --prompt "A red fox walks through a snowy forest at dawn." \
151
+ --duration 15 \
152
+ --resolution 21:9 \
153
+ --greedy
154
+ ```
155
+
156
+ For fair comparisons, use the same decoding mode and seed for every rewriter. Greedy
157
+ decoding is the simplest deterministic setting; sampling is enabled when `--greedy`
158
+ is omitted.
159
+
160
+ ## Output format
161
+
162
+ The model is trained to return exactly three fields in this order:
163
+
164
+ ```text
165
+ integrated_multimodal_description: [Shot 1] ... [Shot 2] At 00:05.000, ...
166
+ overall_soundscape: ...
167
+ non_diegetic_music: ...
168
+ ```
169
+
170
+ Pass the entire three-field result to the MiniMax-H3 T2VA pipeline in
171
+ [LightX2V](https://github.com/ModelTC/LightX2V).
172
+
173
+ ## Generate audio-video with LightX2V
174
+
175
+ ### 1. Install LightX2V
176
+
177
+ Building from source gives access to the latest MiniMax-H3 integration:
178
+
179
+ ```bash
180
+ git clone https://github.com/ModelTC/LightX2V.git
181
+ cd LightX2V
182
+ uv pip install -v . # or: pip install -v .
183
+ ```
184
+
185
+ Follow the [LightX2V Quick Start](https://lightx2v-en.readthedocs.io/en/latest/getting_started/quickstart.html)
186
+ to install the optional optimized attention and quantization operators required by the
187
+ selected configuration.
188
+
189
+ ### 2. Download the MiniMax-H3 weights
190
+
191
+ The generator weights come from the upstream
192
+ [MiniMaxAI/MiniMax-H3](https://huggingface.co/MiniMaxAI/MiniMax-H3) repository:
193
+
194
+ ```bash
195
+ hf download MiniMaxAI/MiniMax-H3 --local-dir /path/to/MiniMax-H3
196
+ ```
197
+
198
+ The LoRA in this repository rewrites text; it does not replace or include the
199
+ MiniMax-H3 generator weights.
200
+
201
+ ### 3. Rewrite the prompt
202
+
203
+ Run this command from the prompt-rewriter repository:
204
+
205
+ ```bash
206
+ python infer.py \
207
+ --prompt "A red fox walks through a snowy forest at dawn." \
208
+ --duration 15 \
209
+ --resolution 16:9 \
210
+ --greedy \
211
+ --output /tmp/h3_rewritten_prompt.txt
212
+ ```
213
+
214
+ ### 4. Generate synchronized video and audio
215
+
216
+ Run the rewritten prompt with LightX2V from the `LightX2V` repository root:
217
+
218
+ ```bash
219
+ source scripts/base/base.sh
220
+ export DTYPE=BF16
221
+ export SENSITIVE_LAYER_DTYPE=FP32
222
+
223
+ python -m lightx2v.infer \
224
+ --model_cls minimax_h3 \
225
+ --task t2av \
226
+ --model_path /path/to/MiniMax-H3 \
227
+ --config_json configs/minimax_h3/minimax_h3_t2av.json \
228
+ --prompt "$(</tmp/h3_rewritten_prompt.txt)" \
229
+ --save_result_path save_results/minimax_h3_t2av.mp4 \
230
+ --seed 42
231
+ ```
232
+
233
+ The output MP4 contains both video and synchronized stereo audio. Make sure that the
234
+ duration and aspect ratio in the LightX2V config match the conditions passed to the
235
+ prompt rewriter. Ready-to-run single-GPU, block-offload, tensor-parallel, and combined
236
+ TP+SP examples are available in the
237
+ **[LightX2V MiniMax-H3 scripts](https://github.com/ModelTC/LightX2V/tree/main/scripts/minimax_h3)**.
238
+
239
+ For lower-memory or multi-GPU inference, start from one of these configurations:
240
+
241
+ | Mode | LightX2V example |
242
+ |---|---|
243
+ | Single GPU | `configs/minimax_h3/minimax_h3_t2av.json` |
244
+ | Block offload | `configs/minimax_h3/minimax_h3_t2av_block_offload.json` |
245
+ | Sequence parallelism | `configs/minimax_h3/minimax_h3_t2av_sp.json` |
246
+ | Tensor parallelism | `configs/minimax_h3/minimax_h3_t2av_tp.json` |
247
+ | Tensor + sequence parallelism | `configs/minimax_h3/minimax_h3_t2av_tp_sp.json` |
248
+
249
+ ## Qualitative comparison
250
+
251
+ The following gallery is designed to compare videos generated through
252
+ [LightX2V](https://github.com/ModelTC/LightX2V) with the same MiniMax-H3 checkpoint and
253
+ identical inference settings. Only the prompt-rewriting method should differ.
254
+
255
+ | Label | Meaning |
256
+ |---|---|
257
+ | Original Prompt (No Rewrite) | The raw user prompt is sent directly to MiniMax-H3 |
258
+ | MiniMax Context-IR | The raw prompt is enhanced by the official hosted Context-IR workflow |
259
+ | Qwen3.6-27B Base Rewriter | The same template is used with the base model and no LoRA |
260
+ | **H3-T2VA Context Rewriter LoRA (Ours)** | Qwen3.6-27B with this task-specific LoRA |
261
+
262
+ ### Prompt 1
263
+
264
+ > **Original prompt:** TODO — paste Prompt 1 here
265
+ > **Conditions:** TODO — duration, aspect ratio, seed, and generation configuration
266
+
267
+ | Original Prompt (No Rewrite) | MiniMax Context-IR | Qwen3.6-27B Base Rewriter | **H3-T2VA Context Rewriter LoRA (Ours)** |
268
+ |---|---|---|---|
269
+ | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt1/original.mp4"></video> | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt1/minimax_context_ir.mp4"></video> | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt1/qwen_base.mp4"></video> | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt1/ours.mp4"></video> |
270
+
271
+ ### Prompt 2
272
+
273
+ > **Original prompt:** TODO — paste Prompt 2 here
274
+ > **Conditions:** TODO — duration, aspect ratio, seed, and generation configuration
275
+
276
+ | Original Prompt (No Rewrite) | MiniMax Context-IR | Qwen3.6-27B Base Rewriter | **H3-T2VA Context Rewriter LoRA (Ours)** |
277
+ |---|---|---|---|
278
+ | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt2/original.mp4"></video> | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt2/minimax_context_ir.mp4"></video> | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt2/qwen_base.mp4"></video> | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt2/ours.mp4"></video> |
279
+
280
+ ### Prompt 3
281
+
282
+ > **Original prompt:** TODO — paste Prompt 3 here
283
+ > **Conditions:** TODO — duration, aspect ratio, seed, and generation configuration
284
+
285
+ | Original Prompt (No Rewrite) | MiniMax Context-IR | Qwen3.6-27B Base Rewriter | **H3-T2VA Context Rewriter LoRA (Ours)** |
286
+ |---|---|---|---|
287
+ | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt3/original.mp4"></video> | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt3/minimax_context_ir.mp4"></video> | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt3/qwen_base.mp4"></video> | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt3/ours.mp4"></video> |
288
+
289
+ ### Prompt 4
290
+
291
+ > **Original prompt:** TODO — paste Prompt 4 here
292
+ > **Conditions:** TODO — duration, aspect ratio, seed, and generation configuration
293
+
294
+ | Original Prompt (No Rewrite) | MiniMax Context-IR | Qwen3.6-27B Base Rewriter | **H3-T2VA Context Rewriter LoRA (Ours)** |
295
+ |---|---|---|---|
296
+ | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt4/original.mp4"></video> | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt4/minimax_context_ir.mp4"></video> | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt4/qwen_base.mp4"></video> | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt4/ours.mp4"></video> |
297
+
298
+ ### Prompt 5
299
+
300
+ > **Original prompt:** TODO — paste Prompt 5 here
301
+ > **Conditions:** TODO — duration, aspect ratio, seed, and generation configuration
302
+
303
+ | Original Prompt (No Rewrite) | MiniMax Context-IR | Qwen3.6-27B Base Rewriter | **H3-T2VA Context Rewriter LoRA (Ours)** |
304
+ |---|---|---|---|
305
+ | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt5/original.mp4"></video> | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt5/minimax_context_ir.mp4"></video> | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt5/qwen_base.mp4"></video> | <video controls src="https://huggingface.co/lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA/resolve/main/assets/examples/prompt5/ours.mp4"></video> |
306
+
307
+ Expected video paths and filenames are documented in
308
+ [`assets/examples/UPLOAD_LAYOUT.md`](assets/examples/UPLOAD_LAYOUT.md).
309
+
310
+ ## Limitations
311
+
312
+ - This release supports text-only T2VA prompt rewriting; it does not consume images,
313
+ videos, or audio references.
314
+ - It is a learned approximation, not an open-source release or exact replica of the
315
+ official H3-Context-IR service.
316
+ - The generated rewrite may add details not explicitly present in a short prompt.
317
+ Review the result before generation when identity, dialogue, timing, or composition
318
+ must be exact.
319
+ - Final quality depends on both prompt rewriting and the MiniMax-H3 inference settings
320
+ selected in LightX2V.
321
+ - Use of MiniMax-H3 is governed by the license and acceptable-use terms published in
322
+ the [official MiniMax-H3 repository](https://huggingface.co/MiniMaxAI/MiniMax-H3).
323
+
324
+ ## Acknowledgements
325
+
326
+ This project is developed by the
327
+ [LightX2V](https://github.com/ModelTC/LightX2V) community to make local MiniMax-H3
328
+ prompt rewriting and audio-video generation easier and more efficient. It is built for
329
+ the [MiniMax-H3](https://huggingface.co/MiniMaxAI/MiniMax-H3) audio-video generation
330
+ model and fine-tuned from [Qwen3.6-27B](https://huggingface.co/Qwen/Qwen3.6-27B).
331
+
332
+ If you use this adapter or the MiniMax-H3 integration, please visit and star
333
+ **[ModelTC/LightX2V](https://github.com/ModelTC/LightX2V)**, where inference support,
334
+ performance optimizations, examples, and future task updates are maintained.
infer.py ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Rewrite one T2VA prompt with the MiniMax-H3 Prompt Rewriter LoRA."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import json
8
+ from pathlib import Path
9
+
10
+ import torch
11
+ import transformers
12
+ from transformers import AutoTokenizer, set_seed
13
+
14
+ from prompt_template import build_messages
15
+
16
+
17
+ DEFAULT_BASE_MODEL = "Qwen/Qwen3.6-27B"
18
+ DEFAULT_ADAPTER = "lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA"
19
+ RESOLUTIONS = ("21:9", "16:9", "4:3", "1:1", "3:4", "9:16")
20
+
21
+
22
+ def get_model_class():
23
+ model_class = getattr(transformers, "AutoModelForImageTextToText", None)
24
+ if model_class is None:
25
+ model_class = getattr(transformers, "AutoModelForVision2Seq", None)
26
+ if model_class is None:
27
+ raise RuntimeError(
28
+ "A recent Transformers version with AutoModelForImageTextToText "
29
+ "support is required. Install the packages in requirements.txt."
30
+ )
31
+ return model_class
32
+
33
+
34
+ def parse_args() -> argparse.Namespace:
35
+ parser = argparse.ArgumentParser(description=__doc__)
36
+ parser.add_argument("--prompt", required=True, help="Original text prompt to rewrite.")
37
+ parser.add_argument("--duration", type=int, choices=range(4, 16), default=10, metavar="4..15")
38
+ parser.add_argument("--resolution", choices=RESOLUTIONS, default="16:9", help="Target aspect ratio.")
39
+ parser.add_argument("--base-model", default=DEFAULT_BASE_MODEL, help="HF model ID or local base-model path.")
40
+ parser.add_argument("--adapter", default=DEFAULT_ADAPTER, help="HF model ID or local PEFT adapter path.")
41
+ parser.add_argument(
42
+ "--base-only",
43
+ action="store_true",
44
+ help="Skip the LoRA and run the Qwen base-model baseline.",
45
+ )
46
+ parser.add_argument("--max-new-tokens", type=int, default=2048)
47
+ parser.add_argument("--dtype", choices=("bfloat16", "float16", "float32"), default="bfloat16")
48
+ parser.add_argument("--attn-implementation", choices=("sdpa", "flash_attention_2", "eager"), default="sdpa")
49
+ parser.add_argument("--temperature", type=float, default=0.7)
50
+ parser.add_argument("--top-p", type=float, default=0.8)
51
+ parser.add_argument("--top-k", type=int, default=20)
52
+ parser.add_argument("--repetition-penalty", type=float, default=1.05)
53
+ parser.add_argument("--greedy", action="store_true", help="Use deterministic greedy decoding.")
54
+ parser.add_argument("--seed", type=int, default=42)
55
+ parser.add_argument(
56
+ "--output",
57
+ type=Path,
58
+ help="Optional output path. A .json file stores conditions and output; other suffixes store plain text.",
59
+ )
60
+ return parser.parse_args()
61
+
62
+
63
+ def input_device(model: torch.nn.Module) -> torch.device:
64
+ """Return the embedding device, including when Accelerate shards the model."""
65
+ embeddings = model.get_input_embeddings()
66
+ if embeddings is not None and hasattr(embeddings, "weight"):
67
+ return embeddings.weight.device
68
+ return next(model.parameters()).device
69
+
70
+
71
+ def main() -> None:
72
+ args = parse_args()
73
+ set_seed(args.seed)
74
+ dtype = getattr(torch, args.dtype)
75
+
76
+ tokenizer = AutoTokenizer.from_pretrained(args.base_model, trust_remote_code=True)
77
+ if tokenizer.pad_token_id is None:
78
+ tokenizer.pad_token = tokenizer.eos_token
79
+
80
+ model = get_model_class().from_pretrained(
81
+ args.base_model,
82
+ torch_dtype=dtype,
83
+ device_map="auto",
84
+ low_cpu_mem_usage=True,
85
+ trust_remote_code=True,
86
+ attn_implementation=args.attn_implementation,
87
+ )
88
+
89
+ if not args.base_only:
90
+ from peft import PeftModel
91
+
92
+ model = PeftModel.from_pretrained(model, args.adapter)
93
+ model.eval()
94
+
95
+ rendered = tokenizer.apply_chat_template(
96
+ build_messages(args.prompt, args.resolution, args.duration),
97
+ tokenize=False,
98
+ add_generation_prompt=True,
99
+ enable_thinking=False,
100
+ )
101
+ inputs = tokenizer(rendered, return_tensors="pt", add_special_tokens=False)
102
+ device = input_device(model)
103
+ inputs = {name: tensor.to(device) for name, tensor in inputs.items()}
104
+
105
+ generation_kwargs = {
106
+ "max_new_tokens": args.max_new_tokens,
107
+ "do_sample": not args.greedy,
108
+ "repetition_penalty": args.repetition_penalty,
109
+ "pad_token_id": tokenizer.pad_token_id,
110
+ "eos_token_id": tokenizer.eos_token_id,
111
+ }
112
+ if not args.greedy:
113
+ generation_kwargs.update(
114
+ temperature=args.temperature,
115
+ top_p=args.top_p,
116
+ top_k=args.top_k,
117
+ )
118
+
119
+ with torch.inference_mode():
120
+ generated = model.generate(**inputs, **generation_kwargs)
121
+ new_tokens = generated[:, inputs["input_ids"].shape[1] :]
122
+ rewritten_prompt = tokenizer.batch_decode(new_tokens, skip_special_tokens=True)[0].strip()
123
+
124
+ if args.output is not None:
125
+ args.output.parent.mkdir(parents=True, exist_ok=True)
126
+ if args.output.suffix.lower() == ".json":
127
+ record = {
128
+ "prompt": args.prompt.strip(),
129
+ "resolution": args.resolution,
130
+ "duration": args.duration,
131
+ "rewritten_prompt": rewritten_prompt,
132
+ "base_model": args.base_model,
133
+ "adapter": None if args.base_only else args.adapter,
134
+ }
135
+ args.output.write_text(json.dumps(record, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
136
+ else:
137
+ args.output.write_text(rewritten_prompt + "\n", encoding="utf-8")
138
+
139
+ print(rewritten_prompt)
140
+
141
+
142
+ if __name__ == "__main__":
143
+ main()
prompt_template.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Prompt template shared by MiniMax-H3 T2VA prompt-rewriter inference."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+ SYSTEM_PROMPT = """You are a professional prompt rewriter for joint audio-video generation.
7
+ Rewrite the user's original prompt into one coherent, production-ready multimodal description for the requested output aspect ratio and duration.
8
+
9
+ Return only these three fields, in this exact order:
10
+ integrated_multimodal_description: ...
11
+ overall_soundscape: ...
12
+ non_diegetic_music: ...
13
+
14
+ Requirements:
15
+ - Expand the visual narrative into clearly numbered shots such as [Shot 1], [Shot 2], and include timestamps for cuts after the first shot when useful.
16
+ - Make the number, timing, and pacing of shots appropriate for the requested duration.
17
+ - Compose the scene for the requested aspect ratio.
18
+ - Preserve the user's intent while adding concrete subjects, appearance, environment, lighting, composition, camera movement, physical motion, and temporal continuity.
19
+ - Keep characters, objects, wardrobe, locations, and spatial relationships consistent across shots.
20
+ - Describe synchronized diegetic audio in overall_soundscape and external score in non_diegetic_music.
21
+ - Do not add explanations, Markdown fences, safety commentary, or fields other than the three requested fields."""
22
+
23
+
24
+ def build_messages(prompt: str, resolution: str, duration: int) -> list[dict[str, str]]:
25
+ """Build the chat messages used during LoRA training and inference."""
26
+ prompt = prompt.strip()
27
+ if not prompt:
28
+ raise ValueError("prompt must not be empty")
29
+
30
+ return [
31
+ {"role": "system", "content": SYSTEM_PROMPT},
32
+ {
33
+ "role": "user",
34
+ "content": (
35
+ f"resolution: {resolution}\n"
36
+ f"duration: {duration}s\n"
37
+ f"original_prompt: {prompt}"
38
+ ),
39
+ },
40
+ ]
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ torch>=2.6
2
+ transformers>=4.57.1
3
+ accelerate>=1.10
4
+ peft>=0.17
5
+ safetensors>=0.5