mlr / app.py
TDN-M's picture
Update app.py
f5f2b71 verified
import gradio as gr
import torch
from diffusers import DiffusionPipeline
from peft import PeftModel
import shutil
import os
# --- Cấu hình mô hình ---
MODEL_NAME = "Qwen/Qwen-Image"
OUTPUT_DIR = "./merged_checkpoint"
def merge_loras(lora_a_id, lora_b_id):
# Xóa thư mục cũ nếu tồn tại
if os.path.exists(OUTPUT_DIR):
shutil.rmtree(OUTPUT_DIR)
os.makedirs(OUTPUT_DIR, exist_ok=True)
print(f"✅ Tải mô hình gốc Qwen-Image từ Hugging Face...")
device = "cuda" if torch.cuda.is_available() else "cpu"
torch_dtype = torch.bfloat16 if torch.cuda.is_available() else torch.float32
try:
pipe = DiffusionPipeline.from_pretrained(
MODEL_NAME,
torch_dtype=torch_dtype,
use_safetensors=True,
safety_checker=None,
feature_extractor=None,
trust_remote_code=True
).to(device)
print("✅ Tải mô hình gốc thành công!")
except Exception as e:
return f"❌ Lỗi khi tải mô hình gốc: {str(e)}"
# --- Hợp nhất LoRA A ---
print(f"🔧 Hợp nhất LoRA A: {lora_a_id}")
try:
pipe.unet = PeftModel.from_pretrained(pipe.unet, lora_a_id)
pipe.unet.merge_and_unload()
print("✅ Hợp nhất LoRA A thành công")
except Exception as e:
return f"❌ Lỗi khi hợp nhất LoRA A ({lora_a_id}): {str(e)}"
# --- Hợp nhất LoRA B ---
print(f"🔧 Hợp nhất LoRA B: {lora_b_id}")
try:
pipe.unet = PeftModel.from_pretrained(pipe.unet, lora_b_id)
pipe.unet.merge_and_unload()
print("✅ Hợp nhất LoRA B thành công")
except Exception as e:
return f"❌ Lỗi khi hợp nhất LoRA B ({lora_b_id}): {str(e)}"
# --- Lưu checkpoint hoàn chỉnh ---
try:
pipe.save_pretrained(OUTPUT_DIR, safe_serialization=True, max_shard_size="2GB")
print(f"✅ Lưu checkpoint vào: {OUTPUT_DIR}")
except Exception as e:
return f"❌ Lỗi khi lưu checkpoint: {str(e)}"
# --- Nén để download ---
shutil.make_archive(OUTPUT_DIR, 'zip', OUTPUT_DIR)
output_zip = OUTPUT_DIR + ".zip"
return output_zip
# --- Giao diện Gradio ---
with gr.Blocks(title="🎨 Qwen-Image: Insw + NSFW LoRA Merger") as demo:
gr.Markdown("""
# 🎨 Qwen-Image: Merge Insw + NSFW LoRA (Online Tool)
Hợp nhất hai LoRA nổi bật trên Hugging Face:
- **`rorito/Insw`**: Phong cách chân dung Trung Hoa cổ điển, tinh tế, ánh sáng dịu.
- **`StuffedPumpkins/nsfw_qwen_image`**: Thêm yếu tố NSFW (gợi cảm, thân thể con người) vào Qwen-Image.
✅ Kết quả: **Chân dung Trung Hoa cổ điển mang phong cách gợi cảm**, vẫn giữ khả năng **render văn bản siêu chuẩn** (chữ Hán, π≈3.14, biển hiệu...).
🔹 Không cần download gì cả
🔹 Chạy hoàn toàn trên cloud (miễn phí)
🔹 Xuất ra file `.zip` dùng ngay trong ComfyUI / Automatic1111
🔹 Tối ưu cho prompt chứa văn bản phức tạp
---
### 📥 Cách dùng:
1. Nhấn “🚀 Hợp nhất LoRA” (mặc định đã điền sẵn 2 LoRA bên dưới).
2. Sau vài phút, hệ thống sẽ tạo ra file `.zip`.
3. Tải về → giải nén → copy `merged_checkpoint/unet/diffusion_pytorch_model.safetensors` vào thư mục model của WebUI.
4. Dùng prompt ví dụ:
`"A beautiful Chinese woman in traditional hanfu, standing beside a neon sign reading '通义千问', soft candlelight, cinematic composition, ultra HD, 4K"`
→ Văn bản Trung và phong cách gợi cảm đều hiện ra chính xác!
> Model gốc: [Qwen-Image on Hugging Face](https://huggingface.co/Qwen/Qwen-Image)
> LoRA A: [rorito/Insw](https://huggingface.co/rorito/Insw)
> LoRA B: [StuffedPumpkins/nsfw_qwen_image](https://huggingface.co/StuffedPumpkins/nsfw_qwen_image)
""")
with gr.Row():
with gr.Column():
lora_a_input = gr.Textbox(label="📌 LoRA A (Chinese Portrait)", value="rorito/Insw", interactive=True)
lora_b_input = gr.Textbox(label="📌 LoRA B (NSFW)", value="StuffedPumpkins/nsfw_qwen_image", interactive=True)
merge_btn = gr.Button("🚀 Hợp nhất LoRA", variant="primary")
with gr.Column():
output_file = gr.File(label="📥 Kết quả: Checkpoint đã hợp nhất (.zip)")
merge_btn.click(fn=merge_loras, inputs=[lora_a_input, lora_b_input], outputs=output_file)
demo.launch()