Spaces:
Paused
Paused
revert to clean eager app.py (remove all AOTI/dynamo machinery); 480p24 has ample headroom, eager is sufficient; align with local run_server
Browse files
app.py
CHANGED
|
@@ -255,116 +255,6 @@ except Exception as e: # noqa: BLE001
|
|
| 255 |
# run_session_blocking (in xvideo/serving/zerogpu_engine.py) reuses the vendored
|
| 256 |
# gate/PE/streaming logic; it is NOT a modification of the existing server.
|
| 257 |
# ---------------------------------------------------------------------------
|
| 258 |
-
_AOTI_STATE = {}
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
def _fork_load_aoti() -> None:
|
| 262 |
-
"""Inside a GPU fork: fetch (idempotent, /data-cached) and load the dev-box
|
| 263 |
-
precompiled AOTInductor VAE encode packages (same sm_120 arch + torch 2.9.1),
|
| 264 |
-
then monkeypatch the encode entrypoints. Executes via dlopen — zero dynamo,
|
| 265 |
-
which is inert in ZeroGPU forks. Fetch happens IN THE FORK so a download
|
| 266 |
-
problem can never wedge the app boot."""
|
| 267 |
-
if _AOTI_STATE.get("installed") or _RUNTIME is None:
|
| 268 |
-
return
|
| 269 |
-
from torch._inductor import aoti_load_package
|
| 270 |
-
aoti_dir = _DATA / "aoti"
|
| 271 |
-
aoti_dir.mkdir(parents=True, exist_ok=True)
|
| 272 |
-
RES = ((480, 840), (840, 480), (720, 1248), (1248, 720))
|
| 273 |
-
wanted = []
|
| 274 |
-
for H, W in RES:
|
| 275 |
-
for t in (9, 1):
|
| 276 |
-
wanted.append(("encode", t, H, W, f"vae_encode_t{t}_{H}x{W}.pt2"))
|
| 277 |
-
for t in (2, 1):
|
| 278 |
-
wanted.append(("decode", t, H, W, f"vae_decode_t{t}_{H}x{W}.pt2"))
|
| 279 |
-
fetch = bool(_AOTI_STATE.pop("fetch", False))
|
| 280 |
-
if fetch:
|
| 281 |
-
for kind, t, H, W, fname in wanted:
|
| 282 |
-
p = aoti_dir / fname
|
| 283 |
-
if p.is_file():
|
| 284 |
-
continue
|
| 285 |
-
try:
|
| 286 |
-
from huggingface_hub import hf_hub_download
|
| 287 |
-
hf_hub_download("wxDai/joyomni-aoti-sm120", fname, repo_type="dataset",
|
| 288 |
-
local_dir=str(aoti_dir))
|
| 289 |
-
print(f"[fork] fetched aoti {fname}", flush=True)
|
| 290 |
-
except Exception: # noqa: BLE001
|
| 291 |
-
_AOTI_STATE.setdefault("log", []).append(f"fetch_fail {fname}"[:120])
|
| 292 |
-
|
| 293 |
-
enc_files, dec_files = {}, {}
|
| 294 |
-
for kind, t, H, W, fname in wanted:
|
| 295 |
-
p = aoti_dir / fname
|
| 296 |
-
if not p.is_file():
|
| 297 |
-
continue
|
| 298 |
-
if kind == "encode":
|
| 299 |
-
enc_files[(t, H, W)] = str(p)
|
| 300 |
-
else:
|
| 301 |
-
dec_files[(t, H * 2 // 3 // 16, W * 2 // 3 // 16)] = str(p)
|
| 302 |
-
if not enc_files and not dec_files:
|
| 303 |
-
return
|
| 304 |
-
loaded = {}
|
| 305 |
-
|
| 306 |
-
def _get(files, key):
|
| 307 |
-
if key in loaded:
|
| 308 |
-
return loaded[key]
|
| 309 |
-
path = files.get(key)
|
| 310 |
-
if path is None:
|
| 311 |
-
loaded[key] = None
|
| 312 |
-
return None
|
| 313 |
-
try:
|
| 314 |
-
loaded[key] = aoti_load_package(path)
|
| 315 |
-
_AOTI_STATE.setdefault("log", []).append(f"lazy-loaded {path.rsplit('/', 1)[-1]}")
|
| 316 |
-
print(f"[fork] aoti lazy-loaded {path.rsplit('/', 1)[-1]}", flush=True)
|
| 317 |
-
except Exception as e: # noqa: BLE001
|
| 318 |
-
loaded[key] = None
|
| 319 |
-
_AOTI_STATE.setdefault("log", []).append(f"load_fail {key}: {e!r}"[:180])
|
| 320 |
-
return loaded[key]
|
| 321 |
-
|
| 322 |
-
def _unwrap_fn(fn):
|
| 323 |
-
while hasattr(fn, "_torchdynamo_orig_callable"):
|
| 324 |
-
fn = fn._torchdynamo_orig_callable
|
| 325 |
-
return fn
|
| 326 |
-
|
| 327 |
-
seen = set()
|
| 328 |
-
for vae in (_RUNTIME.pipeline.vae, _RUNTIME.pseudo_encode_vae, _RUNTIME.decode_vae):
|
| 329 |
-
if vae is None or id(vae) in seen:
|
| 330 |
-
continue
|
| 331 |
-
seen.add(id(vae))
|
| 332 |
-
if enc_files and hasattr(vae, "_encode"):
|
| 333 |
-
fb_e = _unwrap_fn(vae._encode)
|
| 334 |
-
|
| 335 |
-
def _encode_dispatch(x, _fb=fb_e):
|
| 336 |
-
fn = None
|
| 337 |
-
if x.shape[0] == 1 and x.shape[1] == 3:
|
| 338 |
-
fn = _get(enc_files, (int(x.shape[2]), int(x.shape[3]), int(x.shape[4])))
|
| 339 |
-
if fn is None:
|
| 340 |
-
return _fb(x)
|
| 341 |
-
try:
|
| 342 |
-
return fn(x)
|
| 343 |
-
except Exception: # noqa: BLE001
|
| 344 |
-
return _fb(x)
|
| 345 |
-
|
| 346 |
-
vae._encode = _encode_dispatch
|
| 347 |
-
if dec_files and hasattr(vae, "_decode"):
|
| 348 |
-
fb_d = _unwrap_fn(vae._decode)
|
| 349 |
-
|
| 350 |
-
def _decode_dispatch(z, _fb=fb_d):
|
| 351 |
-
fn = None
|
| 352 |
-
if z.shape[0] == 1:
|
| 353 |
-
fn = _get(dec_files, (int(z.shape[2]), int(z.shape[3]), int(z.shape[4])))
|
| 354 |
-
if fn is None:
|
| 355 |
-
return _fb(z)
|
| 356 |
-
try:
|
| 357 |
-
return fn(z)
|
| 358 |
-
except Exception: # noqa: BLE001
|
| 359 |
-
return _fb(z)
|
| 360 |
-
|
| 361 |
-
vae._decode = _decode_dispatch
|
| 362 |
-
_AOTI_STATE["installed"] = True
|
| 363 |
-
_AOTI_STATE.setdefault("log", []).append(
|
| 364 |
-
f"registered enc={len(enc_files)} dec={len(dec_files)} (lazy)")
|
| 365 |
-
print(f"[fork] aoti lazy dispatch registered enc={len(enc_files)} dec={len(dec_files)}", flush=True)
|
| 366 |
-
|
| 367 |
-
|
| 368 |
def _fork_enable_compile() -> None:
|
| 369 |
"""ZeroGPU's CUDA-emulation layer disables torch dynamo in the parent process;
|
| 370 |
forks inherit that, so every torch.compile wrapper silently runs eager (measured:
|
|
@@ -413,13 +303,17 @@ def _fork_enable_compile() -> None:
|
|
| 413 |
setattr(_vae, _attr, _plain)
|
| 414 |
_unwrapped += _n
|
| 415 |
globals()["_FORK_UNWRAPPED"] = _unwrapped
|
| 416 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 417 |
except Exception as e: # noqa: BLE001
|
| 418 |
print(f"[fork] compile re-enable failed: {e!r}", flush=True)
|
| 419 |
-
try:
|
| 420 |
-
_fork_load_aoti()
|
| 421 |
-
except Exception as e: # noqa: BLE001
|
| 422 |
-
print(f"[fork] aoti install failed: {e!r}", flush=True)
|
| 423 |
|
| 424 |
|
| 425 |
def make_gpu_session(in_q, out_q, paths):
|
|
@@ -462,7 +356,6 @@ def _run_session_in_fork(in_q, out_q, paths):
|
|
| 462 |
|
| 463 |
@spaces.GPU(duration=290, size="xlarge")
|
| 464 |
def warmup():
|
| 465 |
-
_AOTI_STATE["fetch"] = True
|
| 466 |
"""Warm up the pipeline inside the fork (real GPU): both orientations at both
|
| 467 |
resolution tiers, same coverage as the standalone server's load-time warmup.
|
| 468 |
720p is included so its VAE compile artifacts land in /data — without this,
|
|
@@ -488,13 +381,6 @@ def gpu_probe():
|
|
| 488 |
|
| 489 |
_fork_enable_compile()
|
| 490 |
out = {"device": torch.cuda.get_device_name(0)}
|
| 491 |
-
try:
|
| 492 |
-
_adir = _DATA / "aoti"
|
| 493 |
-
out["aoti_state"] = {"installed": _AOTI_STATE.get("installed"),
|
| 494 |
-
"log": _AOTI_STATE.get("log", [])[-6:],
|
| 495 |
-
"files": sorted(p.name for p in _adir.glob("*.pt2")) if _adir.is_dir() else []}
|
| 496 |
-
except Exception as e: # noqa: BLE001
|
| 497 |
-
out["aoti_state"] = {"err": repr(e)[:120]}
|
| 498 |
try:
|
| 499 |
import os as _os
|
| 500 |
out["env_torch"] = {k: v for k, v in _os.environ.items()
|
|
@@ -647,8 +533,25 @@ def gpu_probe():
|
|
| 647 |
out["census_err"] = repr(e)[:150]
|
| 648 |
|
| 649 |
try:
|
|
|
|
| 650 |
from xvideo.models.vae import vae_compile as _vc
|
|
|
|
| 651 |
vae_e = _RUNTIME.pipeline.vae
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 652 |
x = torch.zeros(1, 3, 9, 480, 840, device=dev, dtype=torch.bfloat16)
|
| 653 |
x = _vc.prep_input(x)
|
| 654 |
with torch.no_grad(), torch.autocast(device_type="cuda", dtype=torch.bfloat16, enabled=True):
|
|
@@ -660,27 +563,15 @@ def gpu_probe():
|
|
| 660 |
vae_e.encode(x)
|
| 661 |
torch.cuda.synchronize()
|
| 662 |
out["vae_encode_direct_ms"] = round((_t.perf_counter() - t0) / 10 * 1000, 2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 663 |
except Exception as e: # noqa: BLE001
|
| 664 |
out["vae_probe_err"] = repr(e)[:200]
|
| 665 |
|
| 666 |
-
try:
|
| 667 |
-
from xvideo.models.vae import vae_compile as _vc
|
| 668 |
-
vae_d = _RUNTIME.decode_vae
|
| 669 |
-
lat_c = int(getattr(vae_d, "latent_channels", 16) or 16)
|
| 670 |
-
z = torch.zeros(1, lat_c, 2, 60, 105, device=dev, dtype=torch.bfloat16)
|
| 671 |
-
z = _vc.prep_input(z)
|
| 672 |
-
with torch.no_grad(), torch.autocast(device_type="cuda", dtype=torch.bfloat16, enabled=True):
|
| 673 |
-
for _ in range(3):
|
| 674 |
-
vae_d.decode(z, return_dict=False)[0]
|
| 675 |
-
torch.cuda.synchronize()
|
| 676 |
-
t0 = _t.perf_counter()
|
| 677 |
-
for _ in range(10):
|
| 678 |
-
vae_d.decode(z, return_dict=False)[0]
|
| 679 |
-
torch.cuda.synchronize()
|
| 680 |
-
out["vae_decode_direct_ms"] = round((_t.perf_counter() - t0) / 10 * 1000, 2)
|
| 681 |
-
except Exception as e: # noqa: BLE001
|
| 682 |
-
out["vae_decode_err"] = repr(e)[:200]
|
| 683 |
-
|
| 684 |
try:
|
| 685 |
import torch.nn.functional as F
|
| 686 |
torch.backends.cudnn.benchmark = True
|
|
@@ -805,8 +696,7 @@ async def do_warmup():
|
|
| 805 |
|
| 806 |
|
| 807 |
@spaces.GPU(duration=120, size="xlarge")
|
| 808 |
-
def engine_bench(fresh_cache: bool = False, pace: float = 12.0, chunks: int = 16
|
| 809 |
-
height: int = 480, width: int = 840):
|
| 810 |
"""Engine-only throughput probe inside the fork: no session wrapper, no
|
| 811 |
queues — the exact mirror of the dev-box bench. Separates 'fork environment'
|
| 812 |
from 'session machinery' when chasing Space-vs-local speed gaps. Samples SM
|
|
@@ -843,13 +733,13 @@ def engine_bench(fresh_cache: bool = False, pace: float = 12.0, chunks: int = 16
|
|
| 843 |
|
| 844 |
_th.Thread(target=_clk, daemon=True).start()
|
| 845 |
|
| 846 |
-
settings = StreamingSettings(height=
|
| 847 |
seed=42, max_temporal_ids=8, profile_timings=True,
|
| 848 |
output_codec="mjpeg")
|
| 849 |
sess = _RUNTIME.create_v2v_session(
|
| 850 |
"Turn the scene into an oil painting with warm colors.", settings=settings)
|
| 851 |
rng = np.random.default_rng(7)
|
| 852 |
-
base = rng.integers(0, 256, size=(
|
| 853 |
recs = []
|
| 854 |
t0 = _t.time()
|
| 855 |
i = 0
|
|
@@ -860,7 +750,7 @@ def engine_bench(fresh_cache: bool = False, pace: float = 12.0, chunks: int = 16
|
|
| 860 |
now = _t.time()
|
| 861 |
if target > now:
|
| 862 |
_t.sleep(target - now)
|
| 863 |
-
frame = _Image.fromarray(np.roll(base, (i * 7) %
|
| 864 |
for r in sess.push_frame(frame, {"seq": i + 1, "t_capture_ms": 0.0}):
|
| 865 |
p = r.profile or {}
|
| 866 |
recs.append({k: round(float(p[k]), 4) for k in
|
|
@@ -888,7 +778,6 @@ def engine_bench(fresh_cache: bool = False, pace: float = 12.0, chunks: int = 16
|
|
| 888 |
v = [c[k] for c in st if k in c]
|
| 889 |
return round(sum(v) / len(v), 4) if v else None
|
| 890 |
return {"chunks": len(recs), "fresh_cache": bool(fresh_cache), "pace": pace,
|
| 891 |
-
"aoti_log": _AOTI_STATE.get("log", [])[-8:],
|
| 892 |
"dit": _m("dit_denoise_s"), "enc": _m("vae_encode_s"),
|
| 893 |
"ref": _m("reference_prepare_s"), "dec": _m("vae_decode_s"),
|
| 894 |
"jpg": _m("jpeg_encode_s"), "f2t": _m("frames_to_tensor_s"),
|
|
@@ -906,13 +795,11 @@ async def do_gpu_probe():
|
|
| 906 |
|
| 907 |
|
| 908 |
@app.get("/engine-bench")
|
| 909 |
-
async def do_engine_bench(fresh_cache: int = 0, pace: float = 12.0, chunks: int = 16
|
| 910 |
-
height: int = 480, width: int = 840):
|
| 911 |
loop = asyncio.get_event_loop()
|
| 912 |
try:
|
| 913 |
return {"result": await loop.run_in_executor(
|
| 914 |
-
None, lambda: engine_bench(bool(fresh_cache), float(pace), int(chunks)
|
| 915 |
-
int(height), int(width)))}
|
| 916 |
except Exception as e: # noqa: BLE001
|
| 917 |
return JSONResponse({"error": str(e)[:300]}, status_code=500)
|
| 918 |
|
|
|
|
| 255 |
# run_session_blocking (in xvideo/serving/zerogpu_engine.py) reuses the vendored
|
| 256 |
# gate/PE/streaming logic; it is NOT a modification of the existing server.
|
| 257 |
# ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 258 |
def _fork_enable_compile() -> None:
|
| 259 |
"""ZeroGPU's CUDA-emulation layer disables torch dynamo in the parent process;
|
| 260 |
forks inherit that, so every torch.compile wrapper silently runs eager (measured:
|
|
|
|
| 303 |
setattr(_vae, _attr, _plain)
|
| 304 |
_unwrapped += _n
|
| 305 |
globals()["_FORK_UNWRAPPED"] = _unwrapped
|
| 306 |
+
_vc._configured.clear()
|
| 307 |
+
_vc._configured_encode.clear()
|
| 308 |
+
_vc._configured_encode_dynamic.clear()
|
| 309 |
+
if _RUNTIME is not None:
|
| 310 |
+
_vc.maybe_setup_decode(_RUNTIME.decode_vae)
|
| 311 |
+
_vc.maybe_setup_encode(_RUNTIME.pipeline.vae)
|
| 312 |
+
if _RUNTIME.pseudo_encode_vae is not _RUNTIME.pipeline.vae:
|
| 313 |
+
_vc.maybe_setup_encode(_RUNTIME.pseudo_encode_vae)
|
| 314 |
+
print(f"[fork] dynamo re-enabled; unwrapped {_unwrapped} poisoned compile wrappers; VAE re-wrapped fresh", flush=True)
|
| 315 |
except Exception as e: # noqa: BLE001
|
| 316 |
print(f"[fork] compile re-enable failed: {e!r}", flush=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 317 |
|
| 318 |
|
| 319 |
def make_gpu_session(in_q, out_q, paths):
|
|
|
|
| 356 |
|
| 357 |
@spaces.GPU(duration=290, size="xlarge")
|
| 358 |
def warmup():
|
|
|
|
| 359 |
"""Warm up the pipeline inside the fork (real GPU): both orientations at both
|
| 360 |
resolution tiers, same coverage as the standalone server's load-time warmup.
|
| 361 |
720p is included so its VAE compile artifacts land in /data — without this,
|
|
|
|
| 381 |
|
| 382 |
_fork_enable_compile()
|
| 383 |
out = {"device": torch.cuda.get_device_name(0)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 384 |
try:
|
| 385 |
import os as _os
|
| 386 |
out["env_torch"] = {k: v for k, v in _os.environ.items()
|
|
|
|
| 533 |
out["census_err"] = repr(e)[:150]
|
| 534 |
|
| 535 |
try:
|
| 536 |
+
import torch._dynamo.utils as _du
|
| 537 |
from xvideo.models.vae import vae_compile as _vc
|
| 538 |
+
vae_d = _RUNTIME.decode_vae
|
| 539 |
vae_e = _RUNTIME.pipeline.vae
|
| 540 |
+
tgt = getattr(vae_d, "_decode", None) or vae_d.decode
|
| 541 |
+
out["decode_wrap"] = repr(type(tgt))[:90]
|
| 542 |
+
out["decode_is_compiled"] = hasattr(tgt, "_torchdynamo_orig_callable") or "Optimized" in repr(type(tgt))
|
| 543 |
+
lat_c = int(getattr(vae_d, "latent_channels", 16) or 16)
|
| 544 |
+
z = torch.zeros(1, lat_c, 2, 60, 105, device=dev, dtype=torch.bfloat16)
|
| 545 |
+
z = _vc.prep_input(z)
|
| 546 |
+
with torch.no_grad(), torch.autocast(device_type="cuda", dtype=torch.bfloat16, enabled=True):
|
| 547 |
+
for _ in range(3):
|
| 548 |
+
vae_d.decode(z, return_dict=False)[0]
|
| 549 |
+
torch.cuda.synchronize()
|
| 550 |
+
t0 = _t.perf_counter()
|
| 551 |
+
for _ in range(15):
|
| 552 |
+
vae_d.decode(z, return_dict=False)[0]
|
| 553 |
+
torch.cuda.synchronize()
|
| 554 |
+
out["vae_decode_direct_ms"] = round((_t.perf_counter() - t0) / 15 * 1000, 2)
|
| 555 |
x = torch.zeros(1, 3, 9, 480, 840, device=dev, dtype=torch.bfloat16)
|
| 556 |
x = _vc.prep_input(x)
|
| 557 |
with torch.no_grad(), torch.autocast(device_type="cuda", dtype=torch.bfloat16, enabled=True):
|
|
|
|
| 563 |
vae_e.encode(x)
|
| 564 |
torch.cuda.synchronize()
|
| 565 |
out["vae_encode_direct_ms"] = round((_t.perf_counter() - t0) / 10 * 1000, 2)
|
| 566 |
+
fr = _du.counters.get("frames", {})
|
| 567 |
+
out["dynamo_frames"] = {"total": fr.get("total"), "ok": fr.get("ok")}
|
| 568 |
+
st = _du.counters.get("stats", {})
|
| 569 |
+
out["dynamo_unique_graphs"] = st.get("unique_graphs")
|
| 570 |
+
gb = _du.counters.get("graph_break", {})
|
| 571 |
+
out["dynamo_graph_breaks"] = sum(gb.values()) if gb else 0
|
| 572 |
except Exception as e: # noqa: BLE001
|
| 573 |
out["vae_probe_err"] = repr(e)[:200]
|
| 574 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 575 |
try:
|
| 576 |
import torch.nn.functional as F
|
| 577 |
torch.backends.cudnn.benchmark = True
|
|
|
|
| 696 |
|
| 697 |
|
| 698 |
@spaces.GPU(duration=120, size="xlarge")
|
| 699 |
+
def engine_bench(fresh_cache: bool = False, pace: float = 12.0, chunks: int = 16):
|
|
|
|
| 700 |
"""Engine-only throughput probe inside the fork: no session wrapper, no
|
| 701 |
queues — the exact mirror of the dev-box bench. Separates 'fork environment'
|
| 702 |
from 'session machinery' when chasing Space-vs-local speed gaps. Samples SM
|
|
|
|
| 733 |
|
| 734 |
_th.Thread(target=_clk, daemon=True).start()
|
| 735 |
|
| 736 |
+
settings = StreamingSettings(height=480, width=840, num_inference_steps=2,
|
| 737 |
seed=42, max_temporal_ids=8, profile_timings=True,
|
| 738 |
output_codec="mjpeg")
|
| 739 |
sess = _RUNTIME.create_v2v_session(
|
| 740 |
"Turn the scene into an oil painting with warm colors.", settings=settings)
|
| 741 |
rng = np.random.default_rng(7)
|
| 742 |
+
base = rng.integers(0, 256, size=(480, 840, 3), dtype=np.uint8)
|
| 743 |
recs = []
|
| 744 |
t0 = _t.time()
|
| 745 |
i = 0
|
|
|
|
| 750 |
now = _t.time()
|
| 751 |
if target > now:
|
| 752 |
_t.sleep(target - now)
|
| 753 |
+
frame = _Image.fromarray(np.roll(base, (i * 7) % 840, axis=1), mode="RGB")
|
| 754 |
for r in sess.push_frame(frame, {"seq": i + 1, "t_capture_ms": 0.0}):
|
| 755 |
p = r.profile or {}
|
| 756 |
recs.append({k: round(float(p[k]), 4) for k in
|
|
|
|
| 778 |
v = [c[k] for c in st if k in c]
|
| 779 |
return round(sum(v) / len(v), 4) if v else None
|
| 780 |
return {"chunks": len(recs), "fresh_cache": bool(fresh_cache), "pace": pace,
|
|
|
|
| 781 |
"dit": _m("dit_denoise_s"), "enc": _m("vae_encode_s"),
|
| 782 |
"ref": _m("reference_prepare_s"), "dec": _m("vae_decode_s"),
|
| 783 |
"jpg": _m("jpeg_encode_s"), "f2t": _m("frames_to_tensor_s"),
|
|
|
|
| 795 |
|
| 796 |
|
| 797 |
@app.get("/engine-bench")
|
| 798 |
+
async def do_engine_bench(fresh_cache: int = 0, pace: float = 12.0, chunks: int = 16):
|
|
|
|
| 799 |
loop = asyncio.get_event_loop()
|
| 800 |
try:
|
| 801 |
return {"result": await loop.run_in_executor(
|
| 802 |
+
None, lambda: engine_bench(bool(fresh_cache), float(pace), int(chunks)))}
|
|
|
|
| 803 |
except Exception as e: # noqa: BLE001
|
| 804 |
return JSONResponse({"error": str(e)[:300]}, status_code=500)
|
| 805 |
|