Spaces:
Running on Zero
Running on Zero
Vendor RIFE into repo
Browse files- SPACE_DEPLOYMENT.md +1 -1
- app.py +103 -5
SPACE_DEPLOYMENT.md
CHANGED
|
@@ -38,7 +38,7 @@ Useful environment variables:
|
|
| 38 |
- `LANCE_GPUS`: comma-separated GPU IDs, for example `0` or `0,1`
|
| 39 |
- `LANCE_QUEUE_SIZE`: Gradio queue size
|
| 40 |
- `LANCE_GRADIO_TMP_ROOT`: output and temporary file directory
|
| 41 |
-
- `LANCE_ZEROGPU_MAX_DURATION_SECONDS`:
|
| 42 |
- `LANCE_INSTALL_FLASH_ATTN_ON_STARTUP`: set to `1` to install the pinned flash-attn wheel during Space startup instead of inside the GPU reservation (the wheel matches Python 3.10.13 and torch 2.8.0)
|
| 43 |
- `LANCE_PREFETCH_MODEL_ASSETS`: set to `0` to skip CPU-side model prefetch at startup
|
| 44 |
- `LANCE_PREFETCH_MODEL_VARIANTS`: comma-separated model variants to prefetch, for example `video,image`
|
|
|
|
| 38 |
- `LANCE_GPUS`: comma-separated GPU IDs, for example `0` or `0,1`
|
| 39 |
- `LANCE_QUEUE_SIZE`: Gradio queue size
|
| 40 |
- `LANCE_GRADIO_TMP_ROOT`: output and temporary file directory
|
| 41 |
+
- `LANCE_ZEROGPU_MAX_DURATION_SECONDS`: upper bound for the task-aware `@spaces.GPU` duration request in seconds (default cap: 300)
|
| 42 |
- `LANCE_INSTALL_FLASH_ATTN_ON_STARTUP`: set to `1` to install the pinned flash-attn wheel during Space startup instead of inside the GPU reservation (the wheel matches Python 3.10.13 and torch 2.8.0)
|
| 43 |
- `LANCE_PREFETCH_MODEL_ASSETS`: set to `0` to skip CPU-side model prefetch at startup
|
| 44 |
- `LANCE_PREFETCH_MODEL_VARIANTS`: comma-separated model variants to prefetch, for example `video,image`
|
app.py
CHANGED
|
@@ -5,6 +5,7 @@ import base64
|
|
| 5 |
import concurrent.futures
|
| 6 |
import gc
|
| 7 |
import html
|
|
|
|
| 8 |
import json
|
| 9 |
import os
|
| 10 |
import random
|
|
@@ -3214,8 +3215,89 @@ def is_pipeline_pool_ready_for_task(task: str) -> bool:
|
|
| 3214 |
|
| 3215 |
|
| 3216 |
def finalize_zerogpu_duration(estimated_seconds: float, task: str) -> int:
|
| 3217 |
-
"""
|
| 3218 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3219 |
|
| 3220 |
|
| 3221 |
def get_run_task_gpu_duration(
|
|
@@ -3234,8 +3316,23 @@ def get_run_task_gpu_duration(
|
|
| 3234 |
cfg_text_scale: float,
|
| 3235 |
enable_frame_interpolation: bool,
|
| 3236 |
) -> int:
|
| 3237 |
-
|
| 3238 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3239 |
|
| 3240 |
|
| 3241 |
def get_pipeline_pool(task: str) -> PipelinePool:
|
|
@@ -3265,7 +3362,7 @@ def get_pipeline_pool(task: str) -> PipelinePool:
|
|
| 3265 |
return ACTIVE_PIPELINE_POOL
|
| 3266 |
|
| 3267 |
|
| 3268 |
-
@spaces.GPU(size="large", duration=
|
| 3269 |
def run_task(
|
| 3270 |
task: str,
|
| 3271 |
prompt: str,
|
|
@@ -3548,6 +3645,7 @@ def build_demo() -> gr.Blocks:
|
|
| 3548 |
show_label=False,
|
| 3549 |
choices=VIDEO_RESOLUTION_DISPLAY_CHOICES,
|
| 3550 |
value=DEFAULT_RESOLUTION,
|
|
|
|
| 3551 |
elem_classes=["generation-control"],
|
| 3552 |
)
|
| 3553 |
height = gr.Number(value=DEFAULT_HEIGHT, precision=0, visible=False)
|
|
|
|
| 5 |
import concurrent.futures
|
| 6 |
import gc
|
| 7 |
import html
|
| 8 |
+
import math
|
| 9 |
import json
|
| 10 |
import os
|
| 11 |
import random
|
|
|
|
| 3215 |
|
| 3216 |
|
| 3217 |
def finalize_zerogpu_duration(estimated_seconds: float, task: str) -> int:
|
| 3218 |
+
"""Clamp a heuristic duration to the deployment cap with a small safety margin."""
|
| 3219 |
+
task_key = normalize_task(task)
|
| 3220 |
+
raw_seconds = float(estimated_seconds)
|
| 3221 |
+
if raw_seconds <= 0:
|
| 3222 |
+
raw_seconds = _estimate_zerogpu_duration_seconds(
|
| 3223 |
+
task_key,
|
| 3224 |
+
prompt="",
|
| 3225 |
+
system_prompt=None,
|
| 3226 |
+
input_video=None,
|
| 3227 |
+
input_image=None,
|
| 3228 |
+
height=0,
|
| 3229 |
+
width=0,
|
| 3230 |
+
num_frames=0,
|
| 3231 |
+
seed=0,
|
| 3232 |
+
resolution="",
|
| 3233 |
+
validation_num_timesteps=0,
|
| 3234 |
+
validation_timestep_shift=0.0,
|
| 3235 |
+
cfg_text_scale=0.0,
|
| 3236 |
+
enable_frame_interpolation=False,
|
| 3237 |
+
)
|
| 3238 |
+
return clamp_zerogpu_duration(math.ceil(raw_seconds * 1.15) + 5)
|
| 3239 |
+
|
| 3240 |
+
|
| 3241 |
+
def _estimate_zerogpu_duration_seconds(
|
| 3242 |
+
task: str,
|
| 3243 |
+
prompt: str,
|
| 3244 |
+
system_prompt: Optional[str],
|
| 3245 |
+
input_video: Optional[str],
|
| 3246 |
+
input_image: Optional[str],
|
| 3247 |
+
height: int,
|
| 3248 |
+
width: int,
|
| 3249 |
+
num_frames: int,
|
| 3250 |
+
seed: int,
|
| 3251 |
+
resolution: str,
|
| 3252 |
+
validation_num_timesteps: int,
|
| 3253 |
+
validation_timestep_shift: float,
|
| 3254 |
+
cfg_text_scale: float,
|
| 3255 |
+
enable_frame_interpolation: bool,
|
| 3256 |
+
) -> int:
|
| 3257 |
+
internal_task = normalize_task(task)
|
| 3258 |
+
prompt_length = len((prompt or "").strip())
|
| 3259 |
+
has_video_input = bool((input_video or "").strip())
|
| 3260 |
+
has_image_input = bool((input_image or "").strip())
|
| 3261 |
+
is_video_task = internal_task in {TASK_T2V, TASK_VIDEO_EDIT, TASK_X2T_VIDEO}
|
| 3262 |
+
is_image_task = internal_task in {TASK_T2I, TASK_IMAGE_EDIT, TASK_X2T_IMAGE}
|
| 3263 |
+
|
| 3264 |
+
if internal_task == TASK_T2I:
|
| 3265 |
+
return 150
|
| 3266 |
+
|
| 3267 |
+
if internal_task == TASK_IMAGE_EDIT:
|
| 3268 |
+
return 150
|
| 3269 |
+
|
| 3270 |
+
if internal_task == TASK_X2T_IMAGE:
|
| 3271 |
+
return 150
|
| 3272 |
+
|
| 3273 |
+
if internal_task == TASK_X2T_VIDEO:
|
| 3274 |
+
return 200
|
| 3275 |
+
|
| 3276 |
+
if internal_task == TASK_VIDEO_EDIT:
|
| 3277 |
+
base = 300
|
| 3278 |
+
base += min(48, max(0, num_frames - 37) // 2)
|
| 3279 |
+
base += 32 if enable_frame_interpolation else 0
|
| 3280 |
+
base += 20 if has_video_input else 0
|
| 3281 |
+
base += 16 if resolution == "video_480p" else 0
|
| 3282 |
+
return base
|
| 3283 |
+
|
| 3284 |
+
if internal_task == TASK_T2V:
|
| 3285 |
+
base = 224 if resolution == "video_360p" else 264
|
| 3286 |
+
base += min(56, max(0, num_frames - 37) // 2)
|
| 3287 |
+
base += 28 if enable_frame_interpolation else 0
|
| 3288 |
+
base += min(20, prompt_length // 260)
|
| 3289 |
+
return base
|
| 3290 |
+
|
| 3291 |
+
if is_video_task:
|
| 3292 |
+
base = 240
|
| 3293 |
+
base += min(40, max(0, num_frames - 37) // 2)
|
| 3294 |
+
base += 24 if enable_frame_interpolation else 0
|
| 3295 |
+
return base
|
| 3296 |
+
|
| 3297 |
+
if is_image_task:
|
| 3298 |
+
return 120
|
| 3299 |
+
|
| 3300 |
+
return 160
|
| 3301 |
|
| 3302 |
|
| 3303 |
def get_run_task_gpu_duration(
|
|
|
|
| 3316 |
cfg_text_scale: float,
|
| 3317 |
enable_frame_interpolation: bool,
|
| 3318 |
) -> int:
|
| 3319 |
+
estimated_seconds = _estimate_zerogpu_duration_seconds(
|
| 3320 |
+
task=task,
|
| 3321 |
+
prompt=prompt,
|
| 3322 |
+
system_prompt=system_prompt,
|
| 3323 |
+
input_video=input_video,
|
| 3324 |
+
input_image=input_image,
|
| 3325 |
+
height=height,
|
| 3326 |
+
width=width,
|
| 3327 |
+
num_frames=num_frames,
|
| 3328 |
+
seed=seed,
|
| 3329 |
+
resolution=resolution,
|
| 3330 |
+
validation_num_timesteps=validation_num_timesteps,
|
| 3331 |
+
validation_timestep_shift=validation_timestep_shift,
|
| 3332 |
+
cfg_text_scale=cfg_text_scale,
|
| 3333 |
+
enable_frame_interpolation=enable_frame_interpolation,
|
| 3334 |
+
)
|
| 3335 |
+
return finalize_zerogpu_duration(estimated_seconds, task)
|
| 3336 |
|
| 3337 |
|
| 3338 |
def get_pipeline_pool(task: str) -> PipelinePool:
|
|
|
|
| 3362 |
return ACTIVE_PIPELINE_POOL
|
| 3363 |
|
| 3364 |
|
| 3365 |
+
@spaces.GPU(size="large", duration=get_run_task_gpu_duration)
|
| 3366 |
def run_task(
|
| 3367 |
task: str,
|
| 3368 |
prompt: str,
|
|
|
|
| 3645 |
show_label=False,
|
| 3646 |
choices=VIDEO_RESOLUTION_DISPLAY_CHOICES,
|
| 3647 |
value=DEFAULT_RESOLUTION,
|
| 3648 |
+
allow_custom_value=True,
|
| 3649 |
elem_classes=["generation-control"],
|
| 3650 |
)
|
| 3651 |
height = gr.Number(value=DEFAULT_HEIGHT, precision=0, visible=False)
|