Update app.py
Browse files
app.py
CHANGED
|
@@ -1,85 +1,5 @@
|
|
| 1 |
-
import os
|
| 2 |
-
import torch
|
| 3 |
-
import torch.nn as nn
|
| 4 |
-
from huggingface_hub import hf_hub_download
|
| 5 |
-
from torchvision import transforms, models
|
| 6 |
-
from PIL import Image
|
| 7 |
import gradio as gr
|
| 8 |
|
| 9 |
-
# ==========================================
|
| 10 |
-
# 1. CONFIGURATION CHIRURGICALE
|
| 11 |
-
# ==========================================
|
| 12 |
-
DEVICE = torch.device("cpu") # Forcé sur CPU pour un Space CPU standard
|
| 13 |
-
MODEL_INPUT_SIZE = 224 # Taille obligatoire pour le Vision Transformer (ViT)
|
| 14 |
-
REPO_ID = "KTXStudio/MinecraftSkinImg-To-Img"
|
| 15 |
-
FILENAME = "vit_minecraft_core.pth"
|
| 16 |
-
SKIN_SIZE = 128 # Taille cible HD du skin Minecraft
|
| 17 |
-
|
| 18 |
-
# Téléchargement automatique depuis Hugging Face Hub au démarrage
|
| 19 |
-
print("⏳ Téléchargement des poids depuis le Hub...")
|
| 20 |
-
MODEL_PATH = hf_hub_download(repo_id=REPO_ID, filename=FILENAME)
|
| 21 |
-
|
| 22 |
-
# ==========================================
|
| 23 |
-
# 2. ARCHITECTURE EXACTE : VISION TRANSFORMER
|
| 24 |
-
# ==========================================
|
| 25 |
-
class ViTSkinGenerator(nn.Module):
|
| 26 |
-
def __init__(self):
|
| 27 |
-
super().__init__()
|
| 28 |
-
# weights=None remplace pretrained=False dans les versions récentes de torchvision
|
| 29 |
-
vit = models.vit_b_16(weights=None)
|
| 30 |
-
self.transformer_core = vit
|
| 31 |
-
num_features = vit.heads.head.in_features
|
| 32 |
-
|
| 33 |
-
# Décodeur de projection géométrique (Grille propre de 128x128x3)
|
| 34 |
-
self.transformer_core.heads = nn.Sequential(
|
| 35 |
-
nn.Linear(num_features, 2048),
|
| 36 |
-
nn.GELU(),
|
| 37 |
-
nn.Dropout(0.1),
|
| 38 |
-
nn.Linear(2048, 4096),
|
| 39 |
-
nn.GELU(),
|
| 40 |
-
nn.Linear(4096, 3 * SKIN_SIZE * SKIN_SIZE),
|
| 41 |
-
nn.Sigmoid()
|
| 42 |
-
)
|
| 43 |
-
|
| 44 |
-
def forward(self, x):
|
| 45 |
-
out = self.transformer_core(x)
|
| 46 |
-
out = out.view(-1, 3, SKIN_SIZE, SKIN_SIZE)
|
| 47 |
-
return out
|
| 48 |
-
|
| 49 |
-
# ==========================================
|
| 50 |
-
# 3. CHARGEMENT DE VOS POIDS AU LANCEMENT
|
| 51 |
-
# ==========================================
|
| 52 |
-
model = ViTSkinGenerator().to(DEVICE)
|
| 53 |
-
print(f"💾 Chargement des poids depuis le cache local : {MODEL_PATH}...")
|
| 54 |
-
model.load_state_dict(torch.load(MODEL_PATH, map_location=DEVICE))
|
| 55 |
-
model.eval()
|
| 56 |
-
|
| 57 |
-
# ==========================================
|
| 58 |
-
# 4. FONCTION DE PRÉDICTION POUR GRADIO
|
| 59 |
-
# ==========================================
|
| 60 |
-
def predict_skin(input_image):
|
| 61 |
-
if input_image is None:
|
| 62 |
-
return None
|
| 63 |
-
|
| 64 |
-
# 1. Traitement de l'image d'entrée (LANCZOS pour garder la netteté)
|
| 65 |
-
img = input_image.convert("RGB").resize((MODEL_INPUT_SIZE, MODEL_INPUT_SIZE), Image.Resampling.LANCZOS)
|
| 66 |
-
|
| 67 |
-
transform = transforms.Compose([
|
| 68 |
-
transforms.ToTensor(),
|
| 69 |
-
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
|
| 70 |
-
])
|
| 71 |
-
tensor_in = transform(img).unsqueeze(0).to(DEVICE)
|
| 72 |
-
|
| 73 |
-
# 2. Inférence brute et stricte de l'IA
|
| 74 |
-
with torch.no_grad():
|
| 75 |
-
tensor_out = model(tensor_in).squeeze(0).cpu()
|
| 76 |
-
|
| 77 |
-
# 3. Post-traitement minimal (Uniquement l'écrêtage obligatoire pour convertir en image PIL)
|
| 78 |
-
tensor_out = torch.clamp(tensor_out, 0, 1)
|
| 79 |
-
skin_pil = transforms.ToPILImage()(tensor_out)
|
| 80 |
-
skin_final = skin_pil.resize((SKIN_SIZE, SKIN_SIZE), Image.Resampling.NEAREST)
|
| 81 |
-
|
| 82 |
-
return skin_final
|
| 83 |
|
| 84 |
# ==========================================
|
| 85 |
# 5. INTERFACE DESIGN BLOCKS (GRADIO INTERACTIVE)
|
|
@@ -87,27 +7,8 @@ def predict_skin(input_image):
|
|
| 87 |
with gr.Blocks(theme=gr.themes.Soft(primary_hue="green", secondary_hue="slate")) as demo:
|
| 88 |
gr.Markdown(
|
| 89 |
"""
|
| 90 |
-
#
|
| 91 |
-
|
| 92 |
-
"""
|
| 93 |
-
)
|
| 94 |
-
|
| 95 |
-
with gr.Row():
|
| 96 |
-
with gr.Column():
|
| 97 |
-
input_img = gr.Image(type="pil", label="📥 Téléverse ton personnage (Rendu 3D / Image)")
|
| 98 |
-
submit_btn = gr.Button("✨ Générer le Skin HD", variant="primary")
|
| 99 |
-
|
| 100 |
-
with gr.Column():
|
| 101 |
-
output_img = gr.Image(type="pil", label="✨ Skin Minecraft HD Extrait (128x128)", image_mode="RGB")
|
| 102 |
-
|
| 103 |
-
# Lier le bouton à la fonction de prédiction
|
| 104 |
-
submit_btn.click(fn=predict_skin, inputs=input_img, outputs=output_img)
|
| 105 |
-
|
| 106 |
-
gr.Examples(
|
| 107 |
-
examples=["A.jpg"] if os.path.exists("A.jpg") else [],
|
| 108 |
-
inputs=input_img,
|
| 109 |
-
label="Exemples disponibles"
|
| 110 |
-
)
|
| 111 |
|
| 112 |
# Lancement de l'application
|
| 113 |
if __name__ == "__main__":
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
|
| 4 |
# ==========================================
|
| 5 |
# 5. INTERFACE DESIGN BLOCKS (GRADIO INTERACTIVE)
|
|
|
|
| 7 |
with gr.Blocks(theme=gr.themes.Soft(primary_hue="green", secondary_hue="slate")) as demo:
|
| 8 |
gr.Markdown(
|
| 9 |
"""
|
| 10 |
+
#This spaces will be use for another job just wait.
|
| 11 |
+
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
|
| 13 |
# Lancement de l'application
|
| 14 |
if __name__ == "__main__":
|