Skip to content

trainHydra: metric_frames_per_episode: auto, and warn on empty prompts - #671

Draft
RyanPCo wants to merge 1 commit into
ryanco/proprio-per-step-framefrom
ryanco/opscale-ladder
Draft

RyanPCo wants to merge 1 commit into
ryanco/proprio-per-step-framefrom
ryanco/opscale-ladder

Conversation

@RyanPCo

@RyanPCo RyanPCo commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

Adds an opt-in metric_frames_per_episode: auto for val heads and a one-time warning when a sample falls back to an empty prompt.

Behaviour changes

None by default. auto is opt-in, explicit ints keep their meaning, and no shipped config uses it yet. The prompt change is a log line only.

metric_frames_per_episode: auto

  • trainHydra computes K = floor(limit_val_batches * batch_size / episodes) per head and dataset, from the resolved split and that head's loader batch_size, then scales by world size as before. K follows the live filters instead of a hand count that goes stale when a split is defined by SQL filters rather than an episode pin.
  • limit_val_batches=0 (validation off) subsamples nothing.
  • A non-int limit_val_batches, or a missing batch size or split, raises.

Other changes

  • DeterministicEvalMixin._build_prompts warns once when a sample has no annotation and default_prompt is empty, so the text stem silently sees ''.
  • mecka_fold_freeform_opsplit_6d stays frozen. It has no annotation guard (112 of its 462 episodes have segments = NULL), but checkpoints were trained on it. Its header now says so.

The operator-scaling ladder data configs (k = 1/2/4) and their test are kept out of this PR.

Tests

tests/unit/test_eval_loaders.py::test_auto_k_is_derived_from_the_resolved_split covers the formula, the world-size scaling, the limit_val_batches=0 pass-through and the error cases.

🤖 Generated with Claude Code

https://claude.ai/code/session_01HjCQBqQCr2igFEMR7yUovw

RyanPCo commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@RyanPCo
RyanPCo force-pushed the ryanco/opscale-ladder branch from f50f94c to c9c284f Compare September 20, 2026 19:09
@RyanPCo
RyanPCo force-pushed the ryanco/proprio-per-step-frame branch 2 times, most recently from 3f17dfa to c76a447 Compare September 21, 2026 18:45
@RyanPCo
RyanPCo force-pushed the ryanco/opscale-ladder branch 2 times, most recently from 72d026d to bbac4a0 Compare September 22, 2026 13:18
@RyanPCo
RyanPCo force-pushed the ryanco/proprio-per-step-frame branch from c76a447 to 865520b Compare September 22, 2026 13:18
@RyanPCo
RyanPCo force-pushed the ryanco/opscale-ladder branch from 05f1e3e to bbbf371 Compare October 12, 2026 23:19
@RyanPCo
RyanPCo force-pushed the ryanco/proprio-per-step-frame branch from b97f495 to 61037b6 Compare October 12, 2026 23:19
@RyanPCo RyanPCo mentioned this pull request Oct 19, 2026
@RyanPCo
RyanPCo force-pushed the ryanco/proprio-per-step-frame branch from 61037b6 to 97bea62 Compare October 19, 2026 19:47
@RyanPCo
RyanPCo force-pushed the ryanco/opscale-ladder branch from bbbf371 to 8ac8f46 Compare October 19, 2026 19:47
@RyanPCo
RyanPCo force-pushed the ryanco/proprio-per-step-frame branch from 97bea62 to 635b94a Compare October 19, 2026 20:22
@RyanPCo
RyanPCo force-pushed the ryanco/opscale-ladder branch from 8ac8f46 to 4098a1c Compare October 19, 2026 20:22
@RyanPCo
RyanPCo force-pushed the ryanco/proprio-per-step-frame branch from 635b94a to 7d794a9 Compare October 30, 2026 18:27
@RyanPCo
RyanPCo force-pushed the ryanco/opscale-ladder branch from 4098a1c to 256238b Compare October 30, 2026 18:27
@RyanPCo RyanPCo changed the title data: the mecka freeform folding operator-scaling ladder (k = 1/2/4) trainHydra: metric_frames_per_episode: auto, and warn on empty prompts Oct 30, 2026

@RyanPCo RyanPCo left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated adversarial review (read-only; findings were checked by a second skeptical pass before posting): 1 high.

Comment thread egomimic/trainHydra.py
f"resolved split; got limit_val_batches={limit!r}, "
f"batch_size={batch_size!r}, episodes={n_episodes!r}"
)
k = max(1, limit * int(batch_size) // n_episodes)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high (correctness): When val_dataloader returns a list (the default, since train_viz is on), the val loaders get no DistributedSampler (#666 and #673 rely on this). Scaling K by _trainer_world_size therefore makes every rank read the same first limit_val_batches*batch_size frames of an episode-major set that is W times that size. On 8 GPUs, Valid/* and unseen_op_valid/* end up scoring only ~1/8 of the episodes, which defeats the per-episode subsampling, and the metrics change with GPU count. The multiplier predates this PR, but auto builds it into the recommended path. Drop the world-size factor whenever the metric loaders are unsharded (or shard them explicitly), and make the _trainer_world_size/_metric_frames_per_episode docstrings agree with EvalVideo._video_fps.

… empty prompt

The metric budget can be 'auto': trainHydra derives K = floor(limit_val_batches *
batch_size / episodes) per head from the resolved split, so K follows the live
filters instead of a hand count that goes stale when SQL grows (or when
limit_val_batches or the batch size change); limit_val_batches=0 (validation
off) subsamples nothing. Explicit ints keep their meaning, so the flagship
recipes that pin K are untouched.

mecka_fold_freeform_opsplit_6d has no annotation guard and stays frozen; its
header now says so, and HPT warns once when a sample falls back to an empty
default_prompt, as Pi does.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01HjCQBqQCr2igFEMR7yUovw
@RyanPCo

RyanPCo commented Oct 30, 2026

Copy link
Copy Markdown
Contributor Author

Review findings: status after the fixup pass. The fixes are squashed into this PR's commits, and the whole stack was force-pushed.

Fixed

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