Download app.py from dosesnrolls1/Qwen-Image-Edit-2511-LoRAs-Fast: direct link, hf CLI and curl.
- Browser
- Download file 5.43 kB
-
https://huggingface.co/spaces/dosesnrolls1/Qwen-Image-Edit-2511-LoRAs-Fast/resolve/73d18aee1e700b7affb5d59449f25ce89106a1ba/app.py
- Command line
-
hf download hf://spaces/dosesnrolls1/Qwen-Image-Edit-2511-LoRAs-Fast@73d18aee1e700b7affb5d59449f25ce89106a1ba/app.py
-
curl -L -o app.py https://huggingface.co/spaces/dosesnrolls1/Qwen-Image-Edit-2511-LoRAs-Fast/resolve/73d18aee1e700b7affb5d59449f25ce89106a1ba/app.py
5.43 kB
| import os | |
| import spaces | |
| import gc | |
| import shutil | |
| import gradio as gr | |
| import torch | |
| import safetensors.torch | |
| from huggingface_hub import hf_hub_download, HfApi, login | |
| from accelerate import init_empty_weights | |
| # --- Imports from your local modules --- | |
| # Ensure the folder 'qwenimage' is present in the root directory | |
| from qwenimage.transformer_qwenimage import QwenImageTransformer2DModel | |
| # Configuration for the specific Qwen Transformer | |
| TRANSFORMER_CONFIG = { | |
| "attention_head_dim": 128, | |
| "axes_dims_rope": [16, 56, 56], | |
| "guidance_embeds": False, | |
| "in_channels": 64, | |
| "joint_attention_dim": 3584, | |
| "num_attention_heads": 24, | |
| "num_layers": 60, | |
| "out_channels": 16, | |
| "patch_size": 2 | |
| } | |
| def convert_and_upload(hf_token, target_repo_id, private_repo): | |
| """ | |
| Downloads raw weights, converts keys, saves locally, and uploads to HF. | |
| """ | |
| local_dir = "converted_qwen_transformer" | |
| source_repo = "Phr00t/Qwen-Image-Edit-Rapid-AIO" | |
| source_filename = "v19/Qwen-Rapid-AIO-NSFW-v19.safetensors" | |
| yield f"π Starting process...\nAuthenticating with Hugging Face..." | |
| if not hf_token: | |
| raise gr.Error("Please provide a Write-enabled Hugging Face Token.") | |
| try: | |
| login(token=hf_token) | |
| api = HfApi(token=hf_token) | |
| except Exception as e: | |
| raise gr.Error(f"Authentication failed: {e}") | |
| # 1. Download | |
| yield f"π₯ Downloading {source_filename} from {source_repo}..." | |
| try: | |
| checkpoint_path = hf_hub_download(repo_id=source_repo, filename=source_filename) | |
| except Exception as e: | |
| raise gr.Error(f"Download failed: {e}") | |
| # 2. Initialize Empty Model | |
| yield "ποΈ Initializing empty model architecture..." | |
| with init_empty_weights(): | |
| model = QwenImageTransformer2DModel(**TRANSFORMER_CONFIG) | |
| # 3. Load and Filter Keys | |
| yield "π Loading state dict and filtering keys (removing 'model.diffusion_model.')..." | |
| try: | |
| state_dict = safetensors.torch.load_file(checkpoint_path, device="cpu") | |
| new_state_dict = {} | |
| prefix = "model.diffusion_model." | |
| ignored_keys = ["__index_timestep_zero__", "iteration", "global_step"] | |
| for key, value in state_dict.items(): | |
| if key in ignored_keys: | |
| continue | |
| if key.startswith(prefix): | |
| new_key = key[len(prefix):] | |
| new_state_dict[new_key] = value | |
| del state_dict | |
| gc.collect() | |
| except Exception as e: | |
| raise gr.Error(f"Error processing keys: {e}") | |
| # 4. Load Weights into Model | |
| yield "βοΈ Loading weights into the model object..." | |
| try: | |
| # assign=True is needed for accelerate's init_empty_weights | |
| model.load_state_dict(new_state_dict, assign=True, strict=False) | |
| del new_state_dict | |
| gc.collect() | |
| except Exception as e: | |
| raise gr.Error(f"Error loading weights into model: {e}") | |
| # 5. Save Locally | |
| if os.path.exists(local_dir): | |
| shutil.rmtree(local_dir) | |
| os.makedirs(local_dir, exist_ok=True) | |
| yield f"πΎ Saving converted model to local directory: {local_dir}..." | |
| try: | |
| # This saves both config.json and diffusion_pytorch_model.safetensors | |
| model.save_pretrained(local_dir, safe_serialization=True) | |
| except Exception as e: | |
| raise gr.Error(f"Error saving local model: {e}") | |
| # 6. Upload to Hugging Face | |
| yield f"βοΈ Uploading to Hugging Face Repo: {target_repo_id}..." | |
| try: | |
| # Create repo if it doesn't exist | |
| api.create_repo(repo_id=target_repo_id, private=private_repo, exist_ok=True) | |
| api.upload_folder( | |
| folder_path=local_dir, | |
| repo_id=target_repo_id, | |
| commit_message="Upload converted Qwen-Image-Edit Transformer" | |
| ) | |
| except Exception as e: | |
| raise gr.Error(f"Upload failed: {e}") | |
| # Cleanup | |
| shutil.rmtree(local_dir) | |
| gc.collect() | |
| yield f"β Success! Model uploaded to https://huggingface.co/{target_repo_id}" | |
| # --- Gradio UI --- | |
| css = """ | |
| #col-container { max_width: 700px; margin: 0 auto; } | |
| """ | |
| with gr.Blocks() as demo: | |
| with gr.Column(elem_id="col-container"): | |
| gr.Markdown("# π Qwen Transformer Converter & Uploader") | |
| gr.Markdown( | |
| "This tool downloads the raw checkpoints for `Qwen-Image-Edit`, extracts the transformer, " | |
| "fixes the key names, and uploads the clean `diffusers`-ready model to your Hugging Face account." | |
| ) | |
| with gr.Group(): | |
| hf_token = gr.Textbox( | |
| label="Hugging Face Token (Write Access)", | |
| placeholder="hf_...", | |
| type="password" | |
| ) | |
| target_repo = gr.Textbox( | |
| label="Target Repository ID", | |
| placeholder="username/my-converted-qwen-transformer" | |
| ) | |
| is_private = gr.Checkbox(label="Make Repo Private", value=True) | |
| convert_btn = gr.Button("Convert & Upload", variant="primary") | |
| status_output = gr.Textbox(label="Status Log", interactive=False, lines=6) | |
| convert_btn.click( | |
| fn=convert_and_upload, | |
| inputs=[hf_token, target_repo, is_private], | |
| outputs=[status_output] | |
| ) | |
| if __name__ == "__main__": | |
| demo.queue().launch(theme=gr.themes.Soft(), css=css) |