Experiment の復帰と cleanup#
ommx.experiment は、最適化の試行錯誤を 1 つの OMMX Artifact として記録するための API です。Experiment のデータモデル、実行できる logging 例、共有、確認、fork については 実験を記録して共有する を参照してください。
このページでは、失敗時の挙動に絞って説明します。Experiment が commit される前に何が書かれるのか、checkpoint からどう復帰するのか、Local Registry cleanup がどの blob を削除可能と判断するのかを扱います。
保存の境界#
Experiment のデータは 3 つの層に分かれて保存されます。
層 |
保存先 |
役割 |
|---|---|---|
Blob |
Local Registry の content-addressed file |
Attachment、Instance、Solution、run parameters、config、manifest の bytes |
Manifest |
OCI Image Manifest blob |
1 つの immutable な OMMX Artifact を構成する blob 一覧 |
Ref |
Local Registry index の SQLite rows |
manifest を到達可能にする名前または checkpoint pointer |
このページで publish と呼ぶのは、Local Registry の ref を更新して、 すでに書き込まれた manifest を指すようにする操作です。これは local SQLite 上の操作であり、Artifact を remote container registry に push することでは ありません。
log_json() や log_solve() のような logging method は、payload bytes をすぐ Local Registry に書き込みます。Experiment の最後まで全データをメモリに保持してから一括保存するわけではありません。同じ内容が既に存在する場合は既存の CAS blob を再利用し、その modification time を更新します。これにより、最近の active write は GC の grace period で保護されます。
正常に commit() すると、Experiment config と root manifest が書かれ、requested image reference が SQLite に publish されます。ref の publish は payload blob を書き直しません。この順序のため、process が途中で終了すると、どの manifest や ref からも到達できない blob file が残ることがあります。そのような blob は Local Registry GC の対象になります。
Run context と Experiment commit#
Run は context manager として使ってください。Run は 1 つの試行であり、
Run を close することが、その close 済み Run を親 Experiment の未 commit 状態へ
追加する復帰境界になります。Run が close された後、OMMX はその親 Experiment の
draft checkpoint を書き込み、checkpoint ref を publish します。
一方、Experiment は必ずしも context manager として使う必要はありません。 notebook では、1 つの Experiment を複数 cell にまたがって開いたままにするのが 自然な workflow です。1 つの Run を実行し、その結果を可視化・考察し、 次の条件を決めて別の Run を開始し、人間の workflow が終わった時点で明示的に commit します。
from ommx.experiment import Experiment
image_name = "ghcr.io/example/team/experiment:baseline"
experiment = Experiment(image_name)
experiment.log_json("dataset", {"name": "demo"})
with experiment.run() as run:
run.log_parameter("capacity", 47)
# 結果を確認し、plot し、次の条件を決める。
with experiment.run() as run:
run.log_parameter("capacity", 64)
artifact = experiment.commit()
すべての Run があらかじめ決まっている batch script では、
with Experiment(...) は便利な書き方です。正常終了時には commit() を呼び、
例外終了時には成功用の image reference を進めず failed または interrupted
checkpoint を publish します。
操作または event |
保存される状態 |
|---|---|
|
close 済み Run が status |
|
close 済み Run が status |
|
final Experiment が commit され、requested image reference が publish されます。その Experiment の local checkpoint があれば削除されます。 |
|
block 末尾で |
|
成功用の requested image reference は進みません。status |
Run close 後、 |
Run close 後に作られた最新の Experiment draft checkpoint から復帰します。 |
open |
その open Run が書いた payload blob は存在する可能性がありますが、復帰可能な Run state には含まれません。復帰地点は、その Run より前の最新 checkpoint です。 |
KeyboardInterrupt は Run / Experiment ともに "interrupted" として記録されます。それ以外の例外は "failed" として記録されます。
Experiment を context manager として使わない場合、Run の外側で起きた例外は
failed Experiment checkpoint を自動 publish しません。通常の interactive workflow
では、探索中は Run close 後に作られる Experiment draft checkpoint によって復帰可能性を確保し、
Experiment を公開できる状態になった時点で明示的に
commit() します。
Checkpoint から復帰する#
checkpoint から復帰するには、元の Experiment image name を渡します。
from ommx.experiment import Experiment
image_name = "ghcr.io/example/team/experiment:baseline"
experiment = Experiment.restore_from_checkpoint(image_name)
with experiment.run() as run:
run.log_parameter("capacity", 64)
artifact = experiment.commit()
checkpoint ref は元の image name から導出される internal Local Registry ref です。通常の Artifact handle としては公開されないため、復帰したい Experiment では元の image name を保持してください。
restore された Experiment は未 commit の Experiment なので、新しく作った
Experiment と同じように notebook cell をまたいで開いておけます。commit() を
呼ぶと元の requested image reference に publish され、checkpoint は削除されます。
restore 後の Experiment を context manager として使い、そこで再び失敗した場合は、
成功用の image reference を進めず、新しい failed または interrupted checkpoint が
publish されます。
失敗後の到達可能性#
Local Registry cleanup は SQLite refs からの到達可能性で判断します。
Data |
到達可能か |
cleanup の挙動 |
|---|---|---|
commit 済み Experiment image ref |
Yes |
|
Experiment checkpoint ref |
Yes |
|
fork 先 Experiment から OCI |
child ref が保持されていれば Yes |
|
anonymous artifact refs |
ref が存在する間は Yes |
|
manifest/ref publish 前に process が終了して残った blob |
No |
grace period を過ぎると |
実行中 process が書いている blob |
checkpoint または commit されるまでは通常 No |
|
OMMX は SQLite に orphan table を作りません。orphan は GC report のたびに refs と manifests を辿って reachable set を作り、それを Local Registry の CAS file と比較して計算します。
Cleanup workflow#
cleanup command はまず report mode で実行してください。
ommx prune-anonymous
ommx gc
どちらもデフォルトでは dry-run で、registry を変更するのは --delete 指定時だけです。
ommx prune-anonymous --delete
ommx gc --delete
同じ操作は Python SDK からも実行できます。Python API は整形済みの CLI output ではなく、 structured report を返します。
from ommx.artifact import gc, prune_anonymous
prune_report = prune_anonymous()
gc_report = gc()
prune_deleted = prune_anonymous(delete=True)
gc_deleted = gc(delete=True)
default 以外の Local Registry を調べる場合は root=...、GC の grace period を
変える場合は grace_period="2h" を指定します。
一時的な Artifact build や名前なし archive import から anonymous Artifact ref が残っている場合は、先に ommx prune-anonymous を実行します。この command は該当する SQLite refs だけを削除し、blob は unlink しません。その blob は、他の ref から到達できなければ ommx gc で回収可能になります。
ommx gc は mark-sweep を行います。
root は Experiment checkpoint refs を含むすべての SQLite refs です。
到達可能な manifest ごとに、manifest blob、config blob、layer blobs、OCI
subjectmanifest chain を mark します。mark されなかった blob file は unreachable です。
unreachable かつ
--grace-periodより古い blob は orphan candidate として report されます。unreachable だが
--grace-periodより新しい blob は deferred として report されます。--delete指定時は orphan candidate だけを unlink し、削除直前にも各 candidate を再確認します。
default grace period は 24h です。s、m、h、d suffix を指定できます。
ommx gc --grace-period 2h
ommx gc --grace-period 0s
0s は、その registry に書き込み中の OMMX process がないと分かっている場合だけ使ってください。共有 registry や default Local Registry では、open Run や interrupted import の書き込みを消さないよう、非ゼロの grace period を残してください。
通常の report は raw digest ではなく件数と byte size を表示します。特定の missing、invalid、orphan、deferred blob を調べる場合は --show-digests を追加します。
ommx gc --show-digests
ommx gc --delete --show-digests
default 以外の Local Registry を調べる、または掃除する場合は --root <path> を指定します。