Spaces:
Running on Zero
Running on Zero
IdleCloud commited on
Commit ·
9d0fcdf
1
Parent(s): 4c32774
Add secret gate and limit default controls
Browse files
app.py
CHANGED
|
@@ -38,6 +38,14 @@ import aoti
|
|
| 38 |
os.environ["TOKENIZERS_PARALLELISM"] = "true"
|
| 39 |
warnings.filterwarnings("ignore")
|
| 40 |
IS_ZERO_GPU = bool(os.getenv("SPACES_ZERO_GPU"))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
|
| 42 |
# if IS_ZERO_GPU:
|
| 43 |
# print("Loading...")
|
|
@@ -523,6 +531,7 @@ def run_inference(
|
|
| 523 |
|
| 524 |
|
| 525 |
def generate_video(
|
|
|
|
| 526 |
input_image,
|
| 527 |
last_image,
|
| 528 |
prompt,
|
|
@@ -547,11 +556,12 @@ def generate_video(
|
|
| 547 |
prompt and parameters. It uses an FP8 qunatized Wan 2.2 14B Image-to-Video model in with Lightning LoRA
|
| 548 |
for fast generation in 4-8 steps.
|
| 549 |
Args:
|
|
|
|
| 550 |
input_image (PIL.Image): The input image to animate. Will be resized to target dimensions.
|
| 551 |
last_image (PIL.Image, optional): The optional last image for the video.
|
| 552 |
prompt (str): Text prompt describing the desired animation or motion.
|
| 553 |
steps (int, optional): Number of inference steps. More steps = higher quality but slower.
|
| 554 |
-
Defaults to 4. Range: 1-
|
| 555 |
negative_prompt (str, optional): Negative prompt to avoid unwanted elements.
|
| 556 |
Defaults to default_negative_prompt (contains unwanted visual artifacts).
|
| 557 |
duration_seconds (float, optional): Duration of the generated video in seconds.
|
|
@@ -578,7 +588,7 @@ def generate_video(
|
|
| 578 |
- video_path (str): Path for the file download component. Attempt to avoid reconversion in video component.
|
| 579 |
- current_seed (int): The seed used for generation.
|
| 580 |
Raises:
|
| 581 |
-
gr.Error: If input_image is None (no image uploaded).
|
| 582 |
Note:
|
| 583 |
- Frame count is calculated as duration_seconds * FIXED_FPS (24)
|
| 584 |
- Output dimensions are adjusted to be multiples of MOD_VALUE (32)
|
|
@@ -586,6 +596,9 @@ def generate_video(
|
|
| 586 |
- Generation time varies based on steps and duration (see get_duration function)
|
| 587 |
"""
|
| 588 |
|
|
|
|
|
|
|
|
|
|
| 589 |
if input_image is None:
|
| 590 |
raise gr.Error("Please upload an input image.")
|
| 591 |
|
|
@@ -631,6 +644,9 @@ CSS = """
|
|
| 631 |
position: absolute;
|
| 632 |
pointer-events: none;
|
| 633 |
}
|
|
|
|
|
|
|
|
|
|
| 634 |
"""
|
| 635 |
|
| 636 |
|
|
@@ -640,6 +656,12 @@ with gr.Blocks(delete_cache=(3600, 10800)) as demo:
|
|
| 640 |
|
| 641 |
with gr.Row():
|
| 642 |
with gr.Column():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 643 |
input_image_component = gr.Image(type="pil", label="Input Image", sources=["upload", "clipboard"])
|
| 644 |
prompt_input = gr.Textbox(label="Prompt", value=default_prompt_i2v)
|
| 645 |
duration_seconds_input = gr.Slider(minimum=MIN_DURATION, maximum=MAX_DURATION, step=0.1, value=3.5, label="Duration (seconds)", info=f"Clamped to model's {MIN_FRAMES_MODEL}-{MAX_FRAMES_MODEL} frames at {FIXED_FPS}fps.")
|
|
@@ -651,7 +673,7 @@ with gr.Blocks(delete_cache=(3600, 10800)) as demo:
|
|
| 651 |
)
|
| 652 |
safe_mode_checkbox = gr.Checkbox(
|
| 653 |
label="🛠️ Safe Mode",
|
| 654 |
-
value=
|
| 655 |
info="Requests 30% extra processing time to try to prevent unfinished tasks when the server is busy."
|
| 656 |
)
|
| 657 |
with gr.Accordion("Advanced Settings", open=False):
|
|
@@ -660,7 +682,7 @@ with gr.Blocks(delete_cache=(3600, 10800)) as demo:
|
|
| 660 |
quality_slider = gr.Slider(minimum=1, maximum=10, step=1, value=6, label="Video Quality", info="If set to 10, the generated video may be too large and won't play in the Gradio preview.")
|
| 661 |
seed_input = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=42, interactive=True)
|
| 662 |
randomize_seed_checkbox = gr.Checkbox(label="Randomize seed", value=True, interactive=True)
|
| 663 |
-
steps_slider = gr.Slider(minimum=1, maximum=
|
| 664 |
guidance_scale_input = gr.Slider(minimum=0.0, maximum=10.0, step=0.5, value=1, label="Guidance Scale - high noise stage", info="Values above 1 increase GPU usage and may take longer to process.")
|
| 665 |
guidance_scale_2_input = gr.Slider(minimum=0.0, maximum=10.0, step=0.5, value=1, label="Guidance Scale 2 - low noise stage")
|
| 666 |
scheduler_dropdown = gr.Dropdown(
|
|
@@ -692,6 +714,7 @@ with gr.Blocks(delete_cache=(3600, 10800)) as demo:
|
|
| 692 |
file_output = gr.File(label="Download Video")
|
| 693 |
|
| 694 |
ui_inputs = [
|
|
|
|
| 695 |
input_image_component, last_image_component, prompt_input, steps_slider,
|
| 696 |
negative_prompt_input, duration_seconds_input,
|
| 697 |
guidance_scale_input, guidance_scale_2_input, seed_input, randomize_seed_checkbox,
|
|
|
|
| 38 |
os.environ["TOKENIZERS_PARALLELISM"] = "true"
|
| 39 |
warnings.filterwarnings("ignore")
|
| 40 |
IS_ZERO_GPU = bool(os.getenv("SPACES_ZERO_GPU"))
|
| 41 |
+
SECRET_KEY = os.getenv("SECRET_KEY", "")
|
| 42 |
+
_REQUIRE_SECRET_RAW = os.getenv("REQUIRE_SECRET")
|
| 43 |
+
if _REQUIRE_SECRET_RAW is None:
|
| 44 |
+
# When SECRET_KEY is configured as a Space secret, require users to enter it.
|
| 45 |
+
REQUIRE_SECRET = bool(SECRET_KEY)
|
| 46 |
+
else:
|
| 47 |
+
# REQUIRE_SECRET=0 keeps the Space public even if a key exists for testing.
|
| 48 |
+
REQUIRE_SECRET = _REQUIRE_SECRET_RAW.strip().lower() not in {"0", "false", "no", "off"}
|
| 49 |
|
| 50 |
# if IS_ZERO_GPU:
|
| 51 |
# print("Loading...")
|
|
|
|
| 531 |
|
| 532 |
|
| 533 |
def generate_video(
|
| 534 |
+
secret_key,
|
| 535 |
input_image,
|
| 536 |
last_image,
|
| 537 |
prompt,
|
|
|
|
| 556 |
prompt and parameters. It uses an FP8 qunatized Wan 2.2 14B Image-to-Video model in with Lightning LoRA
|
| 557 |
for fast generation in 4-8 steps.
|
| 558 |
Args:
|
| 559 |
+
secret_key (str): Optional access key checked when REQUIRE_SECRET is enabled.
|
| 560 |
input_image (PIL.Image): The input image to animate. Will be resized to target dimensions.
|
| 561 |
last_image (PIL.Image, optional): The optional last image for the video.
|
| 562 |
prompt (str): Text prompt describing the desired animation or motion.
|
| 563 |
steps (int, optional): Number of inference steps. More steps = higher quality but slower.
|
| 564 |
+
Defaults to 4. Range: 1-8.
|
| 565 |
negative_prompt (str, optional): Negative prompt to avoid unwanted elements.
|
| 566 |
Defaults to default_negative_prompt (contains unwanted visual artifacts).
|
| 567 |
duration_seconds (float, optional): Duration of the generated video in seconds.
|
|
|
|
| 588 |
- video_path (str): Path for the file download component. Attempt to avoid reconversion in video component.
|
| 589 |
- current_seed (int): The seed used for generation.
|
| 590 |
Raises:
|
| 591 |
+
gr.Error: If the access key is invalid, or input_image is None (no image uploaded).
|
| 592 |
Note:
|
| 593 |
- Frame count is calculated as duration_seconds * FIXED_FPS (24)
|
| 594 |
- Output dimensions are adjusted to be multiples of MOD_VALUE (32)
|
|
|
|
| 596 |
- Generation time varies based on steps and duration (see get_duration function)
|
| 597 |
"""
|
| 598 |
|
| 599 |
+
if REQUIRE_SECRET and secret_key != SECRET_KEY:
|
| 600 |
+
raise gr.Error("Invalid secret key.")
|
| 601 |
+
|
| 602 |
if input_image is None:
|
| 603 |
raise gr.Error("Please upload an input image.")
|
| 604 |
|
|
|
|
| 644 |
position: absolute;
|
| 645 |
pointer-events: none;
|
| 646 |
}
|
| 647 |
+
#secret-box {
|
| 648 |
+
max-width: 560px;
|
| 649 |
+
}
|
| 650 |
"""
|
| 651 |
|
| 652 |
|
|
|
|
| 656 |
|
| 657 |
with gr.Row():
|
| 658 |
with gr.Column():
|
| 659 |
+
secret_key_input = gr.Textbox(
|
| 660 |
+
label="Secret Key",
|
| 661 |
+
type="password",
|
| 662 |
+
visible=REQUIRE_SECRET,
|
| 663 |
+
elem_id="secret-box",
|
| 664 |
+
)
|
| 665 |
input_image_component = gr.Image(type="pil", label="Input Image", sources=["upload", "clipboard"])
|
| 666 |
prompt_input = gr.Textbox(label="Prompt", value=default_prompt_i2v)
|
| 667 |
duration_seconds_input = gr.Slider(minimum=MIN_DURATION, maximum=MAX_DURATION, step=0.1, value=3.5, label="Duration (seconds)", info=f"Clamped to model's {MIN_FRAMES_MODEL}-{MAX_FRAMES_MODEL} frames at {FIXED_FPS}fps.")
|
|
|
|
| 673 |
)
|
| 674 |
safe_mode_checkbox = gr.Checkbox(
|
| 675 |
label="🛠️ Safe Mode",
|
| 676 |
+
value=False,
|
| 677 |
info="Requests 30% extra processing time to try to prevent unfinished tasks when the server is busy."
|
| 678 |
)
|
| 679 |
with gr.Accordion("Advanced Settings", open=False):
|
|
|
|
| 682 |
quality_slider = gr.Slider(minimum=1, maximum=10, step=1, value=6, label="Video Quality", info="If set to 10, the generated video may be too large and won't play in the Gradio preview.")
|
| 683 |
seed_input = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=42, interactive=True)
|
| 684 |
randomize_seed_checkbox = gr.Checkbox(label="Randomize seed", value=True, interactive=True)
|
| 685 |
+
steps_slider = gr.Slider(minimum=1, maximum=8, step=1, value=6, label="Inference Steps")
|
| 686 |
guidance_scale_input = gr.Slider(minimum=0.0, maximum=10.0, step=0.5, value=1, label="Guidance Scale - high noise stage", info="Values above 1 increase GPU usage and may take longer to process.")
|
| 687 |
guidance_scale_2_input = gr.Slider(minimum=0.0, maximum=10.0, step=0.5, value=1, label="Guidance Scale 2 - low noise stage")
|
| 688 |
scheduler_dropdown = gr.Dropdown(
|
|
|
|
| 714 |
file_output = gr.File(label="Download Video")
|
| 715 |
|
| 716 |
ui_inputs = [
|
| 717 |
+
secret_key_input,
|
| 718 |
input_image_component, last_image_component, prompt_input, steps_slider,
|
| 719 |
negative_prompt_input, duration_seconds_input,
|
| 720 |
guidance_scale_input, guidance_scale_2_input, seed_input, randomize_seed_checkbox,
|