Spaces:
Running on Zero
Running on Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -105,11 +105,7 @@ DEFAULT_PROMPT = (
|
|
| 105 |
"Fine lunar dust lifts and drifts outward with each movement, floating "
|
| 106 |
"in slow arcs before settling back onto the ground."
|
| 107 |
)
|
| 108 |
-
|
| 109 |
-
"worst quality, inconsistent motion, blurry, jittery, distorted, "
|
| 110 |
-
"deformed, artifacts, text, watermark, logo, frame, border, "
|
| 111 |
-
"low resolution, pixelated, unnatural, fake, CGI, cartoon"
|
| 112 |
-
)
|
| 113 |
DEFAULT_FRAME_RATE = 24.0
|
| 114 |
|
| 115 |
# Resolution presets: (width, height)
|
|
@@ -155,7 +151,6 @@ class LTX23DistilledA2VPipeline:
|
|
| 155 |
def __call__(
|
| 156 |
self,
|
| 157 |
prompt: str,
|
| 158 |
-
negative_prompt: str,
|
| 159 |
seed: int,
|
| 160 |
height: int,
|
| 161 |
width: int,
|
|
@@ -176,14 +171,13 @@ class LTX23DistilledA2VPipeline:
|
|
| 176 |
stepper = EulerDiffusionStep()
|
| 177 |
dtype = torch.bfloat16
|
| 178 |
|
| 179 |
-
ctx_p
|
| 180 |
-
[prompt
|
| 181 |
self.model_ledger,
|
| 182 |
enhance_first_prompt=enhance_prompt,
|
| 183 |
enhance_prompt_image=images[0].path if len(images) > 0 else None,
|
| 184 |
)
|
| 185 |
v_context_p, a_context_p = ctx_p.video_encoding, ctx_p.audio_encoding
|
| 186 |
-
v_context_n, a_context_n = ctx_n.video_encoding, ctx_n.audio_encoding
|
| 187 |
|
| 188 |
# ββ Audio encoding (only for conditioning, not output generation) ββ
|
| 189 |
encoded_audio_latent = None
|
|
@@ -217,7 +211,7 @@ class LTX23DistilledA2VPipeline:
|
|
| 217 |
|
| 218 |
# Stage 1: Generate sigmas using LTX2Scheduler with user-specified steps
|
| 219 |
empty_latent = torch.empty(VideoLatentShape.from_pixel_shape(
|
| 220 |
-
VideoPixelShape(batch=1, frames=num_frames, width=width
|
| 221 |
).to_torch_shape())
|
| 222 |
stage_1_sigmas = (
|
| 223 |
LTX2Scheduler()
|
|
@@ -234,11 +228,9 @@ class LTX23DistilledA2VPipeline:
|
|
| 234 |
denoise_fn=multi_modal_guider_denoising_func(
|
| 235 |
video_guider=MultiModalGuider(
|
| 236 |
params=video_guider_params,
|
| 237 |
-
negative_context=v_context_n,
|
| 238 |
),
|
| 239 |
audio_guider=MultiModalGuider(
|
| 240 |
params=audio_guider_params,
|
| 241 |
-
negative_context=a_context_n,
|
| 242 |
),
|
| 243 |
v_context=v_context_p,
|
| 244 |
a_context=a_context_p,
|
|
@@ -246,25 +238,12 @@ class LTX23DistilledA2VPipeline:
|
|
| 246 |
),
|
| 247 |
)
|
| 248 |
|
| 249 |
-
def stage2_denoising_loop(sigmas: torch.Tensor, video_state, audio_state, stepper: DiffusionStepProtocol):
|
| 250 |
-
return euler_denoising_loop(
|
| 251 |
-
sigmas=sigmas,
|
| 252 |
-
video_state=video_state,
|
| 253 |
-
audio_state=audio_state,
|
| 254 |
-
stepper=stepper,
|
| 255 |
-
denoise_fn=simple_denoising_func(
|
| 256 |
-
video_context=v_context_p,
|
| 257 |
-
audio_context=a_context_p,
|
| 258 |
-
transformer=transformer, # noqa: F821
|
| 259 |
-
),
|
| 260 |
-
)
|
| 261 |
-
|
| 262 |
# ββ Stage 1: Half resolution ββ
|
| 263 |
stage_1_output_shape = VideoPixelShape(
|
| 264 |
batch=1,
|
| 265 |
frames=num_frames,
|
| 266 |
-
width=width
|
| 267 |
-
height=height
|
| 268 |
fps=frame_rate,
|
| 269 |
)
|
| 270 |
stage_1_conditionings = combined_image_conditionings(
|
|
@@ -292,43 +271,7 @@ class LTX23DistilledA2VPipeline:
|
|
| 292 |
)
|
| 293 |
|
| 294 |
torch.cuda.synchronize()
|
| 295 |
-
|
| 296 |
-
|
| 297 |
-
# ββ Upscaling ββ
|
| 298 |
-
upscaled_video_latent = upsample_video(
|
| 299 |
-
latent=video_state.latent[:1],
|
| 300 |
-
video_encoder=video_encoder,
|
| 301 |
-
upsampler=self.model_ledger.spatial_upsampler(),
|
| 302 |
-
)
|
| 303 |
-
|
| 304 |
-
# ββ Stage 2: Full resolution ββ
|
| 305 |
-
stage_2_sigmas = torch.tensor(STAGE_2_DISTILLED_SIGMA_VALUES, device=self.device)
|
| 306 |
-
stage_2_output_shape = VideoPixelShape(batch=1, frames=num_frames, width=width, height=height, fps=frame_rate)
|
| 307 |
-
stage_2_conditionings = combined_image_conditionings(
|
| 308 |
-
images=images,
|
| 309 |
-
height=stage_2_output_shape.height,
|
| 310 |
-
width=stage_2_output_shape.width,
|
| 311 |
-
video_encoder=video_encoder,
|
| 312 |
-
dtype=dtype,
|
| 313 |
-
device=self.device,
|
| 314 |
-
)
|
| 315 |
-
video_state, audio_state = denoise_audio_video(
|
| 316 |
-
output_shape=stage_2_output_shape,
|
| 317 |
-
conditionings=stage_2_conditionings,
|
| 318 |
-
noiser=noiser,
|
| 319 |
-
sigmas=stage_2_sigmas,
|
| 320 |
-
stepper=stepper,
|
| 321 |
-
denoising_loop_fn=stage2_denoising_loop,
|
| 322 |
-
components=self.pipeline_components,
|
| 323 |
-
dtype=dtype,
|
| 324 |
-
device=self.device,
|
| 325 |
-
noise_scale=stage_2_sigmas[0],
|
| 326 |
-
initial_video_latent=upscaled_video_latent,
|
| 327 |
-
initial_audio_latent=audio_state.latent,
|
| 328 |
-
)
|
| 329 |
-
|
| 330 |
-
torch.cuda.synchronize()
|
| 331 |
-
# cleanup_memory()
|
| 332 |
|
| 333 |
# ββ Decode both video and audio ββ
|
| 334 |
decoded_video = vae_decode_video(
|
|
@@ -686,7 +629,6 @@ def get_gpu_duration(
|
|
| 686 |
last_image,
|
| 687 |
input_audio,
|
| 688 |
prompt: str,
|
| 689 |
-
negative_prompt: str,
|
| 690 |
duration: float,
|
| 691 |
gpu_duration: float,
|
| 692 |
enhance_prompt: bool = True,
|
|
@@ -730,7 +672,6 @@ def generate_video(
|
|
| 730 |
last_image,
|
| 731 |
input_audio,
|
| 732 |
prompt: str,
|
| 733 |
-
negative_prompt: str,
|
| 734 |
duration: float,
|
| 735 |
gpu_duration: float,
|
| 736 |
enhance_prompt: bool = True,
|
|
@@ -824,7 +765,6 @@ def generate_video(
|
|
| 824 |
|
| 825 |
video, audio = pipeline(
|
| 826 |
prompt=prompt,
|
| 827 |
-
negative_prompt=negative_prompt,
|
| 828 |
seed=current_seed,
|
| 829 |
height=int(height),
|
| 830 |
width=int(width),
|
|
@@ -889,12 +829,6 @@ with gr.Blocks(title="LTX-2.3 Distilled with LoRAs, Negative Prompting, and Adva
|
|
| 889 |
placeholder="Describe the motion and animation you want...",
|
| 890 |
)
|
| 891 |
|
| 892 |
-
negative_prompt = gr.Textbox(
|
| 893 |
-
label="Negative Prompt",
|
| 894 |
-
value="blurry, out of focus, overexposed, underexposed, low contrast, washed out colors, excessive noise, grainy texture, poor lighting, flickering, motion blur, distorted proportions, unnatural skin tones, deformed facial features, asymmetrical face, missing facial features, extra limbs, disfigured hands, wrong hand count, artifacts around text, inconsistent perspective, camera shake, incorrect depth of field, background too sharp, background clutter, distracting reflections, harsh shadows, inconsistent lighting direction, color banding, cartoonish rendering, 3D CGI look, unrealistic materials, uncanny valley effect, incorrect ethnicity, wrong gender, exaggerated expressions, wrong gaze direction, mismatched lip sync, silent or muted audio, distorted voice, robotic voice, echo, background noise, off-sync audio, incorrect dialogue, added dialogue, repetitive speech, jittery movement, awkward pauses, incorrect timing, unnatural transitions, inconsistent framing, tilted camera, flat lighting, inconsistent tone, cinematic oversaturation, stylized filters, or AI artifacts.",
|
| 895 |
-
lines=2,
|
| 896 |
-
)
|
| 897 |
-
|
| 898 |
duration = gr.Slider(
|
| 899 |
label="Duration (seconds)",
|
| 900 |
minimum=1.0, maximum=30.0, value=10.0, step=0.1,
|
|
@@ -914,9 +848,9 @@ with gr.Blocks(title="LTX-2.3 Distilled with LoRAs, Negative Prompting, and Adva
|
|
| 914 |
|
| 915 |
with gr.Row():
|
| 916 |
num_inference_steps = gr.Slider(
|
| 917 |
-
label="
|
| 918 |
minimum=2, maximum=16, value=8, step=1,
|
| 919 |
-
info="Higher = more quality but slower
|
| 920 |
)
|
| 921 |
|
| 922 |
generate_btn = gr.Button("Generate Video", variant="primary", size="lg")
|
|
@@ -1027,7 +961,7 @@ with gr.Blocks(title="LTX-2.3 Distilled with LoRAs, Negative Prompting, and Adva
|
|
| 1027 |
generate_btn.click(
|
| 1028 |
fn=generate_video,
|
| 1029 |
inputs=[
|
| 1030 |
-
first_image, last_image, input_audio, prompt,
|
| 1031 |
enhance_prompt, seed, randomize_seed, height, width,
|
| 1032 |
video_cfg_scale, video_stg_scale, video_rescale_scale, video_a2v_scale,
|
| 1033 |
audio_cfg_scale, audio_stg_scale, audio_rescale_scale, audio_v2a_scale,
|
|
|
|
| 105 |
"Fine lunar dust lifts and drifts outward with each movement, floating "
|
| 106 |
"in slow arcs before settling back onto the ground."
|
| 107 |
)
|
| 108 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
DEFAULT_FRAME_RATE = 24.0
|
| 110 |
|
| 111 |
# Resolution presets: (width, height)
|
|
|
|
| 151 |
def __call__(
|
| 152 |
self,
|
| 153 |
prompt: str,
|
|
|
|
| 154 |
seed: int,
|
| 155 |
height: int,
|
| 156 |
width: int,
|
|
|
|
| 171 |
stepper = EulerDiffusionStep()
|
| 172 |
dtype = torch.bfloat16
|
| 173 |
|
| 174 |
+
ctx_p = encode_prompts(
|
| 175 |
+
[prompt],
|
| 176 |
self.model_ledger,
|
| 177 |
enhance_first_prompt=enhance_prompt,
|
| 178 |
enhance_prompt_image=images[0].path if len(images) > 0 else None,
|
| 179 |
)
|
| 180 |
v_context_p, a_context_p = ctx_p.video_encoding, ctx_p.audio_encoding
|
|
|
|
| 181 |
|
| 182 |
# ββ Audio encoding (only for conditioning, not output generation) ββ
|
| 183 |
encoded_audio_latent = None
|
|
|
|
| 211 |
|
| 212 |
# Stage 1: Generate sigmas using LTX2Scheduler with user-specified steps
|
| 213 |
empty_latent = torch.empty(VideoLatentShape.from_pixel_shape(
|
| 214 |
+
VideoPixelShape(batch=1, frames=num_frames, width=width, height=height, fps=frame_rate)
|
| 215 |
).to_torch_shape())
|
| 216 |
stage_1_sigmas = (
|
| 217 |
LTX2Scheduler()
|
|
|
|
| 228 |
denoise_fn=multi_modal_guider_denoising_func(
|
| 229 |
video_guider=MultiModalGuider(
|
| 230 |
params=video_guider_params,
|
|
|
|
| 231 |
),
|
| 232 |
audio_guider=MultiModalGuider(
|
| 233 |
params=audio_guider_params,
|
|
|
|
| 234 |
),
|
| 235 |
v_context=v_context_p,
|
| 236 |
a_context=a_context_p,
|
|
|
|
| 238 |
),
|
| 239 |
)
|
| 240 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 241 |
# ββ Stage 1: Half resolution ββ
|
| 242 |
stage_1_output_shape = VideoPixelShape(
|
| 243 |
batch=1,
|
| 244 |
frames=num_frames,
|
| 245 |
+
width=width,
|
| 246 |
+
height=height,
|
| 247 |
fps=frame_rate,
|
| 248 |
)
|
| 249 |
stage_1_conditionings = combined_image_conditionings(
|
|
|
|
| 271 |
)
|
| 272 |
|
| 273 |
torch.cuda.synchronize()
|
| 274 |
+
cleanup_memory()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 275 |
|
| 276 |
# ββ Decode both video and audio ββ
|
| 277 |
decoded_video = vae_decode_video(
|
|
|
|
| 629 |
last_image,
|
| 630 |
input_audio,
|
| 631 |
prompt: str,
|
|
|
|
| 632 |
duration: float,
|
| 633 |
gpu_duration: float,
|
| 634 |
enhance_prompt: bool = True,
|
|
|
|
| 672 |
last_image,
|
| 673 |
input_audio,
|
| 674 |
prompt: str,
|
|
|
|
| 675 |
duration: float,
|
| 676 |
gpu_duration: float,
|
| 677 |
enhance_prompt: bool = True,
|
|
|
|
| 765 |
|
| 766 |
video, audio = pipeline(
|
| 767 |
prompt=prompt,
|
|
|
|
| 768 |
seed=current_seed,
|
| 769 |
height=int(height),
|
| 770 |
width=int(width),
|
|
|
|
| 829 |
placeholder="Describe the motion and animation you want...",
|
| 830 |
)
|
| 831 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 832 |
duration = gr.Slider(
|
| 833 |
label="Duration (seconds)",
|
| 834 |
minimum=1.0, maximum=30.0, value=10.0, step=0.1,
|
|
|
|
| 848 |
|
| 849 |
with gr.Row():
|
| 850 |
num_inference_steps = gr.Slider(
|
| 851 |
+
label="Inference Steps",
|
| 852 |
minimum=2, maximum=16, value=8, step=1,
|
| 853 |
+
info="Higher = more quality but slower"
|
| 854 |
)
|
| 855 |
|
| 856 |
generate_btn = gr.Button("Generate Video", variant="primary", size="lg")
|
|
|
|
| 961 |
generate_btn.click(
|
| 962 |
fn=generate_video,
|
| 963 |
inputs=[
|
| 964 |
+
first_image, last_image, input_audio, prompt, duration, gpu_duration,
|
| 965 |
enhance_prompt, seed, randomize_seed, height, width,
|
| 966 |
video_cfg_scale, video_stg_scale, video_rescale_scale, video_a2v_scale,
|
| 967 |
audio_cfg_scale, audio_stg_scale, audio_rescale_scale, audio_v2a_scale,
|