multimodalart HF Staff commited on
Commit
3691fc1
·
verified ·
1 Parent(s): 8866682

Idiomatic ZeroGPU startup packing for the transformer

Browse files
Files changed (1) hide show
  1. app.py +16 -4
app.py CHANGED
@@ -18,7 +18,7 @@ CONDITIONER_SPACE = os.environ.get("H3_CONDITIONER", "diffusers-internal-dev/min
18
  # `lazy` moves all 72.16 GiB onto the card on the first GPU call and leaves it there; `offload` hands placement to
19
  # `ComponentsManager.enable_auto_cpu_offload` instead. Neither puts anything on the card at *startup*, which is
20
  # deliberate — see `load_models`: the 150 GB storage quota, not the 95 GiB card, is what rules that out here.
21
- PLACEMENT = os.environ.get("H3_PLACEMENT", "lazy").lower()
22
  # cuDNN's fused attention is 10-20% faster than the SDPA default on this pool and needs nothing installed.
23
  ATTENTION = os.environ.get("H3_ATTENTION", "_native_cudnn").lower()
24
  GPU_DURATION = int(os.environ.get("H3_GPU_DURATION", "900"))
@@ -122,6 +122,15 @@ def load_models() -> str | None:
122
 
123
  h3_aoti.maybe_load(pipe.transformer)
124
 
 
 
 
 
 
 
 
 
 
125
  if PLACEMENT == "offload":
126
  manager.enable_auto_cpu_offload(device="cuda")
127
  _arm_decode_hooks(pipe)
@@ -189,7 +198,7 @@ def encode_remote(prompt, image_path, last_image_path, canvas, num_frames):
189
  # gpu_seconds = A + B * steps * tokens + C * steps * tokens^2, where tokens is the packed video row count.
190
  # PLACEMENT_ALLOWANCE covers the one-time 72 GiB lazy .to("cuda") a cold worker pays inside its first call.
191
  _DUR_A, _DUR_B, _DUR_C = -6.023, 2.0877e-4, 2.1221e-9
192
- _PLACEMENT_ALLOWANCE, _PAD = 20, 10 # lazy .to on a cold worker measures ~10 s; pack-at-startup exceeds the 150 GB quota
193
 
194
 
195
  def get_duration(prompt_embeds, text_token_tags, image, last_image, height, width, num_frames, steps, seed, *a, **k):
@@ -212,9 +221,12 @@ def _generate(prompt_embeds, text_token_tags, image, last_image, height, width,
212
  import torch
213
 
214
  if PLACEMENT == "lazy":
215
- # 72.16 GiB across PCIe on the first request of a worker, a no-op walk on every one after it. Startup
216
- # placement is not an option here — see `load_models` — and this is what buys the offload-free denoise loop.
217
  PIPE.to("cuda")
 
 
 
 
218
 
219
  state = PIPE(
220
  prompt_embeds=prompt_embeds.to("cuda"),
 
18
  # `lazy` moves all 72.16 GiB onto the card on the first GPU call and leaves it there; `offload` hands placement to
19
  # `ComponentsManager.enable_auto_cpu_offload` instead. Neither puts anything on the card at *startup*, which is
20
  # deliberate — see `load_models`: the 150 GB storage quota, not the 95 GiB card, is what rules that out here.
21
+ PLACEMENT = os.environ.get("H3_PLACEMENT", "pack").lower()
22
  # cuDNN's fused attention is 10-20% faster than the SDPA default on this pool and needs nothing installed.
23
  ATTENTION = os.environ.get("H3_ATTENTION", "_native_cudnn").lower()
24
  GPU_DURATION = int(os.environ.get("H3_GPU_DURATION", "900"))
 
122
 
123
  h3_aoti.maybe_load(pipe.transformer)
124
 
125
+ if PLACEMENT == "pack":
126
+ # Idiomatic ZeroGPU startup placement, scoped to the transformer only. `spaces` packs every
127
+ # startup-resident CUDA tensor into a second on-disk copy; packing all 77.3 GB (transformer + fp32
128
+ # VAEs) busts the 150 GB storage quota (77.3 + 77.3 + shards), but the 61.7 GB transformer alone
129
+ # packs to ~123 GB total and fits. The VAEs (~10 GB) take the lazy path on first GPU call, ~2 s.
130
+ # With AoTI the packed transformer pairs with the precompiled blocks: no placement, no compile,
131
+ # first request runs at steady state.
132
+ pipe.transformer.to("cuda")
133
+
134
  if PLACEMENT == "offload":
135
  manager.enable_auto_cpu_offload(device="cuda")
136
  _arm_decode_hooks(pipe)
 
198
  # gpu_seconds = A + B * steps * tokens + C * steps * tokens^2, where tokens is the packed video row count.
199
  # PLACEMENT_ALLOWANCE covers the one-time 72 GiB lazy .to("cuda") a cold worker pays inside its first call.
200
  _DUR_A, _DUR_B, _DUR_C = -6.023, 2.0877e-4, 2.1221e-9
201
+ _PLACEMENT_ALLOWANCE, _PAD = 12, 10 # pack mode: only the ~10 GB VAEs move on a cold worker
202
 
203
 
204
  def get_duration(prompt_embeds, text_token_tags, image, last_image, height, width, num_frames, steps, seed, *a, **k):
 
221
  import torch
222
 
223
  if PLACEMENT == "lazy":
224
+ # 72.16 GiB across PCIe on the first request of a worker, a no-op walk on every one after it.
 
225
  PIPE.to("cuda")
226
+ elif PLACEMENT == "pack":
227
+ # Transformer was packed at startup; only the ~10 GB of fp32 VAEs walk across on a cold worker.
228
+ PIPE.vae.to("cuda")
229
+ PIPE.audio_vae.to("cuda")
230
 
231
  state = PIPE(
232
  prompt_embeds=prompt_embeds.to("cuda"),