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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +73 -91
app.py CHANGED
@@ -3,102 +3,73 @@ 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
  # -----------------------------------------------------------------------------
@@ -107,30 +78,37 @@ except Exception as e:
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(
116
- prompt=prompt,
117
- negative_prompt=negative_prompt,
118
- num_inference_steps=int(steps),
119
- guidance_scale=float(cfg),
120
- width=int(width),
121
- height=int(height)
122
- ).images[0]
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>
@@ -141,8 +119,10 @@ DEFAULT_PROMPT = """<character_1>
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():
@@ -152,10 +132,12 @@ with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
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()
 
3
  import spaces
4
  import os
5
  import shutil
6
+ from diffusers import DiffusionPipeline
 
7
  from huggingface_hub import snapshot_download
8
 
9
  # -----------------------------------------------------------------------------
10
+ # 1. FUNCIÓN DE REPARACIÓN DE ESTRUCTURA (LA SOLUCIÓN)
11
  # -----------------------------------------------------------------------------
12
  MODEL_ID = "NewBie-AI/NewBie-image-Exp0.1"
13
  LOCAL_DIR = "./newbie_fixed_model"
14
 
15
+ def load_patched_pipeline():
16
+ print(f"🛠️ Iniciando protocolo de reparación v3 para {MODEL_ID}...")
17
 
18
+ # 1. Descargar repositorio completo
19
  if not os.path.exists(LOCAL_DIR):
20
+ print(" ⬇️ Descargando snapshot (esto puede tardar unos minutos)...")
21
+ snapshot_download(repo_id=MODEL_ID, local_dir=LOCAL_DIR)
 
 
 
 
22
 
23
+ # 2. CREAR CARPETA TRANSFORMER (El error original)
24
  transformer_folder = os.path.join(LOCAL_DIR, "transformer")
25
+ os.makedirs(transformer_folder, exist_ok=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
+ # 3. BUSCAR Y MOVER ARCHIVOS PERDIDOS
28
+ # El config dice que el código está en 'transformer/transformer.py', pero suele estar en la raíz.
29
+ # Vamos a copiar TODOS los archivos .py de la raíz a la carpeta transformer por si acaso.
30
+ root_files = [f for f in os.listdir(LOCAL_DIR) if f.endswith(".py")]
 
 
 
 
 
 
 
 
 
31
 
32
+ candidate_found = False
33
+ for f in root_files:
34
+ src = os.path.join(LOCAL_DIR, f)
35
+
36
+ # Copia de seguridad: Copiamos todo .py a la carpeta transformer
37
+ shutil.copy(src, os.path.join(transformer_folder, f))
38
+
39
+ # DETECTIVE: Leemos el archivo para ver si es el modelo principal
40
+ with open(src, "r", encoding="utf-8", errors="ignore") as file_content:
41
+ content = file_content.read()
42
+ # Si el archivo define un Transformer o un Modelo, es nuestro candidato
43
+ if "class" in content and ("Transformer" in content or "Model" in content):
44
+ # Lo copiamos como 'transformer.py' que es lo que pide el json
45
+ shutil.copy(src, os.path.join(transformer_folder, "transformer.py"))
46
+ print(f" ✅ Candidato detectado y renombrado: {f} -> transformer/transformer.py")
47
+ candidate_found = True
 
 
 
 
 
48
 
49
+ # Crear __init__.py obligatorio
50
+ with open(os.path.join(transformer_folder, "__init__.py"), "w") as f: f.write("")
51
 
52
+ if not candidate_found:
53
+ print(" ⚠️ No se detectó un modelo obvio. Copiando el archivo .py más grande como transformer.py")
54
+ # Fallback: Copiar el archivo .py más grande
55
+ largest_py = max(root_files, key=lambda x: os.path.getsize(os.path.join(LOCAL_DIR, x)))
56
+ shutil.copy(os.path.join(LOCAL_DIR, largest_py), os.path.join(transformer_folder, "transformer.py"))
57
+
58
+ # 4. CARGAR MODELO DESDE CARPETA LOCAL ARREGLADA
59
+ print(" 🚀 Cargando pipeline...")
60
+ pipe = DiffusionPipeline.from_pretrained(
61
  LOCAL_DIR,
62
  torch_dtype=torch.bfloat16,
63
+ trust_remote_code=True, # Necesario para ejecutar el código que acabamos de mover
64
+ local_files_only=True
 
 
65
  )
 
66
  return pipe
67
 
68
+ # Carga inicial
69
  try:
70
+ pipe = load_patched_pipeline()
71
  except Exception as e:
72
+ print(f"❌ Error fatal: {e}")
73
  pipe = None
74
 
75
  # -----------------------------------------------------------------------------
 
78
  @spaces.GPU(duration=120)
79
  def generate_image(prompt, negative_prompt, steps, cfg, width, height):
80
  if pipe is None:
81
+ raise gr.Error("El modelo no se cargó correctamente. Revisa los logs.")
82
+
83
  print("🎨 Generando...")
84
  pipe.to("cuda")
85
 
86
+ try:
87
+ image = pipe(
88
+ prompt=prompt,
89
+ negative_prompt=negative_prompt,
90
+ num_inference_steps=int(steps),
91
+ guidance_scale=float(cfg),
92
+ width=int(width),
93
+ height=int(height)
94
+ ).images[0]
95
+ return image
96
+ except Exception as e:
97
+ return None
98
 
99
  # -----------------------------------------------------------------------------
100
+ # 3. INTERFAZ (Corrección de CSS para Gradio 5.0)
101
  # -----------------------------------------------------------------------------
102
+ # Inyectamos CSS usando Markdown HTML en lugar del argumento 'css' que daba error
103
+ custom_css = """
104
+ <style>
105
  .container { max-width: 900px; margin: auto; }
106
+ </style>
107
  """
108
+
109
  DEFAULT_PROMPT = """<character_1>
110
  <gender>1girl</gender>
111
+ <appearance>red_eyes, white_hair, long_hair</appearance>
112
  <clothing>kimono, floral_print</clothing>
113
  <action>standing, holding_fan</action>
114
  </character_1>
 
119
 
120
  DEFAULT_NEG = "low quality, bad anatomy, worst quality, watermark, text"
121
 
122
+ # Quitamos el argumento css=css aquí para evitar el TypeError
123
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
124
+ gr.HTML(custom_css) # Solución al error de CSS
125
+ gr.Markdown("# ⛩️ NewBie Anime Generator (Fixed)")
126
 
127
  with gr.Row():
128
  with gr.Column():
 
132
  with gr.Row():
133
  steps = gr.Slider(10, 50, value=28, label="Pasos")
134
  cfg = gr.Slider(1, 15, value=7.0, label="CFG")
135
+ width = gr.Slider(512, 1280, value=1024, step=64, label="Ancho")
136
+ height = gr.Slider(512, 1280, value=1024, step=64, label="Alto")
137
  with gr.Column():
138
  out = gr.Image(label="Resultado")
139
 
140
+ btn.click(generate_image, inputs=[prompt, neg, steps, cfg, width, height], outputs=out)
141
 
142
  if __name__ == "__main__":
143
  demo.launch()