seawolf2357 commited on
Commit
25bd139
Β·
verified Β·
1 Parent(s): 093d0ab

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +783 -123
app.py CHANGED
@@ -10,195 +10,817 @@ import numpy as np
10
  from PIL import Image
11
  import random
12
 
13
- MODEL_ID = "Wan-AI/Wan2.1-I2V-14B-480P-Diffusers"
 
 
 
14
  LORA_REPO_ID = "Kijai/WanVideo_comfy"
15
  LORA_FILENAME = "Wan21_CausVid_14B_T2V_lora_rank32.safetensors"
16
 
 
17
  image_encoder = CLIPVisionModel.from_pretrained(MODEL_ID, subfolder="image_encoder", torch_dtype=torch.float32)
18
  vae = AutoencoderKLWan.from_pretrained(MODEL_ID, subfolder="vae", torch_dtype=torch.float32)
19
  pipe = WanImageToVideoPipeline.from_pretrained(
20
  MODEL_ID, vae=vae, image_encoder=image_encoder, torch_dtype=torch.bfloat16
21
  )
 
 
22
  pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config, flow_shift=8.0)
23
  pipe.to("cuda")
24
 
25
- causvid_path = hf_hub_download(repo_id=LORA_REPO_ID, filename=LORA_FILENAME)
26
- pipe.load_lora_weights(causvid_path, adapter_name="causvid_lora")
27
- pipe.set_adapters(["causvid_lora"], adapter_weights=[0.95])
28
- pipe.fuse_lora()
 
 
 
 
 
29
 
30
  MOD_VALUE = 32
31
- DEFAULT_H_SLIDER_VALUE = 320
32
- DEFAULT_W_SLIDER_VALUE = 560
33
- NEW_FORMULA_MAX_AREA = 480.0 * 832.0
34
 
35
- SLIDER_MIN_H, SLIDER_MAX_H = 128, 896
36
- SLIDER_MIN_W, SLIDER_MAX_W = 128, 896
37
  MAX_SEED = np.iinfo(np.int32).max
38
 
39
  FIXED_FPS = 24
40
  MIN_FRAMES_MODEL = 8
41
- MAX_FRAMES_MODEL = 120
42
 
43
- default_prompt_i2v = "make this image come alive, cinematic motion, smooth animation"
44
- default_negative_prompt = "Bright tones, overexposed, static, blurred details, subtitles, style, works, paintings, images, static, overall gray, worst quality, low quality, JPEG compression residue, ugly, incomplete, extra fingers, poorly drawn hands, poorly drawn faces, deformed, disfigured, misshapen limbs, fused fingers, still picture, messy background, three legs, many people in the background, walking backwards, watermark, text, signature"
 
45
 
46
- # CSS μŠ€νƒ€μΌ μ •μ˜
47
  custom_css = """
48
- /* 전체 λ°°κ²½ κ·ΈλΌλ””μ–ΈνŠΈ */
49
  .gradio-container {
50
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;
51
- background: linear-gradient(135deg, #667eea 0%, #764ba2 25%, #f093fb 50%, #f5576c 75%, #fa709a 100%) !important;
52
  background-size: 400% 400% !important;
53
- animation: gradientShift 15s ease infinite !important;
54
  }
55
 
56
- @keyframes gradientShift {
57
  0% { background-position: 0% 50%; }
58
- 50% { background-position: 100% 50%; }
 
 
59
  100% { background-position: 0% 50%; }
60
  }
61
 
62
- /* 메인 μ»¨ν…Œμ΄λ„ˆ μŠ€νƒ€μΌ */
63
  .main-container {
64
- backdrop-filter: blur(10px);
65
- background: rgba(255, 255, 255, 0.1) !important;
66
- border-radius: 20px !important;
67
- padding: 30px !important;
68
- box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37) !important;
69
- border: 1px solid rgba(255, 255, 255, 0.18) !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  }
71
 
72
- /* 헀더 μŠ€νƒ€μΌ */
73
  h1 {
74
- background: linear-gradient(45deg, #ffffff, #f0f0f0) !important;
75
  -webkit-background-clip: text !important;
76
  -webkit-text-fill-color: transparent !important;
77
  background-clip: text !important;
78
- font-weight: 800 !important;
79
- font-size: 2.5rem !important;
80
  text-align: center !important;
81
- margin-bottom: 2rem !important;
82
- text-shadow: 2px 2px 4px rgba(0,0,0,0.1) !important;
 
83
  }
84
 
85
- /* μ»΄ν¬λ„ŒνŠΈ μ»¨ν…Œμ΄λ„ˆ μŠ€νƒ€μΌ */
 
 
 
 
 
 
 
 
 
86
  .input-container, .output-container {
87
- background: rgba(255, 255, 255, 0.08) !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  border-radius: 15px !important;
89
- padding: 20px !important;
90
- margin: 10px 0 !important;
91
  backdrop-filter: blur(5px) !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
93
  }
94
 
95
- /* μž…λ ₯ ν•„λ“œ μŠ€νƒ€μΌ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  input, textarea, .gr-box {
97
- background: rgba(255, 255, 255, 0.9) !important;
98
- border: 1px solid rgba(255, 255, 255, 0.3) !important;
99
- border-radius: 10px !important;
100
- color: #333 !important;
101
- transition: all 0.3s ease !important;
 
102
  }
103
 
104
  input:focus, textarea:focus {
105
  background: rgba(255, 255, 255, 1) !important;
106
- border-color: #667eea !important;
107
- box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1) !important;
 
108
  }
109
 
110
- /* λ²„νŠΌ μŠ€νƒ€μΌ */
111
  .generate-btn {
112
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
113
  color: white !important;
114
- font-weight: 600 !important;
115
- font-size: 1.1rem !important;
116
- padding: 12px 30px !important;
117
- border-radius: 50px !important;
118
  border: none !important;
119
  cursor: pointer !important;
120
- transition: all 0.3s ease !important;
121
- box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4) !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  }
123
 
124
  .generate-btn:hover {
125
- transform: translateY(-2px) !important;
126
- box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6) !important;
127
  }
128
 
129
- /* μŠ¬λΌμ΄λ” μŠ€νƒ€μΌ */
130
  input[type="range"] {
131
  background: transparent !important;
132
  }
133
 
134
  input[type="range"]::-webkit-slider-track {
135
- background: rgba(255, 255, 255, 0.3) !important;
136
- border-radius: 5px !important;
137
- height: 6px !important;
138
  }
139
 
140
  input[type="range"]::-webkit-slider-thumb {
141
- background: linear-gradient(135deg, #667eea, #764ba2) !important;
142
- border: 2px solid white !important;
143
  border-radius: 50% !important;
144
  cursor: pointer !important;
145
- width: 18px !important;
146
- height: 18px !important;
147
  -webkit-appearance: none !important;
 
148
  }
149
 
150
- /* Accordion μŠ€νƒ€μΌ */
151
  .gr-accordion {
152
- background: rgba(255, 255, 255, 0.05) !important;
153
- border-radius: 10px !important;
154
- border: 1px solid rgba(255, 255, 255, 0.1) !important;
155
- margin: 15px 0 !important;
 
156
  }
157
 
158
- /* 라벨 μŠ€νƒ€μΌ */
159
  label {
160
  color: #ffffff !important;
161
- font-weight: 500 !important;
162
- font-size: 0.95rem !important;
163
- margin-bottom: 5px !important;
 
164
  }
165
 
166
- /* 이미지 μ—…λ‘œλ“œ μ˜μ—­ */
167
  .image-upload {
168
- border: 2px dashed rgba(255, 255, 255, 0.3) !important;
169
- border-radius: 15px !important;
170
- background: rgba(255, 255, 255, 0.05) !important;
171
- transition: all 0.3s ease !important;
 
172
  }
173
 
174
  .image-upload:hover {
175
- border-color: rgba(255, 255, 255, 0.5) !important;
176
- background: rgba(255, 255, 255, 0.1) !important;
 
177
  }
178
 
179
- /* λΉ„λ””μ˜€ 좜λ ₯ μ˜μ—­ */
180
  video {
181
- border-radius: 15px !important;
182
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3) !important;
 
183
  }
184
 
185
- /* Examples μ„Ήμ…˜ μŠ€νƒ€μΌ */
186
  .gr-examples {
187
- background: rgba(255, 255, 255, 0.05) !important;
188
- border-radius: 15px !important;
189
- padding: 20px !important;
190
- margin-top: 20px !important;
 
191
  }
192
 
193
- /* Checkbox μŠ€νƒ€μΌ */
194
  input[type="checkbox"] {
195
- accent-color: #667eea !important;
 
196
  }
197
 
198
- /* λ°˜μ‘ν˜• μ• λ‹ˆλ©”μ΄μ…˜ */
199
  @media (max-width: 768px) {
200
- h1 { font-size: 2rem !important; }
201
- .main-container { padding: 20px !important; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
  }
203
  """
204
 
@@ -242,17 +864,18 @@ def get_duration(input_image, prompt, height, width,
242
  guidance_scale, steps,
243
  seed, randomize_seed,
244
  progress):
245
- if steps > 4 and duration_seconds > 2:
246
- return 90
247
- elif steps > 4 or duration_seconds > 2:
248
- return 75
 
249
  else:
250
- return 60
251
 
252
  @spaces.GPU(duration=get_duration)
253
  def generate_video(input_image, prompt, height, width,
254
- negative_prompt=default_negative_prompt, duration_seconds = 2,
255
- guidance_scale = 1, steps = 4,
256
  seed = 42, randomize_seed = False,
257
  progress=gr.Progress(track_tqdm=True)):
258
 
@@ -268,11 +891,19 @@ def generate_video(input_image, prompt, height, width,
268
 
269
  resized_image = input_image.resize((target_w, target_h))
270
 
 
 
 
271
  with torch.inference_mode():
272
  output_frames_list = pipe(
273
- image=resized_image, prompt=prompt, negative_prompt=negative_prompt,
274
- height=target_h, width=target_w, num_frames=num_frames,
275
- guidance_scale=float(guidance_scale), num_inference_steps=int(steps),
 
 
 
 
 
276
  generator=torch.Generator(device="cuda").manual_seed(current_seed)
277
  ).frames[0]
278
 
@@ -283,20 +914,30 @@ def generate_video(input_image, prompt, height, width,
283
 
284
  with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
285
  with gr.Column(elem_classes=["main-container"]):
286
- gr.Markdown("# ✨ Fast 4 steps Wan 2.1 I2V (14B) with CausVid LoRA")
287
 
288
- # Add badges side by side
289
  gr.HTML("""
290
  <div class="badge-container">
 
 
 
291
  <a href="https://huggingface.co/spaces/Heartsync/wan2-1-fast-security" target="_blank">
292
- <img src="https://img.shields.io/static/v1?label=WAN%202.1&message=FAST%20%26%20Furios&color=%23008080&labelColor=%230000ff&logo=huggingface&logoColor=%23ffa500&style=for-the-badge" alt="badge">
293
  </a>
294
  <a href="https://huggingface.co/spaces/Heartsync/WAN-VIDEO-AUDIO" target="_blank">
295
- <img src="https://img.shields.io/static/v1?label=WAN%202.1&message=VIDEO%20%26%20AUDIO&color=%23008080&labelColor=%230000ff&logo=huggingface&logoColor=%23ffa500&style=for-the-badge" alt="badge">
296
  </a>
297
  </div>
298
  """)
299
 
 
 
 
 
 
 
 
300
  with gr.Row():
301
  with gr.Column(elem_classes=["input-container"]):
302
  input_image_component = gr.Image(
@@ -305,24 +946,24 @@ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
305
  elem_classes=["image-upload"]
306
  )
307
  prompt_input = gr.Textbox(
308
- label="✏️ Prompt",
309
  value=default_prompt_i2v,
310
- lines=2
311
  )
312
  duration_seconds_input = gr.Slider(
313
  minimum=round(MIN_FRAMES_MODEL/FIXED_FPS,1),
314
  maximum=round(MAX_FRAMES_MODEL/FIXED_FPS,1),
315
  step=0.1,
316
- value=2,
317
  label="⏱️ Duration (seconds)",
318
- info=f"Clamped to model's {MIN_FRAMES_MODEL}-{MAX_FRAMES_MODEL} frames at {FIXED_FPS}fps."
319
  )
320
 
321
- with gr.Accordion("βš™οΈ Advanced Settings", open=False):
322
  negative_prompt_input = gr.Textbox(
323
- label="❌ Negative Prompt",
324
  value=default_negative_prompt,
325
- lines=3
326
  )
327
  seed_input = gr.Slider(
328
  label="🎲 Seed",
@@ -343,40 +984,41 @@ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
343
  maximum=SLIDER_MAX_H,
344
  step=MOD_VALUE,
345
  value=DEFAULT_H_SLIDER_VALUE,
346
- label=f"πŸ“ Output Height (multiple of {MOD_VALUE})"
347
  )
348
  width_input = gr.Slider(
349
  minimum=SLIDER_MIN_W,
350
  maximum=SLIDER_MAX_W,
351
  step=MOD_VALUE,
352
  value=DEFAULT_W_SLIDER_VALUE,
353
- label=f"πŸ“ Output Width (multiple of {MOD_VALUE})"
354
  )
355
  steps_slider = gr.Slider(
356
  minimum=1,
357
- maximum=30,
358
  step=1,
359
- value=4,
360
- label="πŸš€ Inference Steps"
 
361
  )
362
  guidance_scale_input = gr.Slider(
363
  minimum=0.0,
364
  maximum=20.0,
365
  step=0.5,
366
  value=1.0,
367
- label="🎯 Guidance Scale",
368
  visible=False
369
  )
370
 
371
  generate_button = gr.Button(
372
- "🎬 Generate Video",
373
  variant="primary",
374
  elem_classes=["generate-btn"]
375
  )
376
 
377
  with gr.Column(elem_classes=["output-container"]):
378
  video_output = gr.Video(
379
- label="πŸŽ₯ Generated Video",
380
  autoplay=True,
381
  interactive=False
382
  )
@@ -403,15 +1045,33 @@ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
403
  with gr.Column():
404
  gr.Examples(
405
  examples=[
406
- ["peng.png", "a penguin playfully dancing in the snow, Antarctica", 896, 512],
407
- ["forg.jpg", "the frog jumps around", 448, 832],
 
408
  ],
409
  inputs=[input_image_component, prompt_input, height_input, width_input],
410
  outputs=[video_output, seed_input],
411
  fn=generate_video,
412
  cache_examples="lazy",
413
- label="🌟 Example Gallery"
414
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
415
 
416
  if __name__ == "__main__":
417
  demo.queue().launch()
 
10
  from PIL import Image
11
  import random
12
 
13
+ # Updated MODEL_ID to FusionX
14
+ MODEL_ID = "vrgamedevgirl84/Wan14BT2VFusioniX"
15
+
16
+ # Optional fallback LoRA (if needed for additional enhancement)
17
  LORA_REPO_ID = "Kijai/WanVideo_comfy"
18
  LORA_FILENAME = "Wan21_CausVid_14B_T2V_lora_rank32.safetensors"
19
 
20
+ # Load FusionX model components
21
  image_encoder = CLIPVisionModel.from_pretrained(MODEL_ID, subfolder="image_encoder", torch_dtype=torch.float32)
22
  vae = AutoencoderKLWan.from_pretrained(MODEL_ID, subfolder="vae", torch_dtype=torch.float32)
23
  pipe = WanImageToVideoPipeline.from_pretrained(
24
  MODEL_ID, vae=vae, image_encoder=image_encoder, torch_dtype=torch.bfloat16
25
  )
26
+
27
+ # FusionX optimized scheduler settings
28
  pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config, flow_shift=8.0)
29
  pipe.to("cuda")
30
 
31
+ # Optional: Load additional LoRA for extra enhancement (can be commented out if not needed)
32
+ try:
33
+ causvid_path = hf_hub_download(repo_id=LORA_REPO_ID, filename=LORA_FILENAME)
34
+ pipe.load_lora_weights(causvid_path, adapter_name="causvid_lora")
35
+ pipe.set_adapters(["causvid_lora"], adapter_weights=[0.5]) # Lower weight since CausVid is already merged
36
+ pipe.fuse_lora()
37
+ print("Additional CausVid LoRA loaded for extra enhancement")
38
+ except Exception as e:
39
+ print(f"CausVid LoRA not loaded (FusionX already includes CausVid): {e}")
40
 
41
  MOD_VALUE = 32
42
+ DEFAULT_H_SLIDER_VALUE = 576 # FusionX optimized default
43
+ DEFAULT_W_SLIDER_VALUE = 1024 # FusionX optimized default
44
+ NEW_FORMULA_MAX_AREA = 576.0 * 1024.0 # Updated for FusionX
45
 
46
+ SLIDER_MIN_H, SLIDER_MAX_H = 128, 1080
47
+ SLIDER_MIN_W, SLIDER_MAX_W = 128, 1920
48
  MAX_SEED = np.iinfo(np.int32).max
49
 
50
  FIXED_FPS = 24
51
  MIN_FRAMES_MODEL = 8
52
+ MAX_FRAMES_MODEL = 121 # FusionX supports up to 121 frames
53
 
54
+ # Enhanced prompts for FusionX
55
+ default_prompt_i2v = "Cinematic motion, smooth animation, detailed textures, dynamic lighting, professional cinematography"
56
+ default_negative_prompt = "Static image, no motion, blurred details, overexposed, underexposed, low quality, worst quality, JPEG artifacts, ugly, incomplete, extra fingers, poorly drawn hands, poorly drawn faces, deformed, disfigured, misshapen limbs, fused fingers, still picture, messy background, watermark, text, signature"
57
 
58
+ # Enhanced CSS for FusionX theme
59
  custom_css = """
60
+ /* Enhanced FusionX theme with cinematic styling */
61
  .gradio-container {
62
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;
63
+ background: linear-gradient(135deg, #1a1a2e 0%, #16213e 25%, #0f3460 50%, #533a7d 75%, #6a4c93 100%) !important;
64
  background-size: 400% 400% !important;
65
+ animation: cinematicShift 20s ease infinite !important;
66
  }
67
 
68
+ @keyframes cinematicShift {
69
  0% { background-position: 0% 50%; }
70
+ 25% { background-position: 100% 50%; }
71
+ 50% { background-position: 100% 100%; }
72
+ 75% { background-position: 0% 100%; }
73
  100% { background-position: 0% 50%; }
74
  }
75
 
76
+ /* Main container with cinematic glass effect */
77
  .main-container {
78
+ backdrop-filter: blur(15px);
79
+ background: rgba(255, 255, 255, 0.08) !important;
80
+ border-radius: 25px !important;
81
+ padding: 35px !important;
82
+ box-shadow: 0 12px 40px 0 rgba(31, 38, 135, 0.4) !important;
83
+ border: 1px solid rgba(255, 255, 255, 0.15) !important;
84
+ position: relative;
85
+ overflow: hidden;
86
+ }
87
+
88
+ .main-container::before {
89
+ content: '';
90
+ position: absolute;
91
+ top: 0;
92
+ left: 0;
93
+ right: 0;
94
+ bottom: 0;
95
+ background: linear-gradient(45deg, rgba(255,255,255,0.1) 0%, transparent 50%, rgba(255,255,255,0.05) 100%);
96
+ pointer-events: none;
97
  }
98
 
99
+ /* Enhanced header with FusionX branding */
100
  h1 {
101
+ background: linear-gradient(45deg, #ffffff, #f0f8ff, #e6e6fa) !important;
102
  -webkit-background-clip: text !important;
103
  -webkit-text-fill-color: transparent !important;
104
  background-clip: text !important;
105
+ font-weight: 900 !important;
106
+ font-size: 2.8rem !important;
107
  text-align: center !important;
108
+ margin-bottom: 2.5rem !important;
109
+ text-shadow: 2px 2px 8px rgba(0,0,0,0.3) !important;
110
+ position: relative;
111
  }
112
 
113
+ h1::after {
114
+ content: '🎬 FusionX Enhanced';
115
+ display: block;
116
+ font-size: 1rem;
117
+ color: #6a4c93;
118
+ margin-top: 0.5rem;
119
+ font-weight: 500;
120
+ }
121
+
122
+ /* Enhanced component containers */
123
  .input-container, .output-container {
124
+ background: rgba(255, 255, 255, 0.06) !important;
125
+ border-radius: 20px !important;
126
+ padding: 25px !important;
127
+ margin: 15px 0 !important;
128
+ backdrop-filter: blur(10px) !important;
129
+ border: 1px solid rgba(255, 255, 255, 0.12) !important;
130
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1) !important;
131
+ }
132
+
133
+ /* Cinematic input styling */
134
+ input, textarea, .gr-box {
135
+ background: rgba(255, 255, 255, 0.95) !important;
136
+ border: 1px solid rgba(106, 76, 147, 0.3) !important;
137
+ border-radius: 12px !important;
138
+ color: #1a1a2e !important;
139
+ transition: all 0.4s ease !important;
140
+ box-shadow: 0 2px 8px rgba(106, 76, 147, 0.1) !important;
141
+ }
142
+
143
+ input:focus, textarea:focus {
144
+ background: rgba(255, 255, 255, 1) !important;
145
+ border-color: #6a4c93 !important;
146
+ box-shadow: 0 0 0 3px rgba(106, 76, 147, 0.15) !important;
147
+ transform: translateY(-1px) !important;
148
+ }
149
+
150
+ /* Enhanced FusionX button */
151
+ .generate-btn {
152
+ background: linear-gradient(135deg, #6a4c93 0%, #533a7d 50%, #0f3460 100%) !important;
153
+ color: white !important;
154
+ font-weight: 700 !important;
155
+ font-size: 1.2rem !important;
156
+ padding: 15px 40px !important;
157
+ border-radius: 60px !important;
158
+ border: none !important;
159
+ cursor: pointer !important;
160
+ transition: all 0.4s ease !important;
161
+ box-shadow: 0 6px 20px rgba(106, 76, 147, 0.4) !important;
162
+ position: relative;
163
+ overflow: hidden;
164
+ }
165
+
166
+ .generate-btn::before {
167
+ content: '';
168
+ position: absolute;
169
+ top: 0;
170
+ left: -100%;
171
+ width: 100%;
172
+ height: 100%;
173
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
174
+ transition: left 0.5s ease;
175
+ }
176
+
177
+ .generate-btn:hover::before {
178
+ left: 100%;
179
+ }
180
+
181
+ .generate-btn:hover {
182
+ transform: translateY(-3px) scale(1.02) !important;
183
+ box-shadow: 0 8px 25px rgba(106, 76, 147, 0.6) !important;
184
+ }
185
+
186
+ /* Enhanced slider styling */
187
+ input[type="range"] {
188
+ background: transparent !important;
189
+ }
190
+
191
+ input[type="range"]::-webkit-slider-track {
192
+ background: linear-gradient(90deg, rgba(106, 76, 147, 0.3), rgba(83, 58, 125, 0.5)) !important;
193
+ border-radius: 8px !important;
194
+ height: 8px !important;
195
+ }
196
+
197
+ input[type="range"]::-webkit-slider-thumb {
198
+ background: linear-gradient(135deg, #6a4c93, #533a7d) !important;
199
+ border: 3px solid white !important;
200
+ border-radius: 50% !important;
201
+ cursor: pointer !important;
202
+ width: 22px !important;
203
+ height: 22px !important;
204
+ -webkit-appearance: none !important;
205
+ box-shadow: 0 2px 8px rgba(106, 76, 147, 0.3) !important;
206
+ }
207
+
208
+ /* Enhanced accordion */
209
+ .gr-accordion {
210
+ background: rgba(255, 255, 255, 0.04) !important;
211
  border-radius: 15px !important;
212
+ border: 1px solid rgba(255, 255, 255, 0.08) !important;
213
+ margin: 20px 0 !important;
214
  backdrop-filter: blur(5px) !important;
215
+ }
216
+
217
+ /* Enhanced labels */
218
+ label {
219
+ color: #ffffff !important;
220
+ font-weight: 600 !important;
221
+ font-size: 1rem !important;
222
+ margin-bottom: 8px !important;
223
+ text-shadow: 1px 1px 2px rgba(0,0,0,0.5) !important;
224
+ }
225
+
226
+ /* Enhanced image upload */
227
+ .image-upload {
228
+ border: 3px dashed rgba(106, 76, 147, 0.4) !important;
229
+ border-radius: 20px !important;
230
+ background: rgba(255, 255, 255, 0.03) !important;
231
+ transition: all 0.4s ease !important;
232
+ position: relative;
233
+ }
234
+
235
+ .image-upload:hover {
236
+ border-color: rgba(106, 76, 147, 0.7) !important;
237
+ background: rgba(255, 255, 255, 0.08) !important;
238
+ transform: scale(1.01) !important;
239
+ }
240
+
241
+ /* Enhanced video output */
242
+ video {
243
+ border-radius: 20px !important;
244
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4) !important;
245
+ border: 2px solid rgba(106, 76, 147, 0.3) !important;
246
+ }
247
+
248
+ /* Enhanced examples section */
249
+ .gr-examples {
250
+ background: rgba(255, 255, 255, 0.04) !important;
251
+ border-radius: 20px !important;
252
+ padding: 25px !important;
253
+ margin-top: 25px !important;
254
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
255
  }
256
 
257
+ /* Enhanced checkbox */
258
+ input[type="checkbox"] {
259
+ accent-color: #6a4c93 !important;
260
+ transform: scale(1.2) !important;
261
+ }
262
+
263
+ /* Responsive enhancements */
264
+ @media (max-width: 768px) {
265
+ h1 { font-size: 2.2rem !important; }
266
+ .main-container { padding: 25px !important; }
267
+ .generate-btn { padding: 12px 30px !important; font-size: 1.1rem !important; }
268
+ }
269
+
270
+ /* Badge container styling */
271
+ .badge-container {
272
+ display: flex;
273
+ justify-content: center;
274
+ gap: 15px;
275
+ margin: 20px 0;
276
+ flex-wrap: wrap;
277
+ }
278
+
279
+ .badge-container img {
280
+ border-radius: 8px;
281
+ transition: transform 0.3s ease;
282
+ }
283
+
284
+ .badge-container img:hover {
285
+ transform: scale(1.05);
286
+ }
287
+ """
288
+
289
+ def _calculate_new_dimensions_wan(pil_image, mod_val, calculation_max_area,
290
+ min_slider_h, max_slider_h,
291
+ min_slider_w, max_slider_w,
292
+ default_h, default_w):
293
+ orig_w, orig_h = pil_image.size
294
+ if orig_w <= 0 or orig_h <= 0:
295
+ return default_h, default_w
296
+
297
+ aspect_ratio = orig_h / orig_w
298
+
299
+ calc_h = round(np.sqrt(calculation_max_area * aspect_ratio))
300
+ calc_w = round(np.sqrt(calculation_max_area / aspect_ratio))
301
+
302
+ calc_h = max(mod_val, (calc_h // mod_val) * mod_val)
303
+ calc_w = max(mod_val, (calc_w // mod_val) * mod_val)
304
+
305
+ new_h = int(np.clip(calc_h, min_slider_h, (max_slider_h // mod_val) * mod_val))
306
+ new_w = int(np.clip(calc_w, min_slider_w, (max_slider_w // mod_val) * mod_val))
307
+
308
+ return new_h, new_w
309
+
310
+ def handle_image_upload_for_dims_wan(uploaded_pil_image, current_h_val, current_w_val):
311
+ if uploaded_pil_image is None:
312
+ return gr.update(value=DEFAULT_H_SLIDER_VALUE), gr.update(value=DEFAULT_W_SLIDER_VALUE)
313
+ try:
314
+ new_h, new_w = _calculate_new_dimensions_wan(
315
+ uploaded_pil_image, MOD_VALUE, NEW_FORMULA_MAX_AREA,
316
+ SLIDER_MIN_H, SLIDER_MAX_H, SLIDER_MIN_W, SLIDER_MAX_W,
317
+ DEFAULT_H_SLIDER_VALUE, DEFAULT_W_SLIDER_VALUE
318
+ )
319
+ return gr.update(value=new_h), gr.update(value=new_w)
320
+ except Exception as e:
321
+ gr.Warning("Error attempting to calculate new dimensions")
322
+ return gr.update(value=DEFAULT_H_SLIDER_VALUE), gr.update(value=DEFAULT_W_SLIDER_VALUE)
323
+
324
+ def get_duration(input_image, prompt, height, width,
325
+ negative_prompt, duration_seconds,
326
+ guidance_scale, steps,
327
+ seed, randomize_seed,
328
+ progress):
329
+ # FusionX optimized duration calculation
330
+ if steps > 8 and duration_seconds > 3:
331
+ return 100
332
+ elif steps > 8 or duration_seconds > 3:
333
+ return 80
334
+ else:
335
+ return 65
336
+
337
+ @spaces.GPU(duration=get_duration)
338
+ def generate_video(input_image, prompt, height, width,
339
+ negative_prompt=default_negative_prompt, duration_seconds = 3,
340
+ guidance_scale = 1, steps = 8, # FusionX optimized default
341
+ seed = 42, randomize_seed = False,
342
+ progress=gr.Progress(track_tqdm=True)):
343
+
344
+ if input_image is None:
345
+ raise gr.Error("Please upload an input image.")
346
+
347
+ target_h = max(MOD_VALUE, (int(height) // MOD_VALUE) * MOD_VALUE)
348
+ target_w = max(MOD_VALUE, (int(width) // MOD_VALUE) * MOD_VALUE)
349
+
350
+ num_frames = np.clip(int(round(duration_seconds * FIXED_FPS)), MIN_FRAMES_MODEL, MAX_FRAMES_MODEL)
351
+
352
+ current_seed = random.randint(0, MAX_SEED) if randomize_seed else int(seed)
353
+
354
+ resized_image = input_image.resize((target_w, target_h))
355
+
356
+ # Enhanced prompt for FusionX model
357
+ enhanced_prompt = f"{prompt}, cinematic quality, smooth motion, detailed animation"
358
+
359
+ with torch.inference_mode():
360
+ output_frames_list = pipe(
361
+ image=resized_image,
362
+ prompt=enhanced_prompt,
363
+ negative_prompt=negative_prompt,
364
+ height=target_h,
365
+ width=target_w,
366
+ num_frames=num_frames,
367
+ guidance_scale=float(guidance_scale),
368
+ num_inference_steps=int(steps),
369
+ generator=torch.Generator(device="cuda").manual_seed(current_seed)
370
+ ).frames[0]
371
+
372
+ with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmpfile:
373
+ video_path = tmpfile.name
374
+ export_to_video(output_frames_list, video_path, fps=FIXED_FPS)
375
+ return video_path, current_seed
376
+
377
+ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
378
+ with gr.Column(elem_classes=["main-container"]):
379
+ gr.Markdown("# ⚑ Fast FusionX Wan 2.1 I2V Enhanced (14B)")
380
+
381
+ # Enhanced badges for FusionX
382
+ gr.HTML("""
383
+ <div class="badge-container">
384
+ <a href="https://huggingface.co/vrgamedevgirl84/Wan14BT2VFusioniX" target="_blank">
385
+ <img src="https://img.shields.io/static/v1?label=FusionX&message=ENHANCED%20MODEL&color=%236a4c93&labelColor=%23533a7d&logo=huggingface&logoColor=%23ffffff&style=for-the-badge" alt="FusionX Enhanced">
386
+ </a>
387
+ <a href="https://huggingface.co/spaces/Heartsync/wan2-1-fast-security" target="_blank">
388
+ <img src="https://img.shields.io/static/v1?label=WAN%202.1&message=FAST%20%26%20Furios&color=%23008080&labelColor=%230000ff&logo=huggingface&logoColor=%23ffa500&style=for-the-badge" alt="WAN Fast">
389
+ </a>
390
+ <a href="https://huggingface.co/spaces/Heartsync/WAN-VIDEO-AUDIO" target="_blank">
391
+ <img src="https://img.shields.io/static/v1?label=WAN%202.1&message=VIDEO%20%26%20AUDIO&color=%23008080&labelColor=%230000ff&logo=huggingface&logoColor=%23ffa500&style=for-the-badge" alt="WAN Video Audio">
392
+ </a>
393
+ </div>
394
+ """)
395
+
396
+ gr.Markdown("""
397
+ ### πŸš€ Enhanced with FusionX Technology
398
+ **Features:** CausVid + AccVideo + MoviiGen1.1 + MPS Rewards LoRA + Custom Detail Enhancers
399
+
400
+ **Optimizations:** 8-10 steps for premium quality β€’ Enhanced motion realism β€’ Superior temporal consistency
401
+ """)
402
+
403
+ with gr.Row():
404
+ with gr.Column(elem_classes=["input-container"]):
405
+ input_image_component = gr.Image(
406
+ type="pil",
407
+ label="πŸ–ΌοΈ Input Image (auto-resized to target H/W)",
408
+ elem_classes=["image-upload"]
409
+ )
410
+ prompt_input = gr.Textbox(
411
+ label="✏️ Enhanced Prompt (FusionX automatically adds cinematic quality)",
412
+ value=default_prompt_i2v,
413
+ lines=3
414
+ )
415
+ duration_seconds_input = gr.Slider(
416
+ minimum=round(MIN_FRAMES_MODEL/FIXED_FPS,1),
417
+ maximum=round(MAX_FRAMES_MODEL/FIXED_FPS,1),
418
+ step=0.1,
419
+ value=3,
420
+ label="⏱️ Duration (seconds)",
421
+ info=f"FusionX supports {MIN_FRAMES_MODEL}-{MAX_FRAMES_MODEL} frames at {FIXED_FPS}fps. Recommended: 3-5 seconds"
422
+ )
423
+
424
+ with gr.Accordion("βš™οΈ Advanced FusionX Settings", open=False):
425
+ negative_prompt_input = gr.Textbox(
426
+ label="❌ Negative Prompt (Enhanced for FusionX)",
427
+ value=default_negative_prompt,
428
+ lines=4
429
+ )
430
+ seed_input = gr.Slider(
431
+ label="🎲 Seed",
432
+ minimum=0,
433
+ maximum=MAX_SEED,
434
+ step=1,
435
+ value=42,
436
+ interactive=True
437
+ )
438
+ randomize_seed_checkbox = gr.Checkbox(
439
+ label="πŸ”€ Randomize seed",
440
+ value=True,
441
+ interactive=True
442
+ )
443
+ with gr.Row():
444
+ height_input = gr.Slider(
445
+ minimum=SLIDER_MIN_H,
446
+ maximum=SLIDER_MAX_H,
447
+ step=MOD_VALUE,
448
+ value=DEFAULT_H_SLIDER_VALUE,
449
+ label=f"πŸ“ Output Height (FusionX optimized: {MOD_VALUE} multiples)"
450
+ )
451
+ width_input = gr.Slider(
452
+ minimum=SLIDER_MIN_W,
453
+ maximum=SLIDER_MAX_W,
454
+ step=MOD_VALUE,
455
+ value=DEFAULT_W_SLIDER_VALUE,
456
+ label=f"πŸ“ Output Width (FusionX optimized: {MOD_VALUE} multiples)"
457
+ )
458
+ steps_slider = gr.Slider(
459
+ minimum=1,
460
+ maximum=20,
461
+ step=1,
462
+ value=8, # FusionX optimized
463
+ label="πŸš€ Inference Steps (FusionX: 8-10 recommended)",
464
+ info="FusionX delivers excellent results in just 8-10 steps!"
465
+ )
466
+ guidance_scale_input = gr.Slider(
467
+ minimum=0.0,
468
+ maximum=20.0,
469
+ step=0.5,
470
+ value=1.0,
471
+ label="🎯 Guidance Scale (FusionX optimized)",
472
+ visible=False
473
+ )
474
+
475
+ generate_button = gr.Button(
476
+ "🎬 Generate FusionX Video",
477
+ variant="primary",
478
+ elem_classes=["generate-btn"]
479
+ )
480
+
481
+ with gr.Column(elem_classes=["output-container"]):
482
+ video_output = gr.Video(
483
+ label="πŸŽ₯ FusionX Generated Video",
484
+ autoplay=True,
485
+ interactive=False
486
+ )
487
+
488
+ input_image_component.upload(
489
+ fn=handle_image_upload_for_dims_wan,
490
+ inputs=[input_image_component, height_input, width_input],
491
+ outputs=[height_input, width_input]
492
+ )
493
+
494
+ input_image_component.clear(
495
+ fn=handle_image_upload_for_dims_wan,
496
+ inputs=[input_image_component, height_input, width_input],
497
+ outputs=[height_input, width_input]
498
+ )
499
+
500
+ ui_inputs = [
501
+ input_image_component, prompt_input, height_input, width_input,
502
+ negative_prompt_input, duration_seconds_input,
503
+ guidance_scale_input, steps_slider, seed_input, randomize_seed_checkbox
504
+ ]
505
+ generate_button.click(fn=generate_video, inputs=ui_inputs, outputs=[video_output, seed_input])
506
+
507
+ with gr.Column():
508
+ gr.Examples(
509
+ examples=[
510
+ ["peng.png", "a penguin gracefully dancing in the pristine snow, cinematic motion with detailed feathers", 576, 1024],
511
+ ["forg.jpg", "the frog jumps energetically with smooth, lifelike motion and detailed texture", 832, 576],
512
+ ["example.jpg", "person walking through a bustling city street, dynamic camera movement, cinematic lighting", 720, 1280],
513
+ ],
514
+ inputs=[input_image_component, prompt_input, height_input, width_input],
515
+ outputs=[video_output, seed_input],
516
+ fn=generate_video,
517
+ cache_examples="lazy",
518
+ label="🌟 FusionX Example Gallery"
519
+ )
520
+
521
+ gr.Markdown("""
522
+ ### πŸ”§ FusionX Model Information
523
+
524
+ **Base Model:** Wan2.1 14B T2V Enhanced with multiple research-grade components
525
+
526
+ **Integrated Components:**
527
+ - πŸ”— **CausVid**: Advanced causal motion modeling
528
+ - πŸ”— **AccVideo**: Improved temporal alignment & speed boost
529
+ - πŸ”— **MoviiGen1.1**: Cinematic smoothness & lighting
530
+ - πŸ”— **MPS Rewards LoRA**: Motion & detail optimization
531
+ - ✨ **Custom LoRAs**: Texture & clarity enhancements
532
+
533
+ **Performance:** Optimized for 8-10 steps β€’ Up to 50% faster rendering β€’ Enhanced motion quality
534
+
535
+ **License:** Apache 2.0 / MIT - Open source and permissive
536
+ """)
537
+
538
+ if __name__ == "__main__":
539
+ demo.queue().launch()import torch
540
+ from diffusers import AutoencoderKLWan, WanImageToVideoPipeline, UniPCMultistepScheduler
541
+ from diffusers.utils import export_to_video
542
+ from transformers import CLIPVisionModel
543
+ import gradio as gr
544
+ import tempfile
545
+ import spaces
546
+ from huggingface_hub import hf_hub_download
547
+ import numpy as np
548
+ from PIL import Image
549
+ import random
550
+
551
+ # Updated MODEL_ID to FusionX
552
+ MODEL_ID = "vrgamedevgirl84/Wan14BT2VFusioniX"
553
+
554
+ # Optional fallback LoRA (if needed for additional enhancement)
555
+ LORA_REPO_ID = "Kijai/WanVideo_comfy"
556
+ LORA_FILENAME = "Wan21_CausVid_14B_T2V_lora_rank32.safetensors"
557
+
558
+ # Load FusionX model components
559
+ image_encoder = CLIPVisionModel.from_pretrained(MODEL_ID, subfolder="image_encoder", torch_dtype=torch.float32)
560
+ vae = AutoencoderKLWan.from_pretrained(MODEL_ID, subfolder="vae", torch_dtype=torch.float32)
561
+ pipe = WanImageToVideoPipeline.from_pretrained(
562
+ MODEL_ID, vae=vae, image_encoder=image_encoder, torch_dtype=torch.bfloat16
563
+ )
564
+
565
+ # FusionX optimized scheduler settings
566
+ pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config, flow_shift=8.0)
567
+ pipe.to("cuda")
568
+
569
+ # Optional: Load additional LoRA for extra enhancement (can be commented out if not needed)
570
+ try:
571
+ causvid_path = hf_hub_download(repo_id=LORA_REPO_ID, filename=LORA_FILENAME)
572
+ pipe.load_lora_weights(causvid_path, adapter_name="causvid_lora")
573
+ pipe.set_adapters(["causvid_lora"], adapter_weights=[0.5]) # Lower weight since CausVid is already merged
574
+ pipe.fuse_lora()
575
+ print("Additional CausVid LoRA loaded for extra enhancement")
576
+ except Exception as e:
577
+ print(f"CausVid LoRA not loaded (FusionX already includes CausVid): {e}")
578
+
579
+ MOD_VALUE = 32
580
+ DEFAULT_H_SLIDER_VALUE = 576 # FusionX optimized default
581
+ DEFAULT_W_SLIDER_VALUE = 1024 # FusionX optimized default
582
+ NEW_FORMULA_MAX_AREA = 576.0 * 1024.0 # Updated for FusionX
583
+
584
+ SLIDER_MIN_H, SLIDER_MAX_H = 128, 1080
585
+ SLIDER_MIN_W, SLIDER_MAX_W = 128, 1920
586
+ MAX_SEED = np.iinfo(np.int32).max
587
+
588
+ FIXED_FPS = 24
589
+ MIN_FRAMES_MODEL = 8
590
+ MAX_FRAMES_MODEL = 121 # FusionX supports up to 121 frames
591
+
592
+ # Enhanced prompts for FusionX
593
+ default_prompt_i2v = "Cinematic motion, smooth animation, detailed textures, dynamic lighting, professional cinematography"
594
+ default_negative_prompt = "Static image, no motion, blurred details, overexposed, underexposed, low quality, worst quality, JPEG artifacts, ugly, incomplete, extra fingers, poorly drawn hands, poorly drawn faces, deformed, disfigured, misshapen limbs, fused fingers, still picture, messy background, watermark, text, signature"
595
+
596
+ # Enhanced CSS for FusionX theme
597
+ custom_css = """
598
+ /* Enhanced FusionX theme with cinematic styling */
599
+ .gradio-container {
600
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;
601
+ background: linear-gradient(135deg, #1a1a2e 0%, #16213e 25%, #0f3460 50%, #533a7d 75%, #6a4c93 100%) !important;
602
+ background-size: 400% 400% !important;
603
+ animation: cinematicShift 20s ease infinite !important;
604
+ }
605
+
606
+ @keyframes cinematicShift {
607
+ 0% { background-position: 0% 50%; }
608
+ 25% { background-position: 100% 50%; }
609
+ 50% { background-position: 100% 100%; }
610
+ 75% { background-position: 0% 100%; }
611
+ 100% { background-position: 0% 50%; }
612
+ }
613
+
614
+ /* Main container with cinematic glass effect */
615
+ .main-container {
616
+ backdrop-filter: blur(15px);
617
+ background: rgba(255, 255, 255, 0.08) !important;
618
+ border-radius: 25px !important;
619
+ padding: 35px !important;
620
+ box-shadow: 0 12px 40px 0 rgba(31, 38, 135, 0.4) !important;
621
+ border: 1px solid rgba(255, 255, 255, 0.15) !important;
622
+ position: relative;
623
+ overflow: hidden;
624
+ }
625
+
626
+ .main-container::before {
627
+ content: '';
628
+ position: absolute;
629
+ top: 0;
630
+ left: 0;
631
+ right: 0;
632
+ bottom: 0;
633
+ background: linear-gradient(45deg, rgba(255,255,255,0.1) 0%, transparent 50%, rgba(255,255,255,0.05) 100%);
634
+ pointer-events: none;
635
+ }
636
+
637
+ /* Enhanced header with FusionX branding */
638
+ h1 {
639
+ background: linear-gradient(45deg, #ffffff, #f0f8ff, #e6e6fa) !important;
640
+ -webkit-background-clip: text !important;
641
+ -webkit-text-fill-color: transparent !important;
642
+ background-clip: text !important;
643
+ font-weight: 900 !important;
644
+ font-size: 2.8rem !important;
645
+ text-align: center !important;
646
+ margin-bottom: 2.5rem !important;
647
+ text-shadow: 2px 2px 8px rgba(0,0,0,0.3) !important;
648
+ position: relative;
649
+ }
650
+
651
+ h1::after {
652
+ content: '🎬 FusionX Enhanced';
653
+ display: block;
654
+ font-size: 1rem;
655
+ color: #6a4c93;
656
+ margin-top: 0.5rem;
657
+ font-weight: 500;
658
+ }
659
+
660
+ /* Enhanced component containers */
661
+ .input-container, .output-container {
662
+ background: rgba(255, 255, 255, 0.06) !important;
663
+ border-radius: 20px !important;
664
+ padding: 25px !important;
665
+ margin: 15px 0 !important;
666
+ backdrop-filter: blur(10px) !important;
667
+ border: 1px solid rgba(255, 255, 255, 0.12) !important;
668
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1) !important;
669
+ }
670
+
671
+ /* Cinematic input styling */
672
  input, textarea, .gr-box {
673
+ background: rgba(255, 255, 255, 0.95) !important;
674
+ border: 1px solid rgba(106, 76, 147, 0.3) !important;
675
+ border-radius: 12px !important;
676
+ color: #1a1a2e !important;
677
+ transition: all 0.4s ease !important;
678
+ box-shadow: 0 2px 8px rgba(106, 76, 147, 0.1) !important;
679
  }
680
 
681
  input:focus, textarea:focus {
682
  background: rgba(255, 255, 255, 1) !important;
683
+ border-color: #6a4c93 !important;
684
+ box-shadow: 0 0 0 3px rgba(106, 76, 147, 0.15) !important;
685
+ transform: translateY(-1px) !important;
686
  }
687
 
688
+ /* Enhanced FusionX button */
689
  .generate-btn {
690
+ background: linear-gradient(135deg, #6a4c93 0%, #533a7d 50%, #0f3460 100%) !important;
691
  color: white !important;
692
+ font-weight: 700 !important;
693
+ font-size: 1.2rem !important;
694
+ padding: 15px 40px !important;
695
+ border-radius: 60px !important;
696
  border: none !important;
697
  cursor: pointer !important;
698
+ transition: all 0.4s ease !important;
699
+ box-shadow: 0 6px 20px rgba(106, 76, 147, 0.4) !important;
700
+ position: relative;
701
+ overflow: hidden;
702
+ }
703
+
704
+ .generate-btn::before {
705
+ content: '';
706
+ position: absolute;
707
+ top: 0;
708
+ left: -100%;
709
+ width: 100%;
710
+ height: 100%;
711
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
712
+ transition: left 0.5s ease;
713
+ }
714
+
715
+ .generate-btn:hover::before {
716
+ left: 100%;
717
  }
718
 
719
  .generate-btn:hover {
720
+ transform: translateY(-3px) scale(1.02) !important;
721
+ box-shadow: 0 8px 25px rgba(106, 76, 147, 0.6) !important;
722
  }
723
 
724
+ /* Enhanced slider styling */
725
  input[type="range"] {
726
  background: transparent !important;
727
  }
728
 
729
  input[type="range"]::-webkit-slider-track {
730
+ background: linear-gradient(90deg, rgba(106, 76, 147, 0.3), rgba(83, 58, 125, 0.5)) !important;
731
+ border-radius: 8px !important;
732
+ height: 8px !important;
733
  }
734
 
735
  input[type="range"]::-webkit-slider-thumb {
736
+ background: linear-gradient(135deg, #6a4c93, #533a7d) !important;
737
+ border: 3px solid white !important;
738
  border-radius: 50% !important;
739
  cursor: pointer !important;
740
+ width: 22px !important;
741
+ height: 22px !important;
742
  -webkit-appearance: none !important;
743
+ box-shadow: 0 2px 8px rgba(106, 76, 147, 0.3) !important;
744
  }
745
 
746
+ /* Enhanced accordion */
747
  .gr-accordion {
748
+ background: rgba(255, 255, 255, 0.04) !important;
749
+ border-radius: 15px !important;
750
+ border: 1px solid rgba(255, 255, 255, 0.08) !important;
751
+ margin: 20px 0 !important;
752
+ backdrop-filter: blur(5px) !important;
753
  }
754
 
755
+ /* Enhanced labels */
756
  label {
757
  color: #ffffff !important;
758
+ font-weight: 600 !important;
759
+ font-size: 1rem !important;
760
+ margin-bottom: 8px !important;
761
+ text-shadow: 1px 1px 2px rgba(0,0,0,0.5) !important;
762
  }
763
 
764
+ /* Enhanced image upload */
765
  .image-upload {
766
+ border: 3px dashed rgba(106, 76, 147, 0.4) !important;
767
+ border-radius: 20px !important;
768
+ background: rgba(255, 255, 255, 0.03) !important;
769
+ transition: all 0.4s ease !important;
770
+ position: relative;
771
  }
772
 
773
  .image-upload:hover {
774
+ border-color: rgba(106, 76, 147, 0.7) !important;
775
+ background: rgba(255, 255, 255, 0.08) !important;
776
+ transform: scale(1.01) !important;
777
  }
778
 
779
+ /* Enhanced video output */
780
  video {
781
+ border-radius: 20px !important;
782
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4) !important;
783
+ border: 2px solid rgba(106, 76, 147, 0.3) !important;
784
  }
785
 
786
+ /* Enhanced examples section */
787
  .gr-examples {
788
+ background: rgba(255, 255, 255, 0.04) !important;
789
+ border-radius: 20px !important;
790
+ padding: 25px !important;
791
+ margin-top: 25px !important;
792
+ border: 1px solid rgba(255, 255, 255, 0.1) !important;
793
  }
794
 
795
+ /* Enhanced checkbox */
796
  input[type="checkbox"] {
797
+ accent-color: #6a4c93 !important;
798
+ transform: scale(1.2) !important;
799
  }
800
 
801
+ /* Responsive enhancements */
802
  @media (max-width: 768px) {
803
+ h1 { font-size: 2.2rem !important; }
804
+ .main-container { padding: 25px !important; }
805
+ .generate-btn { padding: 12px 30px !important; font-size: 1.1rem !important; }
806
+ }
807
+
808
+ /* Badge container styling */
809
+ .badge-container {
810
+ display: flex;
811
+ justify-content: center;
812
+ gap: 15px;
813
+ margin: 20px 0;
814
+ flex-wrap: wrap;
815
+ }
816
+
817
+ .badge-container img {
818
+ border-radius: 8px;
819
+ transition: transform 0.3s ease;
820
+ }
821
+
822
+ .badge-container img:hover {
823
+ transform: scale(1.05);
824
  }
825
  """
826
 
 
864
  guidance_scale, steps,
865
  seed, randomize_seed,
866
  progress):
867
+ # FusionX optimized duration calculation
868
+ if steps > 8 and duration_seconds > 3:
869
+ return 100
870
+ elif steps > 8 or duration_seconds > 3:
871
+ return 80
872
  else:
873
+ return 65
874
 
875
  @spaces.GPU(duration=get_duration)
876
  def generate_video(input_image, prompt, height, width,
877
+ negative_prompt=default_negative_prompt, duration_seconds = 3,
878
+ guidance_scale = 1, steps = 8, # FusionX optimized default
879
  seed = 42, randomize_seed = False,
880
  progress=gr.Progress(track_tqdm=True)):
881
 
 
891
 
892
  resized_image = input_image.resize((target_w, target_h))
893
 
894
+ # Enhanced prompt for FusionX model
895
+ enhanced_prompt = f"{prompt}, cinematic quality, smooth motion, detailed animation"
896
+
897
  with torch.inference_mode():
898
  output_frames_list = pipe(
899
+ image=resized_image,
900
+ prompt=enhanced_prompt,
901
+ negative_prompt=negative_prompt,
902
+ height=target_h,
903
+ width=target_w,
904
+ num_frames=num_frames,
905
+ guidance_scale=float(guidance_scale),
906
+ num_inference_steps=int(steps),
907
  generator=torch.Generator(device="cuda").manual_seed(current_seed)
908
  ).frames[0]
909
 
 
914
 
915
  with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
916
  with gr.Column(elem_classes=["main-container"]):
917
+ gr.Markdown("# ⚑ Fast FusionX Wan 2.1 I2V Enhanced (14B)")
918
 
919
+ # Enhanced badges for FusionX
920
  gr.HTML("""
921
  <div class="badge-container">
922
+ <a href="https://huggingface.co/vrgamedevgirl84/Wan14BT2VFusioniX" target="_blank">
923
+ <img src="https://img.shields.io/static/v1?label=FusionX&message=ENHANCED%20MODEL&color=%236a4c93&labelColor=%23533a7d&logo=huggingface&logoColor=%23ffffff&style=for-the-badge" alt="FusionX Enhanced">
924
+ </a>
925
  <a href="https://huggingface.co/spaces/Heartsync/wan2-1-fast-security" target="_blank">
926
+ <img src="https://img.shields.io/static/v1?label=WAN%202.1&message=FAST%20%26%20Furios&color=%23008080&labelColor=%230000ff&logo=huggingface&logoColor=%23ffa500&style=for-the-badge" alt="WAN Fast">
927
  </a>
928
  <a href="https://huggingface.co/spaces/Heartsync/WAN-VIDEO-AUDIO" target="_blank">
929
+ <img src="https://img.shields.io/static/v1?label=WAN%202.1&message=VIDEO%20%26%20AUDIO&color=%23008080&labelColor=%230000ff&logo=huggingface&logoColor=%23ffa500&style=for-the-badge" alt="WAN Video Audio">
930
  </a>
931
  </div>
932
  """)
933
 
934
+ gr.Markdown("""
935
+ ### πŸš€ Enhanced with FusionX Technology
936
+ **Features:** CausVid + AccVideo + MoviiGen1.1 + MPS Rewards LoRA + Custom Detail Enhancers
937
+
938
+ **Optimizations:** 8-10 steps for premium quality β€’ Enhanced motion realism β€’ Superior temporal consistency
939
+ """)
940
+
941
  with gr.Row():
942
  with gr.Column(elem_classes=["input-container"]):
943
  input_image_component = gr.Image(
 
946
  elem_classes=["image-upload"]
947
  )
948
  prompt_input = gr.Textbox(
949
+ label="✏️ Enhanced Prompt (FusionX automatically adds cinematic quality)",
950
  value=default_prompt_i2v,
951
+ lines=3
952
  )
953
  duration_seconds_input = gr.Slider(
954
  minimum=round(MIN_FRAMES_MODEL/FIXED_FPS,1),
955
  maximum=round(MAX_FRAMES_MODEL/FIXED_FPS,1),
956
  step=0.1,
957
+ value=3,
958
  label="⏱️ Duration (seconds)",
959
+ info=f"FusionX supports {MIN_FRAMES_MODEL}-{MAX_FRAMES_MODEL} frames at {FIXED_FPS}fps. Recommended: 3-5 seconds"
960
  )
961
 
962
+ with gr.Accordion("βš™οΈ Advanced FusionX Settings", open=False):
963
  negative_prompt_input = gr.Textbox(
964
+ label="❌ Negative Prompt (Enhanced for FusionX)",
965
  value=default_negative_prompt,
966
+ lines=4
967
  )
968
  seed_input = gr.Slider(
969
  label="🎲 Seed",
 
984
  maximum=SLIDER_MAX_H,
985
  step=MOD_VALUE,
986
  value=DEFAULT_H_SLIDER_VALUE,
987
+ label=f"πŸ“ Output Height (FusionX optimized: {MOD_VALUE} multiples)"
988
  )
989
  width_input = gr.Slider(
990
  minimum=SLIDER_MIN_W,
991
  maximum=SLIDER_MAX_W,
992
  step=MOD_VALUE,
993
  value=DEFAULT_W_SLIDER_VALUE,
994
+ label=f"πŸ“ Output Width (FusionX optimized: {MOD_VALUE} multiples)"
995
  )
996
  steps_slider = gr.Slider(
997
  minimum=1,
998
+ maximum=20,
999
  step=1,
1000
+ value=8, # FusionX optimized
1001
+ label="πŸš€ Inference Steps (FusionX: 8-10 recommended)",
1002
+ info="FusionX delivers excellent results in just 8-10 steps!"
1003
  )
1004
  guidance_scale_input = gr.Slider(
1005
  minimum=0.0,
1006
  maximum=20.0,
1007
  step=0.5,
1008
  value=1.0,
1009
+ label="🎯 Guidance Scale (FusionX optimized)",
1010
  visible=False
1011
  )
1012
 
1013
  generate_button = gr.Button(
1014
+ "🎬 Generate FusionX Video",
1015
  variant="primary",
1016
  elem_classes=["generate-btn"]
1017
  )
1018
 
1019
  with gr.Column(elem_classes=["output-container"]):
1020
  video_output = gr.Video(
1021
+ label="πŸŽ₯ FusionX Generated Video",
1022
  autoplay=True,
1023
  interactive=False
1024
  )
 
1045
  with gr.Column():
1046
  gr.Examples(
1047
  examples=[
1048
+ ["peng.png", "a penguin gracefully dancing in the pristine snow, cinematic motion with detailed feathers", 576, 1024],
1049
+ ["forg.jpg", "the frog jumps energetically with smooth, lifelike motion and detailed texture", 832, 576],
1050
+ ["example.jpg", "person walking through a bustling city street, dynamic camera movement, cinematic lighting", 720, 1280],
1051
  ],
1052
  inputs=[input_image_component, prompt_input, height_input, width_input],
1053
  outputs=[video_output, seed_input],
1054
  fn=generate_video,
1055
  cache_examples="lazy",
1056
+ label="🌟 FusionX Example Gallery"
1057
  )
1058
+
1059
+ gr.Markdown("""
1060
+ ### πŸ”§ FusionX Model Information
1061
+
1062
+ **Base Model:** Wan2.1 14B T2V Enhanced with multiple research-grade components
1063
+
1064
+ **Integrated Components:**
1065
+ - πŸ”— **CausVid**: Advanced causal motion modeling
1066
+ - πŸ”— **AccVideo**: Improved temporal alignment & speed boost
1067
+ - πŸ”— **MoviiGen1.1**: Cinematic smoothness & lighting
1068
+ - πŸ”— **MPS Rewards LoRA**: Motion & detail optimization
1069
+ - ✨ **Custom LoRAs**: Texture & clarity enhancements
1070
+
1071
+ **Performance:** Optimized for 8-10 steps β€’ Up to 50% faster rendering β€’ Enhanced motion quality
1072
+
1073
+ **License:** Apache 2.0 / MIT - Open source and permissive
1074
+ """)
1075
 
1076
  if __name__ == "__main__":
1077
  demo.queue().launch()