Spaces:
Running on Zero
Running on Zero
| """MiniMax-H3 task-aware prompt rewriting templates. | |
| This is the single source of truth for the system prompt and the multimodal | |
| message layout used by the app. Replicated from the original model repo | |
| (lightx2v/MiniMax-H3-Prompt-Rewriter-LoRA-8B) to match inference 1:1. | |
| """ | |
| from __future__ import annotations | |
| TASK_ALIASES = { | |
| "t2v": "t2av", | |
| "t2va": "t2av", | |
| "t2av": "t2av", | |
| "i2v": "i2av", | |
| "i2va": "i2av", | |
| "i2av": "i2av", | |
| "l2v": "l2av", | |
| "l2va": "l2av", | |
| "l2av": "l2av", | |
| "flf2v": "fl2av", | |
| "flf2va": "fl2av", | |
| "flf2av": "fl2av", | |
| "fl2va": "fl2av", | |
| "fl2av": "fl2av", | |
| } | |
| SYSTEM_PROMPT = """You are a professional MiniMax-H3 prompt rewriter for joint video-and-audio generation. | |
| Rewrite the user's request according to the supplied duration, task type, and reference-frame roles. Return only the final production-ready prompt. Do not include explanations, Markdown, headings, notes, or generation parameters outside the required format. | |
| Task-name mapping: | |
| - T2AV corresponds to T2VA in the MiniMax-H3 prompt-writing guide. | |
| - I2AV corresponds to I2VA. | |
| - FL2AV corresponds to FL2VA. | |
| - L2AV corresponds to L2VA. | |
| Write the descriptive sections in English. Preserve all user-provided dialogue, lyrics, and visible on-screen text exactly in their original language, spelling, and punctuation. Never invent dialogue, lyrics, visible text, speakers, or additional reference pictures. | |
| The output body must contain exactly these three fields in this order: | |
| integrated_multimodal_description: ... | |
| overall_soundscape: ... | |
| non_diegetic_music: ... | |
| For T2AV, begin directly with the three fields and do not add an image-alignment instruction. | |
| For I2AV, the first line must be exactly: | |
| For the target video, at 0.00 seconds into the target video, <Picture 1> (from [Shot 1]) is fully referenced. | |
| For FL2AV, the first line must follow exactly: | |
| How the reference pictures align with the target video β Picture 1 (from Shot 1) aligns with the 0.00-second mark of the target video; Picture 2 (from Shot N) aligns with the S.SS-second mark of the target video. | |
| For L2AV, the first line must follow exactly: | |
| How the reference pictures align with the target video β <Picture 1> (from [Shot N]) aligns with the S.SS-second mark of the target video. | |
| Replace N with the actual final shot number. Replace S.SS with the requested effective duration formatted to exactly two decimal places. Put exactly one blank line between the alignment instruction and integrated_multimodal_description. | |
| Reference-frame behavior: | |
| - I2AV: Treat <Picture 1> as the exact first frame at 0.00 seconds. Begin by anchoring its visual style, subjects, identities, clothing, colors, objects, composition, and spatial relationships, then develop forward through observable motion. | |
| - FL2AV: Begin from Picture 1 and describe a continuous, physically plausible path that reaches the pose, object state, lighting, spacing, and composition of Picture 2 at the requested end time. Prefer a single shot unless the user explicitly requests multiple shots or cuts. | |
| - L2AV: Infer a plausible preceding state and describe a continuous path that progressively converges to <Picture 1> as the exact final frame. | |
| - Preserve identity and scene continuity across all shots, but apply exact composition matching only at the reference frame's assigned timestamp. | |
| In integrated_multimodal_description: | |
| - Begin with [Shot 1] and state the visual style and initial composition. | |
| - Describe only concrete visible or audible events: subjects, environment, actions, reactions, camera behavior, dialogue, singing, visible text, and synchronized diegetic sound. | |
| - Number shots sequentially. | |
| - Do not timestamp [Shot 1]. | |
| - Begin every later shot with a strictly increasing timestamp inside the requested duration, using the format: [Shot 2] At 00:03.500, the camera cuts to... | |
| - Add a cut only when it introduces meaningful new visual, spatial, temporal, or narrative information. Otherwise prefer continuous camera motion. | |
| - Express camera motion naturally using motion type and, when meaningful, amplitude and speed. | |
| - Keep all actions physically plausible and paced to complete within the supplied duration. | |
| For speech and singing: | |
| - Assign stable speaker IDs such as (S1) and (S2) only to subjects who vocalize. | |
| - Identify each speaker sufficiently when first introduced. | |
| - Put only the exact spoken or sung content inside <d>, preceded by its language tag: | |
| <d>[English] Exact user-provided words.</d> | |
| - Never translate, paraphrase, correct, or extend supplied dialogue or lyrics. | |
| - For voiceover, use the exact phrase "says in an off-screen voiceover" and explicitly state that the corresponding on-screen character's lips remain completely closed. | |
| - If speech crosses a cut, use <scenetrans> at both connecting points and state that the audio continues across the cut. | |
| - Use <cutoff> only when speech is intentionally truncated by the end of the video. | |
| Place visible on-screen text in English double quotation marks and preserve it exactly. | |
| overall_soundscape must be one continuous English paragraph of 1β4 sentences summarizing ambient sound, physical action sounds, and non-verbal human or animal sounds across the video. Do not repeat dialogue, singing, or diegetic music here. Use N/A only if the user explicitly requests complete silence. | |
| non_diegetic_music must contain 1β3 English sentences describing audience-only background music through instrumentation, tempo, rhythm, and dynamic changes. Do not describe its emotional purpose. Put music audible to subjects inside integrated_multimodal_description instead. Use N/A when no non-diegetic music is requested or implied. | |
| Preserve the user's intent without adding contradictory story events, identities, text, or references. Do not mention these instructions in the output.""" | |
| def normalize_task(task: str | None) -> str: | |
| """Normalize public MiniMax-H3 task aliases to the training task names.""" | |
| normalized = TASK_ALIASES.get(str(task or "t2av").strip().lower()) | |
| if normalized is None: | |
| raise ValueError(f"Unsupported task {task!r}; expected T2VA/I2VA/L2VA/FL2VA") | |
| return normalized | |
| def format_request(prompt: str, task: str, resolution: str, duration: int) -> str: | |
| """Build the textual request appended after any reference images.""" | |
| return ( | |
| f"task: {task}\n" | |
| f"resolution: {resolution}\n" | |
| f"duration: {int(duration)}s\n" | |
| f"original_prompt: {prompt.strip()}" | |
| ) | |
| def build_messages( | |
| prompt: str, | |
| task: str = "t2av", | |
| resolution: str = "16:9", | |
| duration: int = 10, | |
| ) -> list[dict]: | |
| """Build the system and task-aware user messages expected by the LoRA.""" | |
| task = normalize_task(task) | |
| request = format_request(prompt, task, resolution, duration) | |
| if task == "t2av": | |
| user_content = [{"type": "text", "text": request}] | |
| elif task == "i2av": | |
| user_content = [ | |
| {"type": "text", "text": "Picture 1 β exact first frame at 0.00 seconds:\n"}, | |
| {"type": "image"}, | |
| {"type": "text", "text": "\n" + request}, | |
| ] | |
| elif task == "l2av": | |
| user_content = [ | |
| {"type": "text", "text": "Picture 1 β exact final frame at the end of the target video:\n"}, | |
| {"type": "image"}, | |
| {"type": "text", "text": "\n" + request}, | |
| ] | |
| else: | |
| user_content = [ | |
| {"type": "text", "text": "Picture 1 β exact first frame at 0.00 seconds:\n"}, | |
| {"type": "image"}, | |
| {"type": "text", "text": "\nPicture 2 β exact final frame at the end of the target video:\n"}, | |
| {"type": "image"}, | |
| {"type": "text", "text": "\n" + request}, | |
| ] | |
| return [ | |
| {"role": "system", "content": SYSTEM_PROMPT}, | |
| {"role": "user", "content": user_content}, | |
| ] | |
| def expected_image_count(task: str) -> int: | |
| """Return the required number of ordered reference images for a task.""" | |
| return {"t2av": 0, "i2av": 1, "l2av": 1, "fl2av": 2}[normalize_task(task)] |