Ingenieria de Datasets
La Calidad de los Datos Supera a la Cantidad
Si hay una leccion que la comunidad de fine-tuning ha aprendido por las malas, es esta: un dataset pequeno de ejemplos de alta calidad superara a un dataset grande de ejemplos mediocres. La investigacion de LIMA (Less Is More for Alignment) mostro que solo 1,000 ejemplos cuidadosamente curados podian producir un modelo competitivo con aquellos entrenados con 50,000+ ejemplos. Tu dataset no es solo una entrada — es el factor individual mas importante que determina si tu modelo fine-tuned tiene exito o fracasa.
Esta leccion cubre todo el pipeline de datos: recolectar ejemplos en bruto, limpiarlos hasta convertirlos en muestras listas para entrenamiento, elegir el formato correcto y entender cuantos ejemplos realmente necesitas.
Recopilando Datos de Entrenamiento
Curacion Manual
El estandar de oro. Los expertos del dominio crean pares de entrada-salida que representan exactamente lo que el modelo deberia producir. Esto es intensivo en trabajo pero produce los datos de mayor calidad.
Proceso:
- Define tu tarea claramente con 3-5 ejemplos de comportamiento ideal
- Crea una rubrica que explique que hace que un ejemplo sea "bueno"
- Haz que los expertos del dominio escriban 50-100 ejemplos siguiendo la rubrica
- Revisa cada ejemplo para consistencia y calidad
- Itera sobre la rubrica basandote en los patrones que encuentres
Consejo: Comienza escribiendo 20 ejemplos tu mismo. Esto te obliga a confrontar casos extremos y ambiguedades en tu definicion de tarea antes de escalar a mas contribuidores.
Logs Existentes y Datos de Produccion
Si tu aplicacion ya existe (incluso con ingenieria de prompts), tus logs de produccion son un dataset esperando a ser creado. Las consultas de usuarios emparejadas con respuestas del modelo que fueron calificadas positivamente por usuarios o verificadas por humanos se convierten en ejemplos de entrenamiento.
# Ejemplo: extrayendo datos de entrenamiento de logs de produccion
import json
training_examples = []
for log in production_logs:
if log["user_rating"] >= 4 and log["human_verified"]:
training_examples.append({
"instruction": log["user_query"],
"output": log["model_response"]
})
# Filtrar por diversidad — evitar ejemplos casi duplicados
# que causarian sobreajuste
Advertencia: Los datos de produccion a menudo tienen un sesgo hacia consultas comunes. Asegurate de incluir ejemplos de la cola de la distribucion — las solicitudes inusuales que confunden a tu sistema actual.
Entrevistas con Expertos del Dominio
Para dominios especializados, las entrevistas estructuradas con expertos pueden generar ejemplos de alta calidad. Pregunta al experto que recorra escenarios reales: "Que le dirias a un paciente que pregunta sobre X?" o "Como clasificarias esta transaccion financiera?"
Graba la conversacion, extrae los pares de entrada-salida y haz que el experto valide los ejemplos formateados finales.
Datos Sinteticos de Modelos Mas Potentes
Usar un modelo mas capaz (GPT-4o, Claude) para generar datos de entrenamiento para un modelo mas pequeno es una estrategia comun y efectiva. La clave es generar ejemplos diversos y de alta calidad que valides antes de entrenar.
import openai
client = openai.OpenAI()
# Generar ejemplos de entrenamiento diversos
seed_topics = ["revision de contratos", "analisis de NDA", "clausula de responsabilidad"]
for topic in seed_topics:
response = client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "system",
"content": "Eres un analista de documentos legales. Genera una consulta "
"realista de usuario y una respuesta ideal para el siguiente tema."
}, {
"role": "user",
"content": f"Tema: {topic}. Genera un ejemplo especifico y realista."
}],
temperature=0.9 # Mayor temperatura para diversidad
)
# Siempre valida los ejemplos generados manualmente
Regla critica: Siempre valida los datos sinteticos. Un modelo mas potente producira salidas que parecen plausibles pero contienen errores sutiles. Presupuesta tiempo para revision humana de cada ejemplo sintetico.
Limpiando tus Datos
Los datos en bruto nunca estan listos para entrenamiento. Aqui esta el pipeline de limpieza que deberias aplicar:
Deduplicacion
Los ejemplos casi duplicados hacen que el modelo memorice en lugar de generalizar. Usa tanto coincidencia exacta como deduplicacion por similitud semantica.
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
model = SentenceTransformer("all-MiniLM-L6-v2")
# Calcular embeddings para todos los ejemplos
texts = [ex["instruction"] + " " + ex["output"] for ex in examples]
embeddings = model.encode(texts)
# Encontrar casi-duplicados (similitud coseno > 0.95)
sim_matrix = cosine_similarity(embeddings)
duplicates = set()
for i in range(len(sim_matrix)):
for j in range(i + 1, len(sim_matrix)):
if sim_matrix[i][j] > 0.95:
duplicates.add(j) # Mantener el primero, marcar el posterior como duplicado
cleaned = [ex for i, ex in enumerate(examples) if i not in duplicates]
print(f"Eliminados {len(duplicates)} casi-duplicados de {len(examples)} ejemplos")
Filtrado de Muestras de Baja Calidad
Elimina ejemplos que son demasiado cortos, demasiado largos, contienen errores de formato o son inconsistentes con tu definicion de tarea.
def quality_filter(example):
output = example["output"]
# Demasiado corto para ser util
if len(output.split()) < 20:
return False
# Demasiado largo (podria ser ruidoso o fuera de tema)
if len(output.split()) > 2000:
return False
# Contiene errores obvios de formato
if output.count("```") % 2 != 0: # Bloques de codigo sin cerrar
return False
# Comienza con patrones de rechazo que no queremos
refusal_patterns = ["No puedo", "Lo siento", "Como IA"]
if any(output.startswith(p) for p in refusal_patterns):
return False
return True
cleaned = [ex for ex in examples if quality_filter(ex)]
Verificaciones de Consistencia
Todos los ejemplos deben seguir las mismas convenciones. Si algunos ejemplos usan encabezados markdown y otros no, si algunos terminan con punto y otros no — estas inconsistencias confunden al modelo.
Escribe una guia de estilo para tu dataset y aplicala programaticamente donde sea posible, manualmente donde sea necesario.
Formatos de Datos
Diferentes objetivos de entrenamiento requieren diferentes formatos de datos. Aqui estan los tres principales:
Formato de Instruccion (Supervised Fine-Tuning)
El formato mas simple. Cada ejemplo es una instruccion (entrada) y una completacion (salida). Se usa para ensenar al modelo a seguir instrucciones especificas.
{
"instruction": "Resume esta clausula legal en lenguaje sencillo",
"input": "La parte indemnizante debera mantener indemne e indemnizar...",
"output": "Esta clausula significa que una parte acepta cubrir cualquier perdida..."
}
Formato de Chat (Conversaciones Multi-Turno)
Para modelos conversacionales, cada ejemplo contiene una conversacion completa con mensajes de sistema, usuario y asistente.
{
"conversations": [
{"role": "system", "content": "Eres un asistente de triaje medico..."},
{"role": "user", "content": "Tengo dolor de cabeza y fiebre leve..."},
{"role": "assistant", "content": "Basandome en tus sintomas..."},
{"role": "user", "content": "Deberia ir a urgencias?"},
{"role": "assistant", "content": "Dada la naturaleza leve de tus sintomas..."}
]
}
Formato de Preferencia (DPO/RLHF)
Para entrenamiento de alineacion, cada ejemplo incluye un prompt, una respuesta elegida (preferida) y una respuesta rechazada (peor).
{
"prompt": "Explica la computacion cuantica a un nino de 10 anos",
"chosen": "Imagina que tienes una moneda magica que puede ser cara Y cruz...",
"rejected": "La computacion cuantica aprovecha fenomenos de mecanica cuantica como la superposicion y el entrelazamiento para realizar calculos en qubits..."
}
Cuantos Datos Necesitas?
No hay una respuesta universal, pero aqui hay guias practicas basadas en experiencia del mundo real:
| Tipo de Tarea | Ejemplos Minimos | Recomendado | Notas | |---------------|-----------------|-------------|-------| | Adaptacion de estilo/tono | 100-200 | 500-1,000 | La consistencia es clave | | Formato de salida | 200-500 | 1,000-2,000 | Cubrir todos los casos extremos | | Conocimiento de dominio | 500-1,000 | 2,000-5,000 | La diversidad importa | | Razonamiento complejo | 1,000-2,000 | 5,000-10,000 | Chain-of-thought ayuda | | Multi-tarea | 500+ por tarea | 1,000+ por tarea | Balance entre tareas |
Importante: Estos numeros asumen ejemplos de alta calidad y diversos. 200 ejemplos cuidadosamente curados superaran a 2,000 ruidosos. Cuando tengas dudas, invierte en calidad sobre cantidad.
Consejo Practico
Antes de comenzar cualquier esfuerzo de recoleccion de datos, crea 10 "ejemplos dorados" — pares de entrada-salida perfectos que representan exactamente lo que quieres que el modelo haga. Usalos como tu estrella del norte durante todo el proceso. Cada nuevo ejemplo deberia ser tan bueno como tu conjunto dorado. Si no lo es, arreglalo o descartalo.
En la proxima leccion, tomaremos tus datos limpios y los formatearemos para frameworks de entrenamiento especificos — Hugging Face, Axolotl y Unsloth — con ejemplos de codigo completos.