XnOwO commited on
Commit
e6fc2ef
·
verified ·
1 Parent(s): b5806ca

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +101 -86
app.py CHANGED
@@ -3,123 +3,138 @@ import torch
3
  import spaces
4
  from diffusers import DiffusionPipeline
5
  import os
 
 
 
6
 
7
  # -----------------------------------------------------------------------------
8
- # 1. CONFIGURACIÓN Y CARGA DEL MODELO
9
  # -----------------------------------------------------------------------------
10
  MODEL_ID = "NewBie-AI/NewBie-image-Exp0.1"
 
11
 
12
- print(f"🔄 Iniciando carga del modelo: {MODEL_ID}")
13
- print(" Nota: Esto puede tardar unos minutos la primera vez mientras se descargan los pesos.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
- # Cargamos el pipeline.
16
- # SOLUCIÓN APLICADA: 'custom_pipeline' fuerza la descarga del script de gestión del repo,
17
- # evitando el error de ruta 'transformer/transformer.py' que te salía antes.
18
- pipe = DiffusionPipeline.from_pretrained(
19
- MODEL_ID,
20
- custom_pipeline=MODEL_ID, # <--- EL CAMBIO CLAVE
21
- torch_dtype=torch.bfloat16, # bfloat16 es nativo y más rápido en A100 (ZeroGPU)
22
- trust_remote_code=True
23
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
  # -----------------------------------------------------------------------------
26
- # 2. FUNCIÓN DE GENERACIÓN (ZeroGPU)
27
  # -----------------------------------------------------------------------------
28
- # El decorador @spaces.GPU maneja la asignación de hardware.
29
- # duration=120 da tiempo suficiente para imágenes grandes sin timeout.
30
  @spaces.GPU(duration=120)
31
  def generate_image(prompt, negative_prompt, steps, cfg, width, height):
32
- print("🚀 ZeroGPU Asignada. Moviendo modelo a CUDA y generando...")
33
-
34
- # Mover a GPU solo dentro de la función decorada
35
  pipe.to("cuda")
36
 
37
- # Ejecutar inferencia
38
- try:
39
- image = pipe(
40
- prompt=prompt,
41
- negative_prompt=negative_prompt,
42
- num_inference_steps=int(steps),
43
- guidance_scale=float(cfg),
44
- width=int(width),
45
- height=int(height)
46
- ).images[0]
47
- return image
48
- except Exception as e:
49
- print(f"Error durante la generación: {e}")
50
- return None
51
 
52
  # -----------------------------------------------------------------------------
53
- # 3. INTERFAZ GRÁFICA (GRADIO)
54
  # -----------------------------------------------------------------------------
55
- # CSS para mejorar un poco la estética
56
  css = """
57
  .container { max-width: 900px; margin: auto; }
58
- textarea { font-family: monospace; }
59
  """
60
 
61
- # Prompt por defecto optimizado para este modelo (Formato XML)
62
  DEFAULT_PROMPT = """<character_1>
63
  <gender>1girl</gender>
64
- <appearance>red_eyes, white_hair, long_hair, floating_hair</appearance>
65
- <clothing>japanese_clothes, kimono, floral_print</clothing>
66
- <action>standing, holding_fan, looking_at_viewer</action>
67
  </character_1>
68
  <general_tags>
69
- <quality>best quality, masterpiece, 4k, highres</quality>
70
- <style>anime, vivid_colors, cherry_blossoms</style>
71
  </general_tags>"""
72
 
73
- DEFAULT_NEGATIVE = "low quality, bad anatomy, worst quality, watermark, text, error, jpeg artifacts, signature"
74
 
75
  with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
76
- gr.Markdown("""
77
- # ⛩️ NewBie Anime Generator (ZeroGPU Edition)
78
-
79
- Este espacio utiliza el modelo experimental **NewBie-image-Exp0.1**.
80
- Este modelo entiende mejor los prompts si usas una estructura **XML** (ver ejemplo abajo).
81
- """)
82
 
83
  with gr.Row():
84
- with gr.Column(scale=1):
85
- prompt_input = gr.Textbox(
86
- label="Prompt (Estructura XML Recomendada)",
87
- value=DEFAULT_PROMPT,
88
- lines=12,
89
- placeholder="Escribe tu prompt aquí..."
90
- )
91
- neg_prompt_input = gr.Textbox(
92
- label="Negative Prompt",
93
- value=DEFAULT_NEGATIVE,
94
- lines=2
95
- )
96
-
97
- with gr.Accordion("⚙️ Configuración Avanzada", open=False):
98
- with gr.Row():
99
- width_slider = gr.Slider(512, 1280, value=1024, step=64, label="Ancho")
100
- height_slider = gr.Slider(512, 1280, value=1024, step=64, label="Alto")
101
- steps_slider = gr.Slider(10, 50, value=28, step=1, label="Pasos (Steps)")
102
- cfg_slider = gr.Slider(1, 15, value=7.0, step=0.1, label="Guidance Scale")
103
-
104
- btn_run = gr.Button("🎨 Generar Imagen", variant="primary", scale=1)
105
-
106
- with gr.Column(scale=1):
107
- output_image = gr.Image(label="Resultado", type="pil", interactive=False)
108
 
109
- # Evento de clic
110
- btn_run.click(
111
- fn=generate_image,
112
- inputs=[
113
- prompt_input,
114
- neg_prompt_input,
115
- steps_slider,
116
- cfg_slider,
117
- width_slider,
118
- height_slider
119
- ],
120
- outputs=output_image
121
- )
122
 
123
- # Lanzar la aplicación
124
  if __name__ == "__main__":
125
  demo.launch()
 
3
  import spaces
4
  from diffusers import DiffusionPipeline
5
  import os
6
+ import shutil
7
+ import json
8
+ from huggingface_hub import snapshot_download
9
 
10
  # -----------------------------------------------------------------------------
11
+ # 1. FUNCIÓN DE REPARACIÓN Y CARGA (La solución al error)
12
  # -----------------------------------------------------------------------------
13
  MODEL_ID = "NewBie-AI/NewBie-image-Exp0.1"
14
+ LOCAL_DIR = "./newbie_fixed_model"
15
 
16
+ def load_fixed_pipeline():
17
+ print(f"🛠️ Iniciando protocolo de reparación para {MODEL_ID}...")
18
+
19
+ # 1. Descargar el repositorio completo a una carpeta local
20
+ if not os.path.exists(LOCAL_DIR):
21
+ print(f" Descargando snapshot del modelo... (Esto tardará un poco)")
22
+ snapshot_download(
23
+ repo_id=MODEL_ID,
24
+ local_dir=LOCAL_DIR,
25
+ ignore_patterns=["*.msgpack", "*.bin"] # Ignoramos binarios redundantes si hay safetensors
26
+ )
27
+
28
+ # 2. Analizar y corregir el fallo de estructura (transformer/transformer.py)
29
+ transformer_folder = os.path.join(LOCAL_DIR, "transformer")
30
+
31
+ # Si la carpeta 'transformer' no existe, la creamos
32
+ if not os.path.exists(transformer_folder):
33
+ os.makedirs(transformer_folder, exist_ok=True)
34
+ print(" Carpeta 'transformer' creada.")
35
+
36
+ # BUSCAMOS EL ARCHIVO PERDIDO
37
+ # El repo suele tener el archivo en la raíz con nombres como 'transformer.py' o 'modeling_newbie.py'
38
+ # Vamos a buscar archivos python candidatos en la raíz
39
+ candidates = [f for f in os.listdir(LOCAL_DIR) if f.endswith(".py") and "test" not in f]
40
+
41
+ # Buscamos específicamente uno que parezca el del transformer
42
+ target_file = None
43
+ for f in candidates:
44
+ if "transformer" in f or "modeling" in f:
45
+ target_file = f
46
+ break
47
+
48
+ # Si encontramos el archivo, lo copiamos a la carpeta transformer/transformer.py
49
+ if target_file:
50
+ src = os.path.join(LOCAL_DIR, target_file)
51
+ dst = os.path.join(transformer_folder, "transformer.py")
52
+ shutil.copy(src, dst)
53
+ print(f" ✅ Archivo reparado: Movido {target_file} a transformer/transformer.py")
54
+
55
+ # También necesitamos un __init__.py vacío para que sea un módulo
56
+ with open(os.path.join(transformer_folder, "__init__.py"), "w") as f:
57
+ f.write("")
58
+ else:
59
+ print(" ⚠️ ADVERTENCIA: No se encontró un archivo Python candidato obvio en la raíz.")
60
 
61
+ # 3. Cargar desde la carpeta local reparada
62
+ print(" Cargando pipeline desde disco local...")
63
+ try:
64
+ pipe = DiffusionPipeline.from_pretrained(
65
+ LOCAL_DIR,
66
+ torch_dtype=torch.bfloat16,
67
+ trust_remote_code=True,
68
+ local_files_only=True
69
+ )
70
+ return pipe
71
+ except Exception as e:
72
+ print(f" ❌ Error fatal cargando localmente: {e}")
73
+ # Intento desesperado: Carga remota estándar si el parche falla,
74
+ # pero quitando custom_pipeline que a veces causa bucles
75
+ return DiffusionPipeline.from_pretrained(
76
+ MODEL_ID,
77
+ torch_dtype=torch.bfloat16,
78
+ trust_remote_code=True
79
+ )
80
+
81
+ # Ejecutamos la carga al iniciar la app
82
+ pipe = load_fixed_pipeline()
83
 
84
  # -----------------------------------------------------------------------------
85
+ # 2. LÓGICA ZEROGPU
86
  # -----------------------------------------------------------------------------
 
 
87
  @spaces.GPU(duration=120)
88
  def generate_image(prompt, negative_prompt, steps, cfg, width, height):
89
+ print("🚀 ZeroGPU Asignada. Generando...")
 
 
90
  pipe.to("cuda")
91
 
92
+ image = pipe(
93
+ prompt=prompt,
94
+ negative_prompt=negative_prompt,
95
+ num_inference_steps=int(steps),
96
+ guidance_scale=float(cfg),
97
+ width=int(width),
98
+ height=int(height)
99
+ ).images[0]
100
+ return image
 
 
 
 
 
101
 
102
  # -----------------------------------------------------------------------------
103
+ # 3. INTERFAZ GRADIO
104
  # -----------------------------------------------------------------------------
 
105
  css = """
106
  .container { max-width: 900px; margin: auto; }
 
107
  """
108
 
 
109
  DEFAULT_PROMPT = """<character_1>
110
  <gender>1girl</gender>
111
+ <appearance>blue_eyes, silver_hair, long_hair</appearance>
112
+ <clothing>school_uniform, serafuku</clothing>
113
+ <action>standing, smile</action>
114
  </character_1>
115
  <general_tags>
116
+ <quality>masterpiece, best quality, 4k</quality>
117
+ <style>anime, vivid_colors</style>
118
  </general_tags>"""
119
 
120
+ DEFAULT_NEGATIVE = "low quality, bad anatomy, worst quality, watermark, text"
121
 
122
  with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
123
+ gr.Markdown("# ⛩️ NewBie Anime Generator (Auto-Fixed Edition)")
124
+ gr.Markdown("Este espacio incluye un script de **auto-reparación** para solucionar el error de estructura del repositorio NewBie-Exp0.1.")
 
 
 
 
125
 
126
  with gr.Row():
127
+ with gr.Column():
128
+ prompt_input = gr.Textbox(label="Prompt (XML)", value=DEFAULT_PROMPT, lines=10)
129
+ neg_prompt_input = gr.Textbox(label="Negative", value=DEFAULT_NEGATIVE)
130
+ with gr.Row():
131
+ steps = gr.Slider(10, 50, value=28, label="Pasos")
132
+ cfg = gr.Slider(1, 15, value=7.0, label="CFG")
133
+ btn = gr.Button("Generar", variant="primary")
134
+ with gr.Column():
135
+ out = gr.Image(label="Resultado")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
 
137
+ btn.click(generate_image, inputs=[prompt_input, neg_prompt_input, steps, cfg], outputs=out)
 
 
 
 
 
 
 
 
 
 
 
 
138
 
 
139
  if __name__ == "__main__":
140
  demo.launch()