Spaces:
Running on Zero
Running on Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -21,9 +21,12 @@ import gradio as gr
|
|
| 21 |
|
| 22 |
MODEL_REPO = os.environ.get("H3_MODEL_REPO", "MiniMaxAI/MiniMax-H3")
|
| 23 |
CONDITIONER_SPACE = os.environ.get("H3_CONDITIONER", "dagloop5/qwen3vl-conditioner")
|
| 24 |
-
# `
|
| 25 |
-
# `
|
| 26 |
-
|
|
|
|
|
|
|
|
|
|
| 27 |
# cuDNN's fused attention is 10-20% faster than the SDPA default on this pool and needs nothing installed.
|
| 28 |
# flash-attention 3 is sm90-only and this card is sm120 (the `zero-a10g` flavour name is legacy).
|
| 29 |
ATTENTION = os.environ.get("H3_ATTENTION", "_native_cudnn").lower()
|
|
@@ -80,9 +83,9 @@ MIN_STEPS = 4
|
|
| 80 |
# Seconds of GPU one request needs, from the packed sequence it is about to denoise: linear in the rows for the
|
| 81 |
# matmuls, quadratic for the attention, against the AoTI block package this Space runs.
|
| 82 |
STEP_LINEAR, STEP_QUADRATIC, SAFETY = 1.1745e-4, 3.8396e-9, 1.3
|
| 83 |
-
#
|
| 84 |
-
# nothing here knows whether the worker it lands on is cold.
|
| 85 |
-
PLACEMENT_ALLOWANCE = int(os.environ.get("H3_PLACEMENT_ALLOWANCE", "
|
| 86 |
AUDIO_LATENTS_PER_SECOND, AUDIO_CHANNELS = 40, 2
|
| 87 |
REFERENCE_IMAGE_SHORT_EDGE, CANVAS_MULTIPLE = 2048, 32
|
| 88 |
DECODE_BASE, DECODE_PER_DEFAULT_CANVAS, DEFAULT_CANVAS_PIXELS = 15, 25, 960 * 544 * 124
|
|
@@ -183,16 +186,15 @@ LOAD_ERROR: str | None = None
|
|
| 183 |
|
| 184 |
|
| 185 |
def load_models() -> str | None:
|
| 186 |
-
"""Load the denoising half at startup,
|
| 187 |
-
|
| 188 |
`MiniMaxH3Ref2VAGeneratorBlocks` declares `transformer_ref`, `vae`, `audio_vae`, the two schedulers and
|
| 189 |
`video_processor`, so `load_components` fetches exactly those subfolders — `text_encoder/` and the `transformer/`
|
| 190 |
partition are never touched. Both autoencoders carry `_keep_in_fp32_modules` over every module and stay float32: a
|
| 191 |
bfloat16 audio VAE decodes the soundtrack roughly 20 dB too quiet.
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
"""
|
| 197 |
global PIPE, MANAGER, LOAD_ERROR
|
| 198 |
|
|
@@ -231,6 +233,10 @@ def load_models() -> str | None:
|
|
| 231 |
if PLACEMENT == "offload":
|
| 232 |
manager.enable_auto_cpu_offload(device="cuda")
|
| 233 |
_arm_decode_hooks(pipe)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 234 |
|
| 235 |
PIPE, MANAGER = pipe, manager
|
| 236 |
print(f"[ref2va] ready in {time.time() - started:.0f}s", flush=True)
|
|
@@ -430,6 +436,9 @@ def _generate(prompt_embeds, text_token_tags, references, height, width, num_fra
|
|
| 430 |
import torch
|
| 431 |
if PLACEMENT == "lazy":
|
| 432 |
PIPE.to("cuda")
|
|
|
|
|
|
|
|
|
|
| 433 |
state = PIPE(
|
| 434 |
prompt_embeds=prompt_embeds.to("cuda"),
|
| 435 |
text_token_tags=text_token_tags,
|
|
|
|
| 21 |
|
| 22 |
MODEL_REPO = os.environ.get("H3_MODEL_REPO", "MiniMaxAI/MiniMax-H3")
|
| 23 |
CONDITIONER_SPACE = os.environ.get("H3_CONDITIONER", "dagloop5/qwen3vl-conditioner")
|
| 24 |
+
# `pack` moves only `transformer_ref` onto the card at startup, the same way fl2va scopes this to its own
|
| 25 |
+
# `transformer` partition: packing the full ~72.16 GiB pipe (plus `spaces`' on-disk pack copy) busts the 150 GB
|
| 26 |
+
# storage quota, but the ~61.7 GiB `transformer_ref` alone fits. The ~10 GB of fp32 VAEs move on the first GPU
|
| 27 |
+
# call instead. `lazy` moves everything on the first GPU call rather than packing anything; `offload` hands
|
| 28 |
+
# placement to `ComponentsManager.enable_auto_cpu_offload`.
|
| 29 |
+
PLACEMENT = os.environ.get("H3_PLACEMENT", "pack").lower()
|
| 30 |
# cuDNN's fused attention is 10-20% faster than the SDPA default on this pool and needs nothing installed.
|
| 31 |
# flash-attention 3 is sm90-only and this card is sm120 (the `zero-a10g` flavour name is legacy).
|
| 32 |
ATTENTION = os.environ.get("H3_ATTENTION", "_native_cudnn").lower()
|
|
|
|
| 83 |
# Seconds of GPU one request needs, from the packed sequence it is about to denoise: linear in the rows for the
|
| 84 |
# matmuls, quadratic for the attention, against the AoTI block package this Space runs.
|
| 85 |
STEP_LINEAR, STEP_QUADRATIC, SAFETY = 1.1745e-4, 3.8396e-9, 1.3
|
| 86 |
+
# `pack` mode: only the ~10 GB of fp32 VAEs move, and only on a cold worker — matches fl2va's own allowance for the
|
| 87 |
+
# identical move. Every request still carries it, because nothing here knows whether the worker it lands on is cold.
|
| 88 |
+
PLACEMENT_ALLOWANCE = int(os.environ.get("H3_PLACEMENT_ALLOWANCE", "8"))
|
| 89 |
AUDIO_LATENTS_PER_SECOND, AUDIO_CHANNELS = 40, 2
|
| 90 |
REFERENCE_IMAGE_SHORT_EDGE, CANVAS_MULTIPLE = 2048, 32
|
| 91 |
DECODE_BASE, DECODE_PER_DEFAULT_CANVAS, DEFAULT_CANVAS_PIXELS = 15, 25, 960 * 544 * 124
|
|
|
|
| 186 |
|
| 187 |
|
| 188 |
def load_models() -> str | None:
|
| 189 |
+
"""Load the denoising half at startup, packing `transformer_ref` onto the card under `pack` placement.
|
|
|
|
| 190 |
`MiniMaxH3Ref2VAGeneratorBlocks` declares `transformer_ref`, `vae`, `audio_vae`, the two schedulers and
|
| 191 |
`video_processor`, so `load_components` fetches exactly those subfolders — `text_encoder/` and the `transformer/`
|
| 192 |
partition are never touched. Both autoencoders carry `_keep_in_fp32_modules` over every module and stay float32: a
|
| 193 |
bfloat16 audio VAE decodes the soundtrack roughly 20 dB too quiet.
|
| 194 |
+
Only `transformer_ref` moves onto the card here, for storage rather than memory: `spaces`' startup `torch.pack()`
|
| 195 |
+
writes every startup-resident CUDA tensor to a second copy on disk, and 77.3 GB of weights plus its pack busts
|
| 196 |
+
the 150 GB quota (`OSError: [Errno 28] No space left on device` out of `os.posix_fallocate`, mid-pack); the
|
| 197 |
+
~61.7 GB `transformer_ref` alone fits, same as fl2va's `transformer`.
|
| 198 |
"""
|
| 199 |
global PIPE, MANAGER, LOAD_ERROR
|
| 200 |
|
|
|
|
| 233 |
if PLACEMENT == "offload":
|
| 234 |
manager.enable_auto_cpu_offload(device="cuda")
|
| 235 |
_arm_decode_hooks(pipe)
|
| 236 |
+
elif PLACEMENT == "pack":
|
| 237 |
+
# Scoped to `transformer_ref`, exactly as fl2va scopes this to its `transformer` partition — see the
|
| 238 |
+
# docstring above for the quota math. The ~10 GB of fp32 VAEs move on the first GPU call instead.
|
| 239 |
+
pipe.transformer_ref.to("cuda")
|
| 240 |
|
| 241 |
PIPE, MANAGER = pipe, manager
|
| 242 |
print(f"[ref2va] ready in {time.time() - started:.0f}s", flush=True)
|
|
|
|
| 436 |
import torch
|
| 437 |
if PLACEMENT == "lazy":
|
| 438 |
PIPE.to("cuda")
|
| 439 |
+
elif PLACEMENT == "pack":
|
| 440 |
+
PIPE.vae.to("cuda")
|
| 441 |
+
PIPE.audio_vae.to("cuda")
|
| 442 |
state = PIPE(
|
| 443 |
prompt_embeds=prompt_embeds.to("cuda"),
|
| 444 |
text_token_tags=text_token_tags,
|