fffiloni commited on
Commit
ccba5b1
·
verified ·
1 Parent(s): 7a90088

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -80
app.py CHANGED
@@ -75,6 +75,7 @@ import sys
75
  import time
76
  import threading
77
  import traceback
 
78
 
79
  import torch
80
 
@@ -132,6 +133,8 @@ try:
132
  except Exception:
133
  pass
134
 
 
 
135
  import gradio as gr
136
 
137
  # ---------------------------------------------------------------------------
@@ -191,6 +194,7 @@ def _runtime_report():
191
  "cuda_available": bool(torch.cuda.is_available()),
192
  "cuda_device_count": int(torch.cuda.device_count()) if torch.cuda.is_available() else 0,
193
  "has_spaces": HAS_SPACES,
 
194
  "torch_compile_bypassed": torch.compile is _asf_zerogpu_compile_bypass,
195
  "hf_home": os.environ.get("HF_HOME", ""),
196
  "hf_modules_cache": os.environ.get("HF_MODULES_CACHE", ""),
@@ -204,6 +208,7 @@ def _lora_report():
204
  "active_strength": _active_lora_strength,
205
  "loaded_loras": sorted(list(_loaded_loras)),
206
  "available_loras": list(KNOWN_LORAS.keys()),
 
207
  }
208
 
209
 
@@ -356,6 +361,12 @@ def _load_lora_if_needed(pipe, lora_label):
356
  if not cfg:
357
  return None
358
 
 
 
 
 
 
 
359
  adapter_name = cfg["adapter_name"]
360
 
361
  if adapter_name in _loaded_loras:
@@ -380,6 +391,30 @@ def _load_lora_if_needed(pipe, lora_label):
380
  return adapter_name
381
 
382
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
383
  def _set_lora(pipe, lora_label, lora_strength, allow_load=True):
384
  """
385
  Activate the selected LoRA, or disable LoRA for base model.
@@ -396,13 +431,7 @@ def _set_lora(pipe, lora_label, lora_strength, allow_load=True):
396
  cfg = KNOWN_LORAS.get(lora_label)
397
 
398
  if not cfg:
399
- if hasattr(transformer, "disable_lora"):
400
- transformer.disable_lora()
401
- elif hasattr(transformer, "set_adapters"):
402
- try:
403
- transformer.set_adapters([], adapter_weights=[])
404
- except Exception:
405
- pass
406
 
407
  _active_lora = None
408
  _active_lora_label = "Base model"
@@ -449,8 +478,8 @@ def load_selected_lora(lora_style, lora_strength):
449
  if pipe is None:
450
  return {
451
  "status": "error",
 
452
  "error": _pipeline_error or "Pipeline failed to load",
453
- "runtime": _runtime_report(),
454
  "lora": _lora_report(),
455
  }
456
 
@@ -460,8 +489,7 @@ def load_selected_lora(lora_style, lora_strength):
460
 
461
  return {
462
  "status": "ready",
463
- "message": "Base model active. No LoRA loaded.",
464
- "runtime": _runtime_report(),
465
  "lora": _lora_report(),
466
  }
467
 
@@ -478,7 +506,6 @@ def load_selected_lora(lora_style, lora_strength):
478
  "status": "ready",
479
  "message": f"LoRA loaded and activated: {lora_style}",
480
  "trigger": trigger,
481
- "runtime": _runtime_report(),
482
  "lora": _lora_report(),
483
  }
484
 
@@ -486,8 +513,8 @@ def load_selected_lora(lora_style, lora_strength):
486
  traceback.print_exc()
487
  return {
488
  "status": "error",
 
489
  "error": f"{type(e).__name__}: {e}",
490
- "runtime": _runtime_report(),
491
  "lora": _lora_report(),
492
  }
493
 
@@ -503,8 +530,8 @@ def disable_lora():
503
  if pipe is None:
504
  return {
505
  "status": "error",
 
506
  "error": _pipeline_error or "Pipeline failed to load",
507
- "runtime": _runtime_report(),
508
  "lora": _lora_report(),
509
  }
510
 
@@ -515,7 +542,6 @@ def disable_lora():
515
  return {
516
  "status": "ready",
517
  "message": "LoRA disabled. Base model active.",
518
- "runtime": _runtime_report(),
519
  "lora": _lora_report(),
520
  }
521
 
@@ -523,8 +549,8 @@ def disable_lora():
523
  traceback.print_exc()
524
  return {
525
  "status": "error",
 
526
  "error": f"{type(e).__name__}: {e}",
527
- "runtime": _runtime_report(),
528
  "lora": _lora_report(),
529
  }
530
 
@@ -547,11 +573,8 @@ def health():
547
  "model_ready": _pipeline is not None,
548
  "pipeline_ready": _pipeline is not None,
549
  "model_id": MODEL_ID,
550
- "model_family": "diffusers_modular_pipeline",
551
- "loader_strategy": "ModularPipeline_from_pretrained_trust_remote_code",
552
  "runtime_mode": "zerogpu_compatibility_compile_bypass",
553
  "last_error": _pipeline_error or "",
554
- "expected_output_type": "video",
555
  "runtime": _runtime_report(),
556
  "lora": _lora_report(),
557
  }
@@ -568,6 +591,7 @@ def warmup_model():
568
  if pipe is None:
569
  return {
570
  "status": "error",
 
571
  "error": _pipeline_error or "Pipeline failed to load",
572
  "runtime": _runtime_report(),
573
  "lora": _lora_report(),
@@ -575,9 +599,8 @@ def warmup_model():
575
 
576
  return {
577
  "status": "ready",
578
- "model_id": MODEL_ID,
579
- "runtime_mode": "zerogpu_compatibility_compile_bypass",
580
  "message": "Model loaded and cached in this Space process.",
 
581
  "runtime": _runtime_report(),
582
  "lora": _lora_report(),
583
  }
@@ -645,14 +668,11 @@ def generate(
645
 
646
  device = "cuda"
647
 
648
- # Make sure the pipeline is on CUDA inside the ZeroGPU-decorated function.
649
  try:
650
  pipe = pipe.to(device)
651
  except Exception as e:
652
  _log(f"Pipeline .to('cuda') warning: {type(e).__name__}: {e}")
653
 
654
- # Activate selected LoRA without hidden loading during generation.
655
- # If user selected a LoRA but did not load it, fail with a clear message.
656
  with _lora_lock:
657
  trigger = _set_lora(
658
  pipe,
@@ -731,79 +751,82 @@ def generate(
731
  with gr.Blocks(title="Krea Realtime Video 14B") as demo:
732
  gr.Markdown(
733
  "# Krea Realtime Video 14B\n\n"
734
- "This Space runs **real local inference** for the Krea Realtime 14B "
735
- "text-to-video model using Diffusers `ModularPipeline`.\n\n"
736
- "⚠️ **ZeroGPU compatibility mode**: `torch.compile` is disabled because "
737
- "ZeroGPU does not support it.\n\n"
738
- "**Video length** is controlled by the number of blocks. "
739
- "Roughly: 1 block ≈ ~1 second, 9 blocks ≈ ~9 seconds. "
740
- "Values above 9 are experimental.\n\n"
741
- "**LoRA support**: select a style, click **Load selected LoRA**, then generate. "
742
- "The Origami preset automatically prefixes the prompt with `[origami]`."
743
  )
744
 
745
  with gr.Row():
746
- with gr.Column():
747
- model_status = gr.JSON(label="Model Status")
748
-
749
- with gr.Row():
750
- warmup_btn = gr.Button("Warm up / Check model", variant="secondary")
751
-
752
- gr.Markdown("## Prompt")
753
-
754
- prompt = gr.Textbox(
755
- label="Prompt",
756
- placeholder="e.g., a cat sitting on a boat",
757
- lines=3,
758
- )
759
 
760
- gr.Markdown("## Style / LoRA")
 
761
 
762
- lora_style = gr.Dropdown(
763
- choices=list(KNOWN_LORAS.keys()),
764
- value="Base model",
765
- label="Style / LoRA",
766
- )
 
 
767
 
768
- lora_strength = gr.Slider(
769
- minimum=0.0,
770
- maximum=1.5,
771
- value=1.0,
772
- step=0.05,
773
- label="LoRA Strength",
774
- )
 
775
 
776
- with gr.Row():
777
- load_lora_btn = gr.Button("Load selected LoRA", variant="secondary")
778
- disable_lora_btn = gr.Button("Disable LoRA / Use Base Model", variant="secondary")
779
 
780
- lora_status = gr.JSON(label="LoRA Status")
 
 
 
781
 
782
- gr.Markdown("## Generation Settings")
 
783
 
784
- num_blocks = gr.Slider(
785
- minimum=1,
786
- maximum=12,
787
- value=9,
788
- step=1,
789
- label="Video Length / Number of Blocks",
790
- )
 
791
 
792
- num_inference_steps = gr.Slider(
793
- minimum=1,
794
- maximum=8,
795
- value=6,
796
- step=1,
797
- label="Inference Steps per Block",
798
- )
799
 
800
- seed = gr.Number(value=42, precision=0, label="Seed")
801
 
802
- generate_btn = gr.Button("Generate Video", variant="primary")
803
 
804
- with gr.Column():
805
  output_video = gr.Video(label="Generated Video")
806
 
 
 
 
 
 
807
  gr.Examples(
808
  examples=[
809
  [
 
75
  import time
76
  import threading
77
  import traceback
78
+ import importlib.util
79
 
80
  import torch
81
 
 
133
  except Exception:
134
  pass
135
 
136
+ PEFT_AVAILABLE = importlib.util.find_spec("peft") is not None
137
+
138
  import gradio as gr
139
 
140
  # ---------------------------------------------------------------------------
 
194
  "cuda_available": bool(torch.cuda.is_available()),
195
  "cuda_device_count": int(torch.cuda.device_count()) if torch.cuda.is_available() else 0,
196
  "has_spaces": HAS_SPACES,
197
+ "peft_available": PEFT_AVAILABLE,
198
  "torch_compile_bypassed": torch.compile is _asf_zerogpu_compile_bypass,
199
  "hf_home": os.environ.get("HF_HOME", ""),
200
  "hf_modules_cache": os.environ.get("HF_MODULES_CACHE", ""),
 
208
  "active_strength": _active_lora_strength,
209
  "loaded_loras": sorted(list(_loaded_loras)),
210
  "available_loras": list(KNOWN_LORAS.keys()),
211
+ "peft_available": PEFT_AVAILABLE,
212
  }
213
 
214
 
 
361
  if not cfg:
362
  return None
363
 
364
+ if not PEFT_AVAILABLE:
365
+ raise RuntimeError(
366
+ "PEFT is required for LoRA support. Add `peft` to requirements.txt "
367
+ "and rebuild the Space."
368
+ )
369
+
370
  adapter_name = cfg["adapter_name"]
371
 
372
  if adapter_name in _loaded_loras:
 
391
  return adapter_name
392
 
393
 
394
+ def _safe_disable_lora(transformer):
395
+ """
396
+ Disable PEFT LoRA if available.
397
+
398
+ Some diffusers methods raise if PEFT is not installed, so this is defensive.
399
+ """
400
+ if transformer is None:
401
+ return
402
+
403
+ if hasattr(transformer, "disable_lora"):
404
+ try:
405
+ transformer.disable_lora()
406
+ return
407
+ except Exception as e:
408
+ _log(f"disable_lora warning: {type(e).__name__}: {e}")
409
+
410
+ if hasattr(transformer, "set_adapters"):
411
+ try:
412
+ transformer.set_adapters([], adapter_weights=[])
413
+ return
414
+ except Exception as e:
415
+ _log(f"set_adapters([]) warning: {type(e).__name__}: {e}")
416
+
417
+
418
  def _set_lora(pipe, lora_label, lora_strength, allow_load=True):
419
  """
420
  Activate the selected LoRA, or disable LoRA for base model.
 
431
  cfg = KNOWN_LORAS.get(lora_label)
432
 
433
  if not cfg:
434
+ _safe_disable_lora(transformer)
 
 
 
 
 
 
435
 
436
  _active_lora = None
437
  _active_lora_label = "Base model"
 
478
  if pipe is None:
479
  return {
480
  "status": "error",
481
+ "message": "Pipeline failed to load.",
482
  "error": _pipeline_error or "Pipeline failed to load",
 
483
  "lora": _lora_report(),
484
  }
485
 
 
489
 
490
  return {
491
  "status": "ready",
492
+ "message": "Base model active. No LoRA selected.",
 
493
  "lora": _lora_report(),
494
  }
495
 
 
506
  "status": "ready",
507
  "message": f"LoRA loaded and activated: {lora_style}",
508
  "trigger": trigger,
 
509
  "lora": _lora_report(),
510
  }
511
 
 
513
  traceback.print_exc()
514
  return {
515
  "status": "error",
516
+ "message": "LoRA load failed.",
517
  "error": f"{type(e).__name__}: {e}",
 
518
  "lora": _lora_report(),
519
  }
520
 
 
530
  if pipe is None:
531
  return {
532
  "status": "error",
533
+ "message": "Pipeline failed to load.",
534
  "error": _pipeline_error or "Pipeline failed to load",
 
535
  "lora": _lora_report(),
536
  }
537
 
 
542
  return {
543
  "status": "ready",
544
  "message": "LoRA disabled. Base model active.",
 
545
  "lora": _lora_report(),
546
  }
547
 
 
549
  traceback.print_exc()
550
  return {
551
  "status": "error",
552
+ "message": "Could not disable LoRA cleanly.",
553
  "error": f"{type(e).__name__}: {e}",
 
554
  "lora": _lora_report(),
555
  }
556
 
 
573
  "model_ready": _pipeline is not None,
574
  "pipeline_ready": _pipeline is not None,
575
  "model_id": MODEL_ID,
 
 
576
  "runtime_mode": "zerogpu_compatibility_compile_bypass",
577
  "last_error": _pipeline_error or "",
 
578
  "runtime": _runtime_report(),
579
  "lora": _lora_report(),
580
  }
 
591
  if pipe is None:
592
  return {
593
  "status": "error",
594
+ "message": "Pipeline failed to load.",
595
  "error": _pipeline_error or "Pipeline failed to load",
596
  "runtime": _runtime_report(),
597
  "lora": _lora_report(),
 
599
 
600
  return {
601
  "status": "ready",
 
 
602
  "message": "Model loaded and cached in this Space process.",
603
+ "model_id": MODEL_ID,
604
  "runtime": _runtime_report(),
605
  "lora": _lora_report(),
606
  }
 
668
 
669
  device = "cuda"
670
 
 
671
  try:
672
  pipe = pipe.to(device)
673
  except Exception as e:
674
  _log(f"Pipeline .to('cuda') warning: {type(e).__name__}: {e}")
675
 
 
 
676
  with _lora_lock:
677
  trigger = _set_lora(
678
  pipe,
 
751
  with gr.Blocks(title="Krea Realtime Video 14B") as demo:
752
  gr.Markdown(
753
  "# Krea Realtime Video 14B\n\n"
754
+ "Real local inference with Diffusers `ModularPipeline` on ZeroGPU.\n\n"
755
+ "The model loads at app startup. Generation uses ZeroGPU. "
756
+ "LoRAs can be loaded manually before generation."
 
 
 
 
 
 
757
  )
758
 
759
  with gr.Row():
760
+ with gr.Column(scale=4):
761
+ with gr.Group():
762
+ gr.Markdown("## 1. Prompt")
763
+ prompt = gr.Textbox(
764
+ label="Prompt",
765
+ placeholder="Describe the video you want to generate...",
766
+ lines=4,
767
+ )
 
 
 
 
 
768
 
769
+ with gr.Group():
770
+ gr.Markdown("## 2. Optional Style / LoRA")
771
 
772
+ with gr.Row():
773
+ lora_style = gr.Dropdown(
774
+ choices=list(KNOWN_LORAS.keys()),
775
+ value="Base model",
776
+ label="Style / LoRA",
777
+ scale=2,
778
+ )
779
 
780
+ lora_strength = gr.Slider(
781
+ minimum=0.0,
782
+ maximum=1.5,
783
+ value=1.0,
784
+ step=0.05,
785
+ label="Strength",
786
+ scale=3,
787
+ )
788
 
789
+ with gr.Row():
790
+ load_lora_btn = gr.Button("Load selected LoRA", variant="secondary")
791
+ disable_lora_btn = gr.Button("Use Base Model", variant="secondary")
792
 
793
+ gr.Markdown(
794
+ "For **Origami**, the app automatically adds the `[origami]` trigger "
795
+ "when generating."
796
+ )
797
 
798
+ with gr.Group():
799
+ gr.Markdown("## 3. Generation Settings")
800
 
801
+ with gr.Row():
802
+ num_blocks = gr.Slider(
803
+ minimum=1,
804
+ maximum=12,
805
+ value=9,
806
+ step=1,
807
+ label="Video Length / Blocks",
808
+ )
809
 
810
+ num_inference_steps = gr.Slider(
811
+ minimum=1,
812
+ maximum=8,
813
+ value=6,
814
+ step=1,
815
+ label="Steps per Block",
816
+ )
817
 
818
+ seed = gr.Number(value=42, precision=0, label="Seed")
819
 
820
+ generate_btn = gr.Button("Generate Video", variant="primary")
821
 
822
+ with gr.Column(scale=5):
823
  output_video = gr.Video(label="Generated Video")
824
 
825
+ with gr.Accordion("Runtime status", open=False):
826
+ model_status = gr.JSON(label="Model Status")
827
+ lora_status = gr.JSON(label="LoRA Status")
828
+ warmup_btn = gr.Button("Refresh model status", variant="secondary")
829
+
830
  gr.Examples(
831
  examples=[
832
  [