Delete FlowFacade_aoti.py
Browse files- FlowFacade_aoti.py +0 -185
FlowFacade_aoti.py
DELETED
|
@@ -1,185 +0,0 @@
|
|
| 1 |
-
import os
|
| 2 |
-
import torch
|
| 3 |
-
import numpy as np
|
| 4 |
-
from PIL import Image
|
| 5 |
-
from typing import Tuple, Optional
|
| 6 |
-
from VideoEngine_aoti import VideoEngineAOTI
|
| 7 |
-
from TextProcessor import TextProcessor
|
| 8 |
-
|
| 9 |
-
try:
|
| 10 |
-
import spaces
|
| 11 |
-
HAS_SPACES = True
|
| 12 |
-
except ImportError:
|
| 13 |
-
HAS_SPACES = False
|
| 14 |
-
class spaces:
|
| 15 |
-
@staticmethod
|
| 16 |
-
def GPU(duration=120):
|
| 17 |
-
def decorator(func):
|
| 18 |
-
return func
|
| 19 |
-
return decorator
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
class FlowFacadeAOTI:
|
| 23 |
-
"""
|
| 24 |
-
Unified interface coordinating all subsystems with AOTI optimization.
|
| 25 |
-
This is the AOTI-enabled version of FlowFacade.
|
| 26 |
-
"""
|
| 27 |
-
|
| 28 |
-
def __init__(self):
|
| 29 |
-
self.is_spaces = os.environ.get('SPACE_ID') is not None
|
| 30 |
-
self.video_engine = VideoEngineAOTI()
|
| 31 |
-
self.text_processor = TextProcessor(resource_manager=None)
|
| 32 |
-
print("✓ DeltaFlow (AOTI) initialized")
|
| 33 |
-
|
| 34 |
-
def _calculate_gpu_duration(self, image: Image.Image, duration_seconds: float,
|
| 35 |
-
num_inference_steps: int, enable_prompt_expansion: bool, **kwargs) -> int:
|
| 36 |
-
"""Calculate dynamic GPU duration for ZeroGPU with AOTI optimization."""
|
| 37 |
-
BASE_FRAMES_HEIGHT_WIDTH = 81 * 832 * 624
|
| 38 |
-
BASE_STEP_DURATION = 8
|
| 39 |
-
|
| 40 |
-
if self.video_engine.use_aoti:
|
| 41 |
-
BASE_STEP_DURATION = int(BASE_STEP_DURATION * 0.6)
|
| 42 |
-
|
| 43 |
-
resized_image = self.video_engine.resize_image(image)
|
| 44 |
-
width, height = resized_image.width, resized_image.height
|
| 45 |
-
frames = self.video_engine.get_num_frames(duration_seconds)
|
| 46 |
-
|
| 47 |
-
factor = frames * width * height / BASE_FRAMES_HEIGHT_WIDTH
|
| 48 |
-
step_duration = BASE_STEP_DURATION * factor ** 1.5
|
| 49 |
-
total_duration = int(num_inference_steps) * step_duration
|
| 50 |
-
|
| 51 |
-
if not self.video_engine.is_loaded:
|
| 52 |
-
total_duration += 150
|
| 53 |
-
|
| 54 |
-
if enable_prompt_expansion:
|
| 55 |
-
total_duration += 40
|
| 56 |
-
|
| 57 |
-
return max(int(total_duration), 300)
|
| 58 |
-
|
| 59 |
-
@spaces.GPU(duration=_calculate_gpu_duration)
|
| 60 |
-
def generate_video_from_image(self, image: Image.Image, user_instruction: str,
|
| 61 |
-
duration_seconds: float = 3.0, num_inference_steps: int = 4,
|
| 62 |
-
guidance_scale: float = 1.0, guidance_scale_2: float = 1.0,
|
| 63 |
-
seed: int = 42, randomize_seed: bool = False,
|
| 64 |
-
enable_prompt_expansion: bool = False,
|
| 65 |
-
progress=None) -> Tuple[str, str, int]:
|
| 66 |
-
"""
|
| 67 |
-
Generate video from image with AOTI-optimized pipeline.
|
| 68 |
-
|
| 69 |
-
Returns:
|
| 70 |
-
tuple: (video_path, final_prompt, seed_used)
|
| 71 |
-
"""
|
| 72 |
-
if image is None:
|
| 73 |
-
raise ValueError("No image provided")
|
| 74 |
-
if not user_instruction or user_instruction.strip() == "":
|
| 75 |
-
raise ValueError("Please provide a motion instruction")
|
| 76 |
-
|
| 77 |
-
try:
|
| 78 |
-
if randomize_seed:
|
| 79 |
-
seed = np.random.randint(0, 2147483647)
|
| 80 |
-
|
| 81 |
-
if enable_prompt_expansion:
|
| 82 |
-
if progress:
|
| 83 |
-
progress(0.1, desc="AI expanding your prompt...")
|
| 84 |
-
final_prompt = self.text_processor.process(user_instruction, auto_unload=True)
|
| 85 |
-
else:
|
| 86 |
-
final_prompt = user_instruction
|
| 87 |
-
|
| 88 |
-
if progress:
|
| 89 |
-
progress(0.2, desc="Preparing GPU memory...")
|
| 90 |
-
|
| 91 |
-
if not self.video_engine.is_loaded:
|
| 92 |
-
import gc
|
| 93 |
-
gc.collect()
|
| 94 |
-
if torch.cuda.is_available():
|
| 95 |
-
torch.cuda.empty_cache()
|
| 96 |
-
torch.cuda.ipc_collect()
|
| 97 |
-
|
| 98 |
-
if progress:
|
| 99 |
-
progress(0.25, desc="Loading video generation model (with AOTI)...")
|
| 100 |
-
self.video_engine.load_model()
|
| 101 |
-
|
| 102 |
-
gc.collect()
|
| 103 |
-
if torch.cuda.is_available():
|
| 104 |
-
torch.cuda.empty_cache()
|
| 105 |
-
|
| 106 |
-
if progress:
|
| 107 |
-
aoti_status = "AOTI enabled" if self.video_engine.use_aoti else "FP8 only"
|
| 108 |
-
progress(0.3, desc=f"Generating video ({aoti_status})...")
|
| 109 |
-
|
| 110 |
-
video_path = self.video_engine.generate_video(
|
| 111 |
-
image=image, prompt=final_prompt, duration_seconds=duration_seconds,
|
| 112 |
-
num_inference_steps=num_inference_steps, guidance_scale=guidance_scale,
|
| 113 |
-
guidance_scale_2=guidance_scale_2, seed=seed
|
| 114 |
-
)
|
| 115 |
-
|
| 116 |
-
if progress:
|
| 117 |
-
progress(1.0, desc="Complete!")
|
| 118 |
-
|
| 119 |
-
return video_path, final_prompt, seed
|
| 120 |
-
|
| 121 |
-
except Exception as e:
|
| 122 |
-
import traceback
|
| 123 |
-
print(f"\n✗ Generation error: {type(e).__name__}: {str(e)}")
|
| 124 |
-
if os.environ.get('DEBUG'):
|
| 125 |
-
print(traceback.format_exc())
|
| 126 |
-
raise RuntimeError(f"Generation failed: {type(e).__name__}: {str(e)}")
|
| 127 |
-
|
| 128 |
-
def cleanup(self) -> None:
|
| 129 |
-
"""Cleanup resources."""
|
| 130 |
-
try:
|
| 131 |
-
if hasattr(self.text_processor, 'is_loaded') and self.text_processor.is_loaded:
|
| 132 |
-
self.text_processor.unload_model()
|
| 133 |
-
torch.cuda.empty_cache()
|
| 134 |
-
except Exception as e:
|
| 135 |
-
if os.environ.get('DEBUG'):
|
| 136 |
-
print(f"⚠ Cleanup warning: {str(e)}")
|
| 137 |
-
|
| 138 |
-
def get_system_info(self) -> dict:
|
| 139 |
-
"""Get system information including AOTI status."""
|
| 140 |
-
quantization_type = "None"
|
| 141 |
-
if torch.cuda.is_available():
|
| 142 |
-
cuda_cap = torch.cuda.get_device_capability()
|
| 143 |
-
fp8_supported = cuda_cap[0] > 8 or (cuda_cap[0] == 8 and cuda_cap[1] >= 9)
|
| 144 |
-
quantization_type = "FP8" if fp8_supported else "INT8"
|
| 145 |
-
|
| 146 |
-
optimizations = [
|
| 147 |
-
"Lightning LoRA (4-8 steps)",
|
| 148 |
-
f"{quantization_type} Quantization"
|
| 149 |
-
]
|
| 150 |
-
|
| 151 |
-
if self.video_engine.use_aoti:
|
| 152 |
-
optimizations.append("AOTI Compilation (1.5-1.8x)")
|
| 153 |
-
|
| 154 |
-
return {
|
| 155 |
-
"device": self.video_engine.device,
|
| 156 |
-
"video_model": VideoEngineAOTI.MODEL_ID,
|
| 157 |
-
"text_model": TextProcessor.MODEL_ID,
|
| 158 |
-
"lightning_lora": "Enabled",
|
| 159 |
-
"quantization": quantization_type,
|
| 160 |
-
"aoti": "Enabled" if self.video_engine.use_aoti else "Disabled",
|
| 161 |
-
"optimizations": optimizations
|
| 162 |
-
}
|
| 163 |
-
|
| 164 |
-
def validate_image(self, image: Image.Image) -> bool:
|
| 165 |
-
"""Validate image dimensions."""
|
| 166 |
-
if image is None:
|
| 167 |
-
return False
|
| 168 |
-
|
| 169 |
-
min_dim, max_dim = 256, 4096
|
| 170 |
-
|
| 171 |
-
if image.width < min_dim or image.height < min_dim:
|
| 172 |
-
print(f"⚠ Image too small: {image.width}x{image.height}")
|
| 173 |
-
return False
|
| 174 |
-
|
| 175 |
-
if image.width > max_dim or image.height > max_dim:
|
| 176 |
-
print(f"⚠ Image too large: {image.width}x{image.height}")
|
| 177 |
-
return False
|
| 178 |
-
|
| 179 |
-
return True
|
| 180 |
-
|
| 181 |
-
def __del__(self):
|
| 182 |
-
try:
|
| 183 |
-
self.cleanup()
|
| 184 |
-
except:
|
| 185 |
-
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|