Andro0s commited on
Commit
ceb558e
·
verified ·
1 Parent(s): 5d66936

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +46 -67
app.py CHANGED
@@ -6,35 +6,24 @@ from transformers import AutoTokenizer, AutoModelForCausalLM, Trainer, TrainingA
6
  from peft import get_peft_model, LoraConfig, TaskType, PeftModel
7
  import json
8
 
9
- # ============================================================
10
- # ⚙️ CONFIGURACIÓN GLOBAL
11
- # ============================================================
12
- # Modelo base para generación de código
13
  BASE_MODEL = "bigcode/santacoder"
14
- LORA_PATH = "./lora_output" # Directorio para guardar los adaptadores LoRA
15
-
16
- # Nombre del archivo donde se guardará el dataset procesado
17
  DATASET_FILE = "codesearchnet_lora_dataset.json"
18
- MAX_TOKEN_LENGTH = 256 # Longitud de secuencia uniforme
19
- NUM_SAMPLES_TO_PROCESS = 1000
20
- DEFAULT_EPOCHS = 10 # <--- ¡ENTRENAMIENTO PROFUNDO!
21
 
22
- # Variables globales
23
  tokenizer = None
24
  lora_model = None
25
  tokenized_dataset = None
26
  lora_generator = None
27
 
28
- # ============================================================
29
- # 🚨 LÓGICA DE PRE-PROCESAMIENTO DE DATOS (INTEGRADA) 🚨
30
- # ============================================================
31
  def prepare_codesearchnet():
32
- """Descarga, procesa y guarda el dataset CodeSearchNet si no existe."""
33
  if os.path.exists(DATASET_FILE):
34
- print(f"Dataset '{DATASET_FILE}' ya existe.")
35
  return
36
 
37
- print(f"🔄 Descargando y procesando CodeSearchNet ({NUM_SAMPLES_TO_PROCESS} muestras)...")
38
 
39
  try:
40
  raw_csn = load_dataset('Nan-Do/code-search-net-python', split=f'train[:{NUM_SAMPLES_TO_PROCESS}]')
@@ -46,33 +35,23 @@ def prepare_codesearchnet():
46
  f"def {example['func_name']}("
47
  )
48
  completion_text = example['code']
49
-
50
- return {
51
- "prompt": prompt_text,
52
- "completion": completion_text
53
- }
54
 
55
  lora_dataset = raw_csn.map(
56
  format_for_lora,
57
  batched=False,
58
  remove_columns=raw_csn["train"].column_names,
59
  )
60
-
61
  lora_dataset.to_json(DATASET_FILE)
62
- print(f"Pre-procesamiento completado. {NUM_SAMPLES_TO_PROCESS} ejemplos guardados en '{DATASET_FILE}'.")
63
 
64
  except Exception as e:
65
- print(f"Error CRÍTICO al descargar/procesar CodeSearchNet. Error: {e}")
66
  minimal_dataset = [{"prompt": "# Error de carga. Intenta de nuevo.", "completion": "pass\n"}] * 10
67
  with open(DATASET_FILE, 'w') as f:
68
  json.dump(minimal_dataset, f)
69
 
70
- # ============================================================
71
- # 🔐 AUTENTICACIÓN Y PRE-CARGA DE RECURSOS (SINGLETON)
72
- # ============================================================
73
-
74
  def setup_resources():
75
- """Carga y configura todos los recursos (modelo, tokenizer, dataset) una sola vez."""
76
  global tokenizer, lora_model, tokenized_dataset
77
 
78
  prepare_codesearchnet()
@@ -81,15 +60,13 @@ def setup_resources():
81
  if hf_token:
82
  login(token=hf_token)
83
 
84
- # 1. Carga del Tokenizer y Modelo Base
85
- print("\n🔄 Cargando modelo base y tokenizer...")
86
  tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL)
87
  base_model = AutoModelForCausalLM.from_pretrained(BASE_MODEL, device_map="auto")
88
 
89
  if tokenizer.pad_token is None:
90
  tokenizer.pad_token = tokenizer.eos_token
91
 
92
- # 2. Configuración y Aplicación LoRA (PEFT)
93
  peft_config = LoraConfig(
94
  task_type=TaskType.CAUSAL_LM,
95
  r=8,
@@ -99,10 +76,9 @@ def setup_resources():
99
  )
100
  lora_model = get_peft_model(base_model, peft_config)
101
 
102
- print(f"Modelo LoRA preparado. Parámetros entrenables listos.")
103
 
104
- # 3. Carga y Tokenización del Dataset
105
- print(f"📚 Cargando y tokenizando dataset: {DATASET_FILE}...")
106
  try:
107
  raw_dataset = load_dataset("json", data_files=DATASET_FILE)
108
 
@@ -119,21 +95,16 @@ def setup_resources():
119
  batched=True,
120
  remove_columns=raw_dataset["train"].column_names if "train" in raw_dataset else [],
121
  )
122
- print("Dataset tokenizado correctamente.")
123
  except Exception as e:
124
  tokenized_dataset = None
125
- print(f"Error al cargar o tokenizar el dataset. {e}")
126
 
127
-
128
- # ============================================================
129
- # ��� FUNCIÓN DE ENTRENAMIENTO
130
- # ============================================================
131
  def train_lora(epochs, batch_size, learning_rate):
132
- """Ejecuta el entrenamiento del modelo LoRA."""
133
  global lora_model, tokenized_dataset, lora_generator
134
 
135
  if tokenized_dataset is None or "train" not in tokenized_dataset:
136
- return f"Error: El dataset no pudo cargarse o está vacío. No se puede entrenar."
137
 
138
  try:
139
  lora_generator = None
@@ -157,19 +128,14 @@ def train_lora(epochs, batch_size, learning_rate):
157
  )
158
 
159
  trainer.train()
160
-
161
  lora_model.save_pretrained(LORA_PATH)
162
  tokenizer.save_pretrained(LORA_PATH)
163
 
164
- return f"Entrenamiento completado. Adaptadores LoRA guardados en **{LORA_PATH}**"
165
  except Exception as e:
166
- return f"Error durante el entrenamiento: {e}"
167
 
168
- # ============================================================
169
- # 🤖 FUNCIÓN DE GENERACIÓN (INFERENCIA)
170
- # ============================================================
171
  def generate_text(prompt_text):
172
- """Genera texto usando el modelo base + adaptadores LoRA."""
173
  global lora_generator
174
 
175
  try:
@@ -179,31 +145,44 @@ def generate_text(prompt_text):
179
  if os.path.exists(LORA_PATH):
180
  print("Cargando adaptadores LoRA...")
181
  model_with_lora = PeftModel.from_pretrained(base_model_gen, LORA_PATH)
 
182
  else:
183
  print("No se encontraron adaptadores LoRA. Usando modelo base.")
184
- model_with_lora = base_model_gen
185
 
186
- final_model = model_with_lora.merge_and_unload()
187
  final_model.eval()
188
-
189
  lora_generator = pipeline("text-generation", model=final_model, tokenizer=tokenizer)
190
  print("Modelo de inferencia listo.")
191
 
192
- output = lora_generator(prompt_text, max_new_tokens=150, temperature=0.7, top_p=0.9)
193
- return output[0]["generated_text"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
 
195
  except Exception as e:
196
- return f"Error generando texto (Asegúrate de que el modelo base/LoRA esté cargado): {e}"
197
 
198
- # ============================================================
199
- # 💻 INTERFAZ GRADIO
200
- # ============================================================
201
  with gr.Blocks(title="AmorCoderAI - LoRA") as demo:
202
  gr.Markdown("# 💙 AmorCoderAI - Entrenamiento y Pruebas LoRA")
203
- gr.Markdown(f"Modelo base: `{BASE_MODEL}`. Usando **{NUM_SAMPLES_TO_PROCESS}** ejemplos de CodeSearchNet.")
204
 
205
  with gr.Tab("🧠 Entrenar (Manual)"):
206
- gr.Markdown(f"--- **¡CUIDADO!** El auto-entrenamiento usará {DEFAULT_EPOCHS} épocas para aprender la sintaxis. ---")
207
  epochs = gr.Number(value=DEFAULT_EPOCHS, label="Épocas", precision=0)
208
  batch_size = gr.Number(value=2, label="Tamaño de lote (ajusta según tu VRAM)", precision=0)
209
  learning_rate = gr.Number(value=5e-5, label="Tasa de aprendizaje")
@@ -217,14 +196,14 @@ with gr.Blocks(title="AmorCoderAI - LoRA") as demo:
217
  )
218
 
219
  with gr.Tab("✨ Probar modelo"):
220
- prompt = gr.Textbox(label="Escribe código (ej: 'def fibonacci(n):')", lines=4)
 
 
 
221
  generate_button = gr.Button("💬 Generar código")
222
- output_box = gr.Textbox(label="Salida generada", lines=10)
223
  generate_button.click(generate_text, inputs=prompt, outputs=output_box)
224
 
225
- # ============================================================
226
- # 🚀 LANZAR APP Y AUTO-ENTRENAMIENTO
227
- # ============================================================
228
  if __name__ == "__main__":
229
  setup_resources()
230
 
 
6
  from peft import get_peft_model, LoraConfig, TaskType, PeftModel
7
  import json
8
 
 
 
 
 
9
  BASE_MODEL = "bigcode/santacoder"
10
+ LORA_PATH = "./lora_output"
 
 
11
  DATASET_FILE = "codesearchnet_lora_dataset.json"
12
+ MAX_TOKEN_LENGTH = 256
13
+ NUM_SAMPLES_TO_PROCESS = 1000
14
+ DEFAULT_EPOCHS = 10
15
 
 
16
  tokenizer = None
17
  lora_model = None
18
  tokenized_dataset = None
19
  lora_generator = None
20
 
 
 
 
21
  def prepare_codesearchnet():
 
22
  if os.path.exists(DATASET_FILE):
23
+ print(f"Dataset '{DATASET_FILE}' ya existe.")
24
  return
25
 
26
+ print(f"Descargando y procesando CodeSearchNet ({NUM_SAMPLES_TO_PROCESS} muestras)...")
27
 
28
  try:
29
  raw_csn = load_dataset('Nan-Do/code-search-net-python', split=f'train[:{NUM_SAMPLES_TO_PROCESS}]')
 
35
  f"def {example['func_name']}("
36
  )
37
  completion_text = example['code']
38
+ return {"prompt": prompt_text, "completion": completion_text}
 
 
 
 
39
 
40
  lora_dataset = raw_csn.map(
41
  format_for_lora,
42
  batched=False,
43
  remove_columns=raw_csn["train"].column_names,
44
  )
 
45
  lora_dataset.to_json(DATASET_FILE)
46
+ print(f"Pre-procesamiento completado. {NUM_SAMPLES_TO_PROCESS} ejemplos guardados en '{DATASET_FILE}'.")
47
 
48
  except Exception as e:
49
+ print(f"Error CRÍTICO al descargar/procesar CodeSearchNet. Error: {e}")
50
  minimal_dataset = [{"prompt": "# Error de carga. Intenta de nuevo.", "completion": "pass\n"}] * 10
51
  with open(DATASET_FILE, 'w') as f:
52
  json.dump(minimal_dataset, f)
53
 
 
 
 
 
54
  def setup_resources():
 
55
  global tokenizer, lora_model, tokenized_dataset
56
 
57
  prepare_codesearchnet()
 
60
  if hf_token:
61
  login(token=hf_token)
62
 
63
+ print("\nCargando modelo base y tokenizer...")
 
64
  tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL)
65
  base_model = AutoModelForCausalLM.from_pretrained(BASE_MODEL, device_map="auto")
66
 
67
  if tokenizer.pad_token is None:
68
  tokenizer.pad_token = tokenizer.eos_token
69
 
 
70
  peft_config = LoraConfig(
71
  task_type=TaskType.CAUSAL_LM,
72
  r=8,
 
76
  )
77
  lora_model = get_peft_model(base_model, peft_config)
78
 
79
+ print(f"Modelo LoRA preparado. Parámetros entrenables listos.")
80
 
81
+ print(f"Cargando y tokenizando dataset: {DATASET_FILE}...")
 
82
  try:
83
  raw_dataset = load_dataset("json", data_files=DATASET_FILE)
84
 
 
95
  batched=True,
96
  remove_columns=raw_dataset["train"].column_names if "train" in raw_dataset else [],
97
  )
98
+ print("Dataset tokenizado correctamente.")
99
  except Exception as e:
100
  tokenized_dataset = None
101
+ print(f"Error al cargar o tokenizar el dataset. {e}")
102
 
 
 
 
 
103
  def train_lora(epochs, batch_size, learning_rate):
 
104
  global lora_model, tokenized_dataset, lora_generator
105
 
106
  if tokenized_dataset is None or "train" not in tokenized_dataset:
107
+ return f"Error: El dataset no pudo cargarse o está vacío. No se puede entrenar."
108
 
109
  try:
110
  lora_generator = None
 
128
  )
129
 
130
  trainer.train()
 
131
  lora_model.save_pretrained(LORA_PATH)
132
  tokenizer.save_pretrained(LORA_PATH)
133
 
134
+ return f"Entrenamiento completado. Adaptadores LoRA guardados en **{LORA_PATH}**"
135
  except Exception as e:
136
+ return f"Error durante el entrenamiento: {e}"
137
 
 
 
 
138
  def generate_text(prompt_text):
 
139
  global lora_generator
140
 
141
  try:
 
145
  if os.path.exists(LORA_PATH):
146
  print("Cargando adaptadores LoRA...")
147
  model_with_lora = PeftModel.from_pretrained(base_model_gen, LORA_PATH)
148
+ final_model = model_with_lora.merge_and_unload()
149
  else:
150
  print("No se encontraron adaptadores LoRA. Usando modelo base.")
151
+ final_model = base_model_gen
152
 
 
153
  final_model.eval()
 
154
  lora_generator = pipeline("text-generation", model=final_model, tokenizer=tokenizer)
155
  print("Modelo de inferencia listo.")
156
 
157
+ prompt_with_indent = prompt_text.strip() + "\n "
158
+
159
+ output = lora_generator(
160
+ prompt_with_indent,
161
+ max_new_tokens=150,
162
+ temperature=0.7,
163
+ top_p=0.9,
164
+ clean_up_tokenization_spaces=True
165
+ )
166
+
167
+ full_output = output[0]["generated_text"]
168
+
169
+ start_index = full_output.find(prompt_with_indent)
170
+ if start_index != -1:
171
+ completion = full_output[start_index + len(prompt_with_indent):]
172
+ else:
173
+ completion = full_output
174
+
175
+ return completion
176
 
177
  except Exception as e:
178
+ return f"Error generando texto (Asegúrate de que el modelo base/LoRA esté cargado): {e}"
179
 
 
 
 
180
  with gr.Blocks(title="AmorCoderAI - LoRA") as demo:
181
  gr.Markdown("# 💙 AmorCoderAI - Entrenamiento y Pruebas LoRA")
182
+ gr.Markdown(f"Modelo base: `{BASE_MODEL}`. Usando **{NUM_SAMPLES_TO_PROCESS}** ejemplos de CodeSearchNet (10 Épocas).")
183
 
184
  with gr.Tab("🧠 Entrenar (Manual)"):
185
+ gr.Markdown(f"--- ¡CUIDADO! El auto-entrenamiento usará {DEFAULT_EPOCHS} épocas para aprender la sintaxis. ---")
186
  epochs = gr.Number(value=DEFAULT_EPOCHS, label="Épocas", precision=0)
187
  batch_size = gr.Number(value=2, label="Tamaño de lote (ajusta según tu VRAM)", precision=0)
188
  learning_rate = gr.Number(value=5e-5, label="Tasa de aprendizaje")
 
196
  )
197
 
198
  with gr.Tab("✨ Probar modelo"):
199
+ prompt = gr.Textbox(
200
+ label="Escribe código (ej: # Descripción: Calcula el factorial de N. \n# Completa la siguiente función:\ndef factorial(n):)",
201
+ lines=4
202
+ )
203
  generate_button = gr.Button("💬 Generar código")
204
+ output_box = gr.Textbox(label="Salida generada (SOLO CÓDIGO)", lines=10)
205
  generate_button.click(generate_text, inputs=prompt, outputs=output_box)
206
 
 
 
 
207
  if __name__ == "__main__":
208
  setup_resources()
209