Create proyecto.py
Browse files- proyecto.py +154 -0
proyecto.py
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# --- PASO 0: Instalación de Librerías ---
|
| 2 |
+
# Descomenta y ejecuta esta celda si no tienes las librerías instaladas
|
| 3 |
+
# !pip install transformers datasets accelerate -U
|
| 4 |
+
# !pip install sentencepiece # Necesario para algunos tokenizers como el de mT5
|
| 5 |
+
|
| 6 |
+
import datasets
|
| 7 |
+
from datasets import Dataset
|
| 8 |
+
from transformers import (
|
| 9 |
+
AutoTokenizer,
|
| 10 |
+
AutoModelForSeq2SeqLM,
|
| 11 |
+
Seq2SeqTrainingArguments,
|
| 12 |
+
Seq2SeqTrainer,
|
| 13 |
+
DataCollatorForSeq2Seq
|
| 14 |
+
)
|
| 15 |
+
|
| 16 |
+
# --- PASO 1: Preparar el Dataset (¡¡¡REEMPLAZAR CON TU DATASET REAL!!!) ---
|
| 17 |
+
# Este es un EJEMPLO MUY PEQUEÑO. Necesitas un dataset GRANDE y REAL.
|
| 18 |
+
# Tu dataset debería tener miles de ejemplos.
|
| 19 |
+
raw_data = {
|
| 20 |
+
"train": [
|
| 21 |
+
{"input_text": "El medico me receto analgesicos.", "target_text": "El médico me recetó analgésicos."},
|
| 22 |
+
{"input_text": "La cancion tiene una melodia pegadiza.", "target_text": "La canción tiene una melodía pegadiza."},
|
| 23 |
+
{"input_text": "La accion legal continuo.", "target_text": "La acción legal continuó."},
|
| 24 |
+
{"input_text": "Manana habra reunion.", "target_text": "Mañana habrá reunión."},
|
| 25 |
+
# ... Agrega MUCHOS MÁS ejemplos aquí ...
|
| 26 |
+
],
|
| 27 |
+
"validation": [
|
| 28 |
+
{"input_text": "La informacion es util.", "target_text": "La información es útil."},
|
| 29 |
+
{"input_text": "El analisis fue complejo.", "target_text": "El análisis fue complejo."},
|
| 30 |
+
# ... Agrega ejemplos de validación ...
|
| 31 |
+
]
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
# Convertir el diccionario a un objeto Dataset de Hugging Face
|
| 35 |
+
raw_datasets = datasets.DatasetDict({
|
| 36 |
+
"train": Dataset.from_dict(raw_data["train"]),
|
| 37 |
+
"validation": Dataset.from_dict(raw_data["validation"])
|
| 38 |
+
})
|
| 39 |
+
|
| 40 |
+
print("Dataset de ejemplo cargado:")
|
| 41 |
+
print(raw_datasets)
|
| 42 |
+
|
| 43 |
+
# --- PASO 2: Cargar Tokenizer y Modelo ---
|
| 44 |
+
# Elegimos un modelo Seq2Seq preentrenado. mT5-small es relativamente ligero.
|
| 45 |
+
# Para mejores resultados, considera modelos más grandes o específicos para español si están disponibles.
|
| 46 |
+
model_checkpoint = "google/mt5-small"
|
| 47 |
+
|
| 48 |
+
tokenizer = AutoTokenizer.from_pretrained(model_checkpoint, legacy=False) # legacy=False recomendado para T5
|
| 49 |
+
model = AutoModelForSeq2SeqLM.from_pretrained(model_checkpoint)
|
| 50 |
+
|
| 51 |
+
# --- PASO 3: Preprocesar el Dataset ---
|
| 52 |
+
max_input_length = 128
|
| 53 |
+
max_target_length = 128
|
| 54 |
+
|
| 55 |
+
def preprocess_function(examples):
|
| 56 |
+
# Asegurarse que los textos son strings
|
| 57 |
+
inputs = [str(ex) for ex in examples["input_text"]]
|
| 58 |
+
targets = [str(ex) for ex in examples["target_text"]]
|
| 59 |
+
|
| 60 |
+
# Tokenizar entradas
|
| 61 |
+
model_inputs = tokenizer(inputs, max_length=max_input_length, truncation=True, padding="max_length")
|
| 62 |
+
|
| 63 |
+
# Tokenizar salidas (targets) como etiquetas
|
| 64 |
+
# Usamos el tokenizer en modo "target" para preparar las labels correctamente para el decoder
|
| 65 |
+
with tokenizer.as_target_tokenizer():
|
| 66 |
+
labels = tokenizer(targets, max_length=max_target_length, truncation=True, padding="max_length")
|
| 67 |
+
|
| 68 |
+
# Los IDs de padding en las etiquetas deben ser ignorados en la función de pérdida
|
| 69 |
+
# Reemplazamos los pad_token_id por -100
|
| 70 |
+
labels["input_ids"] = [
|
| 71 |
+
[(l if l != tokenizer.pad_token_id else -100) for l in label] for label in labels["input_ids"]
|
| 72 |
+
]
|
| 73 |
+
|
| 74 |
+
model_inputs["labels"] = labels["input_ids"]
|
| 75 |
+
return model_inputs
|
| 76 |
+
|
| 77 |
+
# Aplicar la función de preprocesamiento a todo el dataset
|
| 78 |
+
tokenized_datasets = raw_datasets.map(preprocess_function, batched=True)
|
| 79 |
+
|
| 80 |
+
print("\nDataset tokenizado:")
|
| 81 |
+
print(tokenized_datasets)
|
| 82 |
+
|
| 83 |
+
# --- PASO 4: Configurar el Entrenamiento ---
|
| 84 |
+
|
| 85 |
+
# Directorio donde se guardarán los resultados y checkpoints
|
| 86 |
+
output_dir = "./results-accent-corrector"
|
| 87 |
+
|
| 88 |
+
# Argumentos de entrenamiento
|
| 89 |
+
training_args = Seq2SeqTrainingArguments(
|
| 90 |
+
output_dir=output_dir,
|
| 91 |
+
evaluation_strategy="epoch", # Evaluar después de cada época
|
| 92 |
+
learning_rate=2e-5, # Tasa de aprendizaje
|
| 93 |
+
per_device_train_batch_size=8, # Tamaño de lote por GPU/CPU para entrenamiento (ajusta según tu memoria)
|
| 94 |
+
per_device_eval_batch_size=8, # Tamaño de lote por GPU/CPU para evaluación
|
| 95 |
+
weight_decay=0.01, # Decaimiento de peso
|
| 96 |
+
save_total_limit=3, # Guardar solo los últimos 3 checkpoints
|
| 97 |
+
num_train_epochs=3, # Número de épocas (ajusta según tu dataset y convergencia)
|
| 98 |
+
predict_with_generate=True, # Necesario para generar texto durante la evaluación Seq2Seq
|
| 99 |
+
fp16=False, # Cambiar a True si tienes GPU compatible y quieres acelerar (requiere 'accelerate')
|
| 100 |
+
logging_steps=10, # Frecuencia de logging
|
| 101 |
+
# report_to="tensorboard", # Opcional: para visualizar en TensorBoard
|
| 102 |
+
# push_to_hub=False, # Cambiar a True para subir tu modelo al Hub de Hugging Face (necesitas login)
|
| 103 |
+
)
|
| 104 |
+
|
| 105 |
+
# Data Collator: prepara los lotes de datos para el modelo Seq2Seq
|
| 106 |
+
data_collator = DataCollatorForSeq2Seq(tokenizer=tokenizer, model=model)
|
| 107 |
+
|
| 108 |
+
# Crear el objeto Trainer
|
| 109 |
+
trainer = Seq2SeqTrainer(
|
| 110 |
+
model=model,
|
| 111 |
+
args=training_args,
|
| 112 |
+
train_dataset=tokenized_datasets["train"],
|
| 113 |
+
eval_dataset=tokenized_datasets["validation"],
|
| 114 |
+
tokenizer=tokenizer,
|
| 115 |
+
data_collator=data_collator,
|
| 116 |
+
# compute_metrics=compute_metrics, # Opcional: define una función para métricas más avanzadas
|
| 117 |
+
)
|
| 118 |
+
|
| 119 |
+
# --- PASO 5: Entrenar el Modelo ---
|
| 120 |
+
print("\nIniciando entrenamiento...")
|
| 121 |
+
trainer.train()
|
| 122 |
+
print("Entrenamiento completado.")
|
| 123 |
+
|
| 124 |
+
# --- PASO 6: Guardar el Modelo Final y Tokenizer ---
|
| 125 |
+
final_model_path = f"{output_dir}/final_model"
|
| 126 |
+
trainer.save_model(final_model_path)
|
| 127 |
+
tokenizer.save_pretrained(final_model_path)
|
| 128 |
+
print(f"Modelo final y tokenizer guardados en: {final_model_path}")
|
| 129 |
+
|
| 130 |
+
# --- PASO 7: Probar el Modelo Entrenado (Inferencia) ---
|
| 131 |
+
from transformers import pipeline
|
| 132 |
+
|
| 133 |
+
print("\nProbando el modelo afinado...")
|
| 134 |
+
|
| 135 |
+
# Cargar el pipeline con el modelo afinado localmente
|
| 136 |
+
# Si el entrenamiento fue corto o con pocos datos, el resultado puede no ser bueno.
|
| 137 |
+
corrector_pipe = pipeline("text2text-generation", model=final_model_path, tokenizer=final_model_path)
|
| 138 |
+
|
| 139 |
+
# Frases de ejemplo sin acentos
|
| 140 |
+
test_sentences = [
|
| 141 |
+
"Que dia es manana?",
|
| 142 |
+
"La musica clasica me relaja.",
|
| 143 |
+
"El exito requiere dedicacion.",
|
| 144 |
+
"accion" # El ejemplo original del usuario
|
| 145 |
+
]
|
| 146 |
+
|
| 147 |
+
for sentence in test_sentences:
|
| 148 |
+
result = corrector_pipe(sentence, max_length=50) # Ajusta max_length si es necesario
|
| 149 |
+
corrected_text = result[0]['generated_text']
|
| 150 |
+
print(f"Entrada: {sentence}")
|
| 151 |
+
print(f"Salida: {corrected_text}")
|
| 152 |
+
print("---")
|
| 153 |
+
|
| 154 |
+
print("\n¡Proceso terminado!")
|