Onise commited on
Commit
38b7feb
·
verified ·
1 Parent(s): e944e94

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +145 -129
app.py CHANGED
@@ -52,8 +52,7 @@ steel_blue_theme = SteelBlueTheme()
52
 
53
  # ── Device / dtype ─────────────────────────────────────────────────────────────
54
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
55
- dtype = torch.bfloat16
56
-
57
  print("CUDA available:", torch.cuda.is_available())
58
  print("Using device:", device)
59
 
@@ -75,8 +74,8 @@ pipe = QwenImageEditPlusPipeline.from_pretrained(
75
  # ── OOM FIX: Enable VAE tiling and slicing to bound VRAM usage ─────────────────
76
  pipe.vae.enable_tiling(tile_sample_min_width=256, tile_sample_min_height=256)
77
  pipe.vae.enable_slicing()
78
- # ───────────────────────────────────────────────────────────────────────────────
79
 
 
80
  try:
81
  pipe.transformer.set_attn_processor(QwenDoubleStreamAttnProcessorFA3())
82
  print("Flash Attention 3 Processor set successfully.")
@@ -85,127 +84,130 @@ except Exception as e:
85
 
86
  # ── LoRA catalog ──────────────────────────────────────────────────────────
87
  LORA_REPO = "wiikoo/Qwen-lora-nsfw"
 
88
  LORA_CONFIGS = {
89
- "CockQwen_v3": "loras/CockQwen-v3.safetensors",
90
- "Eva_Qwen_V3": "loras/Eva_Qwen_V3.safetensors",
91
- "Facial_Cumshots_V1": "loras/Facial_Cumshots_For_Qwen_Image_V1.safetensors",
92
- "HearmemanAI_V3_Breasts": "loras/HearmemanAI_V3_Rank64_BreastsLoRA_Epoch60.safetensors",
93
- "HearmemanAI_V4_Breasts": "loras/HearmemanAI_V4_Rank128_BreastsLoRA_Epoch80.safetensors",
94
- "InniePussy": "loras/InniePussy.safetensors",
95
- "JTT2_5": "loras/[QWEN] JTT2_5.safetensors",
96
- "LumiNude01a": "loras/LumiNude01a_CE_QWEN_AIT3k.safetensors",
97
- "MEXX_QWEN_TG300": "loras/MEXX_QWEN_TG300_23.safetensors",
98
- "Meta4": "loras/Meta4.safetensors",
99
- "MysticXXX": "loras/Qwen-MysticXXX-v1.safetensors",
100
- "Nsfw_Body_V10": "loras/Qwen_Nsfw_Body_V10-4K.safetensors",
101
- "Nsfw_Body_V14": "loras/Qwen_Nsfw_Body_V14-10K.safetensors",
102
- "OilySkin_V2": "loras/Oily Skin QWEN V2-GMR.safetensors",
103
- "PillowHump_2509": "loras/PillowHump_2509.safetensors",
104
- "PutItHere_V2": "loras/Put it here_Qwen edit_V2.0.safetensors",
105
- "PutItHere_V01": "loras/put it here_QwenEdit_V0.1.safetensors",
106
- "Qwen4Play_v2": "loras/Qwen4Play_v2.safetensors",
107
- "QwenHentai_v3": "loras/QwenImageHentaiPIV_v3.1.safetensors",
108
- "Qwen_Helm": "loras/Qwen-Image-Helm_v0.1.safetensors",
109
- "Qwen_NSFW_Beta1": "loras/Qwen-NSFW.safetensors",
110
- "Qwen_NSFW_Beta2": "loras/Qwen-NSFW-Beta2.safetensors",
111
- "Qwen_NSFW_Beta4": "loras/Qwen-NSFW-Beta4.safetensors",
112
- "Qwen_NSFW_Beta5": "loras/Qwen-NSFW-Beta5.safetensors",
113
- "Qwen_Real_Nud3s": "loras/Qwen_Real_Nud3s.safetensors",
114
- "Qwen_Real_PS": "loras/Qwen-Real PS_v1_83K.safetensors",
115
- "QwenSnofs_v1": "loras/qwen_snofs.safetensors",
116
- "QwenSnofs_v1_1": "loras/QwenSnofs1_1.safetensors",
117
- "Real_Breast_Nipples": "loras/Real Breast Nipples-QWEN-[rbn]-GMR.safetensors",
118
- "SendDudes": "loras/[QWEN] SendDudes.safetensors",
119
- "SendNudesLite": "loras/SendNudesLite (Qwen).safetensors",
120
- "SendNudesPro_Beta": "loras/[QWEN] Send Nudes Pro - Beta v1.safetensors",
121
- "Ultimate_Breast_Nipples": "loras/Ultimate Realistic Breast NIPPLES-QWEN-[rab]-GMR.safetensors",
122
- "ass_up_QWEN": "loras/ass_up_QWEN.safetensors",
123
- "barbell_nipples_QWEN": "loras/QWEN_jtn_barbell.safetensors",
124
- "bfs_v2_face": "loras-sfw/face_swap_5500_qwen_image_edit_2509_v1.safetensors",
125
- "bfs_v2_focus_face": "loras-sfw/bfs_v2_000005000.safetensors",
126
- "bfs_v2_head": "loras-sfw/bfs_v2_head_000007000.safetensors",
127
- "big_nipples_QWEN": "loras/big_nipples_QWEN.safetensors",
128
- "bumpynipples": "loras/bumpynipples1.safetensors",
129
- "cmslt_cum_on_her": "loras/cmslt_2509_2.safetensors",
130
- "consistence_edit_v1": "loras-2/consistence_edit_v1.safetensors",
131
- "consistence_edit_v2": "loras2/consistence_edit_v2.safetensors",
132
- "d33p7hroa7": "loras/d33p7hroa7_qwen.safetensors",
133
- "d1ck_p3n1s_V1_1": "loras/qwen-image_d!ck_P3N1S_LoRA_V1.1.safetensors",
134
- "goblin_anal_v1": "loras/goblin_anal_v1_qwen.safetensors",
135
- "horseshoe_nipple_rings": "loras/horseshoe_nipple_rings_QWEN.safetensors",
136
- "jib_nudity_fixer": "loras/jib_qwen_fix_000002750.safetensors",
137
- "jillin": "loras/jillin1.safetensors",
138
- "male_nude": "loras/lora_nudenan_v1.safetensors",
139
- "milk_juggs": "loras/milk_juggs_QWEN.safetensors",
140
- "n00d_b": "loras/n00d-b-qwen.safetensors",
141
- "nsfw_adv_v1": "loras/qwen-image_nsfw_adv_v1.0.safetensors",
142
- "p0ssy_lora_v1": "loras/p0ssy_lora_v1.safetensors",
143
- "p3nis": "loras/p3nis.safetensors",
144
- "qwen_MCNL": "loras/qwen_MCNL_v1.0.safetensors",
145
- "qwen_PENISLORA": "loras/qwen-PENISLORA.safetensors",
146
- "qwen_hand_grab": "loras/qwen_hand_grab_6000s.safetensors",
147
- "qwen_uncensor": "loras/qwen_uncensor_000014928.safetensors",
148
- "reclining_nude": "loras/reclining_nude_v1_000003500.safetensors",
149
- "remove_clothing": "loras/qwen_image_edit_remove-clothing_v1.0.safetensors",
150
- "royal_treatment_V3": "loras/royal+treatment+V3.safetensors",
151
- "sabi_character": "loras-2/sabi_character_v1.safetensors",
152
- "snapchat_selfie": "loras/qwen_image_snapchat.safetensors",
153
- "uka_qwen": "loras/uka_1_qwen.safetensors",
154
- "ultimate_realistic_breast":"loras/ultimate realistic breast.safetensors",
 
155
  }
156
 
157
  LORA_TRIGGER_WORDS = {
158
- "Qwen4Play_v2": "d0gg13, c0wg1rl, r3v3rs3_c0wg1rl, m15510n4ry, bl0wj0b, penis",
159
- "qwen_MCNL": "nsfw, cum_on_face, blowjob, cowgirlout, creamp1e, penis, l1ck, missionary, nipples, reversecowgirlpov, vagina",
160
- "remove_clothing": "remove her clothing",
161
- "Qwen_Real_Nud3s": "nud3",
162
- "HearmemanAI_V4_Breasts": "large breasts, hard nipples, erect nipples",
163
- "HearmemanAI_V3_Breasts": "large breasts, hard nipples, erect nipples",
164
- "Ultimate_Breast_Nipples": "rab",
165
- "ass_up_QWEN": "ass up showing pussy and anus",
166
- "PillowHump_2509": "Pillow, Humping",
167
- "InniePussy": "Innie pussy, Clean shaven, Vertical slit",
168
- "p0ssy_lora_v1": "Nude",
169
- "CockQwen_v3": "Erect Penis",
170
- "p3nis": "holding a p3nis",
171
- "qwen_PENISLORA": "PENISLORA",
172
- "Facial_Cumshots_V1": "cum",
173
- "bfs_v2_head": "head swap, transfer head from image 1 to image 2",
174
- "bfs_v2_face": "keep the face consistent, preserve facial identity",
175
- "bfs_v2_focus_face": "head swap from Image 1 to Image 2",
176
- "goblin_anal_v1": "anal penetration, spread ass",
177
- "d33p7hroa7": "deepthroat, penis deep in mouth",
178
- "QwenHentai_v3": "nsfw, anime style, explicit",
179
- "Eva_Qwen_V3": "Eva_gothic, in a kneeling position",
180
- "JTT2_5": "massive breasts, large breasts, medium breasts, small breasts",
181
- "MEXX_QWEN_TG300": "nsfw, female body",
182
- "OilySkin_V2": "oilski",
183
- "barbell_nipples_QWEN": "barbell nipple piercings",
184
- "Qwen_Helm": "nsfw, anime style",
185
- "MysticXXX": "nsfw",
186
- "Qwen_NSFW_Beta1": "nsfw",
187
- "Qwen_NSFW_Beta2": "nsfw",
188
- "Qwen_NSFW_Beta4": "nsfw",
189
- "Qwen_NSFW_Beta5": "nsfw",
190
- "QwenSnofs_v1": "sex, missionary, cum, cowgirl, reverse cowgirl, selfie, snapchat selfie, prone position, spooning position, undressing",
191
- "QwenSnofs_v1_1": "nsfw, nude, sex, blowjob, cum, selfie",
192
- "Nsfw_Body_V10": "Hourglass figure, Hairless pussy, Hairly pussy",
193
- "Nsfw_Body_V14": "SSS Waistline, Hairless pussy, Hairly pussy",
194
- "SendNudesLite": "nude",
195
- "SendNudesPro_Beta": "flat chest, small breasts, medium breasts, large breasts, massive breasts, big nipples",
196
- "SendDudes": "Penis",
197
- "cmslt_cum_on_her": "Put cum on her",
198
- "horseshoe_nipple_rings": "horseshoe-ring nipple piercings, circular-barbell nipple piercings",
199
- "jib_nudity_fixer": "nude, nipples, vagina",
200
- "jillin": "masturbating",
201
- "male_nude": "nudeman",
202
- "n00d_b": "nude, art photography",
203
- "nsfw_adv_v1": "nsfw",
204
- "d1ck_p3n1s_V1_1": "P3N1S, penis",
205
- "qwen_uncensor": "nsfw, cum_on_face, blowjob, cowgirlout, creamp1e, penis, l1ck, missionary, nipples, reversecowgirlpov, vagina",
206
- "royal_treatment_V3": "lick ass, blowjob",
207
- "snapchat_selfie": "selfie, snapchat",
208
- "ultimate_realistic_breast":"urb, realistic breast",
 
209
  }
210
 
211
  # Tracks which adapter names have been successfully loaded into the pipeline.
@@ -246,11 +248,24 @@ def load_and_apply_stack(extra_adapters: list[str], extra_weights: list[float]):
246
  if name not in LOADED_ADAPTERS:
247
  try:
248
  print(f"--- Loading adapter: {name} ---")
249
- pipe.load_lora_weights(
250
- LORA_REPO,
251
- weight_name=LORA_CONFIGS[name],
252
- adapter_name=name,
253
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  LOADED_ADAPTERS.add(name)
255
  except Exception as e:
256
  # If it already exists from a previous call in this Space session,
@@ -269,7 +284,6 @@ def load_and_apply_stack(extra_adapters: list[str], extra_weights: list[float]):
269
  pipe.set_adapters(loaded, adapter_weights=weights_out)
270
  else:
271
  pipe.disable_lora()
272
-
273
  return loaded, weights_out
274
 
275
 
@@ -316,7 +330,7 @@ def infer(
316
 
317
  # ── Validate aspect ratio ────────────────────────────────────────────────
318
  # Extreme ratios (>4:1) produce degenerate latent shapes that crash the
319
- # transformer or produce garbage. Reject early with a clear message.
320
  image = input_image.convert("RGB")
321
  w, h = image.size
322
  ratio = max(w, h) / max(min(w, h), 1)
@@ -375,6 +389,7 @@ def infer(
375
  torch.cuda.empty_cache()
376
  # ─────────────────────────────────────────────────────────────────────
377
 
 
378
  # ── UI ─────────────────────────────────────────────────────────────────────────
379
  css = """
380
  #col-container { margin: 0 auto; max-width: 980px; }
@@ -404,6 +419,7 @@ with gr.Blocks(css=css, theme=steel_blue_theme) as demo:
404
  "**Fast local LoRA-powered image editing** powered by `Qwen-Image-Edit-2509` + `Qwen-Image-Edit-Rapid-AIO-V4` + 50+ community LoRAs.<br>"
405
  "Upload an image, describe the edit, optionally stack LoRAs, and hit **Edit Image**."
406
  )
 
407
  with gr.Accordion("💡 Quick Tips", open=False):
408
  gr.Markdown(
409
  "- **LoRAs auto-add trigger words** to your prompt when selected.<br>"
@@ -442,6 +458,7 @@ with gr.Blocks(css=css, theme=steel_blue_theme) as demo:
442
  with gr.Row():
443
  gr.Markdown("**Stack up to 6 LoRAs.** Select a LoRA to auto-fill trigger words in the prompt.")
444
  clear_btn = gr.Button("🧹 Clear All", size="sm", variant="secondary", scale=0)
 
445
  lora_stack = []
446
  for i in range(6):
447
  with gr.Row():
@@ -503,7 +520,6 @@ with gr.Blocks(css=css, theme=steel_blue_theme) as demo:
503
  inputs=[output_image],
504
  outputs=[input_image],
505
  )
506
-
507
  clear_output_btn.click(
508
  fn=lambda: gr.update(value=None),
509
  inputs=None,
@@ -513,4 +529,4 @@ with gr.Blocks(css=css, theme=steel_blue_theme) as demo:
513
  if __name__ == "__main__":
514
  demo.queue(max_size=30).launch(
515
  mcp_server=True, ssr_mode=False, show_error=True
516
- )
 
52
 
53
  # ── Device / dtype ─────────────────────────────────────────────────────────────
54
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
55
+ dtype = torch.bfloat16
 
56
  print("CUDA available:", torch.cuda.is_available())
57
  print("Using device:", device)
58
 
 
74
  # ── OOM FIX: Enable VAE tiling and slicing to bound VRAM usage ─────────────────
75
  pipe.vae.enable_tiling(tile_sample_min_width=256, tile_sample_min_height=256)
76
  pipe.vae.enable_slicing()
 
77
 
78
+ # ───────────────────────────────────────────────────────────────────────────────
79
  try:
80
  pipe.transformer.set_attn_processor(QwenDoubleStreamAttnProcessorFA3())
81
  print("Flash Attention 3 Processor set successfully.")
 
84
 
85
  # ── LoRA catalog ──────────────────────────────────────────────────────────
86
  LORA_REPO = "wiikoo/Qwen-lora-nsfw"
87
+
88
  LORA_CONFIGS = {
89
+ "CockQwen_v3": "loras/CockQwen-v3.safetensors",
90
+ "Eva_Qwen_V3": "loras/Eva_Qwen_V3.safetensors",
91
+ "Facial_Cumshots_V1": "loras/Facial_Cumshots_For_Qwen_Image_V1.safetensors",
92
+ "HearmemanAI_V3_Breasts": "loras/HearmemanAI_V3_Rank64_BreastsLoRA_Epoch60.safetensors",
93
+ "HearmemanAI_V4_Breasts": "loras/HearmemanAI_V4_Rank128_BreastsLoRA_Epoch80.safetensors",
94
+ "InniePussy": "loras/InniePussy.safetensors",
95
+ "JTT2_5": "loras/[QWEN] JTT2_5.safetensors",
96
+ "LumiNude01a": "loras/LumiNude01a_CE_QWEN_AIT3k.safetensors",
97
+ "MEXX_QWEN_TG300": "loras/MEXX_QWEN_TG300_23.safetensors",
98
+ "Meta4": "loras/Meta4.safetensors",
99
+ "MysticXXX": "loras/Qwen-MysticXXX-v1.safetensors",
100
+ "Nsfw_Body_V10": "loras/Qwen_Nsfw_Body_V10-4K.safetensors",
101
+ "Nsfw_Body_V14": "loras/Qwen_Nsfw_Body_V14-10K.safetensors",
102
+ "OilySkin_V2": "loras/Oily Skin QWEN V2-GMR.safetensors",
103
+ "PillowHump_2509": "loras/PillowHump_2509.safetensors",
104
+ "PutItHere_V2": "loras/Put it here_Qwen edit_V2.0.safetensors",
105
+ "PutItHere_V01": "loras/put it here_QwenEdit_V0.1.safetensors",
106
+ "Qwen4Play_v2": "loras/Qwen4Play_v2.safetensors",
107
+ "QwenHentai_v3": "loras/QwenImageHentaiPIV_v3.1.safetensors",
108
+ "Qwen_Helm": "loras/Qwen-Image-Helm_v0.1.safetensors",
109
+ "Qwen_NSFW_Beta1": "loras/Qwen-NSFW.safetensors",
110
+ "Qwen_NSFW_Beta2": "loras/Qwen-NSFW-Beta2.safetensors",
111
+ "Qwen_NSFW_Beta4": "loras/Qwen-NSFW-Beta4.safetensors",
112
+ "Qwen_NSFW_Beta5": "loras/Qwen-NSFW-Beta5.safetensors",
113
+ "Qwen_Real_Nud3s": "loras/Qwen_Real_Nud3s.safetensors",
114
+ "Qwen_Real_PS": "loras/Qwen-Real PS_v1_83K.safetensors",
115
+ "QwenSnofs_v1": "loras/qwen_snofs.safetensors",
116
+ "QwenSnofs_v1_1": "loras/QwenSnofs1_1.safetensors",
117
+ "QwenSnofs_1.3": ("Cassanovason69/Qwensnofs", "Qwen_Snofs_1_3.safetensors"), # ← from other repo
118
+ "Real_Breast_Nipples": "loras/Real Breast Nipples-QWEN-[rbn]-GMR.safetensors",
119
+ "SendDudes": "loras/[QWEN] SendDudes.safetensors",
120
+ "SendNudesLite": "loras/SendNudesLite (Qwen).safetensors",
121
+ "SendNudesPro_Beta": "loras/[QWEN] Send Nudes Pro - Beta v1.safetensors",
122
+ "Ultimate_Breast_Nipples": "loras/Ultimate Realistic Breast NIPPLES-QWEN-[rab]-GMR.safetensors",
123
+ "ass_up_QWEN": "loras/ass_up_QWEN.safetensors",
124
+ "barbell_nipples_QWEN": "loras/QWEN_jtn_barbell.safetensors",
125
+ "bfs_v2_face": "loras-sfw/face_swap_5500_qwen_image_edit_2509_v1.safetensors",
126
+ "bfs_v2_focus_face": "loras-sfw/bfs_v2_000005000.safetensors",
127
+ "bfs_v2_head": "loras-sfw/bfs_v2_head_000007000.safetensors",
128
+ "big_nipples_QWEN": "loras/big_nipples_QWEN.safetensors",
129
+ "bumpynipples": "loras/bumpynipples1.safetensors",
130
+ "cmslt_cum_on_her": "loras/cmslt_2509_2.safetensors",
131
+ "consistence_edit_v1": "loras-2/consistence_edit_v1.safetensors",
132
+ "consistence_edit_v2": "loras2/consistence_edit_v2.safetensors",
133
+ "d33p7hroa7": "loras/d33p7hroa7_qwen.safetensors",
134
+ "d1ck_p3n1s_V1_1": "loras/qwen-image_d!ck_P3N1S_LoRA_V1.1.safetensors",
135
+ "goblin_anal_v1": "loras/goblin_anal_v1_qwen.safetensors",
136
+ "horseshoe_nipple_rings": "loras/horseshoe_nipple_rings_QWEN.safetensors",
137
+ "jib_nudity_fixer": "loras/jib_qwen_fix_000002750.safetensors",
138
+ "jillin": "loras/jillin1.safetensors",
139
+ "male_nude": "loras/lora_nudenan_v1.safetensors",
140
+ "milk_juggs": "loras/milk_juggs_QWEN.safetensors",
141
+ "n00d_b": "loras/n00d-b-qwen.safetensors",
142
+ "nsfw_adv_v1": "loras/qwen-image_nsfw_adv_v1.0.safetensors",
143
+ "p0ssy_lora_v1": "loras/p0ssy_lora_v1.safetensors",
144
+ "p3nis": "loras/p3nis.safetensors",
145
+ "qwen_MCNL": "loras/qwen_MCNL_v1.0.safetensors",
146
+ "qwen_PENISLORA": "loras/qwen-PENISLORA.safetensors",
147
+ "qwen_hand_grab": "loras/qwen_hand_grab_6000s.safetensors",
148
+ "qwen_uncensor": "loras/qwen_uncensor_000014928.safetensors",
149
+ "reclining_nude": "loras/reclining_nude_v1_000003500.safetensors",
150
+ "remove_clothing": "loras/qwen_image_edit_remove-clothing_v1.0.safetensors",
151
+ "royal_treatment_V3": "loras/royal+treatment+V3.safetensors",
152
+ "sabi_character": "loras-2/sabi_character_v1.safetensors",
153
+ "snapchat_selfie": "loras/qwen_image_snapchat.safetensors",
154
+ "uka_qwen": "loras/uka_1_qwen.safetensors",
155
+ "ultimate_realistic_breast": "loras/ultimate realistic breast.safetensors",
156
  }
157
 
158
  LORA_TRIGGER_WORDS = {
159
+ "Qwen4Play_v2": "d0gg13, c0wg1rl, r3v3rs3_c0wg1rl, m15510n4ry, bl0wj0b, penis",
160
+ "qwen_MCNL": "nsfw, cum_on_face, blowjob, cowgirlout, creamp1e, penis, l1ck, missionary, nipples, reversecowgirlpov, vagina",
161
+ "remove_clothing": "remove her clothing",
162
+ "Qwen_Real_Nud3s": "nud3",
163
+ "HearmemanAI_V4_Breasts": "large breasts, hard nipples, erect nipples",
164
+ "HearmemanAI_V3_Breasts": "large breasts, hard nipples, erect nipples",
165
+ "Ultimate_Breast_Nipples": "rab",
166
+ "ass_up_QWEN": "ass up showing pussy and anus",
167
+ "PillowHump_2509": "Pillow, Humping",
168
+ "InniePussy": "Innie pussy, Clean shaven, Vertical slit",
169
+ "p0ssy_lora_v1": "Nude",
170
+ "CockQwen_v3": "Erect Penis",
171
+ "p3nis": "holding a p3nis",
172
+ "qwen_PENISLORA": "PENISLORA",
173
+ "Facial_Cumshots_V1": "cum",
174
+ "bfs_v2_head": "head swap, transfer head from image 1 to image 2",
175
+ "bfs_v2_face": "keep the face consistent, preserve facial identity",
176
+ "bfs_v2_focus_face": "head swap from Image 1 to Image 2",
177
+ "goblin_anal_v1": "anal penetration, spread ass",
178
+ "d33p7hroa7": "deepthroat, penis deep in mouth",
179
+ "QwenHentai_v3": "nsfw, anime style, explicit",
180
+ "Eva_Qwen_V3": "Eva_gothic, in a kneeling position",
181
+ "JTT2_5": "massive breasts, large breasts, medium breasts, small breasts",
182
+ "MEXX_QWEN_TG300": "nsfw, female body",
183
+ "OilySkin_V2": "oilski",
184
+ "barbell_nipples_QWEN": "barbell nipple piercings",
185
+ "Qwen_Helm": "nsfw, anime style",
186
+ "MysticXXX": "nsfw",
187
+ "Qwen_NSFW_Beta1": "nsfw",
188
+ "Qwen_NSFW_Beta2": "nsfw",
189
+ "Qwen_NSFW_Beta4": "nsfw",
190
+ "Qwen_NSFW_Beta5": "nsfw",
191
+ "QwenSnofs_v1": "sex, missionary, cum, cowgirl, reverse cowgirl, selfie, snapchat selfie, prone position, spooning position, undressing",
192
+ "QwenSnofs_v1_1": "nsfw, nude, sex, blowjob, cum, selfie",
193
+ "QwenSnofs_1.3": "nsfw, nude, sex, blowjob, cum, selfie", # same style as previous versions
194
+ "Nsfw_Body_V10": "Hourglass figure, Hairless pussy, Hairly pussy",
195
+ "Nsfw_Body_V14": "SSS Waistline, Hairless pussy, Hairly pussy",
196
+ "SendNudesLite": "nude",
197
+ "SendNudesPro_Beta": "flat chest, small breasts, medium breasts, large breasts, massive breasts, big nipples",
198
+ "SendDudes": "Penis",
199
+ "cmslt_cum_on_her": "Put cum on her",
200
+ "horseshoe_nipple_rings": "horseshoe-ring nipple piercings, circular-barbell nipple piercings",
201
+ "jib_nudity_fixer": "nude, nipples, vagina",
202
+ "jillin": "masturbating",
203
+ "male_nude": "nudeman",
204
+ "n00d_b": "nude, art photography",
205
+ "nsfw_adv_v1": "nsfw",
206
+ "d1ck_p3n1s_V1_1": "P3N1S, penis",
207
+ "qwen_uncensor": "nsfw, cum_on_face, blowjob, cowgirlout, creamp1e, penis, l1ck, missionary, nipples, reversecowgirlpov, vagina",
208
+ "royal_treatment_V3": "lick ass, blowjob",
209
+ "snapchat_selfie": "selfie, snapchat",
210
+ "ultimate_realistic_breast": "urb, realistic breast",
211
  }
212
 
213
  # Tracks which adapter names have been successfully loaded into the pipeline.
 
248
  if name not in LOADED_ADAPTERS:
249
  try:
250
  print(f"--- Loading adapter: {name} ---")
251
+ cfg = LORA_CONFIGS[name]
252
+
253
+ if isinstance(cfg, tuple):
254
+ # LoRA from a different Hugging Face repo
255
+ repo_id, weight_name = cfg
256
+ pipe.load_lora_weights(
257
+ repo_id,
258
+ weight_name=weight_name,
259
+ adapter_name=name,
260
+ )
261
+ else:
262
+ # Normal LoRA from the main LORA_REPO
263
+ pipe.load_lora_weights(
264
+ LORA_REPO,
265
+ weight_name=cfg,
266
+ adapter_name=name,
267
+ )
268
+
269
  LOADED_ADAPTERS.add(name)
270
  except Exception as e:
271
  # If it already exists from a previous call in this Space session,
 
284
  pipe.set_adapters(loaded, adapter_weights=weights_out)
285
  else:
286
  pipe.disable_lora()
 
287
  return loaded, weights_out
288
 
289
 
 
330
 
331
  # ── Validate aspect ratio ────────────────────────────────────────────────
332
  # Extreme ratios (>4:1) produce degenerate latent shapes that crash the
333
+ # transformer or produce garbage. Reject early with a clear message.
334
  image = input_image.convert("RGB")
335
  w, h = image.size
336
  ratio = max(w, h) / max(min(w, h), 1)
 
389
  torch.cuda.empty_cache()
390
  # ─────────────────────────────────────────────────────────────────────
391
 
392
+
393
  # ── UI ─────────────────────────────────────────────────────────────────────────
394
  css = """
395
  #col-container { margin: 0 auto; max-width: 980px; }
 
419
  "**Fast local LoRA-powered image editing** powered by `Qwen-Image-Edit-2509` + `Qwen-Image-Edit-Rapid-AIO-V4` + 50+ community LoRAs.<br>"
420
  "Upload an image, describe the edit, optionally stack LoRAs, and hit **Edit Image**."
421
  )
422
+
423
  with gr.Accordion("💡 Quick Tips", open=False):
424
  gr.Markdown(
425
  "- **LoRAs auto-add trigger words** to your prompt when selected.<br>"
 
458
  with gr.Row():
459
  gr.Markdown("**Stack up to 6 LoRAs.** Select a LoRA to auto-fill trigger words in the prompt.")
460
  clear_btn = gr.Button("🧹 Clear All", size="sm", variant="secondary", scale=0)
461
+
462
  lora_stack = []
463
  for i in range(6):
464
  with gr.Row():
 
520
  inputs=[output_image],
521
  outputs=[input_image],
522
  )
 
523
  clear_output_btn.click(
524
  fn=lambda: gr.update(value=None),
525
  inputs=None,
 
529
  if __name__ == "__main__":
530
  demo.queue(max_size=30).launch(
531
  mcp_server=True, ssr_mode=False, show_error=True
532
+ )