# Kernodeck Reprise v1 — un checkpoint realmente reanudado

Este ejercicio original aprende una pequeña relación numérica sobre 24 líneas sintéticas. Su objetivo es **verificar la reanudación de un entrenamiento**, no obtener el mejor modelo ni medir una GPU. El cálculo se fuerza explícitamente en **CPU**, en `float64`, con un hilo de PyTorch.

El control compara 10 pasos continuos con 5 pasos, un checkpoint y luego 5 pasos nuevos en **otro proceso Python**. Un cuarto proceso omite voluntariamente la restauración de los generadores aleatorios: su deriva debe ser detectada. No se descarga ningún recurso remoto, dato de cliente ni peso preentrenado.

## Requisitos previos

- Un entorno Python con PyTorch y NumPy ya instalados. La prueba proporcionada se ejecutó con **Python 3.14.6, PyTorch 2.11.0+cu128 y NumPy 2.4.4**.
- Alrededor de 1 MB disponible para las cuatro pequeñas carpetas de salida. Las dependencias de Python ocupan su propio espacio.
- Ejecutar los comandos desde la carpeta extraída `kernodeck-reprise-v1`.

El sufijo `+cu128` describe el paquete presente durante la prueba; no significa que este ejercicio haya usado CUDA. **Ningún cálculo CUDA, ROCm, AMP, multitarjeta o distribuido queda validado por este recurso.** No utiliza workers de DataLoader. Otro entorno debe producir su propia prueba; no se garantiza la igualdad entre versiones o plataformas.

## El comando de verificación

```console
python -B verify_resume.py --output runs/preuve-cpu
```

`-B` evita las cachés de bytecode en la carpeta del proyecto. El directorio de salida debe ser nuevo: no se sobrescribe ningún ensayo existente. Para empezar de nuevo, usa por ejemplo `runs/preuve-cpu-2`.

El programa ejecuta cuatro comandos con el mismo intérprete de Python y luego escribe `runs/preuve-cpu/verification.json`. Una ejecución completa produce:

```json
{"device":"cpu","all_checks_passed":true,"positive":true,"negative_divergence_detected":true,"report":"verification.json"}
```

El código de salida vale **0** si el protocolo tiene éxito, **1** si la comparación falla, **2** si la verificación no pudo completarse. El éxito exige a la vez la reanudación positiva y el fallo observable del control negativo. Un archivo de checkpoint simplemente presente no basta.

## Hacer los tres pasos a mano

```console
python -B train.py --steps 10 --output runs/continu
python -B train.py --steps 5 --output runs/coupure
python -B train.py --steps 5 --resume runs/coupure/checkpoint.pt --output runs/reprise
```

Cada línea lanza un proceso distinto. `--steps` significa **pasos adicionales**, así que el tercer comando termina en el paso 10. Cada carpeta contiene `checkpoint.pt`, su huella `checkpoint.pt.sha256` y un resumen legible `summary.json`. Los checkpoints los crea el ejercicio durante la ejecución; no se distribuyen en el archivo.

Para observar el caso incompleto, usa una carpeta nueva:

```console
python -B train.py --steps 5 --resume runs/coupure/checkpoint.pt --omit-rng-restore --output runs/reprise-incomplete
```

Este último comando puede terminar sin error de Python. **Eso no prueba una reanudación correcta.** El comando `verify_resume.py` compara los resultados y constata la diferencia.

## Lo que el modelo hace realmente

`data.csv` contiene una grilla de dos variables y un objetivo sintético: `target = 0.7*x1 - 0.4*x2 + 0.15*x1*x2 + 0.1`. No imita ningún registro de cliente. La red consta de dos entradas, una capa de ocho neuronas, `Tanh`, un dropout de 0,25 y una salida, es decir, 33 parámetros.

El entrenamiento usa Adam con una tasa inicial de 0,03. StepLR divide esa tasa por dos cada tres pasos. Cada batch contiene cuatro líneas: 10 pasos consumen por tanto 40 observaciones, recorriendo de nuevo algunas líneas tras la primera época. La permutación, la época, el cursor y el número de observaciones consumidas se conservan. En el corte tras cinco pasos, el cursor vale 20 sobre 24: la reanudación tiene lugar **dentro del recorrido de datos**.

Tres fuentes aleatorias influyen en el trabajo: Python fija una ligera ganancia sobre las entradas, un generador NumPy PCG64 produce el ruido y las permutaciones, PyTorch produce el dropout. Fijar de nuevo el seed inicial no reconstituye los estados alcanzados en el corte.

## Lo que el checkpoint conserva y en qué orden se relee

El diccionario contiene los pesos, el estado Adam, el estado StepLR, la progresión de los datos, los tres RNG, el historial de pérdidas y tasas, así como las huellas del código y del CSV. El modo `train()` se restablece para la reanudación; la medición de MSE final usa `eval()` y no consume el dropout.

Al reanudar, el código construye primero el modelo, el optimizador y **el planificador**, y luego carga los pesos, el estado del planificador y el del optimizador. Los RNG se restauran al final, después de las construcciones que consumen aleatoriedad. Esta elección respeta la advertencia de la documentación [Optimizer.load_state_dict](https://docs.pytorch.org/docs/2.11/generated/torch.optim.Optimizer.load_state_dict.html).

El estado de Python es una estructura de primitivas. PCG64 proporciona un diccionario de enteros y cadenas; ningún objeto `ndarray` de NumPy se serializa como estado RNG. El estado de PyTorch CPU es un tensor de bytes. Los siguientes sorteos se controlan sin modificar el estado guardado.

## Lectura de la prueba y tolerancia

`verification-cpu.json` es la prueba pública procedente de una ejecución real de esta versión. `source` contiene los SHA-256 de los scripts y del CSV. `protocol` describe los cuatro procesos, la precisión y la tolerancia. `resume_boundary` verifica el siguiente sorteo de cada RNG y la siguiente tasa utilizada tras el corte.

La comparación exige el mismo orden de filas, la misma progresión y el mismo estado de planificador. La desviación absoluta máxima aceptada para los pesos, el estado del optimizador, las pérdidas, la MSE y las tasas es **1e-12**, sin tolerancia relativa (`rtol=0`). El informe conserva las desviaciones medidas, incluso cuando valen cero. También verifica el siguiente sorteo de los RNG al final de los dos recorridos.

El control negativo debe mostrar que olvidar los RNG cambia el resultado. Su MSE puede ser más baja o más alta: esta prueba verifica una trayectoria de reanudación, no una clasificación de calidad. Una divergencia esperada da por tanto `passed: false` en este subtest y `divergence_detected: true`; el protocolo global puede entonces superarse.

## Cargar solo tu propio checkpoint

El cargador usa explícitamente `torch.load(..., map_location="cpu", weights_only=True)` y no ofrece ningún fallback hacia `weights_only=False`. Primero verifica la huella asociada, limita el tamaño y comprueba el esquema, las versiones, el código y los datos. Rechaza un estado incompleto en lugar de reinicializar silenciosamente una parte del entrenamiento.

Utiliza únicamente los checkpoints que **hayas creado con este ejercicio y conservado bajo tu control**. La huella sirve para detectar una modificación; no autentica a un remitente. La carga restringida no hace que un archivo desconocido sea digno de confianza. Consulta [torch.load](https://docs.pytorch.org/docs/2.11/generated/torch.load.html) y [la serialización de PyTorch](https://docs.pytorch.org/docs/2.11/notes/serialization.html).

## Adaptar el ejercicio a tu proyecto

Identifica los estados que tu propio entrenamiento consume realmente: sampler, aumento de datos, optimizador, planificador y generadores particulares. Si usas AMP, añade el estado del scaler en una frontera coherente; este ejercicio no lo hace. Un entrenamiento distribuido también requiere tratar sus procesos y su reparto de datos.

No deduzcas de esta pequeña prueba una duración de alquiler, un rendimiento, una huella de VRAM o una garantía de reanudación para un modelo diferente. Retoma el método: conjunto corto representativo, corte a mitad del trabajo, otro proceso, comparación explícita y control negativo.

## Contenido y licencias

- `train.py`, `verify_resume.py`, esta documentación y el manifiesto: licencia MIT, consulta `LICENSE-MIT.txt`.
- `data.csv`: datos sintéticos originales ofrecidos bajo CC0 1.0, consulta `DATA-LICENSE-CC0.txt`.
- `verification-cpu.json`: mediciones de este ejercicio, sin datos personales, entorno completo, rutas del equipo, tokens o identificadores de sesión.
- `manifest.json`: lista exacta de los archivos distribuidos y de sus SHA-256. El manifiesto no se referencia a sí mismo.
- `SOURCES.md`: enlaces oficiales y límites documentales.

Las dependencias PyTorch, NumPy y Python conservan sus propias licencias. No se redistribuyen en el ZIP.


## Presentación de Kernodeck y compatibilidad del proyecto

Esta reedición del 25 de septiembre de 2026 actualiza el nombre del archivo, la documentación y la marca. Los scripts `train.py` y `verify_resume.py`, el CSV y `verification-cpu.json` siguen siendo idénticos a la entrega ejecutada el 24 de septiembre de 2026. El campo técnico `project` conserva su identificador para los lectores de informes existentes. No se ha vuelto a ejecutar ningún cálculo ni comprobación de CPU/GPU para esta reedición.
