multimodalart HF Staff commited on
Commit
ee44f2f
·
verified ·
1 Parent(s): e7c52db

fix: load weights on CPU then move modules to cuda (ZeroGPU can't intercept safetensors device=cuda)

Browse files
Files changed (1) hide show
  1. app.py +32 -11
app.py CHANGED
@@ -163,41 +163,62 @@ from ltx_distillation.utils import ( # noqa: E402
163
  from ltx_pipelines.utils.model_ledger import ModelLedger # noqa: E402
164
 
165
  DEVICE = torch.device("cuda")
166
-
167
- logger.info("Building model ledger …")
 
 
 
 
 
 
 
 
 
 
 
168
  _ledger = ModelLedger(
169
  dtype=DTYPE,
170
- device=DEVICE,
171
  checkpoint_path=CHECKPOINT_PATH,
172
  gemma_root_path=GEMMA_ROOT,
173
  quantization=QuantizationPolicy.fp8_cast(), # transformer only
174
  )
175
 
176
  logger.info("Loading audio-video DiT (fp8 cast) …")
177
- _transformer = _ledger.transformer()
 
 
 
 
 
178
  logger.info("Loading video VAE …")
179
  _video_vae = VideoVAEWrapper(
180
- encoder=_ledger.video_encoder(),
181
- decoder=_ledger.video_decoder(),
182
  device=DEVICE,
183
  dtype=DTYPE,
184
  ).eval()
 
185
  logger.info("Loading audio VAE + vocoder …")
186
  _audio_vae = AudioVAEWrapper(
187
- encoder=_ledger.audio_encoder(),
188
- decoder=_ledger.audio_decoder(),
189
- vocoder=_ledger.vocoder(),
 
190
  device=DEVICE,
191
  dtype=DTYPE,
192
  ).eval()
193
  AUDIO_SR = _audio_vae.get_output_sample_rate() or 24000
 
194
  logger.info("Loading Gemma-3-12B text encoder + embeddings processor …")
195
  _text_encoder = GemmaTextEncoderWrapper(
196
- text_encoder=_ledger.text_encoder(),
197
- embeddings_processor=_ledger.gemma_embeddings_processor(),
198
  device=DEVICE,
199
  dtype=DTYPE,
200
  ).eval()
 
 
201
  logger.info("All models resident. audio_sample_rate=%d", AUDIO_SR)
202
 
203
  _SIGMAS_CPU = torch.tensor(DENOISING_SIGMAS, dtype=torch.float32)
 
163
  from ltx_pipelines.utils.model_ledger import ModelLedger # noqa: E402
164
 
165
  DEVICE = torch.device("cuda")
166
+ CPU = torch.device("cpu")
167
+
168
+ # The ledger is built on CPU and every module is moved to "cuda" afterwards.
169
+ # That is the authors' own pattern — `create_ltx2_wrapper` / `create_vae_wrappers`
170
+ # / `create_text_encoder_wrapper` all construct a `device=torch.device("cpu")`
171
+ # ledger and then `.to(device)`, because `ModelLedger._target_device()` is handed
172
+ # straight to `safetensors.safe_open(..., device=...)`. Loading weights inside
173
+ # safetensors bypasses ZeroGPU's `torch.cuda` interception, so asking it for
174
+ # "cuda" in the main process dies with "No CUDA GPUs are available". Moving the
175
+ # assembled `nn.Module`s instead goes through the hijacked `Module.to`, which is
176
+ # exactly what ZeroGPU wants: weights get packed and streamed into VRAM on the
177
+ # first `@spaces.GPU` call.
178
+ logger.info("Building model ledger (weights load on CPU, then move to cuda) …")
179
  _ledger = ModelLedger(
180
  dtype=DTYPE,
181
+ device=CPU,
182
  checkpoint_path=CHECKPOINT_PATH,
183
  gemma_root_path=GEMMA_ROOT,
184
  quantization=QuantizationPolicy.fp8_cast(), # transformer only
185
  )
186
 
187
  logger.info("Loading audio-video DiT (fp8 cast) …")
188
+ # NOTE: no `dtype=` here, unlike the authors' unquantized `create_ltx2_wrapper`.
189
+ # `QuantizationPolicy.fp8_cast()` has already stored the transformer-block linear
190
+ # weights as float8_e4m3fn; passing dtype=bfloat16 would upcast them straight back
191
+ # and undo the memory saving that lets this model fit at all.
192
+ _transformer = _ledger.transformer().to(device=DEVICE)
193
+
194
  logger.info("Loading video VAE …")
195
  _video_vae = VideoVAEWrapper(
196
+ encoder=_ledger.video_encoder().to(device=DEVICE, dtype=DTYPE),
197
+ decoder=_ledger.video_decoder().to(device=DEVICE, dtype=DTYPE),
198
  device=DEVICE,
199
  dtype=DTYPE,
200
  ).eval()
201
+
202
  logger.info("Loading audio VAE + vocoder …")
203
  _audio_vae = AudioVAEWrapper(
204
+ # float32 for the audio encoder, matching `create_vae_wrappers`.
205
+ encoder=_ledger.audio_encoder().to(device=DEVICE, dtype=torch.float32),
206
+ decoder=_ledger.audio_decoder().to(device=DEVICE, dtype=DTYPE),
207
+ vocoder=_ledger.vocoder().to(device=DEVICE, dtype=DTYPE),
208
  device=DEVICE,
209
  dtype=DTYPE,
210
  ).eval()
211
  AUDIO_SR = _audio_vae.get_output_sample_rate() or 24000
212
+
213
  logger.info("Loading Gemma-3-12B text encoder + embeddings processor …")
214
  _text_encoder = GemmaTextEncoderWrapper(
215
+ text_encoder=_ledger.text_encoder().to(device=DEVICE, dtype=DTYPE),
216
+ embeddings_processor=_ledger.gemma_embeddings_processor().to(device=DEVICE, dtype=DTYPE),
217
  device=DEVICE,
218
  dtype=DTYPE,
219
  ).eval()
220
+
221
+ gc.collect()
222
  logger.info("All models resident. audio_sample_rate=%d", AUDIO_SR)
223
 
224
  _SIGMAS_CPU = torch.tensor(DENOISING_SIGMAS, dtype=torch.float32)