# Kernodeck Reprise v1 — 実際に再開されたチェックポイント

このオリジナルの演習では、24行の合成データを使って小さな数値的関係を学習します。その目的は、**トレーニングの再開を検証する**ことであり、最良のモデルを得たり、GPUを測定したりすることではありません。計算は明示的に**CPU**上で、`float64`で、PyTorchのスレッド1本で強制されます。

検証では、10ステップ連続の実行と、5ステップ、チェックポイント、そして**別のPythonプロセス**での新たな5ステップを比較します。4つ目のプロセスは乱数生成器の復元を意図的に省略します。そのドリフトが検出されなければなりません。リモートリソース、顧客データ、事前学習済みの重みは一切ダウンロードされません。

## 前提条件

- PyTorchとNumPyがすでにインストールされたPython環境。提供された証跡は**Python 3.14.6、PyTorch 2.11.0+cu128、NumPy 2.4.4**で実行されました。
- 4つの小さな出力フォルダ用に約1 MBの空き容量。Pythonの依存関係はそれ自体の領域を使用します。
- コマンドは展開した `kernodeck-reprise-v1` フォルダから実行してください。

接尾辞 `+cu128` はテスト時に存在したパッケージを表すものであり、この演習がCUDAを使用したことを意味するものではありません。**CUDA、ROCm、AMP、マルチGPU、分散のいずれの計算もこのリソースでは検証されません。**DataLoaderのワーカーも使用しません。別の環境では独自の証跡を生成する必要があり、バージョンやプラットフォーム間での一致は保証されません。

## 検証コマンド

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

`-B` はプロジェクトフォルダ内のバイトコードキャッシュを回避します。出力ディレクトリは新規でなければなりません。既存の試行は上書きされません。やり直すには、例えば `runs/preuve-cpu-2` を使用してください。

このプログラムは同じPythonインタープリタで4つのコマンドを実行し、その後 `runs/preuve-cpu/verification.json` を書き込みます。完全な実行では次のようになります。

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

終了コードは、プロトコルが成功した場合は**0**、比較が失敗した場合は**1**、検証を完了できなかった場合は**2**です。成功には、肯定的な再開と、否定的な検証の観察可能な失敗の両方が必要です。チェックポイントファイルが単に存在するだけでは十分ではありません。

## 3つのステップを手動で実行する

```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` は**追加ステップ数**を意味するため、3番目のコマンドはステップ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` には2変数のグリッドと合成ターゲットが含まれています：`target = 0.7*x1 - 0.4*x2 + 0.15*x1*x2 + 0.1`。これはいかなる顧客の測定値も模倣していません。ネットワークは2つの入力、8ニューロンの層、`Tanh`、0.25のドロップアウト、および出力で構成され、合計33個のパラメータを持ちます。

トレーニングではAdamを初期学習率0.03で使用します。StepLRはこの学習率を3ステップごとに半分にします。各バッチは4行で構成されるため、10ステップで40個の観測値を消費し、最初のエポック以降は一部の行を再び巡回します。順列、エポック、カーソル、消費された観測値の数が保存されます。5ステップ後の中断時点で、カーソルは24のうち20です。再開は**データ巡回の途中**で行われます。

3つの乱数源が処理に影響します：Pythonは入力に対するわずかなゲインを設定し、NumPyのPCG64ジェネレータはノイズと順列を生成し、PyTorchはドロップアウトを生成します。初期シードを再度設定しても、中断時に到達した状態は再現されません。

## チェックポイントが保持する内容と、それが読み戻される順序

辞書には重み、Adam の状態、StepLR の状態、データの進行状況、3 つの 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` には 4 つのプロセス、精度、許容差が記述されています。`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、augmentation、オプティマイザー、スケジューラー、特定のジェネレーターなどです。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 の計算および検証は一切再実行していません。
