File size: 4,625 Bytes
043c5e6
 
 
 
 
 
 
f5f2b71
043c5e6
 
 
 
 
 
 
 
 
f5f2b71
043c5e6
 
 
 
 
 
 
 
 
f5f2b71
 
043c5e6
f5f2b71
043c5e6
f5f2b71
043c5e6
f5f2b71
043c5e6
 
 
 
f5f2b71
043c5e6
 
 
f5f2b71
043c5e6
 
 
 
f5f2b71
043c5e6
 
 
f5f2b71
043c5e6
f5f2b71
 
043c5e6
 
 
f5f2b71
043c5e6
 
 
 
 
 
 
 
 
 
 
 
 
 
f5f2b71
043c5e6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
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()