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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +90 -69
app.py CHANGED
@@ -1,92 +1,115 @@
1
  import gradio as gr
2
  import torch
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(
@@ -100,41 +123,39 @@ def generate_image(prompt, negative_prompt, steps, cfg, width, height):
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()
 
1
  import gradio as gr
2
  import torch
3
  import spaces
 
4
  import os
5
  import shutil
6
+ import sys
7
+ import importlib.util
8
  from huggingface_hub import snapshot_download
9
 
10
  # -----------------------------------------------------------------------------
11
+ # 1. FUNCIÓN DE INGENIERÍA INVERSA Y CARGA
12
  # -----------------------------------------------------------------------------
13
  MODEL_ID = "NewBie-AI/NewBie-image-Exp0.1"
14
  LOCAL_DIR = "./newbie_fixed_model"
15
 
16
+ def load_hard_fixed_pipeline():
17
+ print(f"🛠️ Iniciando protocolo de carga manual para {MODEL_ID}...")
18
 
19
+ # --- PASO 1: Descarga ---
20
  if not os.path.exists(LOCAL_DIR):
21
+ print(f" Descargando snapshot del modelo...")
22
  snapshot_download(
23
  repo_id=MODEL_ID,
24
  local_dir=LOCAL_DIR,
25
+ ignore_patterns=["*.msgpack", "*.bin"]
26
  )
27
 
28
+ # --- PASO 2: Arreglar estructura de carpetas (Transformer) ---
29
  transformer_folder = os.path.join(LOCAL_DIR, "transformer")
 
 
30
  if not os.path.exists(transformer_folder):
31
  os.makedirs(transformer_folder, exist_ok=True)
32
+ # Buscar el archivo del transformer
 
 
 
 
33
  candidates = [f for f in os.listdir(LOCAL_DIR) if f.endswith(".py") and "test" not in f]
 
 
 
34
  for f in candidates:
35
+ # Movemos cualquier cosa que parezca transformer o modeling
36
+ if "transformer" in f.lower() or "modeling" in f.lower():
37
+ src = os.path.join(LOCAL_DIR, f)
38
+ # El model_index suele buscar 'transformer.py' o 'modeling_transformer.py'
39
+ # Lo renombramos a transformer.py para estandarizar
40
+ dst = os.path.join(transformer_folder, "transformer.py")
41
+ if not os.path.exists(dst): # Solo si no existe ya
42
+ shutil.copy(src, dst)
43
+ print(f" 📂 Archivo movido: {f} -> transformer/transformer.py")
44
+
45
+ # Crear __init__.py en transformer para que sea importable
46
+ init_path = os.path.join(transformer_folder, "__init__.py")
47
+ if not os.path.exists(init_path):
48
+ with open(init_path, "w") as f: f.write("")
49
+
50
+ # --- PASO 3: Importación Dinámica del Pipeline (El Fix Crítico) ---
51
+ # Añadimos el directorio al path para que Python encuentre los módulos internos
52
+ sys.path.append(os.path.abspath(LOCAL_DIR))
53
+
54
+ pipeline_class = None
55
+
56
+ # Buscamos qué archivo contiene la clase "NewbiePipeline"
57
+ py_files = [f for f in os.listdir(LOCAL_DIR) if f.endswith(".py")]
58
+
59
+ for py_file in py_files:
60
+ try:
61
+ file_path = os.path.join(LOCAL_DIR, py_file)
62
+ with open(file_path, "r", encoding="utf-8") as f:
63
+ content = f.read()
64
 
65
+ if "class NewbiePipeline" in content:
66
+ print(f" 🎯 Clase encontrada en: {py_file}")
67
+
68
+ # Importar el módulo manualmente
69
+ spec = importlib.util.spec_from_file_location("newbie_pipeline_module", file_path)
70
+ module = importlib.util.module_from_spec(spec)
71
+ sys.modules["newbie_pipeline_module"] = module
72
+ spec.loader.exec_module(module)
73
+
74
+ # Obtener la clase
75
+ pipeline_class = getattr(module, "NewbiePipeline")
76
+ break
77
+ except Exception as e:
78
+ print(f" Saltando archivo {py_file}: {e}")
79
+ continue
80
 
81
+ if pipeline_class is None:
82
+ raise ValueError(" No se encontró la clase 'NewbiePipeline' en ningún archivo .py del repositorio.")
83
+
84
+ # --- PASO 4: Carga del Modelo usando la Clase Importada ---
85
+ print(" 🚀 Cargando pesos usando la clase personalizada...")
86
+ pipe = pipeline_class.from_pretrained(
87
+ LOCAL_DIR,
88
+ torch_dtype=torch.bfloat16,
89
+ low_cpu_mem_usage=True,
90
+ # Importante: Como ya estamos usando la clase directa, no necesitamos custom_pipeline
91
+ # pero mantenemos trust_remote_code por si acaso el transformer lo requiere
92
+ trust_remote_code=True
93
+ )
94
+
95
+ return pipe
 
 
 
 
96
 
97
+ # Ejecutar carga
98
+ try:
99
+ pipe = load_hard_fixed_pipeline()
100
+ except Exception as e:
101
+ print(f"❌ ERROR CRÍTICO EN CARGA: {e}")
102
+ pipe = None
103
 
104
  # -----------------------------------------------------------------------------
105
  # 2. LÓGICA ZEROGPU
106
  # -----------------------------------------------------------------------------
107
  @spaces.GPU(duration=120)
108
  def generate_image(prompt, negative_prompt, steps, cfg, width, height):
109
+ if pipe is None:
110
+ raise gr.Error("El modelo no se pudo cargar. Revisa los logs.")
111
+
112
+ print("🎨 Generando...")
113
  pipe.to("cuda")
114
 
115
  image = pipe(
 
123
  return image
124
 
125
  # -----------------------------------------------------------------------------
126
+ # 3. INTERFAZ
127
  # -----------------------------------------------------------------------------
128
  css = """
129
  .container { max-width: 900px; margin: auto; }
130
  """
 
131
  DEFAULT_PROMPT = """<character_1>
132
  <gender>1girl</gender>
133
+ <appearance>red_eyes, silver_hair, long_hair</appearance>
134
+ <clothing>kimono, floral_print</clothing>
135
+ <action>standing, holding_fan</action>
136
  </character_1>
137
  <general_tags>
138
+ <quality>best quality, masterpiece, 4k</quality>
139
  <style>anime, vivid_colors</style>
140
  </general_tags>"""
141
 
142
+ DEFAULT_NEG = "low quality, bad anatomy, worst quality, watermark, text"
143
 
144
  with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
145
+ gr.Markdown("# ⛩️ NewBie Anime Generator (Hard-Import Fix)")
 
146
 
147
  with gr.Row():
148
  with gr.Column():
149
+ prompt = gr.Textbox(label="Prompt (XML)", value=DEFAULT_PROMPT, lines=10)
150
+ neg = gr.Textbox(label="Negative", value=DEFAULT_NEG)
151
+ btn = gr.Button("Generar", variant="primary")
152
  with gr.Row():
153
  steps = gr.Slider(10, 50, value=28, label="Pasos")
154
  cfg = gr.Slider(1, 15, value=7.0, label="CFG")
 
155
  with gr.Column():
156
  out = gr.Image(label="Resultado")
157
 
158
+ btn.click(generate_image, inputs=[prompt, neg, steps, cfg], outputs=out)
159
 
160
  if __name__ == "__main__":
161
  demo.launch()