File size: 4,845 Bytes
eadf422
 
 
 
 
 
 
 
 
 
 
 
 
 
6909119
eadf422
 
 
 
 
 
6909119
 
 
 
 
 
 
 
 
f8eb276
6909119
 
 
 
f8eb276
 
 
6909119
 
 
 
 
f8eb276
6909119
f8eb276
 
 
 
 
6909119
 
f8eb276
 
eadf422
6909119
eadf422
f8eb276
 
 
 
 
 
 
 
 
 
 
 
6909119
 
 
 
 
f8eb276
 
6909119
f8eb276
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6909119
 
 
 
 
 
 
 
 
f8eb276
 
 
 
 
6909119
f8eb276
 
 
6909119
 
f8eb276
 
eadf422
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
try:
    import spaces
except ImportError:
    class spaces:
        @staticmethod
        def GPU(duration=None):
            def decorator(func):
                return func
            return decorator

import gradio as gr
from diffusers import LTXPipeline
from diffusers.utils import export_to_video
import torch
import random

# Load pipeline
device = "cuda" if torch.cuda.is_available() else "cpu"
pipe = LTXPipeline.from_pretrained("Lightricks/LTX-Video", torch_dtype=torch.bfloat16)
pipe.to(device)

# Styles map
STYLES = {
    "None": "{prompt}",
    "Cinematic": "{prompt}, cinematic style, highly detailed, photorealistic, 8k resolution, dramatic volumetric lighting, depth of field",
    "3D Animation": "{prompt}, 3D Pixar style character, vibrant colors, clean textures, whimsical, ray-traced shadows",
    "Cyberpunk": "{prompt}, cyberpunk aesthetic, glowing neon lights, rain-slicked streets, futuristic atmosphere, high contrast",
    "Anime": "{prompt}, modern anime style, beautiful hand-drawn aesthetics, soft color grading, high detail, studio Ghibli influence"
}

@spaces.GPU(duration=120)  # seconds of GPU time this function may use
def generate(prompt, negative_prompt, num_inference_steps, guidance_scale, resolution, num_frames, style, seed, randomize_seed):
    # Apply style template
    styled_prompt = STYLES.get(style, "{prompt}").format(prompt=prompt)
    
    # Parse resolution (e.g. "768x512")
    width, height = map(int, resolution.split("x"))
    
    if randomize_seed:
        seed = random.randint(0, 2**31 - 1)
        
    generator = torch.Generator(device="cpu").manual_seed(seed)
    
    video = pipe(
        prompt=styled_prompt,
        negative_prompt=negative_prompt,
        width=width,
        height=height,
        num_frames=int(num_frames),
        num_inference_steps=int(num_inference_steps),
        guidance_scale=float(guidance_scale),
        generator=generator
    ).frames[0]
    
    export_to_video(video, "output.mp4", fps=24)
    return "output.mp4", seed

# Custom Gradio UI with advanced quality controls
with gr.Blocks(title="LTX-Video Generator Pro") as demo:
    gr.Markdown("# 🎬 LTX-Video Text-to-Video Generator")
    gr.Markdown("Generate high-quality videos using Lightricks LTX-Video on Hugging Face ZeroGPU.")
    
    with gr.Row():
        with gr.Column(scale=1):
            prompt = gr.Textbox(
                label="Prompt", 
                placeholder="A cinematic shot of a sunset over the ocean, high quality, 4k",
                lines=3
            )
            style = gr.Dropdown(
                label="Prompt Style Preset",
                choices=list(STYLES.keys()),
                value="None"
            )
            negative_prompt = gr.Textbox(
                label="Negative Prompt (Aids Quality)", 
                value="worst quality, low quality, deformed, distorted, blurry, noisy, static, cartoon, lowres",
                lines=2
            )
            
            with gr.Accordion("Advanced Settings (Quality Controls)", open=True):
                resolution = gr.Dropdown(
                    label="Resolution", 
                    choices=["768x512", "512x768", "768x768", "960x544"], 
                    value="768x512"
                )
                num_frames = gr.Slider(
                    label="Number of Frames (Multiple of 8 + 1)", 
                    minimum=17, 
                    maximum=121, 
                    step=8, 
                    value=65
                )
                num_inference_steps = gr.Slider(
                    label="Inference Steps (Higher = more detail)", 
                    minimum=10, 
                    maximum=50, 
                    step=1, 
                    value=30
                )
                guidance_scale = gr.Slider(
                    label="Guidance Scale (Prompt adherence)", 
                    minimum=1.0, 
                    maximum=10.0, 
                    step=0.5, 
                    value=3.0
                )
                seed = gr.Number(
                    label="Seed", 
                    value=42, 
                    precision=0
                )
                randomize_seed = gr.Checkbox(
                    label="Randomize Seed on Generate", 
                    value=True
                )
            
            generate_btn = gr.Button("Generate Video", variant="primary")
            
        with gr.Column(scale=1):
            output_video = gr.Video(label="Generated Video")
            output_seed = gr.Number(label="Used Seed")
            
    generate_btn.click(
        fn=generate,
        inputs=[prompt, negative_prompt, num_inference_steps, guidance_scale, resolution, num_frames, style, seed, randomize_seed],
        outputs=[output_video, output_seed]
    )

demo.launch()