Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -5,12 +5,14 @@ import torch
|
|
| 5 |
import os
|
| 6 |
import json
|
| 7 |
from datetime import datetime
|
| 8 |
-
from PIL import Image
|
| 9 |
|
|
|
|
| 10 |
PRESET_PATH = "prompt_presets.json"
|
| 11 |
IMAGE_SAVE_DIR = "generated_images"
|
| 12 |
os.makedirs(IMAGE_SAVE_DIR, exist_ok=True)
|
| 13 |
|
|
|
|
|
|
|
| 14 |
def upload_to_huggingface(image_path, token, repo_id):
|
| 15 |
try:
|
| 16 |
from huggingface_hub import HfApi
|
|
@@ -32,7 +34,7 @@ def upload_to_huggingface(image_path, token, repo_id):
|
|
| 32 |
except Exception as e:
|
| 33 |
return f"❌ Upload failed: {e}"
|
| 34 |
|
| 35 |
-
def start_training(instance_token, class_token, zip_file, output_dir, max_steps, lr, hf_token):
|
| 36 |
return train_model(
|
| 37 |
instance_token=instance_token,
|
| 38 |
class_token=class_token,
|
|
@@ -40,10 +42,12 @@ def start_training(instance_token, class_token, zip_file, output_dir, max_steps,
|
|
| 40 |
output_dir=output_dir,
|
| 41 |
max_train_steps=max_steps,
|
| 42 |
learning_rate=lr,
|
| 43 |
-
hf_token=hf_token
|
|
|
|
|
|
|
| 44 |
)
|
| 45 |
|
| 46 |
-
def generate_image(prompt, hf_token, model_dir, hf_dataset_repo
|
| 47 |
try:
|
| 48 |
if not os.path.exists(model_dir):
|
| 49 |
return "❌ Error: Trained model directory not found. Please train your model first.", None, None, None
|
|
@@ -53,10 +57,6 @@ def generate_image(prompt, hf_token, model_dir, hf_dataset_repo, reference_img=N
|
|
| 53 |
torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32
|
| 54 |
).to("cuda" if torch.cuda.is_available() else "cpu")
|
| 55 |
|
| 56 |
-
if reference_img:
|
| 57 |
-
ref = Image.open(reference_img).convert("RGB")
|
| 58 |
-
prompt += " using the pose/style from reference image"
|
| 59 |
-
|
| 60 |
image = pipe(prompt).images[0]
|
| 61 |
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
| 62 |
save_path = os.path.join(IMAGE_SAVE_DIR, f"generated_{timestamp}.png")
|
|
@@ -66,76 +66,24 @@ def generate_image(prompt, hf_token, model_dir, hf_dataset_repo, reference_img=N
|
|
| 66 |
except Exception as e:
|
| 67 |
return f"❌ Generation failed: {str(e)}", None, None, None
|
| 68 |
|
| 69 |
-
def build_character_prompt(**kwargs):
|
| 70 |
-
prompt_parts = []
|
| 71 |
-
for key, val in kwargs.items():
|
| 72 |
-
if val:
|
| 73 |
-
prompt_parts.append(f"{key.replace('_', ' ').title()}: {val}")
|
| 74 |
-
return "\n".join(prompt_parts)
|
| 75 |
-
|
| 76 |
def create_ui():
|
| 77 |
with gr.Blocks() as demo:
|
| 78 |
-
with gr.Tab("Character Builder"):
|
| 79 |
-
with gr.Row():
|
| 80 |
-
species = gr.Dropdown(label="Species", choices=["human", "animal hybrid", "demon", "spirit", "elf", "dwarf", "vampire", "fairy", "elemental", "monster"], value="human")
|
| 81 |
-
gender = gr.Dropdown(label="Gender", choices=["male", "female", "trans male", "trans female", "random"], value="female")
|
| 82 |
-
skin_tone = gr.Dropdown(label="Skin Tone", choices=["white", "grey", "black", "dark brown", "light brown", "deep tan", "golden tan", "light tan", "beige", "pale", "random"], value="beige")
|
| 83 |
-
with gr.Row():
|
| 84 |
-
head_shape = gr.Dropdown(label="Head Shape", choices=["oval", "round", "square", "diamond", "heart", "triangle", "random"])
|
| 85 |
-
right_eye = gr.Dropdown(label="Right Eye Color", choices=["black", "brown", "hazel", "green", "blue", "yellow", "red", "amber", "orange", "purple", "random"])
|
| 86 |
-
left_eye = gr.Dropdown(label="Left Eye Color", choices=["black", "brown", "hazel", "green", "blue", "yellow", "red", "amber", "orange", "purple", "random"])
|
| 87 |
-
with gr.Row():
|
| 88 |
-
eye_shape = gr.Dropdown(label="Eye Shape", choices=["almond", "round", "protruding", "mono-lid", "downturn", "upturn", "close-set", "wide-set", "deep-set", "hooded", "random"])
|
| 89 |
-
nose_shape = gr.Dropdown(label="Nose Shape", choices=["hooked", "droopy", "Roman", "aquiline", "Grecian", "button", "pixie", "upturned", "snub", "funnel", "flat", "wide", "bulbous", "crooked", "random"])
|
| 90 |
-
lip_shape = gr.Dropdown(label="Lip Shape", choices=["full", "wide", "narrow", "full upper", "full lower", "heart", "bow", "round", "thin", "downturned", "random"])
|
| 91 |
-
with gr.Row():
|
| 92 |
-
height = gr.Dropdown(label="Height", choices=["very short", "short", "average", "tall", "very tall", "gigantic", "enormous", "random"])
|
| 93 |
-
body_type = gr.Dropdown(label="Body Type Female", choices=["triangle", "inverted triangle", "rectangle", "oval", "round", "hourglass", "bottom heavy", "top heavy", "apple shaped", "pear shaped", "diamond", "thin", "lean", "athletic", "curvy", "voluptuous", "thick", "muscular", "petite", "fat", "random"], multiselect=True)
|
| 94 |
-
|
| 95 |
-
torso = gr.Textbox(label="Torso Clothing Description")
|
| 96 |
-
position = gr.Textbox(label="Body Position")
|
| 97 |
-
background = gr.Textbox(label="Background Description")
|
| 98 |
-
lighting = gr.Textbox(label="Lighting Description")
|
| 99 |
-
mood = gr.Textbox(label="Mood")
|
| 100 |
-
|
| 101 |
-
reference_img = gr.Image(label="Reference Image (Optional)", type="filepath")
|
| 102 |
-
randomize_btn = gr.Button("Randomize")
|
| 103 |
-
art_style = gr.Dropdown(label="Art Style Preset", choices=["Fantasy Manga", "Golden Age Comic", "Silver Age Comic", "90’s Extreme Comic Book", "Modern Comic Book", "Anime", "Realistic"], value="Fantasy Manga")
|
| 104 |
-
hf_token = gr.Textbox(label="Hugging Face Token", type="password")
|
| 105 |
-
model_dir = gr.Textbox(label="Trained Model Directory", value="trained_model")
|
| 106 |
-
hf_dataset_repo = gr.Textbox(label="Hugging Face Dataset Repo ID", value="generated-images")
|
| 107 |
-
prompt_output = gr.Textbox(label="Generated Prompt")
|
| 108 |
-
generate_btn = gr.Button("Generate Prompt & Image")
|
| 109 |
-
image_output = gr.Image(label="Generated Image")
|
| 110 |
-
file_path_display = gr.Textbox(label="File Path")
|
| 111 |
-
upload_status = gr.Textbox(label="Upload Status")
|
| 112 |
-
|
| 113 |
-
def compose_and_generate(*args):
|
| 114 |
-
keys = ["species", "gender", "skin_tone", "head_shape", "right_eye", "left_eye", "eye_shape", "nose_shape", "lip_shape", "height", "body_type", "torso", "position", "background", "lighting", "mood", "art_style"]
|
| 115 |
-
prompt = build_character_prompt(**{k: v for k, v in zip(keys, args[:-4]) if v})
|
| 116 |
-
prompt += f"\nArt style: {args[-4]}"
|
| 117 |
-
return (prompt,) + generate_image(prompt, args[-3], args[-2], args[-1], args[-5])
|
| 118 |
-
|
| 119 |
-
generate_btn.click(
|
| 120 |
-
fn=compose_and_generate,
|
| 121 |
-
inputs=[species, gender, skin_tone, head_shape, right_eye, left_eye, eye_shape, nose_shape, lip_shape, height, body_type, torso, position, background, lighting, mood, art_style, reference_img, hf_token, model_dir, hf_dataset_repo],
|
| 122 |
-
outputs=[prompt_output, image_output, file_path_display, upload_status]
|
| 123 |
-
)
|
| 124 |
-
|
| 125 |
with gr.Tab("Train Model"):
|
| 126 |
instance_token = gr.Textbox(label="Instance Token")
|
| 127 |
class_token = gr.Textbox(label="Class Token")
|
| 128 |
zip_file = gr.File(label="Training ZIP File")
|
| 129 |
output_dir = gr.Textbox(label="Output Directory", value="trained_model")
|
| 130 |
-
max_steps = gr.Number(label="Max Training Steps", value=
|
| 131 |
lr = gr.Number(label="Learning Rate", value=5e-6)
|
|
|
|
|
|
|
| 132 |
hf_token_train = gr.Textbox(label="Hugging Face Token", type="password")
|
| 133 |
train_btn = gr.Button("Start Training")
|
| 134 |
-
train_output = gr.Textbox(label="Training Output")
|
| 135 |
|
| 136 |
train_btn.click(
|
| 137 |
fn=start_training,
|
| 138 |
-
inputs=[instance_token, class_token, zip_file, output_dir, max_steps, lr, hf_token_train],
|
| 139 |
outputs=train_output
|
| 140 |
)
|
| 141 |
|
|
@@ -160,4 +108,3 @@ def create_ui():
|
|
| 160 |
demo = create_ui()
|
| 161 |
if __name__ == "__main__":
|
| 162 |
demo.launch()
|
| 163 |
-
|
|
|
|
| 5 |
import os
|
| 6 |
import json
|
| 7 |
from datetime import datetime
|
|
|
|
| 8 |
|
| 9 |
+
# Path to save/load preset prompts
|
| 10 |
PRESET_PATH = "prompt_presets.json"
|
| 11 |
IMAGE_SAVE_DIR = "generated_images"
|
| 12 |
os.makedirs(IMAGE_SAVE_DIR, exist_ok=True)
|
| 13 |
|
| 14 |
+
# Optional: Upload to HF Hub with repo check
|
| 15 |
+
|
| 16 |
def upload_to_huggingface(image_path, token, repo_id):
|
| 17 |
try:
|
| 18 |
from huggingface_hub import HfApi
|
|
|
|
| 34 |
except Exception as e:
|
| 35 |
return f"❌ Upload failed: {e}"
|
| 36 |
|
| 37 |
+
def start_training(instance_token, class_token, zip_file, output_dir, max_steps, lr, hf_token, seed, precision):
|
| 38 |
return train_model(
|
| 39 |
instance_token=instance_token,
|
| 40 |
class_token=class_token,
|
|
|
|
| 42 |
output_dir=output_dir,
|
| 43 |
max_train_steps=max_steps,
|
| 44 |
learning_rate=lr,
|
| 45 |
+
hf_token=hf_token,
|
| 46 |
+
seed=seed,
|
| 47 |
+
precision=precision
|
| 48 |
)
|
| 49 |
|
| 50 |
+
def generate_image(prompt, hf_token, model_dir, hf_dataset_repo):
|
| 51 |
try:
|
| 52 |
if not os.path.exists(model_dir):
|
| 53 |
return "❌ Error: Trained model directory not found. Please train your model first.", None, None, None
|
|
|
|
| 57 |
torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32
|
| 58 |
).to("cuda" if torch.cuda.is_available() else "cpu")
|
| 59 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
image = pipe(prompt).images[0]
|
| 61 |
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
| 62 |
save_path = os.path.join(IMAGE_SAVE_DIR, f"generated_{timestamp}.png")
|
|
|
|
| 66 |
except Exception as e:
|
| 67 |
return f"❌ Generation failed: {str(e)}", None, None, None
|
| 68 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
def create_ui():
|
| 70 |
with gr.Blocks() as demo:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
with gr.Tab("Train Model"):
|
| 72 |
instance_token = gr.Textbox(label="Instance Token")
|
| 73 |
class_token = gr.Textbox(label="Class Token")
|
| 74 |
zip_file = gr.File(label="Training ZIP File")
|
| 75 |
output_dir = gr.Textbox(label="Output Directory", value="trained_model")
|
| 76 |
+
max_steps = gr.Number(label="Max Training Steps", value=1200)
|
| 77 |
lr = gr.Number(label="Learning Rate", value=5e-6)
|
| 78 |
+
seed = gr.Number(label="Random Seed", value=42)
|
| 79 |
+
precision = gr.Dropdown(label="Precision Mode", choices=["fp16", "fp32"], value="fp16")
|
| 80 |
hf_token_train = gr.Textbox(label="Hugging Face Token", type="password")
|
| 81 |
train_btn = gr.Button("Start Training")
|
| 82 |
+
train_output = gr.Textbox(label="Training Output", lines=8)
|
| 83 |
|
| 84 |
train_btn.click(
|
| 85 |
fn=start_training,
|
| 86 |
+
inputs=[instance_token, class_token, zip_file, output_dir, max_steps, lr, hf_token_train, seed, precision],
|
| 87 |
outputs=train_output
|
| 88 |
)
|
| 89 |
|
|
|
|
| 108 |
demo = create_ui()
|
| 109 |
if __name__ == "__main__":
|
| 110 |
demo.launch()
|
|
|