# Protocolo: un corpus aceptado antes de comparar el coste

Versión 1 — 24 de septiembre de 2026. Esta ficha propone un protocolo para rellenar; no contiene ningún resultado medido ni conjunto de datos. El notebook asociado utiliza un pequeño MLP sintético para aprender a registrar la memoria. No ejecuta el protocolo de negocio que figura a continuación.

## 1. Definir el trabajo útil antes de las pruebas

Ejemplo de trabajo: clasificar un corpus de **1 000 textos**. Constituye tú mismo un conjunto autorizado, representativo de tu uso, con un identificador único y una referencia verificada por texto. Fija la revisión del corpus, del modelo, del tokenizer, del código y la semilla. Conserva por separado la lista de IDs esperados y las salidas individuales para permitir la auditoría.

Define antes de cualquier medición: las clases, el formato de salida, la métrica principal (por ejemplo macro-F1), su umbral de aceptación y la degradación máxima permitida frente a una referencia. Elige una tolerancia pertinente para tu aplicación; aquí no se proporciona ningún valor universal. Los datos de entrenamiento, de ajuste y de evaluación deben permanecer separados.

Un corpus se acepta solo si los 1 000 IDs esperados están presentes exactamente una vez, no figura ninguna respuesta adicional en las salidas, el formato es válido y se cumple la regla de calidad preestablecida. Dos archivos que contengan cada uno 1 000 líneas no demuestran por sí solos la igualdad de los IDs. Archiva la comprobación de los conjuntos y de los duplicados.

## 2. Cambiar solo la variante anunciada

Para estudiar el batch, prepara por ejemplo variantes 1, 4 y 8. Mantén el mismo corpus, orden de las entradas, modelo, tokenizer, precisión y límite de contexto. Si estudias después la precisión, crea un experimento distinto y vuelve a hacer el control de calidad. Describe el truncado: acortar los textos cambia el trabajo realizado.

Registra el GPU real, el número de GPU efectivamente utilizadas, el device, el controlador, Python, PyTorch y el runtime CUDA o ROCm. Inscribe también la versión de tu código, las opciones de generación eventuales y cualquier concurrencia en la máquina en `notes`. Un lote comercial de dos GPU no implica que el programa use ambas.

## 3. Medir pasajes comparables

Anuncia qué abarca el cronómetro: solo el procesamiento o la cadena completa con lectura, tokenización y escritura. Separa carga, primer pasaje y pasajes calentados. El script de memoria solo mide su MLP y no cronometra una cadena de clasificación completa.

Realiza el calentamiento anunciado, luego cinco pasajes medidos por variante en un orden alternado o sorteado de antemano. Guarda cada duración bruta. Reportar la mediana y el rango mínimo–máximo permite ver la dispersión; cinco observaciones no justifican una estimación robusta del p95. No descartes silenciosamente un error o un pasaje lento: conserva su línea y explica el incidente. Vuelve a lanzar en un proceso nuevo si deseas comparar los primeros pasajes en condiciones similares.

Para las mediciones de GPU en PyTorch, sincroniza el device elegido antes del registro inicial y después de la operación. Registra las baselines `allocated` y `reserved`, reinicia las estadísticas de pico y luego conserva los picos absolutos de la fase. `allocated` está incluido en `reserved`: sumarlos contaría dos veces una parte de la memoria. Ambos máximos pueden alcanzarse en instantes diferentes: su diferencia no es una medida de la caché en un instante dado. Las asignaciones de otros procesos y las externas al asignador de PyTorch no están cubiertas.

## 4. Rellenar resultats-bruts.csv

El CSV distribuido contiene únicamente los encabezados. Escribe una línea por pasaje, con un punto decimal y segundos para los tiempos, bytes para la memoria y centavos USD para el forfait. Una celda vacía significa «no registrado»; cero significa realmente cero. Las comas presentes en una nota deben protegerse con las reglas CSV habituales.

| Campos | Sentido y captura |
| --- | --- |
| `experiment_id`, `variant_id` | Identificadores estables del experimento y de la variante. |
| `corpus_revision`, `model_revision`, `tokenizer_revision`, `seed` | Versiones inmutables o huellas, y semilla anunciada. |
| `gpu_model`, `gpu_count`, `device`, `driver_version`, `python_version`, `torch_version`, `runtime_version` | Hardware realmente utilizado y entorno observado; no copies una promesa de la oferta. |
| `precision`, `batch`, `context` | Configuración realmente aplicada. |
| `phase`, `run_index`, `warmup_iterations` | Fase separada (`cold` o `warm`, por ejemplo), número de la pasada, número de calentamientos. No mezcles las duraciones. |
| `expected_ids`, `observed_ids` | Números de IDs esperados y observados; las listas detalladas se conservan con las salidas. |
| `ids_match`, `format_valid` | `true`/`false` tras la verificación real, incluidos duplicados y respuestas adicionales. |
| `quality_metric`, `quality_threshold`, `quality_tolerance`, `quality_value` | Nombre, umbral y tolerancia preestablecidos, y después el valor medido. Precisar el sentido de la tolerancia y la referencia en `notes`. |
| `corpus_accepted` | `true` solo si se cumplen todas las condiciones de validación; si no, `false`. |
| `elapsed_seconds` | Duración bruta del perímetro anunciado, nunca un valor esperado. |
| `baseline_allocated_bytes`, `baseline_reserved_bytes`, `peak_allocated_bytes`, `peak_reserved_bytes` | Registros distintos para el único device medido. Déjalos vacíos si no se midieron. |
| `duration_days`, `lots`, `package_total_usd_minor` | Paquete completo elegido, lotes facturados y precio total en centavos USD; un solo gasto no debe sumarse cinco veces. |
| `accepted_unique_corpora` | Número de corpus útiles distintos aceptados para el análisis económico; este campo no debe sumarse entre repeticiones. |
| `notes` | Perímetro, incidencias, decisiones de calidad, revisión del código y referencias de las piezas conservadas. |

## 5. Calcular sin inventar producción

El precio que hay que comparar es el paquete completo de 3, 7 o 30 días multiplicado por los lotes. Para B200, un lote contiene dos GPU y la tarifa ya cubre ese lote. `calcul_forfaits.py` aplica esta regla a las tarifas proporcionadas.

Si el trabajo útil elegido es un corpus completo aceptado, `--accepted-results` debe recibir el número de corpus distintos efectivamente validados en el periodo. Las cinco repeticiones del mismo corpus sirven para medir la variabilidad: no crean cinco entregables útiles. Fija la unidad antes de la comparación y mantenla para todas las variantes. Sin una cantidad medida y aceptada, deja este parámetro ausente: solo se calculará el coste del paquete. No proyectes automáticamente una cadencia sobre 3, 7 o 30 días.

Conserva juntos el protocolo rellenado, las salidas individuales, los controles de calidad, el CSV en bruto y el cálculo económico. Una configuración más rápida pero no aceptada no cumple el mismo objetivo. Una configuración que supera la memoria sigue siendo una observación de fallo, no un tiempo que haya que sustituir por cero.
