Skip to content

Add resumable checkpoints to BenchmarkRunRecorder - #161

Merged
dylanuys merged 2 commits into
devfrom
fix/checkpoint-resume
Sep 21, 2026
Merged

dylanuys merged 2 commits into
devfrom
fix/checkpoint-resume

Conversation

@dylanuys

@dylanuys dylanuys commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

A restarted benchmark currently loses the predictions held by BenchmarkRunRecorder. This adds opt-in checkpoint/restore directly to that recorder, preserving the existing run ID, prediction rows, start timestamp, dataset counters, metric functions, and parquet output.

Integration

  • BenchmarkRunRecorder.checkpoint() persists pending rows; reopening a recorder with the same run and context restores them through the same row/counter update path used during inference.
  • is_checkpointed() uses the existing build_sample_id() helper. Predictions are distinguished by existing fields: run_id, dataset_name, iteration_index, sample_id, and aug_pass. There is no separate work ID or alternate prediction schema.
  • The append-only storage helper is internal to benchmarks/_checkpoint.py. Atomic batch files and a checksummed commit head distinguish committed records from interrupted writes. Incompatible manifests, corrupt/missing committed batches, cross-run rows, and conflicting replay fail explicitly.
  • Skips and errors now retain the existing augmentation-pass field too; shared batch inference forwards it on errors so base and augmented failures cannot collide.
  • Benchmark package exports follow the package root's lazy-import precedent, allowing recorder recovery and scoring without importing inference backends. Existing public exports are preserved.

Scope and follow-ups

This is PR 1 of resumable benchmarks. Existing callers do not enable checkpointing yet. The next PR will connect it through shared tracker creation and inference, freeze the full sample/configuration manifest, and skip committed samples. bmcore follow-ups will add isolated Modal Volume mounts, replacement sandboxes, worker recovery, stale-run reconciliation, and idempotent finalization.

Checkpoint callers must supply a stable run ID, complete benchmark context (model/evaluator identity, source revisions, sample plan, seed, and scoring settings), and a filesystem-specific persistence callback when local fsync is insufficient. Recorder configuration is included automatically. One coordinator must own each run directory; distributed locking is not provided here. Checksums detect corruption, not malicious alteration of miner-controlled output.

Validation

  • 69 tests passed: checkpoint crash/replay tests, recorder recovery tests, and existing weighted-metric, multiclass-metric, and inference-session tests.
  • Child-process exits cover interruption before batch publication, before head publication, and after commit.
  • Resumed and uninterrupted recorders produce matching DataFrames (including column order), dataset summaries, metrics, and parquet output.
  • Tests distinguish identical samples across datasets, planned sample indices, and base/augmentation passes, and reject changed run/recorder configuration.
  • Full ruff check src tests and git diff --check passed.
  • Recorder imports without torch, torchvision, or transformers. Lightweight CI runs storage tests and recorder integration tests.

Modal Volume durability and end-to-end sandbox interruption recovery remain for the integration PRs; this PR verifies the recorder/storage contract locally.

@dylanuys dylanuys changed the title Add durable checkpoint storage for resumable benchmarks Add resumable checkpoints to BenchmarkRunRecorder Sep 21, 2026
@dylanuys
dylanuys merged commit b8f801b into dev Sep 21, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant