# Kernodeck Reprise v1 — um checkpoint realmente retomado

Este exercício original aprende uma pequena relação numérica sobre 24 linhas sintéticas. Seu objetivo é **verificar a retomada de um treinamento**, não obter o melhor modelo ou medir uma GPU. O cálculo é explicitamente forçado na **CPU**, em `float64`, com uma thread do PyTorch.

O controle compara 10 etapas contínuas a 5 etapas, um checkpoint e, em seguida, 5 novas etapas em **outro processo Python**. Um quarto processo omite voluntariamente a restauração dos geradores aleatórios: seu desvio deve ser detectado. Nenhum recurso remoto, dado de cliente ou peso pré-treinado é baixado.

## Pré-requisitos

- Um ambiente Python com PyTorch e NumPy já instalados. A prova fornecida foi executada com **Python 3.14.6, PyTorch 2.11.0+cu128 e NumPy 2.4.4**.
- Cerca de 1 MB disponível para as quatro pequenas pastas de saída. As dependências Python ocupam seu próprio espaço.
- Executar os comandos a partir da pasta extraída `kernodeck-reprise-v1`.

O sufixo `+cu128` descreve o pacote presente no momento do teste; ele não significa que este exercício usou CUDA. **Nenhum cálculo CUDA, ROCm, AMP, multicartão ou distribuído é validado por este recurso.** Ele não usa workers do DataLoader. Outro ambiente deve produzir sua própria prova; a igualdade não é garantida entre versões ou plataformas.

## O comando de verificação

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

`-B` evita caches de bytecode na pasta do projeto. O diretório de saída deve ser novo: nenhum ensaio existente é sobrescrito. Para recomeçar, use por exemplo `runs/preuve-cpu-2`.

O programa executa quatro comandos com o mesmo interpretador Python e, em seguida, escreve `runs/preuve-cpu/verification.json`. Uma execução completa aguarda:

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

O código de saída vale **0** se o protocolo for bem-sucedido, **1** se a comparação falhar, **2** se a verificação não puder ser concluída. O sucesso exige tanto a retomada positiva quanto a falha observável do controle negativo. Um arquivo de checkpoint simplesmente presente não basta.

## Fazer as três etapas manualmente

```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 linha inicia um processo distinto. `--steps` significa **etapas adicionais**, portanto o terceiro comando termina na etapa 10. Cada pasta contém `checkpoint.pt`, sua impressão digital `checkpoint.pt.sha256` e um resumo legível `summary.json`. Os checkpoints são criados pelo exercício durante a execução; eles não são distribuídos no arquivo compactado.

Para observar o caso incompleto, use uma nova pasta:

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

Esse último comando pode terminar sem erro Python. **Isso não prova uma retomada correta.** O comando `verify_resume.py` compara os resultados e constata a diferença.

## O que o modelo realmente faz

`data.csv` contém uma grade de duas variáveis e um alvo sintético: `target = 0.7*x1 - 0.4*x2 + 0.15*x1*x2 + 0.1`. Ele não imita nenhuma medição de cliente. A rede possui duas entradas, uma camada de oito neurônios, `Tanh`, um dropout de 0,25 e uma saída, ou seja, 33 parâmetros.

O treinamento usa Adam com uma taxa inicial de 0,03. O StepLR divide essa taxa por dois a cada três etapas. Cada batch contém quatro linhas: 10 etapas, portanto, consomem 40 observações, percorrendo novamente algumas linhas após a primeira época. A permutação, a época, o cursor e o número de observações consumidas são conservados. Na interrupção após cinco etapas, o cursor vale 20 de 24: a retomada ocorre **dentro do percurso dos dados**.

Três fontes aleatórias influenciam o trabalho: o Python define um leve ganho sobre as entradas, um gerador NumPy PCG64 produz o ruído e as permutações, o PyTorch produz o dropout. Fixar novamente o seed inicial não reconstitui os estados atingidos na interrupção.

## O que o checkpoint conserva e em que ordem ele é relido

O dicionário contém os pesos, o estado Adam, o estado StepLR, a progressão dos dados, os três RNG, o histórico das perdas e taxas, bem como as impressões digitais do código e do CSV. O modo `train()` é restabelecido para a retomada; a medição de MSE final usa `eval()` e não consome o dropout.

Na retomada, o código constrói primeiro o modelo, o otimizador e **o agendador**, depois carrega os pesos, o estado do agendador e o do otimizador. Os RNG são restaurados por último, após as construções que consomem aleatoriedade. Essa escolha respeita o aviso da documentação [Optimizer.load_state_dict](https://docs.pytorch.org/docs/2.11/generated/torch.optim.Optimizer.load_state_dict.html).

O estado Python é uma estrutura de primitivas. O PCG64 fornece um dicionário de inteiros e strings; nenhum objeto `ndarray` NumPy é serializado como estado RNG. O estado PyTorch CPU é um tensor de bytes. Os próximos sorteios são controlados sem modificar o estado salvo.

## Leitura da prova e tolerância

`verification-cpu.json` é a prova pública resultante de uma execução real desta versão. `source` contém os SHA-256 dos scripts e do CSV. `protocol` descreve os quatro processos, a precisão e a tolerância. `resume_boundary` verifica o próximo sorteio de cada RNG e a próxima taxa utilizada após a interrupção.

A comparação exige a mesma ordem de linhas, a mesma progressão e o mesmo estado de agendador. A diferença absoluta máxima aceita para os pesos, o estado do otimizador, as perdas, a MSE e as taxas é **1e-12**, sem tolerância relativa (`rtol=0`). O relatório conserva as diferenças medidas, mesmo quando valem zero. Ele também verifica o próximo sorteio dos RNG ao final dos dois percursos.

O controle negativo deve mostrar que esquecer os RNG altera o resultado. Sua MSE pode ser mais baixa ou mais alta: esse teste verifica uma trajetória de retomada, não uma classificação de qualidade. Uma divergência esperada resulta, portanto, em `passed: false` nesse subteste e `divergence_detected: true`; o protocolo global pode então ser bem-sucedido.

## Carregar apenas o próprio checkpoint

O carregador usa explicitamente `torch.load(..., map_location="cpu", weights_only=True)` e não oferece nenhum fallback para `weights_only=False`. Ele verifica primeiro a impressão digital associada, limita o tamanho e verifica o esquema, as versões, o código e os dados. Ele rejeita um estado incompleto em vez de reinicializar silenciosamente uma parte do treinamento.

Use apenas os checkpoints que **você criou com este exercício e manteve sob seu controle**. A impressão digital serve para detectar uma modificação; ela não autentica um remetente. O carregamento restrito não torna um arquivo desconhecido confiável. Veja [torch.load](https://docs.pytorch.org/docs/2.11/generated/torch.load.html) e [a serialização PyTorch](https://docs.pytorch.org/docs/2.11/notes/serialization.html).

## Adaptar o exercício ao seu projeto

Identifique os estados que o seu próprio treinamento realmente consome: sampler, augmentation, otimizador, agendador e geradores específicos. Se você usa AMP, adicione o estado do scaler em uma fronteira coerente; este exercício não o faz. Um treinamento distribuído também exige tratar seus processos e sua distribuição de dados.

Não deduza desta pequena prova uma duração de locação, uma taxa de transferência, uma pegada de VRAM ou uma garantia de retomada para um modelo diferente. Retome o método: conjunto curto representativo, interrupção no meio do trabalho, outro processo, comparação explícita e controle negativo.

## Conteúdo e licenças

- `train.py`, `verify_resume.py`, esta documentação e o manifesto: licença MIT, veja `LICENSE-MIT.txt`.
- `data.csv`: dados sintéticos originais oferecidos sob CC0 1.0, veja `DATA-LICENSE-CC0.txt`.
- `verification-cpu.json`: medições deste exercício, sem dados pessoais, ambiente completo, caminhos da máquina, tokens ou identificadores de sessão.
- `manifest.json`: lista exata dos arquivos distribuídos e de seus SHA-256. O manifesto não se referencia a si mesmo.
- `SOURCES.md`: links oficiais e limites documentais.

As dependências PyTorch, NumPy e Python mantêm suas próprias licenças. Elas não são redistribuídas no ZIP.


## Apresentação Kernodeck e compatibilidade do projeto

Esta reedição de 25 de setembro de 2026 atualiza o nome do arquivo, a documentação e a marca. Os scripts `train.py` e `verify_resume.py`, o CSV e `verification-cpu.json` permanecem idênticos à entrega executada em 24 de setembro de 2026. O campo técnico `project` mantém seu identificador para os leitores de relatórios existentes. Nenhum cálculo nem verificação de CPU/GPU foi relançado para esta reedição.
