Update app.py
This commit is contained in:
77
app.py
77
app.py
@@ -259,57 +259,62 @@ v21_path = hf_hub_download(
|
|||||||
filename="v21/Qwen-Rapid-AIO-NSFW-v21.safetensors",
|
filename="v21/Qwen-Rapid-AIO-NSFW-v21.safetensors",
|
||||||
repo_type="model"
|
repo_type="model"
|
||||||
)
|
)
|
||||||
print(f"file ready at: {v21_path}")
|
|
||||||
|
|
||||||
# 2. load the base architecture from the official qwen repo
|
# 2. load the base architecture
|
||||||
# we need this to create the skeleton of the model
|
# we use the default flowmatch scheduler first to ensure the pipe inits correctly,
|
||||||
|
# then we swap it to euler_a later
|
||||||
print("loading base pipeline architecture...")
|
print("loading base pipeline architecture...")
|
||||||
pipe = QwenImageEditPlusPipeline.from_pretrained(
|
pipe = QwenImageEditPlusPipeline.from_pretrained(
|
||||||
"Qwen/Qwen-Image-Edit-2511",
|
"Qwen/Qwen-Image-Edit-2511",
|
||||||
scheduler=EulerAncestralDiscreteScheduler.from_pretrained(
|
|
||||||
"Qwen/Qwen-Image-Edit-2511",
|
|
||||||
subfolder="scheduler"
|
|
||||||
),
|
|
||||||
torch_dtype=torch.bfloat16
|
torch_dtype=torch.bfloat16
|
||||||
).to("cuda")
|
).to("cuda")
|
||||||
|
|
||||||
# 3. load the v21 weights
|
# 3. switch scheduler to Euler Ancestral (Lightning requirement)
|
||||||
print("loading v21 weights into memory...")
|
# we configure it with the base config to keep timestep spacing correct
|
||||||
|
pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
|
||||||
|
|
||||||
|
# 4. load the massive 28GB v21 weights
|
||||||
|
print(f"loading v21 weights from {v21_path}...")
|
||||||
state_dict = load_file(v21_path)
|
state_dict = load_file(v21_path)
|
||||||
|
|
||||||
# 4. filter and inject weights
|
# 5. The "Brutal" Injection
|
||||||
# the AIO file is a "frankenstein" merge of unet, vae, and text encoder.
|
# Because this is an AIO file, keys might be prefixed with "model." or "transformer."
|
||||||
# we need to map the keys correctly. comfyui keys usually differ from diffusers keys.
|
# or they might match the pipeline exactly. We try the root load first.
|
||||||
|
print("injecting AIO weights...")
|
||||||
|
|
||||||
# we attempt to load the diffusion model (transformer) first as it's the most critical
|
# clean up keys if necessary (common in comfyui > diffusers conversions)
|
||||||
print("grafting weights onto the pipeline...")
|
# this removes 'model.diffusion_model.' prefixes if they exist to match diffusers 'transformer.'
|
||||||
try:
|
new_state_dict = {}
|
||||||
# try loading into the transformer/unet component
|
for k, v in state_dict.items():
|
||||||
# most comfyui merges for this model flatten the keys.
|
if k.startswith("model.diffusion_model."):
|
||||||
# we use strict=False to ignore VAE/CLIP keys that might be in the file but belong elsewhere
|
new_key = k.replace("model.diffusion_model.", "transformer.")
|
||||||
if hasattr(pipe, "transformer"):
|
new_state_dict[new_key] = v
|
||||||
# standard 2511 naming
|
elif k.startswith("first_stage_model."):
|
||||||
incompatible = pipe.transformer.load_state_dict(state_dict, strict=False)
|
new_key = k.replace("first_stage_model.", "vae.")
|
||||||
elif hasattr(pipe, "unet"):
|
new_state_dict[new_key] = v
|
||||||
# older 2509 naming
|
elif k.startswith("conditioner.embedders.0."):
|
||||||
incompatible = pipe.unet.load_state_dict(state_dict, strict=False)
|
new_key = k.replace("conditioner.embedders.0.", "text_encoder.")
|
||||||
|
new_state_dict[new_key] = v
|
||||||
else:
|
else:
|
||||||
# absolute fallback: try to load to the root modules
|
new_state_dict[k] = v
|
||||||
# this iterates through the pipe and tries to match keys to submodules
|
|
||||||
for name, module in pipe.named_children():
|
|
||||||
if "model" in name or "transformer" in name or "unet" in name:
|
|
||||||
print(f"attempting load into: {name}")
|
|
||||||
module.load_state_dict(state_dict, strict=False)
|
|
||||||
|
|
||||||
print("success. v21 weights are active.")
|
# if no keys were renamed, just use the original
|
||||||
|
if len(new_state_dict) == len(state_dict):
|
||||||
|
final_dict = state_dict
|
||||||
|
else:
|
||||||
|
print("detected comfyui keys, remapped for diffusers.")
|
||||||
|
final_dict = new_state_dict
|
||||||
|
|
||||||
except Exception as e:
|
# attempt load
|
||||||
print(f"major error during weight loading: {e}")
|
mismatched = pipe.load_state_dict(final_dict, strict=False)
|
||||||
print("attempting root load (desperation mode)...")
|
print("weights loaded.")
|
||||||
pipe.load_state_dict(state_dict, strict=False)
|
print(f"missing keys (ignore if just config/aux): {len(mismatched.missing_keys)}")
|
||||||
|
print(f"unexpected keys (ignore if comfy artifacts): {len(mismatched.unexpected_keys)}")
|
||||||
|
|
||||||
# 5. cleanup and optimize
|
# 6. cleanup
|
||||||
del state_dict
|
del state_dict
|
||||||
|
del new_state_dict
|
||||||
|
del final_dict
|
||||||
gc.collect()
|
gc.collect()
|
||||||
torch.cuda.empty_cache()
|
torch.cuda.empty_cache()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user