Spaces:
Paused
Paused
Sync SeFi Image app from working Space
Browse files- .DS_Store +0 -0
- app.py +35 -1
- requirements.txt +2 -2
- sefi/checkpoints.py +5 -0
- sefi/pipeline.py +3 -1
- sefi/runner.py +4 -1
.DS_Store
ADDED
|
Binary file (6.15 kB). View file
|
|
|
app.py
CHANGED
|
@@ -5,6 +5,7 @@ import gc
|
|
| 5 |
import os
|
| 6 |
import random
|
| 7 |
import threading
|
|
|
|
| 8 |
import traceback
|
| 9 |
import warnings
|
| 10 |
from dataclasses import dataclass
|
|
@@ -330,6 +331,14 @@ def _friendly_error(exc: BaseException, repo_id: str | None = None) -> str:
|
|
| 330 |
return f"{type(exc).__name__}: {text}"
|
| 331 |
|
| 332 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 333 |
def model_defaults(model_key: str):
|
| 334 |
preset = MODEL_PRESETS[model_key]
|
| 335 |
return (
|
|
@@ -369,6 +378,8 @@ def estimate_duration(
|
|
| 369 |
guidance_scale: float,
|
| 370 |
seed: int,
|
| 371 |
randomize_seed: bool,
|
|
|
|
|
|
|
| 372 |
) -> int:
|
| 373 |
del prompt, guidance_scale, seed, randomize_seed
|
| 374 |
preset = MODEL_PRESETS.get(model_key)
|
|
@@ -387,7 +398,9 @@ def generate(
|
|
| 387 |
guidance_scale: float,
|
| 388 |
seed: int,
|
| 389 |
randomize_seed: bool,
|
|
|
|
| 390 |
):
|
|
|
|
| 391 |
prompt = prompt.strip()
|
| 392 |
if not prompt:
|
| 393 |
return None, "Enter a prompt.", seed
|
|
@@ -415,7 +428,25 @@ def generate(
|
|
| 415 |
if torch.cuda.is_available():
|
| 416 |
torch.backends.cuda.matmul.allow_tf32 = True
|
| 417 |
|
|
|
|
| 418 |
pipe = _load_pipe(model_key)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 419 |
images = pipe(
|
| 420 |
prompt,
|
| 421 |
num_inference_steps=steps,
|
|
@@ -423,7 +454,9 @@ def generate(
|
|
| 423 |
height=height,
|
| 424 |
width=width,
|
| 425 |
seed=int(seed),
|
|
|
|
| 426 |
)
|
|
|
|
| 427 |
except Exception as exc:
|
| 428 |
traceback.print_exc()
|
| 429 |
return None, _friendly_error(exc, preset.repo_id), seed
|
|
@@ -435,7 +468,8 @@ def generate(
|
|
| 435 |
images[0],
|
| 436 |
(
|
| 437 |
f"Generated with `{preset.repo_id}` at {width}x{height}, "
|
| 438 |
-
f"{steps} steps, guidance {guidance_scale}, seed {seed}."
|
|
|
|
| 439 |
),
|
| 440 |
seed,
|
| 441 |
)
|
|
|
|
| 5 |
import os
|
| 6 |
import random
|
| 7 |
import threading
|
| 8 |
+
import time
|
| 9 |
import traceback
|
| 10 |
import warnings
|
| 11 |
from dataclasses import dataclass
|
|
|
|
| 331 |
return f"{type(exc).__name__}: {text}"
|
| 332 |
|
| 333 |
|
| 334 |
+
def _format_seconds(seconds: float) -> str:
|
| 335 |
+
seconds = max(0, int(round(seconds)))
|
| 336 |
+
minutes, secs = divmod(seconds, 60)
|
| 337 |
+
if minutes:
|
| 338 |
+
return f"{minutes}m {secs:02d}s"
|
| 339 |
+
return f"{secs}s"
|
| 340 |
+
|
| 341 |
+
|
| 342 |
def model_defaults(model_key: str):
|
| 343 |
preset = MODEL_PRESETS[model_key]
|
| 344 |
return (
|
|
|
|
| 378 |
guidance_scale: float,
|
| 379 |
seed: int,
|
| 380 |
randomize_seed: bool,
|
| 381 |
+
*_args,
|
| 382 |
+
**_kwargs,
|
| 383 |
) -> int:
|
| 384 |
del prompt, guidance_scale, seed, randomize_seed
|
| 385 |
preset = MODEL_PRESETS.get(model_key)
|
|
|
|
| 398 |
guidance_scale: float,
|
| 399 |
seed: int,
|
| 400 |
randomize_seed: bool,
|
| 401 |
+
progress=gr.Progress(track_tqdm=False),
|
| 402 |
):
|
| 403 |
+
request_started_at = time.monotonic()
|
| 404 |
prompt = prompt.strip()
|
| 405 |
if not prompt:
|
| 406 |
return None, "Enter a prompt.", seed
|
|
|
|
| 428 |
if torch.cuda.is_available():
|
| 429 |
torch.backends.cuda.matmul.allow_tf32 = True
|
| 430 |
|
| 431 |
+
progress(0, desc=f"Loading {preset.label}")
|
| 432 |
pipe = _load_pipe(model_key)
|
| 433 |
+
denoise_started_at = time.monotonic()
|
| 434 |
+
progress(0, desc=f"Denoising 0/{steps} steps")
|
| 435 |
+
|
| 436 |
+
def report_step(step: int, total: int) -> None:
|
| 437 |
+
total = max(1, int(total))
|
| 438 |
+
step = min(max(0, int(step)), total)
|
| 439 |
+
elapsed = time.monotonic() - denoise_started_at
|
| 440 |
+
remaining = 0.0
|
| 441 |
+
if step > 0:
|
| 442 |
+
remaining = (elapsed / step) * (total - step)
|
| 443 |
+
desc = (
|
| 444 |
+
f"Denoising {step}/{total} steps | "
|
| 445 |
+
f"elapsed {_format_seconds(elapsed)} | "
|
| 446 |
+
f"ETA {_format_seconds(remaining)}"
|
| 447 |
+
)
|
| 448 |
+
progress(step / total, desc=desc)
|
| 449 |
+
|
| 450 |
images = pipe(
|
| 451 |
prompt,
|
| 452 |
num_inference_steps=steps,
|
|
|
|
| 454 |
height=height,
|
| 455 |
width=width,
|
| 456 |
seed=int(seed),
|
| 457 |
+
progress_callback=report_step,
|
| 458 |
)
|
| 459 |
+
progress(1, desc="Finalizing image")
|
| 460 |
except Exception as exc:
|
| 461 |
traceback.print_exc()
|
| 462 |
return None, _friendly_error(exc, preset.repo_id), seed
|
|
|
|
| 468 |
images[0],
|
| 469 |
(
|
| 470 |
f"Generated with `{preset.repo_id}` at {width}x{height}, "
|
| 471 |
+
f"{steps} steps, guidance {guidance_scale}, seed {seed}. "
|
| 472 |
+
f"Total time: {_format_seconds(time.monotonic() - request_started_at)}."
|
| 473 |
),
|
| 474 |
seed,
|
| 475 |
)
|
requirements.txt
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
gradio==6.19.0
|
| 2 |
spaces>=0.50.0
|
| 3 |
-
torch
|
| 4 |
-
torchvision
|
| 5 |
diffusers>=0.39.0
|
| 6 |
transformers>=5.13.0
|
| 7 |
accelerate>=1.12.0
|
|
|
|
| 1 |
gradio==6.19.0
|
| 2 |
spaces>=0.50.0
|
| 3 |
+
torch==2.9.1
|
| 4 |
+
torchvision==0.24.1
|
| 5 |
diffusers>=0.39.0
|
| 6 |
transformers>=5.13.0
|
| 7 |
accelerate>=1.12.0
|
sefi/checkpoints.py
CHANGED
|
@@ -9,6 +9,10 @@ from pathlib import Path
|
|
| 9 |
CONFIG_FILENAMES = ("sefi_config.yaml", "config.yaml")
|
| 10 |
|
| 11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
def _download_hf_snapshot(
|
| 13 |
repo_id: str,
|
| 14 |
*,
|
|
@@ -26,6 +30,7 @@ def _download_hf_snapshot(
|
|
| 26 |
repo_id=repo_id,
|
| 27 |
cache_dir=str(cache_dir),
|
| 28 |
local_files_only=False,
|
|
|
|
| 29 |
)
|
| 30 |
|
| 31 |
|
|
|
|
| 9 |
CONFIG_FILENAMES = ("sefi_config.yaml", "config.yaml")
|
| 10 |
|
| 11 |
|
| 12 |
+
def _hub_token() -> str | None:
|
| 13 |
+
return os.getenv("HF_TOKEN") or os.getenv("HUGGING_FACE_HUB_TOKEN")
|
| 14 |
+
|
| 15 |
+
|
| 16 |
def _download_hf_snapshot(
|
| 17 |
repo_id: str,
|
| 18 |
*,
|
|
|
|
| 30 |
repo_id=repo_id,
|
| 31 |
cache_dir=str(cache_dir),
|
| 32 |
local_files_only=False,
|
| 33 |
+
token=_hub_token(),
|
| 34 |
)
|
| 35 |
|
| 36 |
|
sefi/pipeline.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
| 3 |
from __future__ import annotations
|
| 4 |
|
| 5 |
from pathlib import Path
|
| 6 |
-
from typing import Iterable
|
| 7 |
|
| 8 |
import torch
|
| 9 |
from PIL import Image
|
|
@@ -106,6 +106,7 @@ class SEFIInferencePipeline:
|
|
| 106 |
batch_size: int | None = None,
|
| 107 |
seed: int | None = None,
|
| 108 |
generator: torch.Generator | None = None,
|
|
|
|
| 109 |
) -> list[Image.Image]:
|
| 110 |
prompt_list = [prompts] if isinstance(prompts, str) else list(prompts)
|
| 111 |
if not prompt_list:
|
|
@@ -156,6 +157,7 @@ class SEFIInferencePipeline:
|
|
| 156 |
height=size.height,
|
| 157 |
width=size.width,
|
| 158 |
generator=gen,
|
|
|
|
| 159 |
)
|
| 160 |
)
|
| 161 |
return images
|
|
|
|
| 3 |
from __future__ import annotations
|
| 4 |
|
| 5 |
from pathlib import Path
|
| 6 |
+
from typing import Callable, Iterable
|
| 7 |
|
| 8 |
import torch
|
| 9 |
from PIL import Image
|
|
|
|
| 106 |
batch_size: int | None = None,
|
| 107 |
seed: int | None = None,
|
| 108 |
generator: torch.Generator | None = None,
|
| 109 |
+
progress_callback: Callable[[int, int], None] | None = None,
|
| 110 |
) -> list[Image.Image]:
|
| 111 |
prompt_list = [prompts] if isinstance(prompts, str) else list(prompts)
|
| 112 |
if not prompt_list:
|
|
|
|
| 157 |
height=size.height,
|
| 158 |
width=size.width,
|
| 159 |
generator=gen,
|
| 160 |
+
progress_callback=progress_callback,
|
| 161 |
)
|
| 162 |
)
|
| 163 |
return images
|
sefi/runner.py
CHANGED
|
@@ -5,7 +5,7 @@ from __future__ import annotations
|
|
| 5 |
import json
|
| 6 |
import math
|
| 7 |
import os
|
| 8 |
-
from typing import Optional
|
| 9 |
|
| 10 |
import torch
|
| 11 |
from PIL import Image
|
|
@@ -606,6 +606,7 @@ class SEFIInferenceRunner:
|
|
| 606 |
height: int,
|
| 607 |
width: int,
|
| 608 |
generator: Optional[torch.Generator] = None,
|
|
|
|
| 609 |
) -> list[Image.Image]:
|
| 610 |
if num_inference_steps <= 0:
|
| 611 |
raise ValueError("num_inference_steps must be > 0")
|
|
@@ -784,6 +785,8 @@ class SEFIInferenceRunner:
|
|
| 784 |
lat_sem = lat_sem + dt_sem * vel_sem
|
| 785 |
lat_tex = lat_tex + dt_tex * vel_tex
|
| 786 |
latents = torch.cat([lat_sem, lat_tex], dim=1)
|
|
|
|
|
|
|
| 787 |
|
| 788 |
texture_latents = latents[:, self.semantic_channels :]
|
| 789 |
decoded = self.texture_codec.decode_texture(
|
|
|
|
| 5 |
import json
|
| 6 |
import math
|
| 7 |
import os
|
| 8 |
+
from typing import Callable, Optional
|
| 9 |
|
| 10 |
import torch
|
| 11 |
from PIL import Image
|
|
|
|
| 606 |
height: int,
|
| 607 |
width: int,
|
| 608 |
generator: Optional[torch.Generator] = None,
|
| 609 |
+
progress_callback: Optional[Callable[[int, int], None]] = None,
|
| 610 |
) -> list[Image.Image]:
|
| 611 |
if num_inference_steps <= 0:
|
| 612 |
raise ValueError("num_inference_steps must be > 0")
|
|
|
|
| 785 |
lat_sem = lat_sem + dt_sem * vel_sem
|
| 786 |
lat_tex = lat_tex + dt_tex * vel_tex
|
| 787 |
latents = torch.cat([lat_sem, lat_tex], dim=1)
|
| 788 |
+
if progress_callback is not None:
|
| 789 |
+
progress_callback(step + 1, num_inference_steps)
|
| 790 |
|
| 791 |
texture_latents = latents[:, self.semantic_channels :]
|
| 792 |
decoded = self.texture_codec.decode_texture(
|