wyh6666 commited on
Commit
be94509
·
verified ·
1 Parent(s): 43aa5dc

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +123 -3
README.md CHANGED
@@ -1,3 +1,123 @@
1
- ---
2
- license: apache-2.0
3
- ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ ---
4
+
5
+ # Qwen-Image-Edit LoRA Adapter
6
+
7
+ This repository contains LoRA weights for **Qwen-Image-Edit**, fine-tuned for instruction-based image editing tasks.
8
+
9
+ ## Model Details
10
+ - **Base Model:** [Qwen-Image-Edit-2509](https://huggingface.co/Qwen/Qwen-Image-Edit-2509) (or your specific base model)
11
+ - **Training:** Fine-tuned using PEFT/LoRA.
12
+
13
+ ## Usage
14
+
15
+ To use this LoRA, you need to load the base `QwenImageEditPlusPipeline` and apply the adapter weights.
16
+
17
+ Since the LoRA keys trained via PEFT often differ from what Diffusers expects, the script below includes an **automatic conversion step** to ensure the weights load correctly.
18
+
19
+ ### Python Inference Script
20
+
21
+ You can run this script to edit a single image.
22
+
23
+ ```python
24
+ import os
25
+ import torch
26
+ from PIL import Image
27
+ from diffusers import QwenImageEditPlusPipeline
28
+ from safetensors.torch import load_file, save_file
29
+
30
+ def load_lora_with_conversion(pipeline, lora_folder_path, weight_name="adapter_model.safetensors"):
31
+ """
32
+ Automatically converts PEFT LoRA keys to Diffusers format if needed and loads them.
33
+ """
34
+ # Define paths
35
+ original_weights_path = os.path.join(lora_folder_path, weight_name)
36
+ converted_weights_path = os.path.join(lora_folder_path, "adapter_model_converted.safetensors")
37
+
38
+ # Check if conversion is needed
39
+ if not os.path.exists(converted_weights_path):
40
+ print(f"⚠️ Converted weights not found. Converting {original_weights_path}...")
41
+
42
+ if not os.path.exists(original_weights_path):
43
+ raise FileNotFoundError(f"Cannot find LoRA weights at {original_weights_path}")
44
+
45
+ state_dict = load_file(original_weights_path)
46
+ new_state_dict = {}
47
+
48
+ # Conversion logic: replace 'base_model.model' with 'transformer'
49
+ for key, value in state_dict.items():
50
+ new_key = key.replace("base_model.model", "transformer")
51
+ new_state_dict[new_key] = value
52
+
53
+ save_file(new_state_dict, converted_weights_path)
54
+ print(f"✅ Conversion saved to {converted_weights_path}")
55
+ else:
56
+ print(f"✅ Found converted weights at {converted_weights_path}")
57
+
58
+ # Load the converted LoRA
59
+ pipeline.load_lora_weights(
60
+ lora_folder_path,
61
+ weight_name="adapter_model_converted.safetensors",
62
+ adapter_name="lora",
63
+ )
64
+ pipeline.set_adapters(["lora"], adapter_weights=[1.0])
65
+ print("🚀 LoRA loaded and active.")
66
+
67
+ def main():
68
+ # --- Configuration ---
69
+ # 1. Path to the base model (Local path or HuggingFace ID)
70
+ base_model_path = "Qwen/Qwen-Image-Edit-2509" # Replace with your local path if needed
71
+
72
+ # 2. Path to THIS LoRA folder (where you downloaded this repo)
73
+ lora_path = "./" # Current directory if you cloned the repo
74
+
75
+ # 3. Input Image and Prompt
76
+ image_path = "test_image.jpg" # Replace with your image path
77
+ prompt = "remove the dog and replace it with a cat"
78
+ output_path = "result.png"
79
+ # ---------------------
80
+
81
+ # Load Pipeline
82
+ print(f"Loading base model from: {base_model_path}")
83
+ pipeline = QwenImageEditPlusPipeline.from_pretrained(
84
+ base_model_path,
85
+ torch_dtype=torch.bfloat16
86
+ )
87
+ pipeline.to("cuda")
88
+
89
+ # Load LoRA
90
+ try:
91
+ load_lora_with_conversion(pipeline, lora_path)
92
+ except Exception as e:
93
+ print(f"Error loading LoRA: {e}")
94
+ return
95
+
96
+ # Load Image
97
+ if not os.path.exists(image_path):
98
+ print(f"Error: Image not found at {image_path}")
99
+ return
100
+
101
+ original_image = Image.open(image_path).convert("RGB")
102
+
103
+ # Inference
104
+ print("🎨 Generating edit...")
105
+ inputs = {
106
+ "image": original_image,
107
+ "prompt": prompt,
108
+ "generator": torch.manual_seed(42), # Fixed seed for reproducibility
109
+ "true_cfg_scale": 4.0, # Recommended for Qwen-Edit
110
+ "guidance_scale": 1.0,
111
+ "negative_prompt": " ",
112
+ "num_inference_steps": 40,
113
+ }
114
+
115
+ with torch.inference_mode():
116
+ output = pipeline(**inputs)
117
+ output_image = output.images[0]
118
+ output_image.save(output_path)
119
+ print(f"✅ Image saved to {output_path}")
120
+
121
+ if __name__ == "__main__":
122
+ main()
123
+