Spaces:
Running
on
Zero
Running
on
Zero
temp: remove all LoRAs except 1 for testing
Browse files- MULTI_LORA_DOCUMENTATION.md +65 -91
- app.py +8 -32
MULTI_LORA_DOCUMENTATION.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
| 1 |
-
# Multi-LoRA Image Editing Implementation
|
| 2 |
|
| 3 |
## Overview
|
| 4 |
|
| 5 |
-
This implementation provides a
|
| 6 |
|
| 7 |
## Architecture
|
| 8 |
|
|
@@ -17,12 +17,12 @@ This implementation provides a comprehensive multi-LoRA (Low-Rank Adaptation) sy
|
|
| 17 |
2. **LoRA Configuration** (`app.py`)
|
| 18 |
- Centralized `LORA_CONFIG` dictionary
|
| 19 |
- Lightning LoRA configured as always-loaded base
|
| 20 |
-
-
|
| 21 |
|
| 22 |
3. **Dynamic UI System** (`app.py`)
|
| 23 |
- Conditional component visibility based on LoRA selection
|
| 24 |
- Lightning LoRA status indication
|
| 25 |
-
- Type-specific UI adaptations (
|
| 26 |
- Real-time interface updates
|
| 27 |
|
| 28 |
## ⚡ Lightning LoRA Always-On Architecture
|
|
@@ -33,7 +33,7 @@ This implementation provides a comprehensive multi-LoRA (Low-Rank Adaptation) sy
|
|
| 33 |
|
| 34 |
- **Consistent Performance**: Always-on 4-step generation
|
| 35 |
- **Enhanced Speed**: Lightning's optimization applies to all operations
|
| 36 |
-
- **Multi-LoRA Fusion**: Combine Lightning speed with
|
| 37 |
|
| 38 |
### Implementation Details
|
| 39 |
|
|
@@ -66,7 +66,7 @@ lora_manager.fuse_lora(LIGHTNING_LORA_NAME)
|
|
| 66 |
def load_and_fuse_additional_lora(lora_name):
|
| 67 |
"""
|
| 68 |
Load an additional LoRA while keeping Lightning LoRA always active.
|
| 69 |
-
This enables combining Lightning's speed with
|
| 70 |
"""
|
| 71 |
# Always keep Lightning LoRA loaded
|
| 72 |
# Load additional LoRA without resetting to base state
|
|
@@ -103,33 +103,25 @@ def infer(lora_name, ...):
|
|
| 103 |
pipe.disable_adapters() # Disable additional LoRA but keep Lightning
|
| 104 |
```
|
| 105 |
|
| 106 |
-
## LoRA
|
| 107 |
|
| 108 |
-
### Supported
|
| 109 |
|
| 110 |
| LoRA Name | Type | Method | Always-On | Description |
|
| 111 |
|-----------|------|--------|-----------|-------------|
|
| 112 |
| **⚡ Lightning (4-Step)** | base | standard | ✅ **Always** | Fast 4-step generation - always active |
|
| 113 |
-
| **None** | edit | none | ❌ | Base model
|
| 114 |
-
| **
|
| 115 |
-
| **InScene (In-Scene Editing)** | edit | standard | ⚡ Lightning+ | Object positioning and perspective changes |
|
| 116 |
-
| **Face Segmentation** | edit | standard | ⚡ Lightning+ | Transform facial images to segmentation masks |
|
| 117 |
-
| **Object Remover** | edit | standard | ⚡ Lightning+ | Remove objects while maintaining background |
|
| 118 |
|
| 119 |
-
### Lightning +
|
| 120 |
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
- **Lightning + Style Transfer**: Fast style application with 4-step generation
|
| 124 |
-
- **Lightning + Object Removal**: Quick object removal with optimized inference
|
| 125 |
-
- **Lightning + Face Segmentation**: Rapid segmentation with enhanced speed
|
| 126 |
-
- **Lightning + In-Scene Editing**: Fast scene modifications with 4-step process
|
| 127 |
|
| 128 |
### LoRA Type Classifications
|
| 129 |
|
| 130 |
- **Base LoRA**: Lightning (always loaded, always active)
|
| 131 |
-
- **
|
| 132 |
-
- **
|
| 133 |
|
| 134 |
## Key Features
|
| 135 |
|
|
@@ -169,18 +161,16 @@ def on_lora_change(lora_name):
|
|
| 169 |
}
|
| 170 |
```
|
| 171 |
|
| 172 |
-
### 3. Multi-LoRA Fusion
|
| 173 |
|
| 174 |
- **Lightning Base**: Always loaded, always active
|
| 175 |
-
- **
|
| 176 |
-
|
| 177 |
-
- **Manual Fusion**: Custom implementation for specialized LoRAs
|
| 178 |
-
- **No Additional LoRA**: Lightning-only operation
|
| 179 |
|
| 180 |
### 4. Memory Management with Lightning
|
| 181 |
|
| 182 |
- Lightning LoRA remains loaded throughout session
|
| 183 |
-
-
|
| 184 |
- GPU memory optimized for Lightning + one additional LoRA
|
| 185 |
- Automatic cleanup of non-Lightning adapters
|
| 186 |
|
|
@@ -189,10 +179,6 @@ def on_lora_change(lora_name):
|
|
| 189 |
Each LoRA has a custom prompt template (Lightning provides base 4-step generation):
|
| 190 |
|
| 191 |
```python
|
| 192 |
-
"InStyle (Style Transfer)": {
|
| 193 |
-
"prompt_template": "Make an image in this style of {prompt}",
|
| 194 |
-
"type": "style"
|
| 195 |
-
},
|
| 196 |
"Object Remover": {
|
| 197 |
"prompt_template": "Remove {prompt}",
|
| 198 |
"type": "edit"
|
|
@@ -204,14 +190,19 @@ Each LoRA has a custom prompt template (Lightning provides base 4-step generatio
|
|
| 204 |
### Basic Usage with Always-On Lightning
|
| 205 |
|
| 206 |
1. **Lightning is Always Active**: No selection needed - Lightning runs all operations
|
| 207 |
-
2. **Select Additional LoRA**: Choose
|
| 208 |
-
3. **Upload Images**:
|
| 209 |
-
|
| 210 |
-
- Edit LoRAs: Upload input image to edit
|
| 211 |
-
4. **Enter Prompt**: Describe the desired modification
|
| 212 |
5. **Configure Settings**: Adjust advanced parameters (4-step generation always enabled)
|
| 213 |
6. **Generate**: Click "Generate!" to process with Lightning optimization
|
| 214 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
### Advanced Configuration
|
| 216 |
|
| 217 |
#### Adding New LoRAs (with Lightning Always-On)
|
|
@@ -236,18 +227,6 @@ lora_manager.register_lora("Custom LoRA", lora_path, **config)
|
|
| 236 |
|
| 237 |
3. **Lightning + Custom LoRA**: Automatically combines with always-on Lightning
|
| 238 |
|
| 239 |
-
#### Custom UI Configuration
|
| 240 |
-
|
| 241 |
-
```python
|
| 242 |
-
ui_config = {
|
| 243 |
-
"description": "Custom LoRA description",
|
| 244 |
-
"ui_components": [
|
| 245 |
-
{"type": "slider", "name": "custom_param", "label": "Custom Parameter", "min": 0, "max": 1, "value": 0.5}
|
| 246 |
-
]
|
| 247 |
-
}
|
| 248 |
-
lora_manager.configure_lora("Custom LoRA", ui_config)
|
| 249 |
-
```
|
| 250 |
-
|
| 251 |
## Technical Implementation
|
| 252 |
|
| 253 |
### Lightning Always-On Process
|
|
@@ -255,7 +234,7 @@ lora_manager.configure_lora("Custom LoRA", ui_config)
|
|
| 255 |
1. **Initialization**: Load Lightning LoRA first
|
| 256 |
2. **Fusion**: Fuse Lightning weights permanently
|
| 257 |
3. **Persistence**: Keep Lightning active throughout session
|
| 258 |
-
4. **Combination**: Load
|
| 259 |
5. **Preservation**: Never unload Lightning LoRA
|
| 260 |
|
| 261 |
### Lightning Loading Process
|
|
@@ -282,35 +261,6 @@ gc.collect()
|
|
| 282 |
torch.cuda.empty_cache()
|
| 283 |
```
|
| 284 |
|
| 285 |
-
### Manual Fusion with Lightning
|
| 286 |
-
|
| 287 |
-
```python
|
| 288 |
-
def fuse_lora_manual(transformer, lora_state_dict, alpha=1.0):
|
| 289 |
-
# Lightning is already fused into transformer
|
| 290 |
-
# Additional manual fusion on top of Lightning
|
| 291 |
-
key_mapping = {}
|
| 292 |
-
for key in lora_state_dict.keys():
|
| 293 |
-
base_key = key.replace('diffusion_model.', '').rsplit('.lora_', 1)[0]
|
| 294 |
-
if base_key not in key_mapping:
|
| 295 |
-
key_mapping[base_key] = {}
|
| 296 |
-
if 'lora_A' in key:
|
| 297 |
-
key_mapping[base_key]['down'] = lora_state_dict[key]
|
| 298 |
-
elif 'lora_B' in key:
|
| 299 |
-
key_mapping[base_key]['up'] = lora_state_dict[key]
|
| 300 |
-
|
| 301 |
-
for name, module in tqdm(transformer.named_modules(), desc="Fusing additional layers"):
|
| 302 |
-
if name in key_mapping and isinstance(module, torch.nn.Linear):
|
| 303 |
-
lora_weights = key_mapping[name]
|
| 304 |
-
if 'down' in lora_weights and 'up' in lora_weights:
|
| 305 |
-
device = module.weight.device
|
| 306 |
-
dtype = module.weight.dtype
|
| 307 |
-
lora_down = lora_weights['down'].to(device, dtype=dtype)
|
| 308 |
-
lora_up = lora_weights['up'].to(device, dtype=dtype)
|
| 309 |
-
merged_delta = lora_up @ lora_down
|
| 310 |
-
module.weight.data += alpha * merged_delta
|
| 311 |
-
return transformer
|
| 312 |
-
```
|
| 313 |
-
|
| 314 |
## Testing and Validation
|
| 315 |
|
| 316 |
### Validation Scripts
|
|
@@ -328,26 +278,33 @@ def fuse_lora_manual(transformer, lora_state_dict, alpha=1.0):
|
|
| 328 |
✅ **UI indicates Lightning always active**
|
| 329 |
✅ **Proper loading sequence implemented**
|
| 330 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 331 |
## Performance Considerations
|
| 332 |
|
| 333 |
### Lightning Always-On Benefits
|
| 334 |
|
| 335 |
- **Consistent Speed**: All operations use 4-step generation
|
| 336 |
- **Reduced Latency**: No loading time for Lightning between requests
|
| 337 |
-
- **Enhanced Performance**: Lightning optimization applies to
|
| 338 |
-
- **Memory Efficiency**: Lightning stays in memory,
|
| 339 |
|
| 340 |
### Speed Optimization
|
| 341 |
|
| 342 |
- **4-Step Generation**: Lightning provides ultra-fast inference
|
| 343 |
- **AOT Compilation**: Ahead-of-time compilation with Lightning active
|
| 344 |
-
- **Adapter Combination**: Lightning +
|
| 345 |
- **Optimized Attention Processors**: FA3 attention with Lightning
|
| 346 |
|
| 347 |
### Memory Optimization
|
| 348 |
|
| 349 |
- Lightning LoRA always in memory (base memory usage)
|
| 350 |
-
-
|
| 351 |
- Efficient adapter switching
|
| 352 |
- GPU memory management for multiple adapters
|
| 353 |
|
|
@@ -365,10 +322,10 @@ def fuse_lora_manual(transformer, lora_state_dict, alpha=1.0):
|
|
| 365 |
- Verify adapter status: `pipe.get_active_adapters()`
|
| 366 |
- Ensure Lightning is not being disabled
|
| 367 |
|
| 368 |
-
3. **
|
| 369 |
-
- Check
|
| 370 |
-
- Verify
|
| 371 |
-
- Monitor memory usage for
|
| 372 |
|
| 373 |
### Debug Mode
|
| 374 |
|
|
@@ -386,10 +343,10 @@ print(f"All active adapters: {pipe.get_active_adapters()}")
|
|
| 386 |
|
| 387 |
### Planned Features
|
| 388 |
|
| 389 |
-
1. **
|
| 390 |
-
2. **
|
| 391 |
-
3. **
|
| 392 |
-
4. **
|
| 393 |
5. **Batch Processing**: Process multiple images with Lightning always-on
|
| 394 |
|
| 395 |
### Extension Points
|
|
@@ -399,10 +356,27 @@ print(f"All active adapters: {pipe.get_active_adapters()}")
|
|
| 399 |
- Advanced multi-LoRA combination algorithms
|
| 400 |
- Lightning performance profiling
|
| 401 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 402 |
## References
|
| 403 |
|
| 404 |
- [Qwen-Image-Edit Model](https://huggingface.co/Qwen/Qwen-Image-Edit-2509)
|
| 405 |
- [Lightning LoRA Repository](https://huggingface.co/lightx2v/Qwen-Image-Lightning)
|
|
|
|
| 406 |
- [Diffusers LoRA Documentation](https://huggingface.co/docs/diffusers/main/en/using-diffusers/loading_adapters)
|
| 407 |
- [PEFT Library](https://github.com/huggingface/peft)
|
| 408 |
- [HuggingFace Spaces Pattern](https://huggingface.co/spaces)
|
|
|
|
| 1 |
+
# Multi-LoRA Image Editing Implementation (Simplified)
|
| 2 |
|
| 3 |
## Overview
|
| 4 |
|
| 5 |
+
This implementation provides a simplified multi-LoRA (Low-Rank Adaptation) system for the Qwen-Image-Edit application, focusing on **Lightning LoRA always active as the base optimization** with only **Object Remover** as an additional LoRA for testing.
|
| 6 |
|
| 7 |
## Architecture
|
| 8 |
|
|
|
|
| 17 |
2. **LoRA Configuration** (`app.py`)
|
| 18 |
- Centralized `LORA_CONFIG` dictionary
|
| 19 |
- Lightning LoRA configured as always-loaded base
|
| 20 |
+
- Simplified to Object Remover for focused testing
|
| 21 |
|
| 22 |
3. **Dynamic UI System** (`app.py`)
|
| 23 |
- Conditional component visibility based on LoRA selection
|
| 24 |
- Lightning LoRA status indication
|
| 25 |
+
- Type-specific UI adaptations (edit vs base)
|
| 26 |
- Real-time interface updates
|
| 27 |
|
| 28 |
## ⚡ Lightning LoRA Always-On Architecture
|
|
|
|
| 33 |
|
| 34 |
- **Consistent Performance**: Always-on 4-step generation
|
| 35 |
- **Enhanced Speed**: Lightning's optimization applies to all operations
|
| 36 |
+
- **Multi-LoRA Fusion**: Combine Lightning speed with Object Remover capabilities
|
| 37 |
|
| 38 |
### Implementation Details
|
| 39 |
|
|
|
|
| 66 |
def load_and_fuse_additional_lora(lora_name):
|
| 67 |
"""
|
| 68 |
Load an additional LoRA while keeping Lightning LoRA always active.
|
| 69 |
+
This enables combining Lightning's speed with Object Remover capabilities.
|
| 70 |
"""
|
| 71 |
# Always keep Lightning LoRA loaded
|
| 72 |
# Load additional LoRA without resetting to base state
|
|
|
|
| 103 |
pipe.disable_adapters() # Disable additional LoRA but keep Lightning
|
| 104 |
```
|
| 105 |
|
| 106 |
+
## Simplified LoRA Configuration
|
| 107 |
|
| 108 |
+
### Current Supported LoRAs
|
| 109 |
|
| 110 |
| LoRA Name | Type | Method | Always-On | Description |
|
| 111 |
|-----------|------|--------|-----------|-------------|
|
| 112 |
| **⚡ Lightning (4-Step)** | base | standard | ✅ **Always** | Fast 4-step generation - always active |
|
| 113 |
+
| **None** | edit | none | ❌ | Base model with Lightning optimization |
|
| 114 |
+
| **Object Remover** | edit | standard | ⚡ Lightning+ | Removes objects from an image while maintaining background consistency |
|
|
|
|
|
|
|
|
|
|
| 115 |
|
| 116 |
+
### Lightning + Object Remover Combination
|
| 117 |
|
| 118 |
+
**Lightning + Object Remover**: Fast object removal with 4-step generation optimization
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
|
| 120 |
### LoRA Type Classifications
|
| 121 |
|
| 122 |
- **Base LoRA**: Lightning (always loaded, always active)
|
| 123 |
+
- **Edit LoRAs**: Object Remover (requires input images, uses standard fusion)
|
| 124 |
+
- **None**: Base model with Lightning optimization
|
| 125 |
|
| 126 |
## Key Features
|
| 127 |
|
|
|
|
| 161 |
}
|
| 162 |
```
|
| 163 |
|
| 164 |
+
### 3. Simplified Multi-LoRA Fusion
|
| 165 |
|
| 166 |
- **Lightning Base**: Always loaded, always active
|
| 167 |
+
- **Object Remover**: Loaded alongside Lightning using standard fusion
|
| 168 |
+
- **None**: Lightning-only operation
|
|
|
|
|
|
|
| 169 |
|
| 170 |
### 4. Memory Management with Lightning
|
| 171 |
|
| 172 |
- Lightning LoRA remains loaded throughout session
|
| 173 |
+
- Object Remover LoRA loaded/unloaded as needed
|
| 174 |
- GPU memory optimized for Lightning + one additional LoRA
|
| 175 |
- Automatic cleanup of non-Lightning adapters
|
| 176 |
|
|
|
|
| 179 |
Each LoRA has a custom prompt template (Lightning provides base 4-step generation):
|
| 180 |
|
| 181 |
```python
|
|
|
|
|
|
|
|
|
|
|
|
|
| 182 |
"Object Remover": {
|
| 183 |
"prompt_template": "Remove {prompt}",
|
| 184 |
"type": "edit"
|
|
|
|
| 190 |
### Basic Usage with Always-On Lightning
|
| 191 |
|
| 192 |
1. **Lightning is Always Active**: No selection needed - Lightning runs all operations
|
| 193 |
+
2. **Select Additional LoRA**: Choose "Object Remover" to combine with Lightning
|
| 194 |
+
3. **Upload Images**: Upload input image to edit
|
| 195 |
+
4. **Enter Prompt**: Describe the object to remove
|
|
|
|
|
|
|
| 196 |
5. **Configure Settings**: Adjust advanced parameters (4-step generation always enabled)
|
| 197 |
6. **Generate**: Click "Generate!" to process with Lightning optimization
|
| 198 |
|
| 199 |
+
### Object Remover Usage
|
| 200 |
+
|
| 201 |
+
1. **Select "Object Remover"** from the dropdown
|
| 202 |
+
2. **Upload Input Image**: The image containing the object to remove
|
| 203 |
+
3. **Enter Prompt**: Describe the object to remove (e.g., "person", "car", "tree")
|
| 204 |
+
4. **Generate**: Lightning + Object Remover will remove the specified object
|
| 205 |
+
|
| 206 |
### Advanced Configuration
|
| 207 |
|
| 208 |
#### Adding New LoRAs (with Lightning Always-On)
|
|
|
|
| 227 |
|
| 228 |
3. **Lightning + Custom LoRA**: Automatically combines with always-on Lightning
|
| 229 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 230 |
## Technical Implementation
|
| 231 |
|
| 232 |
### Lightning Always-On Process
|
|
|
|
| 234 |
1. **Initialization**: Load Lightning LoRA first
|
| 235 |
2. **Fusion**: Fuse Lightning weights permanently
|
| 236 |
3. **Persistence**: Keep Lightning active throughout session
|
| 237 |
+
4. **Combination**: Load Object Remover alongside Lightning
|
| 238 |
5. **Preservation**: Never unload Lightning LoRA
|
| 239 |
|
| 240 |
### Lightning Loading Process
|
|
|
|
| 261 |
torch.cuda.empty_cache()
|
| 262 |
```
|
| 263 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 264 |
## Testing and Validation
|
| 265 |
|
| 266 |
### Validation Scripts
|
|
|
|
| 278 |
✅ **UI indicates Lightning always active**
|
| 279 |
✅ **Proper loading sequence implemented**
|
| 280 |
|
| 281 |
+
### Object Remover Testing
|
| 282 |
+
|
| 283 |
+
✅ **Object Remover loads alongside Lightning**
|
| 284 |
+
✅ **Lightning + Object Remover combination works**
|
| 285 |
+
✅ **Prompt template "Remove {prompt}" functions correctly**
|
| 286 |
+
✅ **Memory management for Lightning + Object Remover**
|
| 287 |
+
|
| 288 |
## Performance Considerations
|
| 289 |
|
| 290 |
### Lightning Always-On Benefits
|
| 291 |
|
| 292 |
- **Consistent Speed**: All operations use 4-step generation
|
| 293 |
- **Reduced Latency**: No loading time for Lightning between requests
|
| 294 |
+
- **Enhanced Performance**: Lightning optimization applies to Object Remover
|
| 295 |
+
- **Memory Efficiency**: Lightning stays in memory, Object Remover loaded as needed
|
| 296 |
|
| 297 |
### Speed Optimization
|
| 298 |
|
| 299 |
- **4-Step Generation**: Lightning provides ultra-fast inference
|
| 300 |
- **AOT Compilation**: Ahead-of-time compilation with Lightning active
|
| 301 |
+
- **Adapter Combination**: Lightning + Object Remover for optimal results
|
| 302 |
- **Optimized Attention Processors**: FA3 attention with Lightning
|
| 303 |
|
| 304 |
### Memory Optimization
|
| 305 |
|
| 306 |
- Lightning LoRA always in memory (base memory usage)
|
| 307 |
+
- Object Remover LoRA loaded on-demand
|
| 308 |
- Efficient adapter switching
|
| 309 |
- GPU memory management for multiple adapters
|
| 310 |
|
|
|
|
| 322 |
- Verify adapter status: `pipe.get_active_adapters()`
|
| 323 |
- Ensure Lightning is not being disabled
|
| 324 |
|
| 325 |
+
3. **Object Remover Issues**
|
| 326 |
+
- Check Object Remover loading: Look for "Lightning + Object Remover now active"
|
| 327 |
+
- Verify prompt format: Should be "Remove {object}"
|
| 328 |
+
- Monitor memory usage for Lightning + Object Remover
|
| 329 |
|
| 330 |
### Debug Mode
|
| 331 |
|
|
|
|
| 343 |
|
| 344 |
### Planned Features
|
| 345 |
|
| 346 |
+
1. **Additional LoRAs**: Add more LoRAs after successful Object Remover testing
|
| 347 |
+
2. **LoRA Blending**: Advanced blending of multiple LoRAs with Lightning
|
| 348 |
+
3. **Lightning Optimization**: Dynamic Lightning parameter adjustment
|
| 349 |
+
4. **Performance Monitoring**: Real-time Lightning performance metrics
|
| 350 |
5. **Batch Processing**: Process multiple images with Lightning always-on
|
| 351 |
|
| 352 |
### Extension Points
|
|
|
|
| 356 |
- Advanced multi-LoRA combination algorithms
|
| 357 |
- Lightning performance profiling
|
| 358 |
|
| 359 |
+
## Simplified Configuration Benefits
|
| 360 |
+
|
| 361 |
+
### Focused Testing
|
| 362 |
+
|
| 363 |
+
- **Reduced Complexity**: Only Lightning + Object Remover to test
|
| 364 |
+
- **Clear Validation**: Easy to verify Lightning always-on functionality
|
| 365 |
+
- **Debugging**: Simplified troubleshooting with fewer variables
|
| 366 |
+
- **Performance**: Clear performance benefits of Lightning always-on
|
| 367 |
+
|
| 368 |
+
### Risk Mitigation
|
| 369 |
+
|
| 370 |
+
- **Gradual Rollout**: Test one LoRA before adding more
|
| 371 |
+
- **Validation**: Ensure Lightning + LoRA combination works correctly
|
| 372 |
+
- **Memory Management**: Verify memory usage with Lightning + one LoRA
|
| 373 |
+
- **User Experience**: Validate simplified UI with fewer options
|
| 374 |
+
|
| 375 |
## References
|
| 376 |
|
| 377 |
- [Qwen-Image-Edit Model](https://huggingface.co/Qwen/Qwen-Image-Edit-2509)
|
| 378 |
- [Lightning LoRA Repository](https://huggingface.co/lightx2v/Qwen-Image-Lightning)
|
| 379 |
+
- [Object Remover LoRA Repository](https://huggingface.co/valiantcat/Qwen-Image-Edit-Remover-General-LoRA)
|
| 380 |
- [Diffusers LoRA Documentation](https://huggingface.co/docs/diffusers/main/en/using-diffusers/loading_adapters)
|
| 381 |
- [PEFT Library](https://github.com/huggingface/peft)
|
| 382 |
- [HuggingFace Spaces Pattern](https://huggingface.co/spaces)
|
app.py
CHANGED
|
@@ -69,7 +69,7 @@ Please strictly follow the rewriting rules below:
|
|
| 69 |
"Restore and colorize the old photo."
|
| 70 |
- Clearly specify the object to be modified. For example:
|
| 71 |
> Original: Modify the subject in Picture 1 to match the style of Picture 2.
|
| 72 |
-
> Rewritten: Change the girl in Picture 1 to the ink-wash style of Picture 2 — rendered in black-and-white watercolor with soft color transitions.
|
| 73 |
|
| 74 |
### 5. Material Replacement
|
| 75 |
- Clearly specify the object and the material. For example: "Change the material of the apple to papercut style."
|
|
@@ -174,7 +174,7 @@ def polish_prompt_hf(prompt, img_list):
|
|
| 174 |
# Fallback to original prompt if enhancement fails
|
| 175 |
return prompt
|
| 176 |
|
| 177 |
-
# Define LoRA configurations with Lightning as always-loaded base
|
| 178 |
LORA_CONFIG = {
|
| 179 |
"Lightning (4-Step)": {
|
| 180 |
"repo_id": "lightx2v/Qwen-Image-Lightning",
|
|
@@ -191,31 +191,7 @@ LORA_CONFIG = {
|
|
| 191 |
"type": "edit",
|
| 192 |
"method": "none",
|
| 193 |
"prompt_template": "{prompt}",
|
| 194 |
-
"description": "Use the base Qwen-Image-Edit model
|
| 195 |
-
},
|
| 196 |
-
"InStyle (Style Transfer)": {
|
| 197 |
-
"repo_id": "peteromallet/Qwen-Image-Edit-InStyle",
|
| 198 |
-
"filename": "InStyle-0.5.safetensors",
|
| 199 |
-
"type": "style",
|
| 200 |
-
"method": "manual_fuse",
|
| 201 |
-
"prompt_template": "Make an image in this style of {prompt}",
|
| 202 |
-
"description": "Transfers the style from a reference image to a new image described by the prompt.",
|
| 203 |
-
},
|
| 204 |
-
"InScene (In-Scene Editing)": {
|
| 205 |
-
"repo_id": "flymy-ai/qwen-image-edit-inscene-lora",
|
| 206 |
-
"filename": "flymy_qwen_image_edit_inscene_lora.safetensors",
|
| 207 |
-
"type": "edit",
|
| 208 |
-
"method": "standard",
|
| 209 |
-
"prompt_template": "{prompt}",
|
| 210 |
-
"description": "Improves in-scene editing, object positioning, and camera perspective changes.",
|
| 211 |
-
},
|
| 212 |
-
"Face Segmentation": {
|
| 213 |
-
"repo_id": "TsienDragon/qwen-image-edit-lora-face-segmentation",
|
| 214 |
-
"filename": "pytorch_lora_weights.safetensors",
|
| 215 |
-
"type": "edit",
|
| 216 |
-
"method": "standard",
|
| 217 |
-
"prompt_template": "change the face to face segmentation mask",
|
| 218 |
-
"description": "Transforms a facial image into a precise segmentation mask.",
|
| 219 |
},
|
| 220 |
"Object Remover": {
|
| 221 |
"repo_id": "valiantcat/Qwen-Image-Edit-Remover-General-LoRA",
|
|
@@ -286,7 +262,7 @@ lora_manager.configure_lora(LIGHTNING_LORA_NAME, {
|
|
| 286 |
lora_manager.load_lora(LIGHTNING_LORA_NAME)
|
| 287 |
lora_manager.fuse_lora(LIGHTNING_LORA_NAME)
|
| 288 |
|
| 289 |
-
# Register other LoRAs
|
| 290 |
for lora_name, config in LORA_CONFIG.items():
|
| 291 |
if lora_name != LIGHTNING_LORA_NAME and config["repo_id"] is not None:
|
| 292 |
lora_path = hf_hub_download(repo_id=config["repo_id"], filename=config["filename"])
|
|
@@ -389,7 +365,7 @@ def infer(
|
|
| 389 |
if style_image is None:
|
| 390 |
raise gr.Error("Style Transfer LoRA requires a Style Reference Image.")
|
| 391 |
image_for_pipeline = style_image
|
| 392 |
-
else: # 'edit'
|
| 393 |
if input_image is None:
|
| 394 |
raise gr.Error("This LoRA requires an Input Image.")
|
| 395 |
image_for_pipeline = input_image
|
|
@@ -451,7 +427,7 @@ with gr.Blocks(css="#col-container { margin: 0 auto; max-width: 1024px; }") as d
|
|
| 451 |
gr.Markdown("""
|
| 452 |
[Learn more](https://github.com/QwenLM/Qwen-Image) about the Qwen-Image series.
|
| 453 |
This demo uses the new [Qwen-Image-Edit-2509](https://huggingface.co/Qwen/Qwen-Image-Edit-2509) with support for multiple LoRA adapters.
|
| 454 |
-
**⚡ Lightning LoRA is always active for fast 4-step generation** - combine it with
|
| 455 |
Try on [Qwen Chat](https://chat.qwen.ai/), or [download model](https://huggingface.co/Qwen/Qwen-Image-Edit-2509) to run locally with ComfyUI or diffusers.
|
| 456 |
""")
|
| 457 |
|
|
@@ -465,10 +441,10 @@ with gr.Blocks(css="#col-container { margin: 0 auto; max-width: 1024px; }") as d
|
|
| 465 |
)
|
| 466 |
lora_description = gr.Markdown(visible=False)
|
| 467 |
|
| 468 |
-
input_image_box = gr.Image(label="Input Image", type="pil", visible=
|
| 469 |
style_image_box = gr.Image(label="Style Reference Image", type="pil", visible=False)
|
| 470 |
|
| 471 |
-
prompt_box = gr.Textbox(label="Prompt", placeholder="Describe the
|
| 472 |
|
| 473 |
run_button = gr.Button("Generate!", variant="primary")
|
| 474 |
|
|
|
|
| 69 |
"Restore and colorize the old photo."
|
| 70 |
- Clearly specify the object to be modified. For example:
|
| 71 |
> Original: Modify the subject in Picture 1 to match the style of Picture 2.
|
| 72 |
+
> Rewritten: "Change the girl in Picture 1 to the ink-wash style of Picture 2 — rendered in black-and-white watercolor with soft color transitions.
|
| 73 |
|
| 74 |
### 5. Material Replacement
|
| 75 |
- Clearly specify the object and the material. For example: "Change the material of the apple to papercut style."
|
|
|
|
| 174 |
# Fallback to original prompt if enhancement fails
|
| 175 |
return prompt
|
| 176 |
|
| 177 |
+
# Define simplified LoRA configurations with Lightning as always-loaded base
|
| 178 |
LORA_CONFIG = {
|
| 179 |
"Lightning (4-Step)": {
|
| 180 |
"repo_id": "lightx2v/Qwen-Image-Lightning",
|
|
|
|
| 191 |
"type": "edit",
|
| 192 |
"method": "none",
|
| 193 |
"prompt_template": "{prompt}",
|
| 194 |
+
"description": "Use the base Qwen-Image-Edit model with Lightning optimization.",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
},
|
| 196 |
"Object Remover": {
|
| 197 |
"repo_id": "valiantcat/Qwen-Image-Edit-Remover-General-LoRA",
|
|
|
|
| 262 |
lora_manager.load_lora(LIGHTNING_LORA_NAME)
|
| 263 |
lora_manager.fuse_lora(LIGHTNING_LORA_NAME)
|
| 264 |
|
| 265 |
+
# Register other LoRAs (only Object Remover for testing)
|
| 266 |
for lora_name, config in LORA_CONFIG.items():
|
| 267 |
if lora_name != LIGHTNING_LORA_NAME and config["repo_id"] is not None:
|
| 268 |
lora_path = hf_hub_download(repo_id=config["repo_id"], filename=config["filename"])
|
|
|
|
| 365 |
if style_image is None:
|
| 366 |
raise gr.Error("Style Transfer LoRA requires a Style Reference Image.")
|
| 367 |
image_for_pipeline = style_image
|
| 368 |
+
else: # 'edit' or 'base'
|
| 369 |
if input_image is None:
|
| 370 |
raise gr.Error("This LoRA requires an Input Image.")
|
| 371 |
image_for_pipeline = input_image
|
|
|
|
| 427 |
gr.Markdown("""
|
| 428 |
[Learn more](https://github.com/QwenLM/Qwen-Image) about the Qwen-Image series.
|
| 429 |
This demo uses the new [Qwen-Image-Edit-2509](https://huggingface.co/Qwen/Qwen-Image-Edit-2509) with support for multiple LoRA adapters.
|
| 430 |
+
**⚡ Lightning LoRA is always active for fast 4-step generation** - combine it with Object Remover for optimized performance.
|
| 431 |
Try on [Qwen Chat](https://chat.qwen.ai/), or [download model](https://huggingface.co/Qwen/Qwen-Image-Edit-2509) to run locally with ComfyUI or diffusers.
|
| 432 |
""")
|
| 433 |
|
|
|
|
| 441 |
)
|
| 442 |
lora_description = gr.Markdown(visible=False)
|
| 443 |
|
| 444 |
+
input_image_box = gr.Image(label="Input Image", type="pil", visible=True)
|
| 445 |
style_image_box = gr.Image(label="Style Reference Image", type="pil", visible=False)
|
| 446 |
|
| 447 |
+
prompt_box = gr.Textbox(label="Prompt", placeholder="Describe the object to remove...")
|
| 448 |
|
| 449 |
run_button = gr.Button("Generate!", variant="primary")
|
| 450 |
|