KKNTR commited on
Commit
aa40fa7
·
verified ·
1 Parent(s): 54e4b6c

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +131 -0
  2. requirements.txt +8 -0
app.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from diffusers import StableDiffusionXLPipeline
3
+ import gradio as gr
4
+ import spaces
5
+ import random
6
+
7
+ model_id = "kkntr/sdxl-kkntr"
8
+
9
+ pipe = StableDiffusionXLPipeline.from_pretrained(
10
+ model_id,
11
+ torch_dtype=torch.float16,
12
+ use_safetensors=True
13
+ ).to("cuda")
14
+
15
+ # --- Rekisteröidään pysyvät LoRAt ADAPTEREINA (ei painoja vielä) ---
16
+ PERSISTENT_LORAS = {
17
+ "base1": ("kkntr/lora12", 0.4), # oletuspaino; muutettavissa generate():ssa
18
+ "base2": ("kkntr/lora2", 0.3),
19
+ "base3": ("kkntr/lora13", 0.9),
20
+ "base4": ("kkntr/lora1", 0.2),
21
+ "base5": ("kkntr/lora16", 0.0),
22
+
23
+ }
24
+ for name, (repo, _) in PERSISTENT_LORAS.items():
25
+ pipe.load_lora_weights(repo, adapter_name=name)
26
+
27
+ # --- Rekisteröidään tyyli-LoRAt ADAPTEREINA (ei painoja vielä) ---
28
+ STYLE_LORAS = {
29
+ "None": (None, 0.0, "", None),
30
+ "Foreskin play": ("kkntr/lora5", 1.0, "foreskin insertion", "style_fp"),
31
+ "Cum through clothing": ("kkntr/lora6", 1.0, "cum in clothing", "style_cc"),
32
+ "Penis through leghole": ("kkntr/lora7", 1.0, "penis through leghole, loose shorts, poking out", "style_ptl"),
33
+ "Frottage": ("kkntr/lora8", 1.0, "byfrottage, frottage", "style_fr"),
34
+ "Penis towards viewer": ("kkntr/lora9", 1.0, "penis_towards_viewer", "style_ptv"),
35
+ "Foreskin play closeup": ("kkntr/lora11", 1.0, "ZonkFS, close-up, furry, anthro, faceless male, penis, foreskin, fellatio, oral, foreskin kiss, foreskin play, side view, steam", "style_fscl"),
36
+ }
37
+ for key, spec in STYLE_LORAS.items():
38
+ repo = spec[0]
39
+ adapter_name = spec[3]
40
+ if repo and adapter_name:
41
+ pipe.load_lora_weights(repo, adapter_name=adapter_name)
42
+
43
+ resolutions = [
44
+ (592, 1768), (608, 1696), (640, 1624), (672, 1544),
45
+ (720, 1440), (744, 1392), (784, 1320), (832, 1248),
46
+ (864, 1208), (880, 1184), (912, 1144), (976, 1072),
47
+ (1024, 1024), (1072, 912), (1144, 912), (1184, 880),
48
+ (1208, 864), (1248, 832), (1320, 784), (1392, 744),
49
+ (1440, 720), (1544, 672), (1624, 640), (1696, 608),
50
+ (1768, 592),
51
+ ]
52
+
53
+ @spaces.GPU
54
+ def generate(prompt, negative_prompt, width, height, random_res, selected_style):
55
+ if random_res:
56
+ width, height = random.choice(resolutions)
57
+
58
+ # Rakennetaan listat aktiivisista adaptereista ja niiden painoista
59
+ adapter_names = []
60
+ adapter_weights = []
61
+
62
+ # 1) Pysyvät LoRAt
63
+ for name, (_, w) in PERSISTENT_LORAS.items():
64
+ adapter_names.append(name)
65
+ adapter_weights.append(w)
66
+
67
+ # 2) Tyyli-LoRA + trigger
68
+ if selected_style in STYLE_LORAS and selected_style != "None":
69
+ repo, style_w, trigger, style_adapter = STYLE_LORAS[selected_style]
70
+ prompt = f"{trigger}, {prompt}"
71
+ adapter_names.append(style_adapter)
72
+ adapter_weights.append(style_w) # esim. 7.0 jos haluat “mössöä”
73
+ # jos "None", ei lisätä tyyliadapteria
74
+
75
+ # Varmuuden vuoksi: ei fuseta, vaan käytetään dynaamisia painoja
76
+ # Jos olet joskus fusennut, nollaa se ensin:
77
+ try:
78
+ pipe.unfuse_lora()
79
+ except Exception:
80
+ pass
81
+
82
+ pipe.set_adapters(adapter_names, adapter_weights=adapter_weights)
83
+
84
+ quality_suffix = (
85
+ ", (anthro), (male), (best quality), high resolution, (ultra detailed),"
86
+ " 8k, (highly detailed), (masterpiece), (sharp focus), (intricate details),"
87
+ " (perfect anatomy), (depth of field), high dynamic range, (smooth shading),"
88
+ " (realistic shadows), (rich texture), professional color grading, (fine details),"
89
+ " ultra sharp, HDR, (anatomically correct), painterly realism, 20r0j_2, civifur"
90
+ )
91
+
92
+ full_prompt = prompt + quality_suffix
93
+
94
+ image = pipe(
95
+ prompt=full_prompt,
96
+ negative_prompt=negative_prompt,
97
+ width=width,
98
+ height=height,
99
+ num_inference_steps=35,
100
+ guidance_scale=7.5
101
+ ).images[0]
102
+
103
+ # (Valinnainen) palautetaan tekstiin näkyviin mitkä adapterit ja painot oli käytössä
104
+ used = ", ".join([f"{n}:{w}" for n, w in zip(adapter_names, adapter_weights)])
105
+ return image, f"{full_prompt}\n\n[adapters] {used}"
106
+
107
+ # UI sama kuin ennen
108
+ gr.Interface(
109
+ fn=generate,
110
+ inputs=[
111
+ gr.Textbox(label="Prompt"),
112
+ gr.Textbox(
113
+ label="Negative Prompt",
114
+ value="(worst quality), (low quality), (blurry), (bad anatomy), (fused fingers), (extra fingers), (missing fingers), (deformed), (jpeg artifacts), (watermark), (signature), text, error, out of frame, bad hands, bad feet, bad proportions, fused limbs, cropped, username, logo, bad perspective, lowres, overexposure, bad artist, bad composition, distorted, oversaturated, mutated, bad shadow, multiple limbs, extra arms, extra legs, bad background, tilted, bad lighting, bad face, ugly, bad eyes, disfigured, multiple pictures"
115
+ ),
116
+ gr.Slider(minimum=512, maximum=1024, step=64, value=768, label="Width"),
117
+ gr.Slider(minimum=512, maximum=1024, step=64, value=768, label="Height"),
118
+ gr.Checkbox(label="Random resolution mode (override sliders)", value=True),
119
+ gr.Dropdown(
120
+ choices=list(STYLE_LORAS.keys()),
121
+ value="None",
122
+ label="Select Style"
123
+ )
124
+ ],
125
+ outputs=[
126
+ gr.Image(label="Generated Image"),
127
+ gr.Textbox(label="Used Prompt", lines=6)
128
+ ],
129
+ title="FURRYSTYLE",
130
+ description="Give a prompt"
131
+ ).launch()
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ torch
2
+ diffusers[torch]
3
+ transformers
4
+ accelerate
5
+ safetensors
6
+ gradio
7
+ spaces
8
+ peft