multimodalart HF Staff commited on
Commit
afa40de
·
verified ·
1 Parent(s): 42b1a75

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +46 -4
app.py CHANGED
@@ -8,6 +8,7 @@ import gradio as gr
8
  import random
9
  import numpy as np
10
  from diffusers import DiffusionPipeline, AutoencoderTiny, AutoencoderKL
 
11
 
12
  dtype = torch.bfloat16
13
  device = "cuda"
@@ -21,15 +22,56 @@ good_vae = AutoencoderKL.from_pretrained(
21
  # Load base FLUX.1-dev with tiny VAE
22
  BASE_MODEL = "black-forest-labs/FLUX.1-dev"
23
  CMO_LORA = "Bruece/FLUX.1-dev-CMO"
 
 
 
24
 
25
  pipe = DiffusionPipeline.from_pretrained(
26
  BASE_MODEL, torch_dtype=dtype, vae=taef1
27
  ).to(device)
28
 
29
- # Load the CMO LoRA adapter using diffusers' built-in loader (ZeroGPU-safe)
30
- pipe.load_lora_weights(CMO_LORA)
31
- pipe.fuse_lora()
32
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  torch.cuda.empty_cache()
34
 
35
  MAX_SEED = np.iinfo(np.int32).max
 
8
  import random
9
  import numpy as np
10
  from diffusers import DiffusionPipeline, AutoencoderTiny, AutoencoderKL
11
+ from huggingface_hub import hf_hub_download
12
 
13
  dtype = torch.bfloat16
14
  device = "cuda"
 
22
  # Load base FLUX.1-dev with tiny VAE
23
  BASE_MODEL = "black-forest-labs/FLUX.1-dev"
24
  CMO_LORA = "Bruece/FLUX.1-dev-CMO"
25
+ LORA_ALPHA = 128
26
+ LORA_R = 64
27
+ LORA_SCALE = LORA_ALPHA / LORA_R # = 2.0
28
 
29
  pipe = DiffusionPipeline.from_pretrained(
30
  BASE_MODEL, torch_dtype=dtype, vae=taef1
31
  ).to(device)
32
 
33
+ # Manually load and merge the CMO LoRA adapter weights.
34
+ # Use safetensors.safe_open (numpy backend, no torch) to avoid ZeroGPU's
35
+ # torch patching which fails at module scope (no CUDA available yet).
36
+ from safetensors import safe_open
37
+
38
+ _lora_path = hf_hub_download(CMO_LORA, "adapter_model.safetensors", repo_type="model")
39
+
40
+ # Load all LoRA weights as numpy arrays first, then merge into the transformer
41
+ _lora_a_pairs = {} # module_path -> A weight (numpy)
42
+ _lora_b_pairs = {} # module_path -> B weight (numpy)
43
+
44
+ with safe_open(_lora_path, framework="numpy", device="cpu") as _f:
45
+ for _key in _f.keys():
46
+ if not _key.startswith("base_model.model."):
47
+ continue
48
+ _rest = _key[len("base_model.model."):]
49
+ if _rest.endswith(".lora_A.weight"):
50
+ _module_path = _rest[: -len(".lora_A.weight")]
51
+ _lora_a_pairs[_module_path] = _f.get_tensor(_key)
52
+ elif _rest.endswith(".lora_B.weight"):
53
+ _module_path = _rest[: -len(".lora_B.weight")]
54
+ _lora_b_pairs[_module_path] = _f.get_tensor(_key)
55
+
56
+ # Merge LoRA weights into the transformer: w_new = w_orig + scale * (B @ A)
57
+ _merge_count = 0
58
+ for _module_path, _a_np in _lora_a_pairs.items():
59
+ if _module_path not in _lora_b_pairs:
60
+ continue
61
+ _b_np = _lora_b_pairs[_module_path]
62
+ # Navigate to the module in the transformer
63
+ _module = pipe.transformer
64
+ for _part in _module_path.split("."):
65
+ _module = getattr(_module, _part)
66
+ # Merge: w_orig + scale * (B @ A)
67
+ _a_tensor = torch.from_numpy(_a_np)
68
+ _b_tensor = torch.from_numpy(_b_np)
69
+ _delta = (_b_tensor.float() @ _a_tensor.float()) * LORA_SCALE
70
+ _module.weight.data.add_(_delta.to(_module.weight.data.dtype))
71
+ _merge_count += 1
72
+
73
+ print(f"CMO LoRA: merged {_merge_count} adapter pairs into FLUX.1-dev transformer")
74
+ del _lora_a_pairs, _lora_b_pairs
75
  torch.cuda.empty_cache()
76
 
77
  MAX_SEED = np.iinfo(np.int32).max