# Kernodeck 重启 v1 —— 一次真正重新开始的检查点

这个原始练习在 24 行合成数据上学习一个简单的数值关系。它的目标是**验证训练的重启**，而不是获得最佳模型或衡量 GPU。计算被明确强制在 **CPU** 上以 `float64` 进行，仅使用一个 PyTorch 线程。

该验证将 10 个连续步骤与 5 个步骤、一个检查点，然后在**另一个 Python 进程**中进行 5 个新步骤进行比较。第四个进程有意省略随机生成器的恢复：它的漂移必须被检测出来。不会下载任何远程资源、客户数据或预训练权重。

## 前提条件

- 一个已安装 PyTorch 和 NumPy 的 Python 环境。所提供的验证是在 **Python 3.14.6、PyTorch 2.11.0+cu128 和 NumPy 2.4.4** 下运行的。
- 四个小型输出目录大约需要 1 MB 可用空间。Python 依赖项占用各自的空间。
- 从解压后的 `kernodeck-reprise-v1` 文件夹中执行命令。

后缀 `+cu128` 描述的是测试时存在的软件包；它并不意味着本练习使用了 CUDA。**本资源不验证任何 CUDA、ROCm、AMP、多卡或分布式计算。**它不使用 DataLoader worker。其他环境必须产生自己的验证；不同版本或平台之间不保证相等。

## 验证命令

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

`-B` 避免在项目文件夹中产生字节码缓存。输出目录必须是新的：不会覆盖任何现有试验。要重新开始，例如使用 `runs/preuve-cpu-2`。

程序使用同一个 Python 解释器执行四条命令，然后写入 `runs/preuve-cpu/verification.json`。一次完整的运行预期输出：

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

如果协议成功，退出码为 **0**；如果比较失败，为 **1**；如果验证无法完成，为 **2**。成功既要求正向重启成功，也要求负向对照出现可观察的失败。仅仅存在一个检查点文件是不够的。

## 手动完成这三个步骤

```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
```

每一行启动一个独立的进程。`--steps` 表示**额外步骤**，因此第三条命令在第 10 步结束。每个文件夹包含 `checkpoint.pt`、其哈希 `checkpoint.pt.sha256` 以及一个可读的摘要 `summary.json`。检查点由练习在运行时创建；它们不会随压缩包分发。

要观察不完整的情况，请使用一个新文件夹：

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

最后这条命令可能会在没有 Python 错误的情况下结束。**这并不证明重启是正确的。**命令 `verify_resume.py` 会比较结果并发现差异。

## 模型实际做了什么

`data.csv` 包含一个由两个变量组成的网格和一个合成目标：`target = 0.7*x1 - 0.4*x2 + 0.15*x1*x2 + 0.1`。它不模仿任何客户记录。该网络包含两个输入、一个由八个神经元组成的层、`Tanh`、一个 0.25 的 dropout 和一个输出，共 33 个参数。

训练使用 Adam，初始学习率为 0.03。StepLR 每三步将该学习率减半。每个 batch 包含四行：因此 10 个步骤消耗 40 个观测值，在第一个 epoch 之后会再次遍历某些行。排列、epoch、游标和已消耗的观测数都会被保留。在五个步骤后中断时，游标为 24 中的 20：重启发生在**数据遍历的内部**。

三个随机源影响工作：Python 为输入设置一个轻微的增益，一个 NumPy PCG64 生成器产生噪声和排列，PyTorch 产生 dropout。重新固定初始 seed 并不能重建中断时达到的状态。

## 检查点保留了什么，以及以什么顺序被重新读取

字典包含权重、Adam 状态、StepLR 状态、数据进度、三个 RNG、损失与学习率历史，以及代码和 CSV 的指纹。恢复时会重新设为 `train()` 模式；最终的 MSE 测量使用 `eval()`，不会消耗 dropout。

恢复时，代码先构建模型、优化器和**调度器**，然后加载权重、调度器状态和优化器状态。RNG 最后恢复，放在那些会消耗随机性的构建步骤之后。这一选择遵循文档 [Optimizer.load_state_dict](https://docs.pytorch.org/docs/2.11/generated/torch.optim.Optimizer.load_state_dict.html) 中的警告。

Python 状态是由基本类型组成的结构。PCG64 提供的是由整数和字符串组成的字典；没有任何 NumPy `ndarray` 对象被作为 RNG 状态序列化。PyTorch CPU 状态是一个字节张量。后续抽样在不修改已保存状态的前提下受到控制。

## 证据解读与容差

`verification-cpu.json` 是来自该版本一次真实运行的公开证据。`source` 包含脚本和 CSV 的 SHA-256。`protocol` 描述四个进程、精度和容差。`resume_boundary` 验证每个 RNG 的下一次抽样，以及中断后使用的下一个学习率。

比较要求行顺序相同、进度相同、调度器状态相同。权重、优化器状态、损失、MSE 和学习率所接受的最大绝对误差为 **1e-12**，不使用相对容差（`rtol=0`）。报告会保留测得的误差，即使它们为零。它还会在两条路径结束时验证 RNG 的下一次抽样。

负向对照必须表明，遗漏 RNG 会改变结果。其 MSE 可能更低或更高：此测试验证的是恢复轨迹，而不是质量排名。因此，预期中的偏差会在该子测试中给出 `passed: false` 和 `divergence_detected: true`；此时整体协议仍可通过。

## 只加载自己的检查点

加载器显式使用 `torch.load(..., map_location="cpu", weights_only=True)`，并且不提供任何回退到 `weights_only=False` 的选项。它先验证相关指纹，限制大小，并检查模式、版本、代码和数据。它会拒绝不完整的状态，而不是静默地重新初始化训练的一部分。

请仅使用**你通过本练习创建并保管在自己控制之下**的检查点。指纹用于检测修改；它并不验证发送方身份。受限加载并不会让未知文件变得可信。参见 [torch.load](https://docs.pytorch.org/docs/2.11/generated/torch.load.html) 和 [PyTorch 序列化](https://docs.pytorch.org/docs/2.11/notes/serialization.html)。

## 将练习适配到你的项目

找出你自己的训练实际会消耗哪些状态：sampler、数据增强、优化器、调度器和特定生成器。如果你使用 AMP，请在一致的边界处加入 scaler 状态；本练习没有这样做。分布式训练还需要处理其进程及数据划分。

不要从这个小证据推断出针对不同模型的租用时长、吞吐量、VRAM 占用或恢复保证。请沿用该方法：有代表性的短数据集、在工作进行到一半时中断、另一个进程、显式比较和负向对照。

## 内容与许可证

- `train.py`、`verify_resume.py`、本文档和清单：MIT 许可证，参见 `LICENSE-MIT.txt`。
- `data.csv`：原创合成数据，以 CC0 1.0 提供，参见 `DATA-LICENSE-CC0.txt`。
- `verification-cpu.json`：本练习的测量结果，不含个人数据、完整环境、本机路径、令牌或会话标识符。
- `manifest.json`：所分发文件及其 SHA-256 的准确列表。清单不引用自身。
- `SOURCES.md`：官方链接和文档限制。

PyTorch、NumPy 和 Python 依赖保留各自的许可证。它们不会在 ZIP 中再分发。


## Kernodeck 介绍与项目兼容性

本次 2026 年 9 月 25 日的重新发布更新了归档名称、文档和品牌。脚本 `train.py` 和 `verify_resume.py`、CSV 以及 `verification-cpu.json` 与 2026 年 9 月 24 日执行的交付版本保持一致。技术字段 `project` 保留其标识符，以供现有报告读取程序使用。本次重新发布未重新运行任何 CPU/GPU 计算或检查。
