Construir un Conjunto de Datos de Ajuste Fino Desde la Web: URLs a JSONL

Un buen ajuste fino es 90% el conjunto de datos. Esta es la canalización desde URLs crudas hasta JSONL limpio: obtención a escala, deduplicación, filtros de licencia y el formato de chat que los entrenadores realmente esperan.

Un ajuste fino es tan bueno como los datos que le proporcionas, y la parte más difícil del ajuste fino casi nunca es la ejecución del entrenamiento, sino construir un conjunto de datos limpio. La web es la fuente más rica de esos datos, pero las páginas crudas son desordenadas, duplicadas, sin etiquetar y legalmente desiguales. Esta guía es la canalización desde URLs hasta JSONL listo para entrenamiento: cuántos datos realmente necesitas, cómo obtenerlos a escala, cómo limpiarlos y deduplicarlos, cómo manejar las licencias y cómo formatearlos en la estructura de chat que los entrenadores esperan. Se asume que estás construyendo un ajuste fino de instrucciones o chat a partir de contenido web público.

¿Cuántos datos realmente necesitas?

Comienza con objetivos realistas para no construir en exceso o en defecto. El mínimo práctico para un ajuste fino que produzca resultados razonables es alrededor de 100 filas; para un rendimiento sólido generalmente se desea más de 1,000. Más usualmente ayuda, pero solo si está limpio: mil ejemplos bien etiquetados superan a diez mil ruidosos. Como referencia de escala, el clásico conjunto de datos Alpaca fue de 52,000 pares de instrucción/salida, generados al solicitar un modelo más fuerte. Y si estás usando un modelo grande para generar ejemplos sintéticos, inícialo con al menos diez ejemplos escritos a mano para que aprenda la estructura y el tono exactos que deseas antes de que produzca más.

Obtención: rastreo a markdown limpio

El objetivo en la etapa de obtención es texto limpio, no HTML crudo. Una fila de ajuste fino quiere el contenido de una página: el artículo, los documentos, las preguntas y respuestas, sin las barras de navegación, los banners de cookies y el marcado de anuncios que contaminan un scrape ingenuo. Así que rastrea tus páginas objetivo y conviértelas a markdown al ingresar, lo que elimina el contenido genérico mientras mantiene la estructura como encabezados y listas. A cualquier volumen real te encontrarás con límites de tasa y bloqueos de IP, así que dirige el rastreo a través de un grupo rotativo. Una Scraper API que devuelve markdown directamente hace ambos trabajos: salida limpia y resistencia a bloqueos, en una sola llamada, por eso lo cubrimos en nuestra guía sobre alimentar LLMs con datos web frescos.

# Sketch: crawl target URLs to clean markdown, ready for shaping into rows.
import requests

API = "https://api.quantumproxies.io/scrape"   # returns markdown, handles rotation

def fetch_markdown(url):
    r = requests.get(API, params={"url": url, "format": "markdown"},
                     headers={"Authorization": "Bearer YOUR_KEY"}, timeout=60)
    return r.json()["markdown"]

docs = [fetch_markdown(u) for u in seed_urls]   # clean text, no boilerplate
Diagrama de canalización desde URLs a un conjunto de datos de ajuste fino: fuente a markdown limpio, limpieza y deduplicación, formato como mensajes JSONL, luego tarjeta del conjunto de datos y división de entrenamiento/evaluación
El modelo solo ve tu conjunto de datos, por lo que cada etapa que elimina basura mejora directamente el ajuste fino.

El formato JSONL que los entrenadores esperan

La mayoría de las herramientas modernas de ajuste fino predeterminan a un formato conversacional JSONL: un objeto JSON por línea, cada uno con un array messages de pares rol/contenido, donde los roles son system, user y assistant y los turnos de usuario/asistente se alternan. Ese es el formato de chat que los entrenadores al estilo de Hugging Face y OpenAI ingieren. Los conjuntos de datos de instrucciones más antiguos usan una forma de tres campos (instruction, input, output) — adecuado para ajuste fino supervisado de un solo turno — y también existen formatos de conversación de varios turnos, pero se convierten limpiamente en la forma de mensajes. Elige un formato objetivo y estandariza todo a él.

// One training example per line (.jsonl). Chat / messages format:
{"messages":[
  {"role":"system","content":"You classify support tickets by urgency."},
  {"role":"user","content":"My payment failed three times and the event is tomorrow."},
  {"role":"assistant","content":"high"}
]}
{"messages":[
  {"role":"system","content":"You classify support tickets by urgency."},
  {"role":"user","content":"How do I change my avatar?"},
  {"role":"assistant","content":"low"}
]}

Ajusta el formato al objetivo de entrenamiento: texto sin procesar para preentrenamiento continuo, instrucción más salida o chat de varios turnos para ajuste fino supervisado, respuestas clasificadas para métodos basados en preferencias. Si estás construyendo un ajuste fino de razonamiento, mantén la pregunta y la respuesta pero reescribe la respuesta para incluir los pasos de cadena de pensamiento que deseas que el modelo aprenda.

Limpieza: donde se gana la calidad

Esta es la etapa que decide tu resultado, y es principalmente un filtrado poco glamuroso. Nunca asumas que las filas obtenidas de la web o generadas por el modelo son correctas — inspecciónalas. Los modos de falla recurrentes son específicos y vale la pena verificarlos por nombre:

Un buen hábito es mantener tanto el JSONL pre-limpio como el limpio para que puedas medir lo que eliminaste. Y equilibra el conjunto a través de categorías — una clase sobre-representada enseña al modelo a sobre-predecirla.

Deduplicación y licencias

Los datos web están llenos de repeticiones — artículos sindicados, documentos reflejados, párrafos de contenido genérico — y los duplicados dañan silenciosamente un ajuste fino al sobreponderar lo que se repite. Haz dos pasadas: deduplicación de coincidencia exacta mediante el hash del texto normalizado para capturar filas idénticas, luego detección de casi duplicados (una técnica de similitud o shingling como MinHash) para capturar copias reescritas que un hash exacto pasa por alto. En cuanto a licencias, sé deliberado: no todo lo público es libremente reutilizable. Rastrea la fuente y la licencia de cada documento, filtra el contenido cuyos términos prohíban el uso para entrenamiento, y prefiere fuentes con permisos claros de reutilización. Es mucho más barato registrar la procedencia mientras rastreas que reconstruirla después de haber mezclado todo.

Obtén datos web limpios para LLMs

Combina, documenta y divide

Cuando estás extrayendo de varias fuentes, estandarízalas todas a un formato y fusiónalas en un solo conjunto de datos unificado antes de entrenar — un buen ajuste fino en el conjunto combinado supera al ajuste fino secuencial en cada fuente, lo que tiende a erosionar lo que el modelo aprendió antes. Luego escribe una tarjeta del conjunto de datos: un breve registro de dónde provienen los datos, cómo se limpiaron, su tamaño y distribución de etiquetas, sus licencias y cualquier limitación conocida. Es lo que hace que el conjunto de datos sea reproducible y auditable meses después. Finalmente, reserva una división de evaluación que nunca entrenes, para que puedas medir el ajuste fino honestamente en lugar de calificarlo en datos que memorizó. Si estás alimentando un sistema de recuperación en lugar de un ajuste fino, nuestra guía de canalización RAG cubre el lado de actualización del mismo problema.

Panel de estadísticas que muestra tamaños de conjuntos de datos de ajuste fino: mínimo de 100 filas, más de 1000 para óptimo, 10 ejemplos semilla para generación sintética, 52000 filas de Alpaca
Por debajo de aproximadamente 100 filas un ajuste fino apenas aprende; más allá de 1,000 filas limpias, la calidad supera a la cantidad.

Preguntas frecuentes

¿Cuántas filas necesito para ajustar finamente un LLM?

Alrededor de 100 filas es el mínimo práctico para resultados razonables, y más de 1,000 es un buen objetivo para un rendimiento sólido. Más generalmente ayuda, pero solo si los datos se mantienen limpios — un conjunto más pequeño y bien etiquetado supera a uno grande y ruidoso. Para generación sintética, inicia el generador con al menos diez ejemplos escritos a mano para que aprenda tu formato exacto primero.

¿En qué formato deben estar los datos de ajuste fino?

JSONL — un objeto JSON por línea. La mayoría de los entrenadores modernos predeterminan a un formato conversacional con un array messages de pares rol-contenido de sistema/usuario/asistente. Los conjuntos de datos de instrucciones más antiguos usan campos de instrucción/entrada/salida. Elige un formato objetivo basado en tu objetivo de entrenamiento y estandariza cada fuente a él antes de entrenar.

¿Cómo limpio un conjunto de datos extraído para ajuste fino?

Convierte páginas a markdown para eliminar contenido genérico, luego filtra manualmente los fallos comunes: etiquetas inconsistentes, respuestas fuera de objetivo, filas mal etiquetadas y texto de navegación o cookies sobrante. Deduplica con un hash exacto y una pasada de casi duplicados, equilibra las categorías, y mantén tanto las versiones crudas como las limpias para que puedas medir lo que eliminaste.

¿Puedo usar cualquier contenido web para entrenar un modelo?

No automáticamente — público no significa libremente reutilizable. Algunos contenidos tienen términos que prohíben el uso para entrenamiento, y los datos personales traen sus propias reglas. Rastrea la fuente y la licencia de cada documento mientras lo recopilas, filtra cualquier cosa cuyos términos prohíban el entrenamiento, y prefiere fuentes con permisos claros. Esta es información general, no asesoramiento legal; busca asesoría para conjuntos de datos comerciales.

Construir un conjunto de datos de ajuste fino desde la web es una canalización de filtrado: fuente markdown limpio, dale forma al formato de mensajes que tu entrenador espera, deduplica y verifica etiquetas sin piedad, filtra por licencia y documenta el resultado. Obtén aproximadamente mil filas limpias y reserva una división de evaluación honesta, y gastarás tu presupuesto de entrenamiento en señal en lugar de ruido.

Construye tu conjunto de datos con datos web de QuantumProxies