=Apyhtml20 commited on
Commit
0f63870
·
1 Parent(s): f5d95c2

Initial commit

Browse files
Files changed (2) hide show
  1. app.py +115 -0
  2. requirements.txt +7 -0
app.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import numpy as np
4
+ import random
5
+ from diffusers import FluxImg2ImgPipeline
6
+ from PIL import Image
7
+
8
+ dtype = torch.bfloat16
9
+ device = "cuda" if torch.cuda.is_available() else "cpu"
10
+ MAX_SEED = np.iinfo(np.int32).max
11
+
12
+ MODEL_ID = "black-forest-labs/FLUX.1-dev"
13
+ LORA_REPO = "alvdansen/flux-koda"
14
+ LORA_FILE = "flux_dev_koda_araminta_k.safetensors"
15
+
16
+ STYLES = {
17
+ "Anime": {
18
+ "lora": "alvdansen/flux-koda",
19
+ "file": "flux_dev_koda_araminta_k.safetensors",
20
+ "prompt": "anime style portrait, detailed face, vibrant colors, high quality"
21
+ },
22
+ "Pixel Art": {
23
+ "lora": "nerijs/pixel-art-xl",
24
+ "file": "pixel-art-xl.safetensors",
25
+ "prompt": "pixel art avatar, 16-bit style, retro game character"
26
+ },
27
+ "Ghibli": {
28
+ "lora": "aleksa-codes/flux-ghibsky-illustration",
29
+ "file": "flux_ghibsky_illustration.safetensors",
30
+ "prompt": "ghibli studio style illustration, soft colors, dreamy atmosphere"
31
+ },
32
+ }
33
+
34
+ print("Chargement du modèle...")
35
+ pipe = FluxImg2ImgPipeline.from_pretrained(MODEL_ID, torch_dtype=dtype)
36
+ pipe.to(device)
37
+
38
+ current_style = None
39
+
40
+ def generate_avatar(
41
+ input_image,
42
+ style_name,
43
+ strength,
44
+ seed,
45
+ randomize_seed,
46
+ progress=gr.Progress(track_tqdm=True)
47
+ ):
48
+ global current_style
49
+
50
+ if input_image is None:
51
+ raise gr.Error("Veuillez uploader une photo !")
52
+
53
+ # Charger le bon LoRA selon le style
54
+ if style_name != current_style:
55
+ style = STYLES[style_name]
56
+ pipe.unload_lora_weights()
57
+ pipe.load_lora_weights(style["lora"], weight_name=style["file"])
58
+ current_style = style_name
59
+
60
+ if randomize_seed:
61
+ seed = random.randint(0, MAX_SEED)
62
+
63
+ generator = torch.Generator(device=device).manual_seed(seed)
64
+ prompt = STYLES[style_name]["prompt"]
65
+
66
+ # Redimensionner l'image input
67
+ input_image = input_image.resize((512, 512))
68
+
69
+ result = pipe(
70
+ prompt=prompt,
71
+ image=input_image,
72
+ strength=strength, # 0.5 = garde ressemblance, 0.9 = full style
73
+ num_inference_steps=20,
74
+ guidance_scale=3.5,
75
+ generator=generator,
76
+ ).images[0]
77
+
78
+ return (input_image, result), seed
79
+
80
+
81
+ with gr.Blocks() as demo:
82
+ gr.Markdown("# Avatar Generator — Transformez votre photo en personnage")
83
+
84
+ with gr.Row():
85
+ with gr.Column():
86
+ input_img = gr.Image(label="Votre photo", type="pil")
87
+ style = gr.Radio(
88
+ choices=list(STYLES.keys()),
89
+ label="Style d'avatar",
90
+ value="Anime"
91
+ )
92
+ strength = gr.Slider(
93
+ label="Intensité du style",
94
+ minimum=0.3, maximum=0.95,
95
+ step=0.05, value=0.7,
96
+ info="Bas = garde votre visage, Haut = stylisation forte"
97
+ )
98
+ with gr.Accordion("Paramètres avancés", open=False):
99
+ seed = gr.Slider(0, MAX_SEED, step=1, value=42, label="Seed")
100
+ randomize_seed = gr.Checkbox(label="Seed aléatoire", value=True)
101
+
102
+ btn = gr.Button("Générer mon avatar", variant="primary")
103
+
104
+ result_slider = gr.ImageSlider(label="Avant / Après", type="pil")
105
+
106
+ seed_out = gr.Number(label="Seed utilisé", visible=False)
107
+
108
+ btn.click(
109
+ fn=generate_avatar,
110
+ inputs=[input_img, style, strength, seed, randomize_seed],
111
+ outputs=[result_slider, seed_out]
112
+ )
113
+
114
+ if __name__ == "__main__":
115
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ gradio>=4.0
2
+ diffusers>=0.27
3
+ transformers
4
+ torch
5
+ accelerate
6
+ safetensors
7
+ Pillow