signsur4739379373 commited on
Commit
06a6fb0
·
verified ·
1 Parent(s): 8670264

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -40
app.py CHANGED
@@ -259,57 +259,62 @@ v21_path = hf_hub_download(
259
  filename="v21/Qwen-Rapid-AIO-NSFW-v21.safetensors",
260
  repo_type="model"
261
  )
262
- print(f"file ready at: {v21_path}")
263
 
264
- # 2. load the base architecture from the official qwen repo
265
- # we need this to create the skeleton of the model
 
266
  print("loading base pipeline architecture...")
267
  pipe = QwenImageEditPlusPipeline.from_pretrained(
268
  "Qwen/Qwen-Image-Edit-2511",
269
- scheduler=EulerAncestralDiscreteScheduler.from_pretrained(
270
- "Qwen/Qwen-Image-Edit-2511",
271
- subfolder="scheduler"
272
- ),
273
  torch_dtype=torch.bfloat16
274
  ).to("cuda")
275
 
276
- # 3. load the v21 weights
277
- print("loading v21 weights into memory...")
 
 
 
 
278
  state_dict = load_file(v21_path)
279
 
280
- # 4. filter and inject weights
281
- # the AIO file is a "frankenstein" merge of unet, vae, and text encoder.
282
- # we need to map the keys correctly. comfyui keys usually differ from diffusers keys.
283
-
284
- # we attempt to load the diffusion model (transformer) first as it's the most critical
285
- print("grafting weights onto the pipeline...")
286
- try:
287
- # try loading into the transformer/unet component
288
- # most comfyui merges for this model flatten the keys.
289
- # we use strict=False to ignore VAE/CLIP keys that might be in the file but belong elsewhere
290
- if hasattr(pipe, "transformer"):
291
- # standard 2511 naming
292
- incompatible = pipe.transformer.load_state_dict(state_dict, strict=False)
293
- elif hasattr(pipe, "unet"):
294
- # older 2509 naming
295
- incompatible = pipe.unet.load_state_dict(state_dict, strict=False)
 
 
296
  else:
297
- # absolute fallback: try to load to the root modules
298
- # this iterates through the pipe and tries to match keys to submodules
299
- for name, module in pipe.named_children():
300
- if "model" in name or "transformer" in name or "unet" in name:
301
- print(f"attempting load into: {name}")
302
- module.load_state_dict(state_dict, strict=False)
303
-
304
- print("success. v21 weights are active.")
305
-
306
- except Exception as e:
307
- print(f"major error during weight loading: {e}")
308
- print("attempting root load (desperation mode)...")
309
- pipe.load_state_dict(state_dict, strict=False)
310
-
311
- # 5. cleanup and optimize
 
312
  del state_dict
 
 
313
  gc.collect()
314
  torch.cuda.empty_cache()
315
 
 
259
  filename="v21/Qwen-Rapid-AIO-NSFW-v21.safetensors",
260
  repo_type="model"
261
  )
 
262
 
263
+ # 2. load the base architecture
264
+ # we use the default flowmatch scheduler first to ensure the pipe inits correctly,
265
+ # then we swap it to euler_a later
266
  print("loading base pipeline architecture...")
267
  pipe = QwenImageEditPlusPipeline.from_pretrained(
268
  "Qwen/Qwen-Image-Edit-2511",
 
 
 
 
269
  torch_dtype=torch.bfloat16
270
  ).to("cuda")
271
 
272
+ # 3. switch scheduler to Euler Ancestral (Lightning requirement)
273
+ # we configure it with the base config to keep timestep spacing correct
274
+ pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
275
+
276
+ # 4. load the massive 28GB v21 weights
277
+ print(f"loading v21 weights from {v21_path}...")
278
  state_dict = load_file(v21_path)
279
 
280
+ # 5. The "Brutal" Injection
281
+ # Because this is an AIO file, keys might be prefixed with "model." or "transformer."
282
+ # or they might match the pipeline exactly. We try the root load first.
283
+ print("injecting AIO weights...")
284
+
285
+ # clean up keys if necessary (common in comfyui > diffusers conversions)
286
+ # this removes 'model.diffusion_model.' prefixes if they exist to match diffusers 'transformer.'
287
+ new_state_dict = {}
288
+ for k, v in state_dict.items():
289
+ if k.startswith("model.diffusion_model."):
290
+ new_key = k.replace("model.diffusion_model.", "transformer.")
291
+ new_state_dict[new_key] = v
292
+ elif k.startswith("first_stage_model."):
293
+ new_key = k.replace("first_stage_model.", "vae.")
294
+ new_state_dict[new_key] = v
295
+ elif k.startswith("conditioner.embedders.0."):
296
+ new_key = k.replace("conditioner.embedders.0.", "text_encoder.")
297
+ new_state_dict[new_key] = v
298
  else:
299
+ new_state_dict[k] = v
300
+
301
+ # if no keys were renamed, just use the original
302
+ if len(new_state_dict) == len(state_dict):
303
+ final_dict = state_dict
304
+ else:
305
+ print("detected comfyui keys, remapped for diffusers.")
306
+ final_dict = new_state_dict
307
+
308
+ # attempt load
309
+ mismatched = pipe.load_state_dict(final_dict, strict=False)
310
+ print("weights loaded.")
311
+ print(f"missing keys (ignore if just config/aux): {len(mismatched.missing_keys)}")
312
+ print(f"unexpected keys (ignore if comfy artifacts): {len(mismatched.unexpected_keys)}")
313
+
314
+ # 6. cleanup
315
  del state_dict
316
+ del new_state_dict
317
+ del final_dict
318
  gc.collect()
319
  torch.cuda.empty_cache()
320