Spaces:
Runtime error
Runtime error
fix: load weights on CPU then move modules to cuda (ZeroGPU can't intercept safetensors device=cuda)
Browse files
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 168 |
_ledger = ModelLedger(
|
| 169 |
dtype=DTYPE,
|
| 170 |
-
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
|
| 188 |
-
|
| 189 |
-
|
|
|
|
| 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)
|