dagloop5 commited on
Commit
b31af1d
·
verified ·
1 Parent(s): c95bf71

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +33 -0
app.py CHANGED
@@ -38,6 +38,11 @@ ATTENTION = os.environ.get("H3_ATTENTION", "_native_cudnn").lower()
38
  GPU_SIZE = os.environ.get("H3_GPU_SIZE", "xlarge")
39
 
40
  LORA_REPO = os.environ.get("H3_LORA_REPO", "dagloop5/LoRA")
 
 
 
 
 
41
  # Each entry is (repo, filename) so a LoRA can come from any repo, not just LORA_REPO — the two Lightx2v files
42
  # live in lightx2v/Minimax-h3-Turbo, not dagloop5/LoRA.
43
  LORA_FILES = {
@@ -388,6 +393,34 @@ def load_models() -> str | None:
388
  blocks = MiniMaxH3GeneratorBlocks()
389
  print(f"[gen] loading {[c.name for c in blocks.expected_components]} from {MODEL_REPO} ...", flush=True)
390
  pipe = blocks.init_pipeline(MODEL_REPO, components_manager=manager, collection="h3")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
391
  pipe.load_components(dtype=torch.bfloat16)
392
  pipe.transformer.set_attention_backend(ATTENTION)
393
 
 
38
  GPU_SIZE = os.environ.get("H3_GPU_SIZE", "xlarge")
39
 
40
  LORA_REPO = os.environ.get("H3_LORA_REPO", "dagloop5/LoRA")
41
+ # A finetuned transformer, as a single monolithic safetensors file rather than MODEL_REPO's own sharded
42
+ # `transformer/` subfolder — everything else (VAE, schedulers, config) still comes from MODEL_REPO. Empty by
43
+ # default, which reproduces the official weights exactly.
44
+ CUSTOM_TRANSFORMER_REPO = os.environ.get("H3_CUSTOM_TRANSFORMER_REPO", "TenStrip/10Eros-Max")
45
+ CUSTOM_TRANSFORMER_FILE = os.environ.get("H3_CUSTOM_TRANSFORMER_FILE", "10Eros_Max_h3_TURBO-hybrid_beta3.safetensors")
46
  # Each entry is (repo, filename) so a LoRA can come from any repo, not just LORA_REPO — the two Lightx2v files
47
  # live in lightx2v/Minimax-h3-Turbo, not dagloop5/LoRA.
48
  LORA_FILES = {
 
393
  blocks = MiniMaxH3GeneratorBlocks()
394
  print(f"[gen] loading {[c.name for c in blocks.expected_components]} from {MODEL_REPO} ...", flush=True)
395
  pipe = blocks.init_pipeline(MODEL_REPO, components_manager=manager, collection="h3")
396
+
397
+ if CUSTOM_TRANSFORMER_REPO:
398
+ # `load_config` fetches only `transformer/config.json` (a few KB) — not the 61.7 GiB of weights
399
+ # `load_components` would otherwise pull from MODEL_REPO. Constructed on `torch.device("meta")` so
400
+ # the architecture exists with no real memory behind it yet, then `load_state_dict(assign=True)`
401
+ # materializes real tensors directly from the finetune's own state dict — the only real allocation
402
+ # in this path, and it happens exactly once, for the weights actually being kept.
403
+ #
404
+ # Setting `pipe.transformer` here, before `load_components()` runs, is what makes `load_components()`
405
+ # skip fetching it at all: its own `names=None` branch only loads components where
406
+ # `getattr(self, name, None) is None`.
407
+ from huggingface_hub import hf_hub_download
408
+ from safetensors.torch import load_file
409
+
410
+ from diffusers.models import MiniMaxH3Transformer3DModel
411
+
412
+ config, _ = MiniMaxH3Transformer3DModel.load_config(
413
+ MODEL_REPO, subfolder="transformer", return_unused_kwargs=True
414
+ )
415
+ with torch.device("meta"):
416
+ custom_transformer = MiniMaxH3Transformer3DModel.from_config(config)
417
+ custom_path = hf_hub_download(CUSTOM_TRANSFORMER_REPO, CUSTOM_TRANSFORMER_FILE)
418
+ # `strict=True`: a finetune with a genuinely different key set is a real architecture mismatch, not
419
+ # something to load partially and hope for the best on.
420
+ custom_transformer.load_state_dict(load_file(custom_path), strict=True, assign=True)
421
+ pipe.update_components(transformer=custom_transformer)
422
+ print(f"[gen] transformer replaced with {CUSTOM_TRANSFORMER_REPO}/{CUSTOM_TRANSFORMER_FILE}", flush=True)
423
+
424
  pipe.load_components(dtype=torch.bfloat16)
425
  pipe.transformer.set_attention_backend(ATTENTION)
426